2012-01-24 98 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。

乾杯!