帧缓冲区纹理为空/黑色

1 opengl framebuffer

当将我的帧缓冲区附加纹理渲染到显示四边形时,它变成黑色,这对我来说绝对没有意义,因为我有第二个带有深度纹理的帧缓冲区,它工作得很好。此外,当将渲染的输出显示到屏幕上而不是将其存储在 FBO 中时,它会按应有的方式渲染,并且 GL_FRAMEBUFFER_COMPLETE 和 glGetError 不会返回任何错误。

使用generateBuffer方法生成缓冲区(normalBuffer,normalMap,GL_RGBA,GL_COLOR_ATTACHMENT0):

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);
Run Code Online (Sandbox Code Playgroud)

然后使用以下方法填充纹理:

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);
Run Code Online (Sandbox Code Playgroud)

和顶点着色器:

#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);
}
Run Code Online (Sandbox Code Playgroud)

和片段着色器:

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

显示四边形的片段着色器是:

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

显示四边形的顶点着色器与深度纹理的顶点着色器完全相同,工作得很好,所以这不可能是失败的部分。

我很确定,解决方案非常简单,我只是忽略了一些东西,但我就是无法找出我的错误。

预先感谢每个人寻找这个问题并试图帮助我。

der*_*ass 5

问题就出在这里:

std::vector<GLenum> drawBuffers = { GL_NONE };
glDrawBuffers(1, drawBuffers.data());
Run Code Online (Sandbox Code Playgroud)

这基本上告诉 GL 丢弃片段着色器的(颜色)输出。当您打算渲染颜色附件时,为什么要设置glDrawBuffers为?GL_NONE

结果是黑色,这对我来说完全没有意义,因为我有第二个带有深度纹理的帧缓冲区,它工作得很好。

新创建的 FBO 的初始绘制缓冲区设置为{GL_COLOR_ATTACHMENT0}。上面的代码对于仅深度渲染目标有意义,因为在这种情况下没有颜色附件,并且保持GL_COLOR_ATTACHMENT0绘制缓冲区状态将导致GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER帧缓冲区错误状态。