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