将 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 知识问答之夜炫耀一下。如果真有这种事。 :)
我得到以下代码在 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 知识问答之夜炫耀一下。如果真有这种事。 :)