2012-01-24 134 views
6

我一直有一个问题让我的程序化创建的OpenGL视图在某些iOS版本/设备上工作。它似乎是越狱设备上最常见的,但也发生在普通设备上。它似乎只是v4.1或4.2.1,它失败了。未能完成framebuffer对象8cd6(iOS,以编程方式创建OpenGL视图)

我拥有的设备是越狱(这不是我的,当然不是我的选择越狱!),并有iOS的v4.1(8B117)。

错误是8cd6,这意味着它未能附加framebuffer(或沿着这些行的东西)。

我已经搜索和搜索,但没有找到其他解决方案的帮助。他们中的大多数也使用深度缓冲区,但我的纯粹是2D,没有深度缓冲区。

这是我如何创建缓冲区:

glGenFramebuffersOES(1, &defaultFramebuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 

glGenRenderbuffersOES(1, &colorRenderbuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 

其他设置值:

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrthof(0, rect.size.width, 0, rect.size.height, -1, 1); 
glMatrixMode(GL_MODELVIEW); 
glViewport(0, 0, rect.size.width, rect.size.height); 

glDisable(GL_DEPTH_TEST); 
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND_SRC); 
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

int* mts = calloc(1, sizeof(int)); 
glGetIntegerv(GL_MAX_TEXTURE_SIZE, mts); 

resizeFromLayer:

-(BOOL) resizeFromLayer: (CAEAGLLayer*) _layer 
{ 
    // Allocate color buffer backing based on the current layer size 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

    NSLog(@"Layer Bounds: %f x %f", _layer.bounds.size.width, _layer.bounds.size.height); 
    NSLog(@"Layer Position: %f x %f", _layer.bounds.origin.x, _layer.bounds.origin.y); 
    if(![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable: _layer]) 
    { 
     NSLog(@"renderBufferStorage failed!"); 
    } 

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); 
    NSLog(@"Backing: %d x %d", backingWidth, backingHeight); 

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

    return YES; 
} 

这行 “无法做出完整的帧缓冲区对象” 是被错误代码8cd6调用。

+0

您可能尝试向'glGetError()'添加一些调用,以查看该调用之前的所有内容是否成功。 – user1118321

+1

8CD6('GL_FRAMEBUFFER_INCLOMPLETE_ATTACHMENT')并不意味着它“无法附加帧缓冲区”(无论你是什么意思),但其附件之一(纹理或渲染缓冲区绑定到颜色或深度附件)是不完整的。所以它似乎是以某种方式破坏了渲染缓冲存储器。 –

+0

你确定在调用'glCheckFramebufferStatus'时绑定了正确的FBO吗? –

回答

4

感谢上面的两位用户,我帮助我了解了一些东西。

我感动缓冲区的创建出来的类的初始化函数,并创建了两个新的功能:

[self destroyFrameBuffer]; 
[self createFrameBuffer]; 

-(void) destroyFrameBuffer 
{ 
    // Tear down GL 
    if (defaultFramebuffer) 
    { 
     glDeleteFramebuffersOES(1, &defaultFramebuffer); 
     defaultFramebuffer = 0; 
    } 

    if (colorRenderbuffer) 
    { 
     glDeleteRenderbuffersOES(1, &colorRenderbuffer); 
     colorRenderbuffer = 0; 
    } 
} 

-(void) createFrameBuffer 
{ 
    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer 
    glGenFramebuffersOES(1, &defaultFramebuffer); 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 

    glGenRenderbuffersOES(1, &colorRenderbuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 

    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer); 
} 

然后我在resizeFromLayer函数的开始加入调用这些

+0

首先,这是你的问题和没有答案的更新。其次,你没有说这是否能解决任何问题。在这种情况下,这可能是一个答案。但是第三,即使这样也不好,因为每当窗口/大小被调整时,你都会破坏并创建一个新的FBO。这只是解决真正的问题的办法,它必须在别的地方。 –

+2

“我有两个用户在上面排序,这让我意识到了一些事情。” - 我怎么不说它解决了问题?这种方法似乎是在iOS上处理它的一种相当标准的方式。 – AnonymousReality

+0

Chistian在iOS中,当devide被重新定向时,你会销毁并重新创建帧缓冲区 - 这需要调整它的大小。这是在iOS中执行此操作的标准方式。 – badweasel

0

我使用cocos2d的版本2.x 我用上述解决方案来建立我的解决方案,该解决我的问题simliar:

-(void) destroyFrameBuffer 
{ 
    // Tear down GL 
    if (_defaultFramebuffer) 
    { 
     glDeleteFramebuffers(1, &_defaultFramebuffer); 
     _defaultFramebuffer = 0; 
    } 

    if (_colorRenderbuffer) 
    { 
     glDeleteRenderbuffers(1, &_colorRenderbuffer); 
     _colorRenderbuffer = 0; 
    } 


} 

-(void) createFrameBuffer 
{ 
    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer 
    glGenFramebuffers(1, &_defaultFramebuffer); 
    NSAssert(_defaultFramebuffer, @"Can't create default frame buffer"); 

    glGenRenderbuffers(1, &_colorRenderbuffer); 
    NSAssert(_colorRenderbuffer, @"Can't create default render buffer"); 

    glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer); 
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer); 

} 

- (BOOL)resizeFromLayer:(CAEAGLLayer *)layer 
{ 

    [self destroyFrameBuffer]; 
    [self createFrameBuffer]; 
    etc..... 
1

我刚刚在一个项目我工作的

错误印刷同样的问题是:

未能绑定EAGLDrawable:到GL_RENDERBUFFER 1

无法制作完成帧缓冲区对象8cd6

为了解决这个问题我必须确保我仅标记视图重绘,而其self.window不是零

我使用的是GLKView我自己CADisplayLink

+0

我有一个类似的问题,只有问题是我的GLKView有一个零大小。 Self.window不是零,如果我放弃渲染,直到大小非空(可能autosizing还没有运行),它工作正常。 – prewett

0

花费了大量的时间,我发现了这个“无法做出完整的帧缓冲区对象”我使用使用屏蔽上CCSprite的解决方案,但在此之前初始化OpenGL的方法后,这使掩码成为可能我在视图中添加精灵,在添加之前,您必须添加1秒的调度程序,并在该调度程序中将视图中添加您的ccsprite。

干杯!