OpenGL 中的离屏帧缓冲区
我正在使用 OpenGL 创建一个 iPhone 游戏,我想在屏幕外的帧缓冲区上绘制,然后使用该帧缓冲区作为在实际屏幕上绘制的纹理。我的代码基于 Apple 的 和 GLSprite 示例,但似乎在切换绘图目标时,我做得不对,因为我只得到了空白纹理。我正在使用的代码如下。怎么了?动态渲染纹理的最佳方法是什么?
下面的创建屏幕外帧缓冲区给了我 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];
I'm creating an iPhone game using OpenGL, and I want to draw onto an offscreen framebuffer, then using that framebuffer as a texture for drawing on the actual screen. I based my code off Apple's and the GLSprite example, but it seems I'm not doing it right when it comes to switching the drawing target, as I only get a blank texture. The code I'm using is below. What is wrong? What is the best way to render a texture on the fly?
The Creating an Offscreen Framebuffer below is giving me the 8cd6 error code.
Creating the Screen Framebuffer
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;
}
Creating an Offscreen Framebuffer
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);
}
Drawing, Loop:
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];
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题很简单:您忘记了在屏幕上绘制。你知道,默认的帧缓冲区,当你执行
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
时你会得到什么,在编写这段代码之前你渲染得很好。不存在“屏幕上”帧缓冲区对象这样的东西。根据定义,所有用户定义的 FBO 均位于屏幕外。
您根本不应该拥有这个
viewFramebuffer
FBO。相反,您应该绘制到纹理,然后使用该纹理绘制到默认帧缓冲区。The problem is simple: you've forgotten to draw to the screen. You know, the default framebuffer, what you get when you do
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
The thing you were rendering to just fine before writing this code.There is no such thing as a "onscreen" framebuffer object. All user-defined FBOs are by definition, off-screen.
You shouldn't have this
viewFramebuffer
FBO at all. Instead, you should draw to your texture, then use that texture to draw to the default framebuffer.鉴于您收到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES ,您至少在创建屏幕外帧缓冲区时遇到了问题。查看您的代码,我没有看到为此离屏帧缓冲区创建颜色渲染缓冲区(当渲染到 CAEAGLLayer 时,该层本身创建颜色渲染缓冲区)。
我相信您需要在屏幕外帧缓冲区创建代码中添加类似以下内容的内容(您需要将
OES
后缀添加到此处的一个或多个函数,因为这些函数来自 OpenGL ES 2.0应用):Given that you're getting a
GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
, you at least have a problem with the creation of your offscreen framebuffer. Looking at your code, nowhere do I see the creation of a color renderbuffer for this offscreen framebuffer (when rendering to a CAEAGLLayer, the layer itself creates the color renderbuffer).I believe that you'll need to add something like the following in your offscreen framebuffer creation code (you will need to add the
OES
suffix to one or more functions here, because these are from an OpenGL ES 2.0 application):