Hello,
I’ve been working on an opengl application and have come across a bug I can’t seem to find, and was hoping someone who frequents this forum might be able to help. I’ve included a lot of detail below in case it is helpful, but the basic question is “how do you ensure that all drawing operations on an FBO have completed prior to trying to read out the FBO contents?”
Here are all the details. The application draws to an FBO, and then copies the contents of that FBO to the back buffer, then calls swap buffers. The bug is that when the window is resized there is flickering. It looks like the contents of the entire window are not being drawn for some frames but are instead being replaced by the background color. If I skip the FBO and write directly to the back buffer, then the bug goes away. If I open the application in gDEbugger and proceed frame by frame, then the bug goes away. In gDEbugger every frame looks perfect.
The bug seems to be associated with synchronizing the drawing to the FBO with reading from the FBO. In the original code, I didn’t have anything explicit in the code to force the FBO to update prior to reading from it. When I added a glFinish() call things got a little better, but I still get occasional flickering. Nonetheless, the fact that things improved seemed like a clue that this is related.
Here is the list of calls that are performed on the frame just after resize as captured in gDEbugger:
/* stuff to resize the FBO */
glXMakeCurrent(0x0000000000654D90, 73400322, 0x00000000006F9440)
glBindFramebuffer(GL_FRAMEBUFFER, 1)
glBindRenderbuffer(GL_RENDERBUFFER, 1)
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 640, 481)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 1)
glCheckFramebufferStatus(GL_FRAMEBUFFER)
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glViewport(0, 0, 640, 481)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-0.5, 0.5, -0.37578124, 0.37578124, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
/* empty the back buffer */
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT)
/* draw to the FBO /
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 1)
glClearColor(0, 0, 0, 0)
glClear(GL_COLOR_BUFFER_BIT)
glDisable(GL_BLEND)
/ Draw stuff using combination of these calls:
glBindBuffer
glDrawElements
glUniform
glVertexAttrib
glEnableClientState
glVertexAttribPointer
glVertexPointer
glUseProgram
*/
/* copy FBO to the back buffer */
glEnable(GL_BLEND)
glBlendFunc(1, 1)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
glBindFramebuffer(GL_READ_FRAMEBUFFER, 1)
glUseProgram(1)
glFinish()
glCopyPixels(0, 0, 640, 480, GL_COLOR)
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0)
glUseProgram(0)
glXSwapBuffers(0x0000000000654D90, 73400322)
Does anyone have any idea how one is supposed to synchronize drawing to an FBO with reading from the FBO? I’ve checked the documentation but I’ve come up empty.
Many thanks!
-Jim