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



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

版本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);  
}

所有对象都被正确绘制到两个纹理,但只有第一个纹理(ATTACHMENT0)在每帧都被清除,这是错误的。

版本2

我试着插入一行代码。。。

glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ;  

在(#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 ;
}

它不再工作(症状类似于版本1),为什么?

opengl手册中说"上下文状态的更改将存储在该对象中",因此glDrawBuffers()的状态修改将存储在"framebufferID12"中,对吗?那么,为什么我每次都要把它称为

我可能误解了一些opengl的概念,请有人启发我。

编辑1:谢谢j-p。我同意这是有道理的,但该州不应该已经记录在联邦调查局吗?

编辑2(接受答案):雷托·科拉迪的答案是正确的!我正在使用一个不太标准的库LWJGL。

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

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

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

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

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

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

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

最新更新