Opengl - glDrawBuffers修改存储在FBO中吗?没有?

jav*_*ver 6 opengl state-machine render-to-texture

我尝试创建一个附有2个纹理的FrameBuffer(Multi Render Targets).然后在每个时间步骤中,清除和绘制两个纹理,如下面的代码.(某些部分将被替换为伪代码,以缩短它.)

版本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);  
}
Run Code Online (Sandbox Code Playgroud)

所有对象都正确地绘制到两个质感,但只有第一个纹理(ATTACHMENT0)被清除每一帧,这是不对的.

版本2

我尝试插入一行代码......

glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ;  
Run Code Online (Sandbox Code Playgroud)

在(#1#),它按预期工作,即清除所有两个纹理.

(图片http://s13.postimg.org/66k9lr5av/gl_Draw_Buffer.jpg)

版本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 ;
}
Run Code Online (Sandbox Code Playgroud)

它不再起作用(症状如版本1),为什么?

opengl手册说"对上下文状态的更改将存储在这个对象中",所以glDrawBuffers()的状态修改 会存储在"framebufferID12"中吗?那么,为什么我必须每次都调用它(或每次我改变FBO)

我可能会误解一些opengl的概念,请有人赐教.

编辑1:谢谢jp.我同意这是有道理的,但是不应该将状态记录在FBO中吗?

编辑2(接受答案):Reto Koradi的回答是正确的!我正在使用一个名为LWJGL的不太标准的库.

Ret*_*adi 7

是的,绘制缓冲区设置是帧缓冲区状态的一部分.例如,如果您查看OpenGL 3.3规范文档,它将在第299页的表6.23中列出,标题为"Framebuffer(每帧缓冲对象的状态)".

FBO的默认值是单个绘制缓冲区,即GL_COLOR_ATTACHMENT0.从同一规范,第214页:

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

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

现在,如果你把glDrawBuffers()呼叫作为FBO设置的一部分,为什么它似乎不适合你,这有点神秘.我在你的代码中注意到的一件事是你正在使用EXTFBO调用的形式.我怀疑这可能与你的问题有关.

自3.0版以来,FBO已成为标准OpenGL的一部分.如果您有任何方式使用OpenGL 3.0或更高版本,我强烈建议您使用标准入口点.虽然扩展通常在功能成为标准后仍然有效,但我总是怀疑它们如何与其他功能交互.特别是,在3.0之前有多个FBO功能扩展,具有不同的行为.如果与标准FBO功能相比,其中一些与其他OpenGL调用的交互方式不同,我不会感到惊讶.

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