[英]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.