3
\$\begingroup\$

I'm trying to make an example of deferred rendering. I'm trying to render to three separate textures the position, the normal and the color. Here is the setup :

void setup()
{
    //generate and bind fbo
    glGenFramebuffers(1, &fboHandle);
    glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);

    //generate the depth buffer
    glGenRenderbuffers(1, &depthBuf);
    glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WindowSize, WindowSize);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf);

    //Create positin, normal and color buffers
    createBufTex(GL_TEXTURE0, GL_RGB32F, posTex);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, posTex, 0);
    createBufTex(GL_TEXTURE1, GL_RGB32F, normTex);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, normTex, 0);
    createBufTex(GL_TEXTURE2, GL_RGB8, colorTex);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, colorTex, 0);

    //Attach the texture to fbo 

    GLenum drawbuf[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };

    glDrawBuffers(3, drawbuf);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        std::cout << "Frame buffer not created. \n" << glCheckFramebufferStatus(GL_FRAMEBUFFER);

    //unbind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    createGeometry();

    glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));

    glm::mat4 proj = glm::perspective(45.0f, 800.0f / 800.0f, 0.1f, 100.0f);

    PV = proj * view;

    LightPos = glGetUniformLocation(renderProgram, "pointLight.position");
    LightIntensity = glGetUniformLocation(renderProgram, "pointLight.Intensity");

    defaultlight.intensity = glm::vec3(0.7f);

    renderPlane.initBuffer();
}

Here is the render call:

glm::mat4 MVP;

// Clear the color buffer and the depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Clear the screen to white
glClearColor(1.0, 1.0, 1.0, 1.0);

// Tell OpenGL to use the shader program you've created.
glUseProgram(program);

glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);
glViewport(0, 0, 800, 800);
{
    //Sphere1
    // Set the uniform matrix in our shader to our MVP matrix for the first object.
    MVP = PV * glm::translate(glm::mat4(1), sphere1.origin);
    glUniformMatrix4fv(uniMVP, 1, GL_FALSE, glm::value_ptr(MVP));
    // Draw the Gameobjects
    glBindVertexArray(sphere1.base.vao);
    glDrawArrays(GL_TRIANGLES, 0, sphere1.base.numberOfVertices);

    //Sphere2
    // Set the uniform matrix in our shader to our MVP matrix for the first object.
    MVP = PV * glm::translate(glm::mat4(1), sphere2.origin);
    glUniformMatrix4fv(uniMVP, 1, GL_FALSE, glm::value_ptr(MVP));
    // Draw the Gameobjects
    glBindVertexArray(sphere2.base.vao);
    glDrawArrays(GL_TRIANGLES, 0, sphere2.base.numberOfVertices);
}

glUseProgram(renderProgram);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, 800, 800);
{
    glBindVertexArray(renderPlane.vao);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, posTex);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, normTex);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, colorTex);

    glDrawArrays(GL_TRIANGLES, 0, renderPlane.numberOfVertices);
}

The vertex Shader :

#version 430 core // Identifies the version of the shader, this line must be on a separate line from the rest of the shader code

layout(location = 0) in vec3 in_position;    // Get in a vec3 for position
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec4 in_color;        // Get in a vec4 for color

out vec3 out_pos;
out vec3 out_normal;
out vec4 out_color; // Our vec4 color variable containing r, g, b, a

uniform mat4 MVP; // Our uniform MVP matrix to modify our position values

void main(void)
{
    out_color = in_color;    // Pass the color through
    gl_Position = MVP * vec4(in_position, 1.0); //w is 1.0, also notice cast to a vec4
}

and the Fragment Shader:

#version 430 core // Identifies the version of the shader, this line must be on a separate line from the rest of the shader code

layout(location = 0) out vec3 texPos;
layout(location = 1) out vec3 texNormal;
layout(location = 2) out vec3 texColor;

in vec3 out_pos;
in vec3 out_normal;
in vec4 out_color;    // Take in a vec4 for color

void main(void)
{
    texPos = out_pos;
    texColor = vec3(1.0f, 0.0f, 1.0f);
    texNormal = out_normal;
}

I'm using Nvidia's Nsight to view the pipeline. I figured out that the textures are properly being bound to the FBO. The Texture's color values are not altered at all, even though the depth buffer clearly shows two spheres being rendered. Any suggestions would be helpful.

\$\endgroup\$
  • \$\begingroup\$ Have you tried just outputting data to one texture instead of 3 at once? \$\endgroup\$ – Honeybunch Nov 19 '15 at 1:32
  • \$\begingroup\$ Yeah, I did. Same result. I did another example of implementing gaussian blur, it works just fine in that implementation. The only difference between them would be, when I set the storage space for the texture buffer, I set the GLenum type as GL_FLOAT instead of GL_UNSIGNED_BYTE. \$\endgroup\$ – Srinivasan Nov 20 '15 at 21:01
  • \$\begingroup\$ Have you enabled OpenGL context debugging? Maybe there's an error that you haven't caught with a callback? Try using glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); and glDebugMessageCallback(GLPrintErrorCallback, NULL);docs.gl/gl4/glDebugMessageCallback \$\endgroup\$ – Honeybunch Nov 20 '15 at 21:36
  • \$\begingroup\$ I tried using context debugging. I did not get any error message with local windows debugger. But using NSIGHT gives me a bunch of error messages. I assume this is normal as NSIGHT would be using numerous callbacks from the GPU for processing. One of the warning I got with nsight is "Fragment shader is going to be recompiled because the shader key based on GL state mismatches. \$\endgroup\$ – Srinivasan Nov 20 '15 at 23:29
  • \$\begingroup\$ Could it be possible that I'm setting up the texture wrong ? glActiveTexture(texUnit); glGenTextures(1, &texId); glBindTexture(GL_TEXTURE_2D, texId); glTexImage2D(GL_TEXTURE_2D, 0, format, WindowSize, WindowSize, 0, GL_RGB, GL_FLOAT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); \$\endgroup\$ – Srinivasan Nov 21 '15 at 0:18
2
\$\begingroup\$

I figured out the cause of the problem. I had to clear the depth buffer before rendering the screen filling quad, even though I switch the frame buffer. Apparently the quad culls the objects behind it, causing the textures not to appear

I did glClear(GL_DEPTH_BUFFER_BIT) before I unbound the FBO.

This fixed the issue for me.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.