OpenGL-ES,iPhone和间歇性错误:GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES(0x8CD6)

wes*_*der 3 iphone opengl-es

我有一个在UIView中使用OpenGL-ES和EAGLContext的应用程序 - 非常像Apple的GLPaint示例代码应用程序.

我在iPhone 4上看到这个bug可能很重要,但在我的iPad上却看不到.

大多数情况下,这非常有效.但是,我在createFrameBuffer方法中从glCheckFramebufferStatusOES()获取GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES.原因是backingWidth和backingHeight都是0.

我试图理解self.layer和它的大小之间的关系 - 它不是(0,0) - 以及backingWidth和backingHeight的值.我的UIView及其CALayer都具有'正确'大小,而glGetRenderbufferParameterivOES()为GL_RENDERBUFFER_WIDTH_OES和GL_RENDERBUFFER_HEIGHT_OES返回0.

这是我的createFrameBuffer方法 - 它在很多时候都有效.

- (BOOL)createFramebuffer
 { 
 // Generate IDs for a framebuffer object and a color renderbuffer
 glGenFramebuffersOES(1, &viewFramebuffer);
 glGenRenderbuffersOES(1, &viewRenderbuffer);

 glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

 glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

 // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
 // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view).
 [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];

 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

 //DLog(@" backing size = (%d, %d)", backingWidth, backingHeight);
 glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
 glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
 DLog(@" backing size = (%d, %d)", backingWidth, backingHeight);


 err = glGetError();
 if (err != GL_NO_ERROR)
  DLog(@"Error. glError: 0x%04X", err);

 // For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer.
 glGenRenderbuffersOES(1, &depthRenderbuffer);
 glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
 glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);

 glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);

 if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
  {
  NSLog(@"failed to make complete framebuffer object 0x%X", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
  return NO;
  }

 return YES;
 }
Run Code Online (Sandbox Code Playgroud)

当backingWidth和backingHeight不为零时,glCheckFramebufferStatusOES()不会返回任何错误.

Tom*_*sen 7

我有同样的问题.对我来说,修复是在去年的opengl示例代码中,Apple在每个layoutSubviews调用中重建了renderbuffer.现在,如果您创建一个iPhone模板opengl项目,您将看到layoutSubviews只会破坏renderbuffer.然后在每次绘制时,如果渲染缓冲区为零,则创建它.这是更好的原因当你即将绘制所有CAlayers等应该全部闪亮并准备好去.

我认为我的情况下渲染缓冲区是在EagleView图层无法使用时尝试构建的 - 即处于某种拆卸状态.在任何情况下,当我更改我的代码以匹配它工作.

此外,对此代码的调用也较少,这可能更快.在启动时,有很多场景加载和移动,使用我的应用程序生成1/2打布局子视图调用.

由于Apple代码中的注释往往很少,因此layoutsubviews调用中有一个注释很重要:

// The framebuffer will be re-created at the beginning of the next 
   setFramebuffer method call.
Run Code Online (Sandbox Code Playgroud)

--Tom