Hi all!
I try to do some -very simple- fluid simulation on the GPU [currently NV30, Linux, NVIDIA 76.67 Driver].
I use OpenGL FBO’s and use 3 textures, 2 for input, 1 for output. Then textures are cycled, to achieve feedback.
Frame #1: RTT to texture 0, reading from 1 and 2
Frame #2: RTT to texture 2, reading from 0 and 1
Frame #3: RTT to texture 1, reading from 2 and 0
Frame #4: RTT to texture 0, reading from 1 and 2
This works quite well, using one FBO with a shared depth buffer and the three textures [GL_FLOAT_R32_NV, GL_TEXTURE_RECTANGLE_NV] which are attached in this round-robin style.
Now I wanted to mask out some part of the computation using the depth test. So I bind the FBO with a dummy texture and a DEPTH_ATTACHMENT renderbuffer. I clear the depth buffer to 1.0, initially. Then I draw the mask with depth test disabled, depth write enabled, setting depth values to 0.0 where NO computation should be done.
In the simulation loop I leave the depth buffer unchanged (glDepthMask(GL_FALSE), glDepthFunc(GL_LESS), no more glClear). I enable the depth test and draw a fullscreen quad with depth values 0.75 into the FBO. I thought I would get updates only where there is no 0.0 in the depth buffer. But somehow this does not work, I only get strange results. This all works o.k. if I always clear the depth buffer and render the mask every time in the loop -> something I try to avoid, because the mask is static.
The question is: What is going to happen with the DEPTH_ATTACHMENT of the FBO, when the color attachments are switched? Is it kept as it was?
I could not find anything in the FBO spec.
Any hints?
Thanks in advance!
GordonS
Thanks for the answer.
Well, I verified the depth buffer was written to with correct values.
Also, when clearing/writing to it every frame in the loop, everything was correct.
But, I kept on searching and the solution is:
When attaching a new texture as render target also re-attach the already attached depth buffer.
<generate fbo, renderbuffer, 3 textures texId[3]>
<RenderLoop Start>
// attach new texture and re-attach renderbuffer
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, texId[0], 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthId);
<render to texture and shared depth buffer, read from texId[1] and texId[2]>
// unattach texture and render buffer -> why???
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, 0, 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
<render other stuff>
<cycle texId array temp=texId[2], texId[2]=texId[1], texId[1]=texId[0], texId[0]=temp>
<RenderLoop End>
So this did the trick. I don’t know, why
(1) I have to attach/unattach the depth buffer every time.
(2) I also have to unattach the texture every time, altough I attach a different texture to the same COLOR_ATTACHMENT. I thought this would automatically unattach the old texture, but this does not work.
Thanks again for any hints.
GordonS
Thanks for the answer.
Well, I verified the depth buffer was written to with correct values.
Also, when clearing/writing to it every frame in the loop, everything was correct.
But, I kept on searching and the solution is:
When attaching a new texture as render target also re-attach the already attached depth buffer.
<generate fbo, renderbuffer, 3 textures texId[3]>
<RenderLoop Start>
// attach new texture and re-attach renderbuffer
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, texId[0], 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthId);
<render to texture and shared depth buffer, read from texId[1] and texId[2]>
// unattach texture and render buffer -> why???
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, 0, 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
<render other stuff>
<cycle texId array temp=texId[2], texId[2]=texId[1], texId[1]=texId[0], texId[0]=temp>
<RenderLoop End>
So this did the trick. I don’t know, why
(1) I have to attach/unattach the depth buffer every time.
(2) I also have to unattach the texture every time, altough I attach a different texture to the same COLOR_ATTACHMENT. I thought this would automatically unattach the old texture, but this does not work.
Thanks again for any hints.
GordonS
Thanks for the answer.
Well, I verified the depth buffer was written to with correct values.
Also, when clearing/writing to it every frame in the loop, everything was correct.
But, I kept on searching and the solution is:
When attaching a new texture as render target also re-attach the already attached depth buffer.
<generate fbo, renderbuffer, 3 textures texId[3]>
<RenderLoop Start>
// attach new texture and re-attach renderbuffer
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, texId[0], 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthId);
<render to texture and shared depth buffer, read from texId[1] and texId[2]>
// unattach texture and render buffer -> why???
FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, 0, 0);
FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
BindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
<render other stuff>
<cycle texId array temp=texId[2], texId[2]=texId[1], texId[1]=texId[0], texId[0]=temp>
<RenderLoop End>
So this did the trick. I don’t know, why
(1) I have to attach/unattach the depth buffer every time.
(2) I also have to unattach the texture every time, altough I attach a different texture to the same COLOR_ATTACHMENT. I thought this would automatically unattach the old texture, but this does not work.
Thanks again for any hints.
GordonS