代码之家  ›  专栏  ›  技术社区  ›  Alexey

gldrawarrays崩溃,exc_bad_访问

  •  3
  • Alexey  · 技术社区  · 14 年前

    我正在编写一个iPhone应用程序,它使用带有CaealLayer层的uiview。除了1个小问题之外,一切都很好,而且工作正常:有时它会与exc-bad-u访问和以下堆栈跟踪崩溃:

        [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子视图方法:
    Init:

        ...
        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矩阵,所以我猜在那里不会发生什么不好的事情。
    LayoutSubviews:

        - (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];
    

    对于所列代码的任何评论或关于如何找出此错误原因的建议,我将不胜感激。

    1 回复  |  直到 14 年前
        1
  •  3
  •   Ben Zotto sberry    14 年前

    我会怀疑 totalPoints 正在将变量传递给drawarray,或者如果这些数组不是静态的,则可能是VertexCorrdinates或TextureCoordinates的值。崩溃意味着你在绘制数组时离开了内存的末尾。我不太怀疑你的GL设置,更关心你的内存管理,以及你在旋转过程中所画的不同之处。

    (另外,fwiw,我不认为每次绑定渲染缓冲区时都应该调用renderbufferstorage)。创建它们时只需要执行一次。也就是说,当您更改缓冲区的大小并从头重新创建它们时,我不确定您是否真的应该销毁它们。)

    推荐文章