windowswinapiopenglwgl

Correct usage of wglMakeCurrent?


Is wglMakeCurrent supposed to be called only once or does it need to be called before every buffer swap? Can current opengl context be reset by some external thing other then setting it via wglMakeCurrent?

I am here just to narrow the possible problem. I can't post relevant code here because I have no idea which part is relevant.

Currently I have loop that does makeCurrent -> clear -> render. It renders correctly. I tried make context current on initialization without making it current every draw, but it rendered empty screen. Only when I exited window the correct render flickered for one frame. I figured that something is wrong by using nvidia's graphics debugger. The debugger's overlay strangelly flickered. It doesn't do that with other applications.


Solution

  • Is wglMakeCurrent supposed to be called only once

    Each GL context can be made current to at most one thread and drawable at every single point in time. If you only use one Window and one GL Context, it is enough to call wglMakeCurrent only once after you created the context and the window.

    If you use one context for multiple windows, you have to re-bind it at least once per frame and window. Note that switching the current context or window traditionally implied flushing the GL pipeline, but this can nowadays be prevented via the KHR_context_flush_control extension, making such a scheme much more efficient.

    If you use multiple threads but a single GL context, you must push around the context from thread to thread by making it uncurrent in some thread, and making it current again in the new thread, and so on. But that scheme should almost never be necessary. Fur mutli-threaded GL, you should create mutlipe shared contexts, and then, you usually need one wglMakeCurrent per thread.

    or does it need to be called before every buffer swap?

    Note that the SwapBuffers function is not a GL function (hence also no gl prefix in the name), and therefore, does work independently of the currently active GL context - the function takes the HDC of the window you want the buffer swap to occur.

    Can current opengl context be reset by some external thing other then setting it via wglMakeCurrent?

    No, not really. There is the graphics reset situation which can be handled via ARB_robustness:

    *   Provide a mechanism for an OpenGL application to learn about
        graphics resets that affect the context.  When a graphics reset
        occurs, the OpenGL context becomes unusable and the application
        must create a new context to continue operation. Detecting a
        graphics reset happens through an inexpensive query.
    

    But such a _graphics reset does not unbind the current GL context - the affected context is just not usable any more.