【问题标题】:OpenGL how can I attach a depth buffer to a framebuffer using a multisampled 2d textureOpenGL如何使用多采样2d纹理将深度缓冲区附加到帧缓冲区
【发布时间】:2015-11-07 20:56:06
【问题描述】:

当我使用 GL_TEXTURE_2D_MULTISAMPLE 时,如何将深度缓冲区附加到我的帧缓冲区对象。下面代码中的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);

大部分代码来自this

编辑

状态检查错误,应该是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

通过使用两个纹理而不是一个纹理和一个渲染缓冲区来解决这个问题:

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);

我仍然对原始实现的问题很感兴趣,所以问题仍然存在。

【问题讨论】:

  • 多重采样深度纹理是 DX10.1 的一项功能。但是,当这些东西被添加到 GL 时,DX10.1 已经是旧闻了。因此,将多重采样纹理与多重采样渲染缓冲区混合和匹配应该没有什么特别的。您仅有的两个附件是 0​​ 处的颜色附件和深度附件吗?
  • @AndonM.Coleman 是的,除了给出的代码之外,没有其他附件。

标签: c++ opengl fbo depth-buffer msaa


【解决方案1】:

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

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2018-10-05
    • 1970-01-01
    • 2014-12-05
    • 2011-10-09
    • 2017-05-12
    相关资源
    最近更新 更多