我尝试创建一个带有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
的入口点)。这将有望解决你的问题。