2010-07-08 253 views
3

我正在寫一個iPhone應用程序使用UIView與CAEAGLayer作爲其圖層。一切都很好,並從1個小題工作分開:有時它與EXC_BAD_ACCESS崩潰和下面的堆棧跟蹤:glDrawArrays崩潰與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和佈局子視圖的方法:
初始化:

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

我會很感激的上市代碼或建議,我怎麼能找到這個錯誤的原因的任何意見。

回答

3

我會懷疑totalPoints變量傳遞給drawArrays,或者可能是vertexCorrdinates或textureCoordinates的值,如果這些數組不是靜態的。你的崩潰意味着你在繪製數組的同時走出內存的盡頭。我對您的GL設置不太懷疑,並且更關心您的內存管理,以及您在輪換期間繪製的內容。 (另外,FWIW,我認爲你不應該在每次綁定渲染緩衝區時調用RenderBufferStorage,你創建它們時只需要做一次,也就是說,我並不是這樣做的。當你改變它們的大小並且從頭開始重新創建它們時,肯定不應該破壞緩衝區。)

+0

那麼,所有的數組都是靜態的(至少它的大小永遠不會改變),totalPoints只是一個#define常量。無論如何,我最終從頭開始重新創建opengl視圖,每次設備旋轉時,都會有所幫助。 我不確定它是否是解決問題的好方法,但至少可以工作=) – Alexey 2010-07-29 06:49:27

相關問題