【问题标题】:OpenGL: GL_FRAMEBUFFER_UNSUPPORTED on specific combinations of framebuffer attachmentsOpenGL:GL_FRAMEBUFFER_UNSUPPORTED 在帧缓冲附件的特定组合上
【发布时间】:2015-06-20 10:28:42
【问题描述】:

我试图将多个目标附加到帧缓冲区对象。我有以下问题:

使用浮动纹理附件和深度附件时没有错误。 使用浮动纹理附件和整数纹理附件时也没有错误。尽管这些组合有效,但我不能同时使用浮点、整数和深度附件。这导致GL_FRAMEBUFFER_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 卡上没有发生错误。

我在每次gl* 函数调用之后使用glbinding 调用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, &param);

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

我真的不知道该怎么做才能让它发挥作用......

【问题讨论】:

    标签: c++ opengl textures nvidia framebuffer


    【解决方案1】:

    我真的不知道该怎么做才能让它发挥作用......

    您的 OpenGL 实现告诉您,您选择的配置不受支持。你必须接受这一点。 OpenGL 规范不要求所有实现都支持特定的格式组合,因此,如果您希望编程具有可移植性和健壮性,如果遇到 GL_FRAMEBUFFER_UNSUPPORTED 错误,您将不得不逐渐降低格式要求,直到可行找到了组合。

    关于支持的内容的一个很好的提示是枚举所有支持创建 OpenGL 上下文的 FBConfig;通常这是允许的 FBO 配置的子集。

    【讨论】:

    • 谢谢,我只是尝试了更多配置,发现在使用GL_DEPTH_COMPONENT32F 而不是GL_DEPTH_COMPONENT16 时它可以工作。
    【解决方案2】:

    以防其他人像我一样遇到这个问题。支持格式的确切组合因 OpenGL 实现而异,但任何实现都必须支持一组格式。如果您坚持这些,您将不必担心可移植性。这些要求在 OpenGL wiki 中的 Framebuffer CompletenessRequired Image Formats 中进行了描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 2023-01-21
      • 2016-01-01
      • 2015-07-07
      相关资源
      最近更新 更多