简体   繁体   English

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

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

How can I attach a depth-buffer to my framebufferobject when I use GL_TEXTURE_2D_MULTISAMPLE. 使用GL_TEXTURE_2D_MULTISAMPLE时如何将深度缓冲区附加到我的framebuffer对象。 glCheckFramebufferStatus(msaa_fbo) from the code below returns 0. From the documentation this seems to mean that msaa_fba is not a framebuffer, but it is created from glGenFramebuffers(1, &msaa_fbo); 下面代码中的glCheckFramebufferStatus(msaa_fbo)返回0。从文档中看,这似乎意味着msaa_fba不是帧缓冲区,而是从glGenFramebuffers(1, &msaa_fbo); .

Additionally, if an error occurs, zero is returned. 此外,如果发生错误,则返回零。 GL_INVALID_ENUM is generated if target is not GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER. 如果目标不是GL_DRAW_FRAMEBUFFER,GL_READ_FRAMEBUFFER或GL_FRAMEBUFFER,则生成GL_INVALID_ENUM。

The error is 1280, which I think means GL_INVALID_ENUM. 错误是1280,我认为这意味着GL_INVALID_ENUM。

If i remove the depth buffer attachment the program runs and renders (although without depth testing). 如果我删除深度缓冲区附件,程序将运行并渲染(尽管没有深度测试)。 The error is still present when it runs then. 该错误在运行时仍然存在。 With the depth attachment included there is an error (1286) after every frame, which is INVALID_FRAMEBUFFER. 包括深度附件在内,每帧之后都有一个错误(1286),为INVALID_FRAMEBUFFER。 I don't know how to continue from here. 我不知道如何从这里继续。 Some examples I've looked at do somewhat the same but seem to work. 我看过的一些例子做了一些相同的事情,但似乎可行。

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

Most of the code is from this . 大部分代码都来自于此

EDIT 编辑

The status check was wrong, it should've been GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 状态检查错误,应该是GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); . Now there is no error when I don't include the depth. 现在,当我不包括深度时,就没有错误了。 When I include depth I get this error now: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE . 当我包括深度时,我现在得到此错误: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE

EDIT 2 编辑2

Documentation claims that this happens when GL_TEXTURE_SAMPLES and GL_RENDERBUFFER:SAMPLES don't match. 文档声称这是在GL_TEXTURE_SAMPLES和GL_RENDERBUFFER:SAMPLES不匹配时发生的。

GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; 如果所有连接的渲染缓冲区的GL_RENDERBUFFER_SAMPLES的值都不相同,则返回GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; 如果GL_TEXTURE_SAMPLES的值对于所有附加纹理都不相同; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES. 或者,如果附加的图像是渲染缓冲区和纹理的混合,则GL_RENDERBUFFER_SAMPLES的值与GL_TEXTURE_SAMPLES的值不匹配。

But they do! 但是他们做到了!

I've tested them like this: 我已经像这样测试了它们:

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;

Output is: 输出为:

GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
GL_TEXTURE_SAMPLES: 8
GL_RENDERBUFFER_SAMPLES: 8

EDIT 3 编辑3

Worked around this by using two textures instead of a texture and a renderbuffer like this: 通过使用两个纹理而不是一个纹理和一个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);

I'm am still interested in what was wrong with the original implementation, so question is still standing. 我仍然对原始实现的问题感兴趣,因此问题仍然存在。

You need to used fixed sample locations for the texture if you mix it with renderbuffers. 如果将纹理与渲染缓冲区混合,则需要使用固定的样本位置。 From the spec, in section "Framebuffer Completeness": 根据规格,在“帧缓冲区完整性”部分中:

The value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures; 对于所有附加纹理,TEXTURE_FIXED_SAMPLE_LOCATIONS的值都相同; and, if the attached images are a mix of renderbuffers and textures, the value of TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures. 并且,如果附加的图像是渲染缓冲区和纹理的混合,则所有附加的纹理的TEXTURE_FIXED_SAMPLE_LOCATIONS的值都必须为TRUE。

{FRAMEBUFFER_INCOMPLETE_MULTISAMPLE} {FRAMEBUFFER_INCOMPLETE_MULTISAMPLE}

To avoid this error condition, you the call for setting up the texture storage needs to be changed to: 为避免此错误情况,您需要将用于设置纹理存储的调用更改为:

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