繁体   English   中英

OpenGL如何使用多重采样2D纹理将深度缓冲区附加到帧缓冲区

[英]OpenGL how can I attach a depth buffer to a framebuffer using a multisampled 2d texture

使用GL_TEXTURE_2D_MULTISAMPLE时如何将深度缓冲区附加到我的framebuffer对象。 下面代码中的glCheckFramebufferStatus(msaa_fbo)返回0。从文档中看,这似乎意味着msaa_fba不是帧缓冲区,而是从glGenFramebuffers(1, &msaa_fbo);

此外,如果发生错误,则返回零。 如果目标不是GL_DRAW_FRAMEBUFFER,GL_READ_FRAMEBUFFER或GL_FRAMEBUFFER,则生成GL_INVALID_ENUM。

错误是1280,我认为这意味着GL_INVALID_ENUM。

如果我删除深度缓冲区附件,程序将运行并渲染(尽管没有深度测试)。 该错误在运行时仍然存在。 包括深度附件在内,每帧之后都有一个错误(1286),为INVALID_FRAMEBUFFER。 我不知道如何从这里继续。 我看过的一些例子做了一些相同的事情,但似乎可行。

glGenTextures(1, &render_target_texture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, render_target_texture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, NUM_SAMPLES, GL_RGBA8, width, height, false);

glGenFramebuffers(1, &msaa_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, msaa_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, render_target_texture, 0);

glGenRenderbuffers(1, &depth_render_buffer);
glBindRenderbuffer(GL_RENDERBUFFER, depth_render_buffer);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, NUM_SAMPLES, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_render_buffer);

GLenum status = glCheckFramebufferStatus(msaa_fbo);

大部分代码都来自于此

编辑

状态检查错误,应该是GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 现在,当我不包括深度时,就没有错误了。 当我包括深度时,我现在得到此错误: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE

编辑2

文档声称这是在GL_TEXTURE_SAMPLES和GL_RENDERBUFFER:SAMPLES不匹配时发生的。

如果所有连接的渲染缓冲区的GL_RENDERBUFFER_SAMPLES的值都不相同,则返回GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; 如果GL_TEXTURE_SAMPLES的值对于所有附加纹理都不相同; 或者,如果附加的图像是渲染缓冲区和纹理的混合,则GL_RENDERBUFFER_SAMPLES的值与GL_TEXTURE_SAMPLES的值不匹配。

但是他们做到了!

我已经像这样测试了它们:

std::cout << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << std::endl;
GLsizei gts, grs;
glGetTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &gts);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &grs);
std::cout << "GL_TEXTURE_SAMPLES: " << gts << std::endl;
std::cout << "GL_RENDERBUFFER_SAMPLES: " << grs << std::endl;

输出为:

GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
GL_TEXTURE_SAMPLES: 8
GL_RENDERBUFFER_SAMPLES: 8

编辑3

通过使用两个纹理而不是一个纹理和一个renderbuffer来解决此问题:

glGenFramebuffers(1, &msaa_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, msaa_fbo);

glGenTextures(1, &render_texture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, render_texture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, NUM_SAMPLES, GL_RGBA8, width, height, false);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, render_texture, 0);

glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, depth_texture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, NUM_SAMPLES, GL_DEPTH_COMPONENT, width, height, false);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depth_texture, 0);

我仍然对原始实现的问题感兴趣,因此问题仍然存在。

如果将纹理与渲染缓冲区混合,则需要使用固定的样本位置。 根据规格,在“帧缓冲区完整性”部分中:

对于所有附加纹理,TEXTURE_FIXED_SAMPLE_LOCATIONS的值都相同; 并且,如果附加的图像是渲染缓冲区和纹理的混合,则所有附加的纹理的TEXTURE_FIXED_SAMPLE_LOCATIONS的值都必须为TRUE。

{FRAMEBUFFER_INCOMPLETE_MULTISAMPLE}

为避免此错误情况,您需要将用于设置纹理存储的调用更改为:

glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
    NUM_SAMPLES, GL_RGBA8, width, height, GL_TRUE);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM