Multiple Render Targets in OpenGL with Cg

smilestone322發表於2017-08-15

轉自:https://stackoverflow.com/questions/10386993/multiple-render-targets-in-opengl-with-cg


I'm trying (in vain) to set up MRT using OpenGL and NVIDIA's Cg shader system, with the ultimate goal of deferred rendering. I've successfully gotten both shaders and Render To Texture for single targets working, but as soon as I attempt rendering an object to multiple render targets, it fails to show up in any of them.

I'm setting up the Frame Buffer Object in the following way:

// 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();

My shader (which compiles using the profile returned by cgGLGetLatestProfile) is:

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;
}

Does anyone have any clue as to why this might be failing?

shareimprove this question
 
 
You put // Call glDrawBuffers in a comment, but I don't actually see this call anywhere. Is that just a copying error? – Tim Apr 30 '12 at 18:35
 
@Tim: Yes, it was just a copying error. I've fixed it now. – Matt Kline Apr 30 '12 at 18:39
 
BTW, you should only check framebuffer completeness after you've finished poking at it. The whole point of having the check is so that you can go through incomplete framebuffer states on your way from one complete FBO state to another. – Nicol Bolas Apr 30 '12 at 21:47
 
The issue seems to be a deeper-seated one with Cg. I'll post more when I have more figured out. – Matt Kline May 1 '12 at 16:02
 
The issue I posted here seems to be causing the problem. – Matt Kline May 1 '12 at 17:07

The above method is correct. The issues seem to be with a combination of the hardware and Cg. On my laptop with an integrated chipset, MRT fails and a slew of other shader-related issues occur, despite Cg returning no errors. On my desktop machine with a GeForce GTX260, everything works perfectly.

shareimprove this answer





相關文章