[英]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, >s);
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.