Multiple OpenGL contexts, multiple windows, multithreading, and vsync

后端 未结 2 1265
一生所求
一生所求 2021-01-30 14:37

I am creating a graphical user interface application using OpenGL in which there can be any number of windows - \"multi-document interface\" style.

If there were one win

相关标签:
2条回答
  • 2021-01-30 15:22

    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 frame For 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...

    0 讨论(0)
  • 2021-01-30 15:37

    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 operations
    foreach 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 operations
    foreach 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 buffer
    foreach 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()
    
    0 讨论(0)
提交回复
热议问题