Opengl-glDrawBuffers修改是否存储在FBO中?不

Opengl-glDrawBuffers修改是否存储在FBO中?不,opengl,state-machine,render-to-texture,Opengl,State Machine,Render To Texture,我尝试创建一个帧缓冲区,其中附加了两个纹理(多重渲染目标)。然后在每个时间步骤中,两个纹理都被清除并绘制,如下代码所示。(某些部分将被替换为伪代码以使其更短。) 第1版 //beginning of the 1st time step initialize(framebufferID12) //^ I quite sure it is done correctly, //^ Note : there is no glDrawBuffers() calling loop , do once

我尝试创建一个帧缓冲区,其中附加了两个纹理(多重渲染目标)。然后在每个时间步骤中,两个纹理都被清除并绘制,如下代码所示。(某些部分将被替换为伪代码以使其更短。)

第1版

//beginning of the 1st time step
initialize(framebufferID12)
//^ I quite sure it is done correctly, 
//^ Note : there is no glDrawBuffers()  calling

loop , do once every time step {
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID12);  
    //(#1#) a line will be add here in version 2 (see belowed) <------------
    glClearColor (0.5f, 0.0f, 0.5f, 0.0f);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    //  paint a lot of object here , using glsl (Shader .frag, .vert)
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);  
}
在(#1#),它按预期工作,即清除所有两个纹理

(图片)

第3版

从版本2开始,我glDrawBuffers()语句移动到帧缓冲区初始化内部,如下所示

initialize(int framebufferID12){
    int nameFBO = glGenFramebuffersEXT();
    int nameTexture0=glGenTextures();
    int nameTexture1=glGenTextures();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,nameFBO);
      glBindTexture(nameTexture0);
      glTexImage2D( .... ); glTexParameteri(...);
      glFramebufferTexture2DEXT( ATTACHMENT0, nameTexture0);
      glBindTexture(nameTexture1);
      glTexImage2D( .... ); glTexParameteri(...);
      glFramebufferTexture2DEXT( ATTACHMENT0, nameTexture1);
      glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ;  //<--- moved here ---
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
    return nameFBO ;
}
初始化(int-framebufferID12){
int nameFBO=glGenFramebuffersEXT();
int nameTexture0=glGenTextures();
int nameTexture1=glGenTextures();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,nameFBO);
glBindTexture(nameTexture0);
glTexImage2D(…);glTexParameteri(…);
glFramebufferTexture2DEXT(附件0,名称Texture0);
glBindTexture(nameTexture1);
glTexImage2D(…);glTexParameteri(…);
glFramebufferTexture2DEXT(附件0,名称Texture1);

glDrawBuffers({ATTACHMENT0,ATTACHMENT1});//是的,DrawBuffers设置是帧缓冲区状态的一部分。例如,如果您查看OpenGL 3.3规范文档,它在第299页的表6.23中列出,标题为“帧缓冲区(每个帧缓冲区对象的状态)”

FBO的默认值为单绘制缓冲区,即
GL\u COLOR\u ATTACHMENT0
。来自同一规范,第214页:

对于帧缓冲区对象,在初始状态下,片段颜色零的绘制缓冲区为color_ATTACHMENT0。对于默认帧缓冲区和帧缓冲区对象,片段颜色零以外的绘制缓冲区的初始状态为NONE

因此,如果您有多个绘图缓冲区,则需要显式的
glDrawBuffers()
调用

现在,如果您将
glDrawBuffers()
调用作为FBO设置的一部分,那么为什么它似乎对您不起作用,这有点神秘。我在您的代码中注意到的一点是,您正在使用FBO调用的
EXT
形式。我怀疑这可能与您的问题有关

FBO从3.0版开始就是标准OpenGL的一部分。如果您有任何方法可以使用OpenGL 3.0或更高版本,我强烈建议您使用标准入口点。虽然扩展功能即使在成为标准功能后仍然正常工作,但我始终怀疑它们与其他功能的交互方式。尤其是早期,在3.0之前,FBO功能有多个扩展,具有不同的行为。如果其中一些扩展与其他OpenGL调用的交互方式与标准FBO功能不同,我不会感到惊讶


因此,尝试使用标准入口点(名称中没有
EXT
的入口点)。这将有望解决您的问题。

我认为,如果不使用默认配置,每次绑定到新缓冲区时,您都必须调整绘图缓冲区。但我不是专家。。。
initialize(int framebufferID12){
    int nameFBO = glGenFramebuffersEXT();
    int nameTexture0=glGenTextures();
    int nameTexture1=glGenTextures();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,nameFBO);
      glBindTexture(nameTexture0);
      glTexImage2D( .... ); glTexParameteri(...);
      glFramebufferTexture2DEXT( ATTACHMENT0, nameTexture0);
      glBindTexture(nameTexture1);
      glTexImage2D( .... ); glTexParameteri(...);
      glFramebufferTexture2DEXT( ATTACHMENT0, nameTexture1);
      glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ;  //<--- moved here ---
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
    return nameFBO ;
}