C++ OpenGL:GL\u帧缓冲区\u在特定的帧缓冲区附件组合上不受支持
我正在尝试将多个目标附加到帧缓冲区对象。我有以下问题: 使用浮动纹理附件和深度附件时没有错误。 使用浮动纹理附件和整数纹理附件时也没有错误。虽然这些组合可以工作,但我不能同时使用浮点、整数和深度附件。这将导致C++ OpenGL:GL\u帧缓冲区\u在特定的帧缓冲区附件组合上不受支持,c++,opengl,textures,nvidia,framebuffer,C++,Opengl,Textures,Nvidia,Framebuffer,我正在尝试将多个目标附加到帧缓冲区对象。我有以下问题: 使用浮动纹理附件和深度附件时没有错误。 使用浮动纹理附件和整数纹理附件时也没有错误。虽然这些组合可以工作,但我不能同时使用浮点、整数和深度附件。这将导致GL\u FRAMEBUFFER\u UNSUPPORTED状态 这是我的代码: //working: Framebuffer fb = Framebuffer( 1280,720, { //AttachmentInfo(GL_DEPTH_COMPONENT1
GL\u FRAMEBUFFER\u UNSUPPORTED
状态
这是我的代码:
//working:
Framebuffer fb = Framebuffer(
1280,720,
{
//AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
}
);
//working:
Framebuffer fb = Framebuffer(
1280,720,
{
AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
//AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
}
);
//NOT working:
Framebuffer fb = Framebuffer(
1280,720,
{
AttachmentInfo(GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT),
AttachmentInfo(GL_RG32F,GL_COLOR_ATTACHMENT0),
AttachmentInfo(GL_RGB16UI,GL_COLOR_ATTACHMENT1),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT2),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT3),
AttachmentInfo(GL_RGBA16F,GL_COLOR_ATTACHMENT4),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT5),
AttachmentInfo(GL_RGB32F,GL_COLOR_ATTACHMENT6),
}
);
注意:我仅在使用NVidia GTX 970图形卡时出现此错误。在稍旧的ATI卡上,未发生任何错误
我使用glbinding
在每次gl*
函数调用后调用glGetError
,因此我知道没有发生其他错误
这是我的Framebuffer
对象的构造函数代码:
Framebuffer::Framebuffer(uint width,uint height,initializer_list<AttachmentInfo> attachments)
:width(width),height(height)
{
glGenFramebuffers(1,&fbID);
glBindFramebuffer(GL_FRAMEBUFFER,fbID);
if(std::none_of(attachments.begin(),attachments.end(),[](const AttachmentInfo& a){
return a.attachment == GL_DEPTH_ATTACHMENT;
})){
//depth test needs either a depth renderbuffer or depth attachment.
unsigned int rboID=0;
glGenRenderbuffers(1, &rboID);
glBindRenderbuffer(GL_RENDERBUFFER, rboID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,rboID);
}
vector<GLenum> buffers;
glActiveTexture(GL_TEXTURE0);
for(AttachmentInfo attachment:attachments){
GLuint tID;
glGenTextures(1, &tID);
glBindTexture(GL_TEXTURE_2D,tID);
GLint param;
glGetInternalformativ(GL_TEXTURE_2D, attachment.internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1, ¶m);
if(param != GL_FULL_SUPPORT){
_log(WARNING,"Internal format " << attachment.internalFormat << " support is " << GLenum(param) << ".");
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GLint(GL_LINEAR));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GLint(GL_LINEAR));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GLint(GL_CLAMP_TO_EDGE));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GLint(GL_CLAMP_TO_EDGE));
if(attachment.attachment == GL_DEPTH_ATTACHMENT){
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GLint(GL_COMPARE_REF_TO_TEXTURE));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GLint(GL_LESS));
}
glTexStorage2D(GL_TEXTURE_2D,1,attachment.internalFormat,width,height);
glFramebufferTexture(GL_FRAMEBUFFER, attachment.attachment, tID, 0);
if(Tools::startsWith(glbinding::Meta::getString(attachment.attachment),"GL_COLOR_ATTACHMENT")){
buffers.push_back(attachment.attachment);
}
texMap[attachment.attachment]=new Texture(tID,GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
}
if(buffers.empty()){
buffers.push_back(GL_NONE);
}
glDrawBuffers(buffers.size(),buffers.data());
GLenum error=glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(error != GL_FRAMEBUFFER_COMPLETE){
_log(ERROR,"Framebuffer error: " << error);
}
unbind();
}
Framebuffer::Framebuffer(uint宽度、uint高度、初始值设定项\u列表附件)
:宽度(宽度)、高度(高度)
{
GLGEN帧缓冲区(1,&fbID);
glBindFramebuffer(GL_FRAMEBUFFER,fbID);
if(std::none_of(attachments.begin()、attachments.end()、[](const AttachmentInfo&a){
返回a.attachment==GL\u DEPTH\u attachment;
})){
//深度测试需要深度渲染缓冲或深度附件。
无符号int-rboID=0;
glGenRenderbuffers(1,&rboID);
glbinderbuffer(GL_RENDERBUFFER,rboID);
GLrenderBuffer存储(GL_RENDERBUFFER、GL_DEPTH_组件、宽度、高度);
glBindRenderbuffer(GL_RENDERBUFFER,0);
glFramebufferRenderbuffer(GL_帧缓冲区、GL_深度附件、GL_RENDERBUFFER、rboID);
}
向量缓冲器;
玻璃纹理(GL_纹理0);
用于(附件信息附件:附件){
胶合tID;
glGenTextures(1和tID);
glBindTexture(GLU纹理2D,tID);
闪烁参数;
glGetInternalformativ(GL_纹理_2D、attachment.internalFormat、GL_帧缓冲区_可渲染、1和参数);
if(参数!=GL_完全支持){
_日志(警告,“内部格式”
我真的不知道我能做什么使它工作
您的OpenGL实现告诉您,您选择的配置不受支持。您必须接受这一点。OpenGL规范不要求所有实现都支持特定的格式组合,因此,如果您希望程序具有可移植性和健壮性,如果您遇到GL\u FRAMEBUFFER\u不受支持的错误,您将遇到错误逐步降低格式要求,直到找到可行的组合
关于支持什么的一个很好的提示是枚举创建OpenGL上下文所支持的所有FBConfig;通常这是允许的FBO配置的子集
我真的不知道我能做什么使它工作
您的OpenGL实现告诉您,您选择的配置不受支持。您必须接受这一点。OpenGL规范不要求所有实现都支持特定的格式组合,因此,如果您希望程序具有可移植性和健壮性,如果您遇到GL\u FRAMEBUFFER\u不受支持的错误,您将遇到错误逐步降低格式要求,直到找到可行的组合
关于支持什么的一个很好的提示是枚举创建OpenGL上下文所支持的所有FBConfig;通常这是允许的FBO配置的子集。以防其他人像我一样遇到这个问题。支持的格式的确切组合因OpenGL实现而异,但有一组格式是任何实现都必须支持。如果坚持这些,就不必担心可移植性。这些要求在和上的OpenGL wiki中进行了描述。以防其他人像我一样遇到这个问题。支持的格式的确切组合因OpenGL实现而异,但有一组格式可供任何实现使用必须支持。如果你坚持这些,你就不必担心可移植性。这些要求在和上的OpenGL wiki中有描述。谢谢,我刚刚尝试了更多的配置,发现它在使用GL\u DEPTH\u组件32f
而不是GL\u DEPTH\u组件16
时有效。谢谢,我刚刚尝试了更多的配置发现它在使用GL_DEPTH_component 32f
而不是GL_DEPTH_component 16
时有效。