将 OpenGL ES 帧缓冲区移植到 OpenGL

Porting OpenGL ES Framebuffer to OpenGL

我得到以下代码在 iOS 和 Android 上工作得很好:

unsigned int depth_texture = 0,
             framebuffer = 0;

glGenTextures( 1, &depth_texture );
glBindTexture( GL_TEXTURE_2D, depth_texture );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

glTexImage2D( GL_TEXTURE_2D,
              0,
              GL_DEPTH_COMPONENT,
              256,
              256,
              0,
              GL_DEPTH_COMPONENT,
              GL_UNSIGNED_INT,
              NULL );

glBindTexture( GL_TEXTURE_2D, 0 );

glGenFramebuffers( 1, &framebuffer );

glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );

glFramebufferTexture2D( GL_FRAMEBUFFER,
                        GL_DEPTH_ATTACHMENT,
                        GL_TEXTURE_2D,
                        depth_texture,
                        0 );

unsigned int type = glCheckFramebufferStatus( GL_FRAMEBUFFER );

if( type == GL_FRAMEBUFFER_COMPLETE )
{ printf( "Complete!" ); }
else
{ printf( "Error!" ); }

现在我将此代码移植到 OpenGL 桌面(2.1 及更高版本),但它无法工作。我总是收到错误 GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER。我发现让它工作的唯一方法是指定一个 COLOR_ATTACHMENT (这将修复绘图缓冲区错误)。我阅读了 GL glFrameBuffer 文档,但我无法理解为什么上面的代码不起作用。我只想将深度渲染到纹理中......我错过了什么吗?

如果您不想渲染到任何颜色缓冲区,您需要一个指定的调用:

glDrawBuffer(GL_NONE);

这是每个帧缓冲区的状态,因此需要在绑定 FBO 时调用它。

如果你错过了这个,你将得到你所看到的错误,正如 OpenGL 3.3 规范中“帧缓冲区完整性”下的错误条件所指定的那样:

The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be NONE for any color attachment point(s) named by DRAW_BUFFERi.

{FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER}

FBO 的默认绘制缓冲区是 GL_COLOR_ATTACHMENT0,因此如果您没有 GL_COLOR_ATTACHMENT0 的附件并保留默认绘制缓冲区,则此错误情况适用。

为避免非常相似的 GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 错误情况,您还需要将读取缓冲区设置为 GL_NONE:

glReadBuffer(GL_NONE);

据我所知,这些错误条件列在任何 OpenGL ES 规范中。所以那里不需要 glDrawBuffer() 调用。

更奇怪的是:检查从 3.0 开始的所有桌面 OpenGL 规范,其中引入了 FBO,错误情况列在 3.1、3.2、3.3 和 4.0 的规范中。它不在 3.0 中,更有趣的是,它在 4.1 及更高版本中 gone。正如@derhass 在评论中指出的那样,这是成为 OpenGL 4.1 核心的 ARB_ES2_compatibility 扩展的一部分。

记住这个,你可以在下一个 OpenGL 知识问答之夜炫耀一下。如果真有这种事。 :)