帧缓冲对象(FBO)和渲染/深度缓冲区的关系

3
我在网上看到了很多例子(例如这个),它们都做以下操作:
  • 创建并绑定FBO
  • 创建并绑定缓冲区(纹理、渲染、深度、模板)
  • 然后,解绑缓冲区
  • 要使用FBO-绑定FBO,进行操作,然后解绑FBO
  • 但是,还要绑定纹理缓冲区以进行读写等操作
  • 但是从未见过重新绑定其他缓冲区(渲染、深度、模板),为什么?

缓冲区创建、绑定/解绑的示例(下面的代码仅用于示例,以展示我所解释的内容,且可以完美运行):

// create a framebuffer object, you need to delete them when program exits.
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);

// create color buffer object and attached to fbo
glGenRenderbuffersEXT(1, &rboId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, TEXTURE_WIDTH, TEXTURE_HEIGHT);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); //UnBind

if(useDepthBuffer) {
  glGenRenderbuffersEXT(1, &rboIdDepth);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboIdDepth);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); //UnBind
}

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, rboId);
if(useDepthBuffer)
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboIdDepth);


// check FBO status
printFramebufferInfo();
bool status = checkFramebufferStatus();
if(!status)
  fboUsed = false;
.
//then,
.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// Do the work
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

1. 为什么我们在使用/绘制对象到FBO时不需要再次绑定所有缓冲区?
2. 这里的底层操作是什么?
编辑:附加->绑定和解除附加->取消绑定。
2个回答

8

我不确定我是否完全理解了你的意思,但绑定到附着点(GL_COLOR_ATTACHMENT...) 的渲染缓冲区是每个FBO状态的,而且这个FBO状态保持不变,你只需要绑定FBO告诉OpenGL这个FBO现在被使用,所有你之前设置的状态都会生效。


我也感觉“完全一样”。但是我没有收到任何授权文件来证明这一点。这就是为什么我提出这个问题。让我们看看其他人的回答。谢谢。 - Rudi
1
@Rudi 你可以相信我,我了解这个。你也可以查看OpenGL规范来获取官方信息。 - Christian Rau

3

我认为通过

  • 然后,分离缓冲区

你提到的是

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboIdDepth);

然而,这不是一个分离操作,而是一个“解绑”操作,意思有所不同。渲染缓冲仍然附加到FBO上。但绑定操作会选择用于执行以下缓冲区对象操作的缓冲区对象。这有点像某些语言中的“with”语句。
实际上,不必绑定的缓冲区对象的附加操作在此处发生。
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                             GL_COLOR_ATTACHMENT0_EXT, 
                             GL_RENDERBUFFER_EXT, 
                             rboId ); // rboID != 0

这将通过匹配进行分离。

glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
                             GL_COLOR_ATTACHMENT0_EXT, 
                             GL_RENDERBUFFER_EXT, 
                             0 );

我已经编辑了问题:attach改为Bind,deattach改为UnBind。谢谢。 - Rudi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接