OpenGL中的屏幕外帧错误

时间:2012-01-30 01:13:46

标签: ios opengl-es framebuffer

我正在使用OpenGL创建一个iPhone游戏,我想绘制一个屏幕外的帧缓冲区,然后使用该帧缓冲区作为在实际屏幕上绘制的纹理。我将我的代码基于Apple's和GLSprite示例,但在切换绘图目标时,我似乎没有做到这一点,因为我只得到一个空白纹理。我正在使用的代码如下。怎么了?什么是动态渲染纹理的最佳方法?

下面创建一个Offscreen Framebuffer给我8cd6错误代码。

创建屏幕帧缓冲区

glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

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

创建屏幕外帧缓冲区

glGenFramebuffers(1, &offscreenFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, offscreenFramebuffer);

glGenTextures(1,&framebufferTexture);
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
    NSLog(@"ERROR: %x", status);
}

绘图,循环:

glBindTexture(GL_TEXTURE_2D,textureFromFile); //Switch to a texture from a file
glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreenFramebuffer); //Switch to the offscreen framebuffer
//Render the texture to be used later
glBindTexture(GL_TEXTURE_2D,framebufferTexture); //Switch to the offscreen framebuffer's texture
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); //Switch to the screen framebuffer
//Do the drawing using the texture rendered just before, and present this to the screen.

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

2 个答案:

答案 0 :(得分:4)

问题很简单:你忘了画到屏幕。你知道,默认的帧缓冲,你在做glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);时得到的东西你在编写这段代码之前就已经完成了渲染。

没有“屏幕上”帧缓冲对象这样的东西。根据定义,所有用户定义的FBO都在屏幕外。

你根本不应该拥有这个viewFramebuffer FBO。相反,您应该绘制到纹理,然后使用该纹理绘制到默认的帧缓冲区。

答案 1 :(得分:0)

鉴于您获得GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES,您至少在创建屏幕外帧缓冲区时遇到问题。看看你的代码,我无处可见为这个屏幕外的帧缓冲区创建一个颜色渲染缓冲区(当渲染到CAEAGLLayer时,图层本身会创建颜色渲染缓冲区)。

我相信您需要在屏幕外的帧缓冲区创建代码中添加以下内容(您需要在此处将OES后缀添加到一个或多个函数中,因为它们来自OpenGL ES 2.0应用程序):

    glGenRenderbuffers(1, &renderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize.width, bufferSize.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); 
相关问题