2012-08-24 157 views
2

我正在用OpenGL ES 2.0和GLKit編碼2D遊戲。我的架構基於Ian Terrel的遊戲教程。OpenGL ES 2.0和GLKit:從GLKBaseEffect着色器到OpenGl

我最近發現GLKBaseEffect(提供了簡單着色器mgmt)泄漏,並且使得我的應用程序有時會崩潰。我現在使用我自己的着色器文件(基於Ray Wenderlich教程),但是現在我已經成功顯示了openGl背景顏色。我的形狀顏色和紋理不再顯示。

重要事項:我當時嚴重地設置了當前上下文,現在openGL說無效Drawable。

這裏是我的shape.m代碼的一部分:

@implementation P3Shape 

const GLushort indices[] = { 
    0,1,2,3 
}; 

typedef struct { 
    float Position[2]; 
    float Color[4]; 
    float TexCoord[2]; 
} Vertex; 

//testing 
const Vertex Vertices[] = { 
    // Front 
    {{10, -15}, {1, 0, 0, 1}, {1, 0}}, 
    {{10, 15}, {0, 1, 0, 1}, {1, 0}}, 
    {{-10, 10}, {0, 0, 1, 1}, {0, 0}}, 
    {{-10, -1}, {0, 0, 0, 1}, {0, 1}}, 
}; 

- (id)initWithLayer:(CAEAGLLayer *)layer { 
    self = [super init]; 
    if (self) { 
     [...] 
     _currentContext = [P3SessionState currentContext]; 
     _eaglLayer = layer; 
     _eaglLayer.opaque = YES; 
     [self setupRenderBuffer];   
     [self setupFrameBuffer]; 
     [self addToProgram]; 
     [self createBuffers]; 
    } 
    return self; 
} 


- (int)numVertices { 
    return 0; 
} 

- (void) addToProgram { 
    // setted before in the gamemanager 
    GLuint programHandle = [P3SessionState programHandle]; 

    _positionSlot = glGetAttribLocation(programHandle, "Position"); 
    _colorSlot = glGetAttribLocation(programHandle, "SourceColor"); 

    _projectionUniform = glGetUniformLocation(programHandle, "Projection"); 
    _modelViewUniform = glGetUniformLocation(programHandle, "Modelview"); 

    _texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn"); 
    _textureUniform = glGetUniformLocation(programHandle, "Texture"); 
} 

- (void)setupRenderBuffer { 
    glGenRenderbuffers(1, &_colorRenderBuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);   
    [_currentContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];  
} 

- (void)setupFrameBuffer {  
    GLuint framebuffer; 
    glGenFramebuffers(1, &framebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderBuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer); 
} 

- (void)createBuffers { 
    // Static index data 
    glGenBuffers(1, &indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); 

    glGenBuffers(1, &vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 
} 

// initialize the vertex data 

- (GLKVector2 *)vertices { 
    if (vertexData == nil) { 
     vertexData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.numVertices]; 
    } 
    return [vertexData mutableBytes]; 
} 

// set a textureImage, allocate a glname and enable the GL_TEXTURE_2D and all 
- (void)setTextureImage:(UIImage *)image { 
    CGImageRef spriteImage = image.CGImage; 
    if (!spriteImage) { 
     NSLog(@"Failed to load image %@", image); 
     exit(1); 
    } 

    size_t width = CGImageGetWidth(spriteImage); 
    size_t height = CGImageGetHeight(spriteImage); 

    GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte)); 

    CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);  

    CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage); 

    CGContextRelease(spriteContext); 

    GLuint texName; 
    glGenTextures(1, &texName); 
    glBindTexture(GL_TEXTURE_2D, texName); 

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); 

    free(spriteData);   
    _imageTexture = texName; 
}  

- (GLKVector2 *)textureCoordinates { 
    if (textureCoordinateData == nil) 
     textureCoordinateData = [NSMutableData dataWithLength:sizeof(GLKVector2)*self.numVertices]; 
    return [textureCoordinateData mutableBytes]; 
} 


- (void)render { 

    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glUniformMatrix4fv(_modelViewUniform, 1, 0, modelview.m); 
    glUniformMatrix4fv(_projectionUniform, 1, 0, projectionMatrix.m); 

    glEnableVertexAttribArray(_positionSlot); 

    glEnableVertexAttribArray(_colorSlot); 
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); 

    glVertexAttribPointer(_positionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 
    glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3)); 
    if(texture != nil) { 
     glEnableVertexAttribArray(_texCoordSlot); 
     glActiveTexture(GL_TEXTURE0); // unneccc in practice 
     glBindTexture(GL_TEXTURE_2D, _imageTexture); 
     glUniform1i(_textureUniform, 0); // unnecc in practice 
     glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); 
    } 

     glDrawElements(GL_TRIANGLE_FAN, sizeof(indices)/sizeof(GLushort), GL_UNSIGNED_SHORT, (void*)0); 
    } 
    //is cleanup code that tells the shader that we’re done using vertex position data. 
    glDisableVertexAttribArray(GLKVertexAttribPosition); 

    if (texture != nil) 
     glDisableVertexAttribArray(GLKVertexAttribTexCoord0); 

    [_currentContext presentRenderbuffer:GL_RENDERBUFFER]; 

    glDisable(GL_BLEND); 
} 

// draw the shape in the selected scene 
- (void)renderInScene:(P3Scene *)theScene { 

    projectionMatrix = [theScene projectionMatrix]; 

    modelview = GLKMatrix4Multiply(GLKMatrix4MakeTranslation(0, 0, 0), GLKMatrix4MakeRotation(0, 0, 0, 1)); 
    modelview = GLKMatrix4Multiply(modelview, GLKMatrix4MakeScale(scale.x, scale.y, 1)); 

    [self render]; 
} 

-(void)update:(NSTimeInterval)dt { 
    if(self.toDraw) 
     [spriteAnimation update:dt]; 
} 

@end 

正如你所看到的,我用一個頂點數組和基本顏色測試,但它並沒有區別。 OpenGL似乎設置正確,因爲我的視圖是綠色的,這要歸功於glClearColor(0,104.0/255.0,55.0/255.0,1.0)。渲染功能中的

這裏對引擎收錄的文件:

P3Shape.m on pastebin

又是誰創造OGL程序

P3GameManager.m on pastebin

任何想法經理?

編輯:也許我的着色器有問題?

頂點:

attribute vec4 Position; 
attribute vec4 SourceColor; 

varying vec4 DestinationColor; 

uniform mat4 Projection; 
uniform mat4 Modelview; 

attribute vec2 TexCoordIn; // New 
varying vec2 TexCoordOut; // New 

void main(void) { 
    DestinationColor = SourceColor; 
    gl_Position = Projection * Modelview * Position; 
    TexCoordOut = TexCoordIn; // New 
} 

和片段:

varying lowp vec4 DestinationColor; 

varying lowp vec2 TexCoordOut; // New 
uniform sampler2D Texture; // New 

void main(void) { 
    gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); // New 
} 
+0

Checked glGetError? – Tim

+0

我在我的主循環中嘗試過glGetError,它總是返回GL_NO_ERROR。 –

+0

同樣的結果,如果我評論該行: [_currentContext presentRenderbuffer:GL_RENDERBUFFER]; 這裏可能有問題嗎? –

回答

1

我建議使用GLKViewController和GLKView簡化設置。同樣,用GLKTextureLoader代替你的紋理加載。

我還沒有看到GLKBaseEffect泄漏內存並導致崩潰的任何問題。我建議發佈一個關於這個特定問題的新問題,並且如果你不需要自定義着色器(看起來你沒有),那麼返回使用GLKBaseEffect。將使您的代碼更容易管理和調試。