OpenGL:深度附件破坏帧缓冲区
OpenGL: Depth Attachment breaks Framebuffer
我需要一双新鲜的眼睛。在重写我的引擎时,我在编写延迟渲染路径时偶然发现了这个问题。仅当我不使用深度附件时才会显示帧缓冲区,这意味着渲染有问题,但如果我这样做,所有输出都是空白的。我写了很多图形处理 类 但我在这里分解了代码:
初始化:
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();
请注意,我的代码比这更面向对象,我不得不从上下文中取出很多代码。我的问题是,为什么将深度附件附加到帧缓冲区会导致帧缓冲区空白,而删除它却能正常工作,我该如何解决?
编辑:我知道它不是渲染缓冲区,我只是称它为深度纹理,因为它曾经是渲染缓冲区,但我忘了更改名称。
当您没有深度缓冲区时,每个片段都会自动通过深度测试。现在添加深度缓冲区后,深度测试将生效(假设您启用了它)。但是,你忘了清除你的深度缓冲区:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
您清除了默认帧缓冲区的颜色和深度缓冲区(或另一个 FBO,当时绑定的),但没有清除 fbo
的深度缓冲区...
深度纹理最初全为零的可能性很高。使用默认深度约定,这意味着它已经是最接近的值,因此对于您绘制的任何内容,深度测试都可能会失败。
我需要一双新鲜的眼睛。在重写我的引擎时,我在编写延迟渲染路径时偶然发现了这个问题。仅当我不使用深度附件时才会显示帧缓冲区,这意味着渲染有问题,但如果我这样做,所有输出都是空白的。我写了很多图形处理 类 但我在这里分解了代码:
初始化:
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();
请注意,我的代码比这更面向对象,我不得不从上下文中取出很多代码。我的问题是,为什么将深度附件附加到帧缓冲区会导致帧缓冲区空白,而删除它却能正常工作,我该如何解决?
编辑:我知道它不是渲染缓冲区,我只是称它为深度纹理,因为它曾经是渲染缓冲区,但我忘了更改名称。
当您没有深度缓冲区时,每个片段都会自动通过深度测试。现在添加深度缓冲区后,深度测试将生效(假设您启用了它)。但是,你忘了清除你的深度缓冲区:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
您清除了默认帧缓冲区的颜色和深度缓冲区(或另一个 FBO,当时绑定的),但没有清除 fbo
的深度缓冲区...
深度纹理最初全为零的可能性很高。使用默认深度约定,这意味着它已经是最接近的值,因此对于您绘制的任何内容,深度测试都可能会失败。