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.
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\$