3

CAEAGLayer をレイヤーとして使用する UIView を使用する iPhone アプリケーションを作成しています。1 つの小さな問題を除けば、すべて問題なく動作しています。EXC_BAD_ACCESS と次のスタック トレースでクラッシュすることがあります。

    [EAGLView draw]
    glDrawArrays_Exec
    PrepareToDraw
    DrawFramebufferMakeResident
    AttachmentMakeResident
    TextureMakeResident
    memmove

次の行でクラッシュします。

    glVertexPointer(3, GL_FLOAT, 0, vertexCoordinates);
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoordinates);
    glBindTexture(GL_TEXTURE_2D, textures[kActiveSideLeft]);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, totalPoints); //<--Crash here

アプリケーションがクラッシュするのは、インターフェイスの回転が変更されたときだけです (これは、ビュー フレームが変更されたときの唯一のケースでもあります)。頻繁にクラッシュすることはありません。ほとんどの場合、この問題を再現するには、デバイスを回転させるのに 3 ~ 5 分かかります。
私はCAEAGLLayerの初期化/フレーム変更に関連する間違いを犯していると思います.それはそれがクラッシュする場所だからです(私は信じています).
init と layout サブビューのメソッドは次のとおり
です。

    ...
    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;     
    eaglLayer.opaque = TRUE;

    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
    if (!context || ![EAGLContext setCurrentContext:context])
    {
        [self release];
        return nil;
    }

    glGenFramebuffersOES(1, &defaultFramebuffer);
    glGenRenderbuffersOES(1, &colorRenderbuffer);
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
    ...

セット フレームでは、GL_MODELVIEW と GL_POJECTION のマトリックスのみを設定しているので、悪いことは何も起こらないと思います。
レイアウトサブビュー:

    - (void)layoutSubviews
    {
      [EAGLContext setCurrentContext:context];

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);

        NSAssert1(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) == GL_FRAMEBUFFER_COMPLETE_OES, @"Failed to make complete framebuffer object: %X", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    }

Draw メソッド自体は次のようになります。

        if ([EAGLContext currentContext] != context) {
            [EAGLContext setCurrentContext:context];
        }

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
        glViewport(0, 0, backingWidth, backingHeight);

        ...//drawing different triangle strips here

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        [context presentRenderbuffer:GL_RENDERBUFFER_OES];

リストされたコードに関するコメントや、このバグの原因を突き止める方法についての提案をいただければ幸いです。

4

1 に答える 1

3

totalPointsそれらの配列が静的でない場合、drawArrays、または vertexCorrdinates または textureCoordinates の値に変数が渡されるのではないかと疑っています。あなたのクラッシュは、配列の描画中にメモリの終わりを歩いていることを意味します。私はあなたの GL 設定についてはあまり疑っていませんが、メモリ管理と、ローテーション中に異なる描画内容についてより心配しています。

(また、FWIW、レンダー バッファーをバインドするたびに RenderBufferStorage を呼び出す必要はないと思います。それらを作成するときに一度だけ行う必要があります。サイズを変更してゼロから再作成するときに実際にバッファーを破棄することはありません。)

于 2010-07-08T15:35:16.530 に答える