1
votes

when rendering my framebuffer attached texture to a display quad, it turns out black, which makes absolutely no sense to me, since I have a second framebuffer with a depth texture, which workes perfectly fine. Also when displaying the rendered output onto the screen instead of storing it in the FBO, it is rendered as it should be and also GL_FRAMEBUFFER_COMPLETE and glGetError return no errors.

The buffer is generated using generateBuffer(normalBuffer, normalMap, GL_RGBA, GL_COLOR_ATTACHMENT0) using the method generateBuffer:

glGenFramebuffers(1, &buffer);

glGenTextures(1, &map);
glBindTexture(GL_TEXTURE_2D, map);
glTexImage2D(GL_TEXTURE_2D, 0, macro, depthWidth, depthHeight, 0, macro, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

glBindFramebuffer(GL_FRAMEBUFFER, buffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, map, 0);

std::vector<GLenum> drawBuffers = { GL_NONE };

glDrawBuffers(1, drawBuffers.data());
GLenum status2 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status2 != GL_FRAMEBUFFER_COMPLETE)
{
     std::cout << "incomplete framebuffer object " << status2 << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);

The texture is then filled with data using:

Shader::setActiveProgram(normalShaderProgram);

normalShaderProgram->setMat4("lightSpace", ligthProjection * lightView);

glViewport(0, 0, depthWidth, depthHeight);
glBindFramebuffer(GL_FRAMEBUFFER, normalBuffer);
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);

normalShaderProgram->setMat4("model", model);

glBindVertexArray(cubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

and the vertex shader:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4 lightSpace;
uniform mat4 model;
out vec3 color;
void main()
{
gl_Position = lightSpace * vec4(aPos, 1.0);
color = (aNormal * vec3(0.5)) + vec3(0.5);
}

and the fragment shader:

#version 330 core
layout(location = 0) out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = color;
}

The fragment shader for the display quad is:

#version 330 core
out vec4 FragColor;
in vec2 uv;
uniform sampler2D normalMap;
void main()
{
FragColor = texture(normalMap, uv);
}

The vertex shader for the display quad is exactly the same as for the depth texture, which works perfectly fine, so this cannot be the failing part.

I am pretty sure, that the solution is very easy and I am just overlooking something, but I just cannot figure out my mistake.

Thanks in advance for everyone looking and this problem and trying to help me.

1
Any framebuffer needs at least one color attachment to be valid. Check the OpenGL error log using GLint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);, and then switch case GL_FRAMEBUFFER_COMPLETE:.ワイきんぐ

1 Answers

4
votes

The issue lies here:

std::vector<GLenum> drawBuffers = { GL_NONE };
glDrawBuffers(1, drawBuffers.data());

This basically tells the GL to throw away the (color) output of your fragment shader. Why are you setting glDrawBuffers to GL_NONE when you intend to render to the color attachment?

It turns out black, which makes absolutely no sense to me, since I have a second framebuffer with a depth texture, which workes perfectly fine.

The initial draw buffer setting for a newly created FBO is {GL_COLOR_ATTACHMENT0}. The above code makes sense for a depth-only render target, because there is no color attachment in that case, and keeping the GL_COLOR_ATTACHMENT0 draw buffer state would result in a GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER framebuffer error status.