我尝试创建一个附有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);
}
所有对象都正确绘制到两个纹理,但仅每帧清除第一个纹理(ATTACHMENT0),这是错误的。
版本2
我尝试插入一行代码......
glDrawBuffers({ATTACHMENT0,ATTACHMENT1}) ;
at(#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的不太标准的库。
答案 0 :(得分:6)
是的,绘制缓冲区设置是帧缓冲区状态的一部分。例如,如果您查看OpenGL 3.3规范文档,它将在第299页的表6.23中列出,标题为&#34; Framebuffer(每帧缓冲对象的状态)&#34;。
FBO的默认值是单个绘制缓冲区,即GL_COLOR_ATTACHMENT0
。从同一规范,第214页:
对于帧缓冲对象,在初始状态下,片段颜色为零的绘制缓冲区为COLOR_ATTACHMENT0。对于默认的帧缓冲区和帧缓冲区对象,除零之外的碎片颜色的初始绘制缓冲区状态为NONE。
因此,如果您有多个绘制缓冲区,则需要显式glDrawBuffers()
调用。
现在,如果你作为FBO设置的一部分进行glDrawBuffers()
调用,它为什么似乎不适合你,这有点神秘。我在您的代码中注意到的一件事是您正在使用FBO调用的EXT
形式。我怀疑这可能与你的问题有关。
自3.0版以来,FBO已成为标准OpenGL的一部分。如果您有任何方式可以使用OpenGL 3.0或更高版本,我强烈建议您使用标准入口点。虽然扩展通常在功能已成为标准之后仍然有效,但我总是怀疑它们如何与其他功能交互。特别是,在3.0之前有多个FBO功能扩展,具有不同的行为。如果与标准FBO功能相比,其中一些与其他OpenGL调用的交互方式不同,我不会感到惊讶。
因此,请尝试使用标准入口点(名称中没有EXT
的入口点)。这有望解决您的问题。