OpenGL: 深度附件破坏帧缓冲

3

我需要一个新的角度。在重写我的引擎时,我在编写延迟渲染路径时遇到了这个问题。如果我不使用深度附件,则帧缓冲仅显示,这意味着渲染存在故障,但是如果我使用深度附件,则所有输出都为空白。我编写了很多图形处理类,但我在这里简化了代码:

初始化:

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glClearColor(0, 0, 0, 1);
glViewport(0, 0, 1024, 768);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderPreparation();

numBuffer = 3;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
numBuffers = numBuffer;
targetBuffer = 0;
textures = new unsigned int[numBuffers];
glGenTextures(numBuffers, textures);

这将被执行三次:

glBindTexture(GL_TEXTURE_2D, textures[targetBuffer]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, colorType, width, height, 0, colorFormat, colorDataType, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + targetBuffer, GL_TEXTURE_2D, textures[targetBuffer], 0);
targetBuffer++;

然后我创建深度附件:

glGenTextures(1, &renderBuffer);
glBindTexture(GL_TEXTURE_2D, renderBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderBuffer, 0);

编辑2:忘记了FBO的最后一部分:

GLenum *DrawBuffers = new GLenum[numBuffers];
for (size_t i = 0; i < numBuffers; i++)
    DrawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;

glDrawBuffers(numBuffers, DrawBuffers);

// Report errors
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
    fprintf(stderr, "Framebuffer Error. Status 0x%x\n", status);
}

// Unbind
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

最后,我的绘图(所有几何着色器的计算都在此之前完成):
geometryShader->Use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
graphicsWrapper->render(Geometry);

int val[3] = { 0,1,2 };
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
deferredShader->Use();

glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, textures[2]);

// I use this system so it's compatible with Uniform Buffer
//       Objects and the rendering code of other graphics languages
deferredShader->PassData(&val);
deferredShader->SetInteger();
deferredShader->SetInteger();
deferredShader->SetInteger();

glClear(GL_COLOR_BUFFER_BIT);

vaoQuad->Bind();
graphicsWrapper->DrawVertexArray(4);
vaoQuad->Unbind();

请注意,我的代码比这个更面向对象,并且我不得不把大部分的代码脱离上下文。我的问题是,为什么将深度附件绑定到帧缓冲会导致帧缓冲变空白,而移除它就可以正常显示?如何解决?
修改后:我知道这不是渲染缓冲区,我只是叫深度纹理这个名字,因为它以前是一个渲染缓冲区,我忘记改名字了。
1个回答

2

当您没有深度缓冲区时,每个片段都将自动通过深度测试。现在,当您添加深度缓冲区后,深度测试将生效(假设您已启用它)。但是,您忘记清除深度缓冲区:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);

您清除了默认帧缓冲区的颜色和深度缓冲区(或在此时绑定的其他FBO),但没有清除fbo的深度缓冲区...

很有可能您的深度纹理最初全部为零。按照默认深度约定,这意味着它已经是最近的值,因此深度测试可能会对您绘制的任何内容失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接