glDrawArrays崩溃与EXC_BAD_ACCESS [英] glDrawArrays crash with EXC_BAD_ACCESS

查看:925
本文介绍了glDrawArrays崩溃与EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个iPhone应用程序,该应用程序使用带有CAEAGLayer作为其层的UIView.一切都很好,并且可以解决1个小问题:有时它会因EXC_BAD_ACCESS和以下堆栈跟踪而崩溃:

I'm writing an iPhone application which uses UIView with a CAEAGLayer as its layer. Everything is fine and working apart from 1 small problem: sometimes it crashes with EXC_BAD_ACCESS and the following stack trace:

    [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子视图方法:
初始化:

Application will only crash during interface rotation change (that also happens to be the only case when the view frame changes). It doesn't crash often; most of the time it takes 3-5 minutes of rotating device to reproduce this problem.
I believe I'm making a mistake which is related to CAEAGLLayer initialization / frame change since that's where it crashes (I believe).
So here are the init and layout subviews methods:
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:

On set frame I only set GL_MODELVIEW and GL_POJECTION matrixes, so I guess nothing bad can happen there.
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方法本身看起来像:

Draw method itself looks like:

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

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

I'd appreciate any comments on the listed code or suggestions about how can I find out the cause of this bug.

推荐答案

如果将totalPoints变量传递给drawArrays,或者如果这些数组不是静态的,则可能会怀疑您的vertexCorrdinates或textureCoordinates值.您的崩溃意味着您在绘制数组时走出了内存的尽头.我不太怀疑您的GL设置,而更关心您的内存管理,以及您在轮换期间绘制的不同内容.

I'd be suspicious of the totalPoints variable being passed to drawArrays, or maybe your values for vertexCorrdinates or textureCoordinates, if those arrays aren't static. Your crash implies that you're walking off the end of memory while drawing the arrays. I'm less suspicious of your GL setup and more concerned about your memory management, and what you're drawing that's different during the rotation.

(另外,FWIW,我不认为您每次绑定渲染缓冲区时都应该调用RenderBufferStorage.在创建它们时只需要这样做一次.也就是说,我不确定因此,在更改缓冲区大小并从头开始重新创建缓冲区时,您实际上不应该销毁它们.)

(Also, FWIW, I don't think you should be calling RenderBufferStorage every time you bind the render buffer(s). You should only need to do that once when you create them. That said, I'm not sure that you shouldn't actually destroy the buffers when you change their size and just recreate them from scratch.)

这篇关于glDrawArrays崩溃与EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆