2012-04-30 47 views
4

我試圖(徒勞)使用OpenGL和NVIDIA的Cg着色器系統設置MRT,最終目標是延遲渲染。我已經爲單個目標成功地獲得了着色器和渲染到紋理,但是隻要我嘗試將對象渲染到多個渲染目標,它就無法在任何渲染目標中顯示出來。OpenGL中的多個渲染目標與Cg

,我在下面的方式建立幀緩衝對象:

// Initialize textures 
// (I'll spare you the code since I've done that without issues) 

// Initialize the FBO 
glGenFramebuffers(1, &fbo); 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
glGenRenderbuffers(1, &depthBuff); 
glBindRenderbuffer(GL_RENDERBUFFER, depthBuff); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 
          GL_RENDERBUFFER, depthBuff); 

// -snip- 

// Bind each texture we want to use to the FBO at rtNum 
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + rtNum, 
         GL_TEXTURE_2D, tex->getID(), 0); 
// Check to make sure we're good to go 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
    throw Exceptions::GLException("Frame buffer object is not complete.", 
           __FUNCTION__); 
} 

// -snip- 

// Call glDrawBuffers with the RTs we want to render to 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
unique_ptr<GLenum[]> arr(new GLenum[num]); 
for (size_t c = 0; c < num; ++c) 
    arr[c] = GL_COLOR_ATTACHMENT0 + c; 
glDrawBuffers(num, arr.get()); 
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 
    throw Exceptions::GLException("Frame buffer object is not complete.", 
           __FUNCTION__); 

// -snip- 

// Set up the FBO for rendering 
glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
glPushAttrib(GL_VIEWPORT_BIT); 
glViewport(0, 0, width, height); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

// Draw calls here 

glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glPopAttrib(); 

我的着色器(使用cgGLGetLatestProfile返回的配置文件來編譯)是:

struct VertexShaderOutput { 
    float4 position : POSITION; 
    float3 normal : TEXCOORD0; 
    float4 color : COLOR; 
}; 

VertexShaderOutput VS_Main(float4 local : POSITION, 
         float4 normal : NORMAL, 
         float4 color : COLOR, 
         uniform float4x4 modelViewProj, 
         uniform float4x4 modelViewIT) 
{ 
    VertexShaderOutput OUT; 
    OUT.position = mul(modelViewProj, local); 
    OUT.normal= mul(modelViewIT, normal).xyz; 
    OUT.color = color; 
    return OUT; 
} 

struct FragmentShaderOutput { 
    float4 unlit : COLOR0; 
    float4 normAndDepth : COLOR1; 
}; 

FragmentShaderOutput FS_Main(VertexShaderOutput vsOut) 
{ 
    FragmentShaderOutput OUT; 
    OUT.unlit = float4(1.0f, 1.0f, 0.0f, 1.0f);//vsOut.color; 
    OUT.normAndDepth.rgb = vsOut.normal; 
    // Calculate depth later 
    OUT.normAndDepth.a = 1.0f; 
    return OUT; 
} 

沒有人有任何線索爲什麼這可能會失敗?

+0

您將'//調用glDrawBuffers'放入評論中,但我實際上並沒有在任何地方看到此調用。這只是一個複製錯誤? – Tim

+0

@Tim:是的,這只是一個複製錯誤。我現在修好了。 –

+0

順便說一句,你應該只檢查幀緩衝完成後,你已經完成了戳它。檢查的關鍵在於,您可以在完成FBO狀態的過程中檢查不完整的幀緩衝區狀態。 –

回答

1

以上方法是正確的。這些問題似乎與硬件和Cg的結合。在我的帶有集成芯片組的筆記本電腦上,儘管Cg沒有返回任何錯誤,但MRT卻出現了一系列與其他着色器相關的問題。在配備GeForce GTX260的臺式機上,一切正常。