Multiple OpenGL contexts, multiple windows, multithreading, and vsync Multiple OpenGL contexts, multiple windows, multithreading, and vsync multithreading multithreading

Multiple OpenGL contexts, multiple windows, multithreading, and vsync


swap buffers (vsync causes this to block until vertical monitor refresh)

No, it doesn't block. The buffer swap call may return immediately and not block. What it does however is inserting a synchronization point so that execution of commands altering the back buffer is delayed until the buffer swap happened. The OpenGL command queue is of limited length. Thus once the command queue is full, futher OpenGL calls will block the program until further commands can be pushes into the queue.

Also the buffer swap is not an OpenGL operation. It's a graphics / windowing system level operation and happens independent of the OpenGL context. Just look at the buffer swap functions: The only parameter they take are a handle to the drawable (=window). In fact even if you have multiple OpenGL contexts operating on a single drawable, you swap the buffer only once; and you can do it without a OpenGL context being current on the drawable at all.

So the usual approach is:

' first do all the drawing operationsforeach w in windows:    foreach ctx in w.contexts:        ctx.make_current(w)        do_opengl_stuff()        glFlush()' with all the drawing commands issued' loop over all the windows and issue' the buffer swaps.foreach w in windows:    w.swap_buffers()

Since the buffer swap does not block, you can issue all the buffer swaps for all the windows, without getting delayed by V-Sync. However the next OpenGL drawing command that addresses a back buffer issued for swapping will likely stall.

A workaround for that is using an FBO into which the actual drawing happens and combine this with a loop doing the FBO blit to the back buffer before the swap buffer loop:

' first do all the drawing operationsforeach w in windows:    foreach ctx in w.contexts:        ctx.make_current(w)        glBindFramebuffer(GL_DRAW_BUFFER, ctx.master_fbo)        do_opengl_stuff()        glFlush()' blit the FBOs' renderbuffers to the main back bufferforeach w in windows:    foreach ctx in w.contexts:        ctx.make_current(w)        glBindFramebuffer(GL_DRAW_BUFFER, 0)        blit_renderbuffer_to_backbuffer(ctx.master_renderbuffer)        glFlush()' with all the drawing commands issued' loop over all the windows and issue' the buffer swaps.foreach w in windows:    w.swap_buffers()


thanks @andrewrk for all theses research, i personnaly do like that :

Create first window and his opengl context with double buffer.Active vsync on this window (swapinterval 1)

Create others windows and attach first context with double buffer.Disable vsync on theses others window (swapinterval 0)

For each frameFor invert each window (the one with vsync enable at the end).wglMakeCurrent(hdc, commonContext);
draw.SwapBuffer

In that manner, i achieve the vsync and all window are based on this same vsync.

But i encoutered problem without aero : tearing...