2015-06-20 29 views
1

我試圖將多個目標附加到幀緩衝區對象。我有以下問題:關於幀緩衝區附件的特定組合的OpenGL:GL_FRAMEBUFFER_UNSUPPORTED

使用浮動紋理附件和深度附件時沒有錯誤。 使用浮動紋理附件和整數紋理附件時也沒有錯誤。雖然這些組合工作,我不能同時使用浮點,整數和深度附件。這導致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卡上沒有發生錯誤。

我使用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, &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(); 
} 

林真的出出主意我能做些什麼,使其工作...

回答

4

我真的出來的想法我可以使它工作...

你的OpenGL實現告訴你,你選擇的配置不受支持。你必須接受這一點。 OpenGL規範並不要求所有實現都支持格式的特定組合,因此如果您想要編程爲可移植且健壯的,那麼如果出現GL_FRAMEBUFFER_UNSUPPORTED錯誤,則必須逐步降低格式要求直至可行組合被發現。

支持什麼的一個很好的提示是枚舉所有支持創建OpenGL上下文的FBConfigs;通常這是允許的FBO配置的子集。

+0

謝謝,我只是嘗試了一些更多的配置,發現它使用'GL_DEPTH_COMPONENT32F'而不是'GL_DEPTH_COMPONENT16'。 – tly

相關問題