Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. WGL Window on non-GUI thread
QtWS25 Last Chance

WGL Window on non-GUI thread

Scheduled Pinned Locked Moved Solved General and Desktop
qopenglcontextwglopengl32.dllqwindow
4 Posts 2 Posters 967 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    rtavakko
    wrote on 31 Mar 2021, 12:41 last edited by
    #1

    Hi guys,

    I started out trying to create an OpenGL render window on a non-GUI thread using QT's OpenGL resources as explained in this thread:

    https://forum.qt.io/topic/123151/qwindow-on-a-non-gui-thread

    My reason for attempting to do this is because my GUI thread is pretty busy with a lot of events and widgets and this causes stuttering and dropped frames when I use a QWindow.

    At the moment, I've gotten as far as creating a native WGL context / window which I used to create a QOpenGLContext:
    Here is a github link to the project: https://github.com/rtavakko/WinGL

    void OpenGLNativeRenderWindow::showNative()
    {
        //Create native window and context
        createNative();
    
        //Allocate memory for the context object and prepare to create it
        openGLContext = new QOpenGLContext(this);
    
        QWGLNativeContext nativeContext(hglrc,hwnd);
        openGLContext->setNativeHandle(QVariant::fromValue(nativeContext));
    
        openGLContext->setFormat(openGLFormat);
        if(sharedOpenGLContext)
            openGLContext->setShareContext(sharedOpenGLContext);
    
        //Make sure the context is created & is sharing resources with the shared context
        bool contextCreated = openGLContext->create();
        assert(contextCreated);
    
        if(sharedOpenGLContext)
        {
            bool sharing = QOpenGLContext::areSharing(openGLContext,sharedOpenGLContext);
            assert(sharing);
        }
    
        //Resize / show window
        resize(renderSpecs.frameType.width,renderSpecs.frameType.height);
        visible = !ShowWindow(hwnd,SW_SHOWNORMAL);
    }
    

    All the resources, including the native window, are created without issues and I'm able to make the QT context current on a separate thread and OpenGL rendering also produces no errors but Hello Triangle doesn't render on my window. It seems that the native WGL context and the QT context are still separate entities.

    If I make direct WGL calls to make the context current / swap buffers, I seem to be able to make OpenGL calls on the native window but it still seems I can't access the resources the QT context renders (e.g. FBO output texture).

    Any thoughts on what could be wrong?

    Cheers!

    1 Reply Last reply
    0
    • R Offline
      R Offline
      rtavakko
      wrote on 23 Aug 2021, 16:22 last edited by rtavakko
      #3

      It seems like it is not possible to render into a native OpenGL window on a separate thread using QT resources and classes. This is the project I worked on for this:
      https://github.com/rtavakko/GLFWInterop

      There are no errors and OpenGL also seems happy when rendering but no frame is rendered into the native window.

      It seems like the QT - native OpenGL interop system is designed to render from a native window into a window managed by QT e.g. a QWindow which does not really solve this issue. The QWindow would still live on the GUI thread which would mean that your rendering performance is limited by how efficiently your UI and widgets run.

      I had success completely getting away from the QT OpenGL classes and only using GLEW along with GLFW windows. GLFW allows resource sharing between OpenGL contexts / windows and also having render windows on different threads. This is a link to the GLFW project:
      https://github.com/rtavakko/GLFWEngine

      So it seems the only option at this point is to have a QT-based GUI and a third party OpenGL engine. It would definitely make sense to have a QT class similar to QWindow that can live in a non-GUI thread but this is not possible at the moment.

      1 Reply Last reply
      1
      • R Offline
        R Offline
        rtavakko
        wrote on 25 May 2021, 20:00 last edited by
        #2

        Any ideas on this?

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rtavakko
          wrote on 23 Aug 2021, 16:22 last edited by rtavakko
          #3

          It seems like it is not possible to render into a native OpenGL window on a separate thread using QT resources and classes. This is the project I worked on for this:
          https://github.com/rtavakko/GLFWInterop

          There are no errors and OpenGL also seems happy when rendering but no frame is rendered into the native window.

          It seems like the QT - native OpenGL interop system is designed to render from a native window into a window managed by QT e.g. a QWindow which does not really solve this issue. The QWindow would still live on the GUI thread which would mean that your rendering performance is limited by how efficiently your UI and widgets run.

          I had success completely getting away from the QT OpenGL classes and only using GLEW along with GLFW windows. GLFW allows resource sharing between OpenGL contexts / windows and also having render windows on different threads. This is a link to the GLFW project:
          https://github.com/rtavakko/GLFWEngine

          So it seems the only option at this point is to have a QT-based GUI and a third party OpenGL engine. It would definitely make sense to have a QT class similar to QWindow that can live in a non-GUI thread but this is not possible at the moment.

          1 Reply Last reply
          1
          • S Offline
            S Offline
            stretchthebits
            wrote on 24 Aug 2021, 02:34 last edited by
            #4

            Here are all the WGL functions
            https://docs.microsoft.com/en-us/windows/win32/opengl/wgl-functions

            The function of interest is
            wglMakeCurrent
            https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-wglmakecurrent

            The line of interest is
            "A thread must set a current rendering context before calling any OpenGL functions. Otherwise, all OpenGL calls are ignored."

            so, what I recommend is to call
            wglMakeCurrent(NULL, NULL); (or whatever the Qt equivalent is.)
            from your GUI thread.

            Then, in your other thread, make a context current by calling.
            wglMakeCurrent(hdc, glcontext); (or whatever the Qt equivalent is.)
            and now, you can make gl funciton calls.

            When you are finished, call
            wglMakeCurrent(NULL, NULL);
            then, release the GL context, destroy the GL context and all that stuff.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved