我正在编写一个使用UIView并将CAEAGLayer作为其图层的iPhone应用程序。一切都很好,除了一个小问题之外还有其他问题:有时它会因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子视图方法:
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];
我很感激对所列代码的任何评论或有关如何找出此错误原因的建议。
答案 0 :(得分:3)
我怀疑传递给drawArrays的totalPoints
变量,或者你的vertexCorrdinates或textureCoordinates的值,如果那些数组不是静态的。你的崩溃意味着你在绘制数组时走出了内存的末尾。我对你的GL设置不太怀疑,更关心你的内存管理,以及你在轮换期间所做的不同。
(另外,FWIW,我不认为你每次绑定渲染缓冲区时都应该调用RenderBufferStorage。你只需要在创建它们时执行一次。那就是说,我不确定当你改变它们的大小并且只是从头开始重新创建它们时,你不应该实际销毁缓冲区。)