ios opengl es 2模板缓冲区无法正常工作

时间:2014-01-04 01:36:17

标签: ios opengl-es glkit stencil-buffer

AppDelegate.h

#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
#import <GLKit/GLKMath.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, GLKViewDelegate, GLKViewControllerDelegate> {
    GLKTextureInfo *icon, *logo, *mask;
    GLKMatrixStackRef mvStack;
}
@property int xCord;
@property GLKBaseEffect* effect;
@property (strong, nonatomic) UIWindow *window;
@end

AppDelegate.mm

#import "AppDelegate.h"
#include "pthread.h"
#include <string>
#include <OpenGLES/ES2/gl.h>

@implementation AppDelegate

GLKTextureInfo* loadTexture(std::string fileName)
{
    NSError *error;

    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil];

    NSString *path = [[NSBundle mainBundle] pathForResource:[NSString stringWithCString:fileName.c_str() encoding:[NSString defaultCStringEncoding]] ofType:nil];

    FILE * f = fopen([path cStringUsingEncoding:1 ], "rb");
    fseek(f,0,SEEK_END);
    const int sz = ftell(f);
    unsigned char buffer[sz];
    fseek(f, 0,SEEK_SET);
    fread(buffer, sz, 1, f);

    fclose(f);

    NSData * data = [NSData dataWithBytes:buffer length:sz ];

    GLKTextureInfo* texture = [GLKTextureLoader textureWithContentsOfData:data options:options error:&error];
    if (error) {
        NSLog(@"Error loading texture from image: %@",error);
        return nil;
    }
    return texture;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    CGRect bound = [UIScreen mainScreen].bounds;

    EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    [EAGLContext setCurrentContext:context];

    GLKView *view = [[GLKView alloc] initWithFrame:bound context:context];
    view.delegate = self;

    GLKViewController *controller = [[GLKViewController alloc] init];
    controller.delegate = self;
    controller.view = view;
    controller.preferredFramesPerSecond = 60;

    self.window = [[UIWindow alloc] initWithFrame:bound];
    self.window.rootViewController = controller;
    [self.window makeKeyAndVisible];

    _effect = [[GLKBaseEffect alloc] init];
    _effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(0,view.bounds.size.width, view.bounds.size.height,0,1,-1);

    NSLog(@"width = %f, height = %f", view.bounds.size.width,view.bounds.size.height);

    logo = loadTexture("logo.png");
    mask = loadTexture("mask.png");

    mvStack = GLKMatrixStackCreate(NULL);
    GLuint depthRenderbuffer;
    glGenRenderbuffers(1, &depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, view.bounds.size.width,view.bounds.size.height);
    return YES;
}

- (void)glkViewControllerUpdate:(GLKViewController *)controller 
{
}

- (void) drawImage:(GLKTextureInfo*)img x:(float)x  y:(float)y 
{
    GLKMatrixStackPush(mvStack);
    GLKMatrixStackTranslate(mvStack, x, y, 0);
    float imgVert[4][2] = {
        {0,0},
        {0,1},
        {1,1},
        {1,0},
    };
    float w = img.width;
    float h = img.height;
    float w2 = w/2;
    float h2 = h/2;
    float vertices[4][2] = {
        {-w2, h2},
        {-w2,-h2},
        {w2,-h2},
        {w2,h2}
    };

    _effect.texture2d0.enabled = YES;
    _effect.texture2d0.name = img.name;
    _effect.transform.modelviewMatrix = GLKMatrixStackGetMatrix4(mvStack);
    [_effect prepareToDraw];

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(GLKVertexAttribTexCoord0,2,GL_FLOAT,GL_FALSE,0,imgVert);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableVertexAttribArray(GLKVertexAttribPosition);
    glDisableVertexAttribArray(GLKVertexAttribTexCoord0);

    _effect.texture2d0.enabled = NO;
    GLKMatrixStackPop(mvStack);
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{
    glEnable(GL_BLEND);
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    glClearStencil(0);
    glStencilMask(1);
    glEnable ( GL_STENCIL_TEST );

    glClearColor(0,1 , 0.5, 0.5);
    glClear(GL_COLOR_BUFFER_BIT  | GL_STENCIL_BUFFER_BIT);

    glColorMask ( GL_FALSE , GL_FALSE , GL_FALSE , GL_FALSE );
    glStencilFunc ( GL_ALWAYS , 1 , ~0);
    glStencilOp ( GL_REPLACE , GL_REPLACE , GL_REPLACE );

//    [self drawImage:mask x:300 y:100];

    float vertices[3][2] = {
        {200, 150},
        {400,150},
        {300,50}
    };

    _effect.transform.modelviewMatrix = GLKMatrix4Identity;
    [_effect prepareToDraw];
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 3);
    glDisableVertexAttribArray(GLKVertexAttribPosition);

    glColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE );
    glStencilFunc ( GL_EQUAL , 1 , ~0);
    glStencilOp ( GL_KEEP , GL_KEEP , GL_KEEP );

    [self drawImage:logo x:300 y:100];
}
@end

使用模板缓冲区进行一些简单的测试。我首先尝试将mask.png绘制到模板缓冲区并屏蔽logo.png中的某些部分。但它不起作用。然后我想也许在模板缓冲区中使用纹理可能有问题,所以我从使用蒙版图像切换到白色三角形,但它也不起作用....

@mobob:谢谢,它有效:D view.drawableStencilFormat = GLKViewDrawableStencilFormat8;

0 个答案:

没有答案