2

OpenGL ES 2.0 と GLKit を使用して 2D ゲームをコーディングしています。私のアーキテクチャは、Ian Terrel チュートリアルによる Games に基づいています。

最近、GLKBaseEffect (シンプルなシェーダー管理を提供) がリークし、アプリがクラッシュすることがあることがわかりました。現在、独自のシェーダー ファイル (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

ご覧のとおり、Vertices 配列と基本色でテストしていますが、違いはありません。glClearColor (0, 104.0/255.0, 55.0/255.0, 1.0);のおかげで私のビューは緑色であるため、OpenGl は正しく設定されているようです。レンダリング機能で。

ここに pastebin のファイル:

ペーストビンの P3Shape.m

そして、ogl プログラムを作成するマネージャー

ペーストビンの P3GameManager.m

何か案は ?

編集:おそらく私のシェーダーに問題がありますか?

バーテックス :

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
}
4

1 に答える 1

1

セットアップを簡素化するために、GLKViewController と GLKView を使用することをお勧めします。同様に、テクスチャの読み込みを GLKTextureLoader に置き換えます。

GLKBaseEffect がメモリをリークしてクラッシュを引き起こすという問題は見たことがありません。この特定の問題について新しい質問を投稿し、カスタム シェーダーが必要ない場合は GLKBaseEffect の使用に戻ることをお勧めします (必要ないようです)。コードの管理とデバッグがはるかに簡単になります。

于 2012-09-11T23:04:21.597 に答える