Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 650
Matt Kline Avatar asked Nov 04 '22 00:11

Matt Kline


1 Answers

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.

like image 80
Matt Kline Avatar answered Nov 11 '22 05:11

Matt Kline