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

7
我尝试创建一个带有两个纹理的FrameBuffer(多渲染目标)。然后在每个时间步骤中,两个纹理都会被清除并绘制,代码如下所示。(为了缩短长度,部分内容将被替换为伪代码。)

第一版

//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”中,对吗?那么,为什么我每次步骤(或每次更改FBO时)都要调用它呢?

我可能误解了一些OpenGL的概念,请有经验的人给我启示。

编辑1:感谢j-p。我同意这是有道理的,但状态不应该已经记录在FBO中吗?

编辑2(接受答案):Reto Koradi的答案是正确的!我正在使用一个不太标准的库,叫做LWJGL。


如果没有使用默认配置,每次绑定到新的缓冲区时需要调整绘制缓冲区,这对我来说是有道理的。但我不是专家... - j-p
1个回答

8
是的,绘制缓冲区设置是帧缓冲状态的一部分。如果你查看例如OpenGL 3.3规范文档,它在第299页的表6.23中列出,标题为“帧缓冲对象(每个帧缓冲对象的状态)”。
FBO的默认值是单个绘制缓冲区,即GL_COLOR_ATTACHMENT0。从同一规范的第214页开始:
对于帧缓冲对象,在初始状态下,片段颜色零的绘制缓冲区为COLOR_ATTACHMENT0。对于默认帧缓冲和帧缓冲对象,片段颜色其他值的绘制缓冲区的初始状态为NONE。
因此,如果你有多个绘制缓冲区,需要显式调用glDrawBuffers()。
现在,如果你将glDrawBuffers()作为FBO设置的一部分进行调用,为什么似乎不起作用,这有点神秘。我注意到你的代码中使用了FBO调用的EXT形式。我怀疑这可能与你的问题有关。
自OpenGL 3.0以来,FBO已成为标准OpenGL的一部分。如果你有任何使用OpenGL 3.0或更高版本的方法,我强烈建议你使用标准入口点。虽然扩展通常在功能已成为标准后仍然有效,但我总是怀疑它们如何与其他功能交互。特别是,在3.0之前有多个FBO功能的扩展,具有不同的行为。我不会惊讶如果其中一些与其他OpenGL调用相比标准的FBO功能有所不同。
因此,请尝试使用标准入口点(名称中没有EXT)。这将希望解决你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接