3

我正在编写一个 iPhone 应用程序,它使用 UIView 和 CAEAGLayer 作为其层。除了 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 初始化/帧更改有关的错误,因为那是它崩溃的地方(我相信)。
所以这里是初始化和布局子视图方法:
初始化:

    ...
    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 回答