2016-02-13 67 views
1

從連接到同一個FBO(GL_RGB32F)的另一個紋理讀取數據時,寫入附加到FBO的紋理(GL_R8格式)時遇到了一些麻煩。我相信問題是在我的片段着色器中的輸出類型。寫入GL_R8紋理

紋理初始化:

glGenFramebuffers(1, &rBuffer->fbo); 
    glBindFramebuffer(GL_FRAMEBUFFER, rBuffer->fbo); 


    glGenTextures(RayBuffer_TextureType_NUMTEXTURES, rBuffer->textures); 
    ... 
    glBindTexture(GL_TEXTURE_2D, rBuffer->textures[RayBuffer_TextureType_SHADOW]); 
    glTexImage2D 
    (
      GL_TEXTURE_2D, 
      0,   
      GL_R8,   
      textureWidth, 
      textureHeight, 
      0, 
      GL_RED, 
      GL_UNSIGNED_BYTE, 
      NULL 
    ); 

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    glFramebufferTexture2D 
    (
      GL_FRAMEBUFFER,         
      GL_COLOR_ATTACHMENT0 + RayBuffer_TextureType_SHADOW, 
      GL_TEXTURE_2D, 
      rBuffer->textures[RayBuffer_TextureType_SHADOW], 
      0 
    ); 

裝訂:

glBindFramebuffer(GL_FRAMEBUFFER, rBuffer->fbo); 

    glDrawBuffer(GL_COLOR_ATTACHMENT0 + RayBuffer_TextureType_SHADOW); 

    glActiveTexture(GL_TEXTURE0 + RayBuffer_TextureType_POSITION); 
    glBindTexture(GL_TEXTURE_2D, rBuffer->textures[RayBuffer_TextureType_POSITION]); 

幾何着色器:

#version 330 
layout(triangles) in; 
layout (triangle_strip, max_vertices=4) out; 
uniform sampler2D positionTexture; 
uniform vec3 lightDirection; 
uniform vec3 rightDirection; 
uniform vec3 upDirection; 
uniform vec2 screenSize; 
void main() 
{ 



    gl_Position = vec4(1.0f, 1.0f, 0.0f, 1.0f); 
    EmitVertex(); 

    gl_Position = vec4(-1.0f, 1.0f, 0.0f, 1.0f); 
    EmitVertex(); 

    gl_Position = vec4(1.0f, -1.0f, 0.0f, 1.0f); 
    EmitVertex(); 

    gl_Position = vec4(-1.0f, -1.0f, 0.0f, 1.0f); 
    EmitVertex(); 

    EndPrimitive(); 
} 

片段着色器:

#version 330 
layout (location = 3) out float out_shadow; 
void main() 
{ 
    out_shadow = 1.0f; 
} 

位塊傳輸紋理到屏幕上:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
    glBindFramebuffer(GL_READ_FRAMEBUFFER, members->rBuffer->fbo); 
    glReadBuffer(GL_COLOR_ATTACHMENT0 + RayBuffer_TextureType_SHADOW); 
    glBlitFramebuffer 
    (
      0, 0, eBuffer->windowWidth, eBuffer->windowHeight, 
      0, 0, eBuffer->windowWidth, eBuffer->windowHeight, 
      GL_COLOR_BUFFER_BIT, GL_LINEAR 
    ); 

它是安全的假設,RayBuffer_TextureType_SHADOW是3.此外,應該注意到我已經去除了所有的幾何着色器的複雜性,試圖找到的由來問題。該代碼產生一個完全黑屏,而我期待一個完全紅色的屏幕。

回答

3

我相信問題出在你綁定輸出緩衝區的方式。臨界線是在這裏:

layout (location = 3) out float out_shadow; 

你似乎假設值3需要對FBO的附色的渲染到索引匹配:

glFramebufferTexture2D 
(
    GL_FRAMEBUFFER,         
    GL_COLOR_ATTACHMENT0 + RayBuffer_TextureType_SHADOW, 

與值3爲RayBuffer_TextureType_SHADOW

這不是片段着色器輸出與FBO附件關聯的工作方式。在規範的大部分部分,用layout(location=...)限定符指定的值稱爲色號。例如OpenGL的3.3規格的190頁上,而描述glBindFragDataLocationIndexed(),它談論:

定義變量改變出到片段的顏色數目的用戶自網絡連接的結合[..]

而下一個頁面(重點由我加的)上:

當一個程序鏈接,如果沒有綁定或者通過BindFragDataLocationIndexed或BindFragDataLocation,或明確指定設置的着色器文本中的任何改變了變數將自動綁定到片段顏色和由GL指數。

現在,這些「顏色編號」與您指定的繪圖緩衝區的索引相匹配。從glDrawBuffer()同一文檔的210頁中的描述:

德音響內斯該組色彩緩衝器來零被寫入該片段顏色。

因此,與您的來電:

glDrawBuffer(GL_COLOR_ATTACHMENT0 + RayBuffer_TextureType_SHADOW); 

您指定的顏色由片段着色器產生的寫入附件您的FBO的3

這一切都意味着,你需要指定顏色數的片段着色器的輸出:如果你生產的多個輸出

layout (location = 0) out float out_shadow; 

顏色數大於0是唯一有用的你的片段着色器。在這種情況下,location值指定傳遞給glDrawBuffers()的輸出寫入的列表中的顏色緩衝區的索引。

+0

哦,我的天啊,這是我的一個誤解。謝謝你澄清這一點。這很有道理。我將更新我的代碼並返回結果。 –

+0

這很有效,但更重要的是,我現在正確理解了如何渲染紋理。再次感謝你。我注意到問題的題目並不代表我在這裏所犯的根本錯誤。有人認爲它應該改變爲別的東西(以及會有什麼建議)? –