繁体   English   中英

OpenGL/GLSL 4.5 - 在默认 FBO 中使用 MRT

[英]OpenGL/GLSL 4.5 - using MRT in the default FBO

我正在使用 MRT 解决 OpenGL 4.5 中的 3D 拣货问题。 (参考链接: http://ogldev.atspace.co.uk/www/tutorial29/tutorial29.html

根据我在网上查到的资料,我们在使用捷运时一般都会申请一个新的FBO。 如果是这样,我应该在 3D 拾取期间对场景进行两次 daw(3D 拾取的新 FBO,以及屏幕的默认 FBO),这将是浪费时间。

所以我想知道MRT是否可以在默认的FBO中使用,但我遇到了一些问题。

这是我的代码。

// apply the texture buffer attached to GL_COLOR_ATTACHMENT1. (GL_COLOR_ATTACHMENT0 is reserved for the screen ?)
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &m_pickingColorTexture);
glBindTexture(GL_TEXTURE_2D, m_pickingColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, w, h, 0, GL_RGB, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_pickingColorTexture, 0);
glDisable(GL_TEXTURE_2D);

// draw code. 
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);
glDrawElements(........);

// fragment shader, output two kinds of things: frag_color0 for screen display, frag_color1 for 3D picking
 .......
layout (location = 0) out vec4 frag_color0; 
layout (location = 1) out vec4 frag_color1; 
 
void main() {
     frag_color0 = vec4(...);
     frag_color1 = vec4(...);
}

// query the result
glReadBuffer(GL_COLOR_ATTACHMENT1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, &pixelInfo);

当我最后查询 GL_COLOR_ATTACHMENT1 时,结果似乎是 frag_color0 而不是 frag_color1。

如果有人可以帮助我解决问题,我将不胜感激,谢谢!

当我最后查询GL_COLOR_ATTACHMENT1时,结果似乎是frag_color0而不是frag_color1

不,不是,唯一的原因是 FBO 0 没有GL_COLOR_ATTACHMENT1 ,所以你不能查询它。 FBO 0 指的是窗口系统提供的帧缓冲区(通过 windows 上的像素格式、X11/Unix 上的视觉或 fbconfig 以及其他特定于平台的方式指定)。

这个帧缓冲区可能有也可能没有深度缓冲区,可能有也可能没有模板缓冲区,可能有也可能没有(旧的,已弃用的)累积缓冲区,并且可能有以下颜色缓冲区

  • GL_BACK_LEFT
  • GL_BACK_RIGHT
  • GL_FRONT_LEFT
  • GL_FRONT_RIGHT

这是你能得到的最多的,只有当你的 GPU 和驱动程序支持 3D 立体渲染的“quadbuffer stereo”模式时。 在典型情况下,您将只有两个:

  • GL_BACK :绘制新帧的缓冲区
  • GL_FRONT :当前显示在屏幕上的缓冲区。

您不能从 GL 中更改任何这些缓冲区配置(您只能在设置连接 GL 上下文的 window 时影响这一点),并且无法将 GL 对象(纹理、渲染缓冲区)与默认帧缓冲区混合

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_pickingColorTexture, 0);

如果在绑定 FBO 0 时调用它,这只会导致 GL 错误,否则会被忽略。 这些情况也是如此:

 GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, buffers); [...] glReadBuffer(GL_COLOR_ATTACHMENT1);

因此,您要渲染的是 glDrawBuffer 的默认值,在典型情况下为GL_BACK ,您的第二个着色器 output 最终无处可去,而您正在读回的是glReadBuffer的默认值,这也是GL_BACK在典型情况下。

根据我在网上查到的资料,我们在使用捷运时一般都会申请一个新的FBO。

您在网上查到的信息是正确的。 对于 OpenGL 中的 MRT,您需要设置自定义 FBO,并且不能与 FBO 0 中的缓冲区共享它。(从技术上讲,这并不完全正确,您仍然可以使用 FBO 0 设置 MRT,并使用像{GL_FRONT, GL_BACK}或者如果你有一个支持立体声的 GPU,你甚至可以(错误地)使用{GL_BACK_LEFT,GL_BACK_RIGHT} 。但这些的实际用例非常有限)。

如果是这样,我应该在 3D 拾取期间绘制两次场景(3D 拾取的新 FBO,以及屏幕的默认 FBO),这将是浪费时间。

不一定是这样。 您仍然可以使用 MRT 将其渲染到一些自定义 FBO 中,然后只GL_BACK缓冲区

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM