Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Multithreaded opengl

    General and Desktop
    3
    5
    7154
    Loading More Posts
    • 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.
    • A
      awallin last edited by

      Hi,
      I'm trying to compile/run this example:
      http://doc.qt.nokia.com/qq/qq06-glimpsing.html

      My code is here:
      https://github.com/aewallin/sandbox/tree/master/qt_opengl_threads

      I'm on Ubuntu 11.04 with qt4.7 and I am getting:
      X Error: BadAccess (attempt to access private resource denied) 10
      Extension: 155 (Uknown extension)
      Minor opcode: 26 (Unknown request)
      Resource id: 0x64000cd
      QGLContext::makeCurrent(): Failed.

      any suggestions? are there more recent examples for this?
      feel free to fork my code and edit on github!

      thanks,
      Anders

      1 Reply Last reply Reply Quote 0
      • D
        dangelog last edited by

        I don't know anything about opengl, but my suggestion is: don't use 8+ years old articles. That's referring to Qt3 stuff. Start with 4.8 and read http://labs.qt.nokia.com/2011/06/03/threaded-opengl-in-4-8/

        Software Engineer
        KDAB (UK) Ltd., a KDAB Group company

        1 Reply Last reply Reply Quote 0
        • A
          awallin last edited by

          I'll look at qt4.8 when it comes to a stable ubuntu release (too much of a hassle to install it manually)

          anyway it seems a call to
          QGLWidget::doneCurrent() is required to release the current QGLContext.

          also it seems double-buffering works less than great for me, so I turned that off.

          after that, from the QThread subclass the QGLWidget::makeCurrent() succeeds and I can do OpenGL drawing as usual. Here's a screenshot of my current code (just pushed to github):
          http://imagebin.org/177291

          1 Reply Last reply Reply Quote 0
          • B
            bms20 last edited by

            My suggestion would be to avoid multi-threaded opengl context sharing at all costs. You don't actually need Qt 4.8 either.

            Designate a single thread to do opengl calls, and stick to it like its a a matter of life and death - i.e. no gl*() calls in any other thread.

            I have spent the last six months dealing with reliability problems and opengl drivers. The approach I have taken is to use exactly one opengl context, the one created in the QGLWidget. If you create another opengl context and attempt to share it (say with an upload thread) you are asking for problems:

            On Linux/MESA/ Intel graphics - you will run into assertion failures in Xlib/glXSwapBuffers().
            Linux/NVidia - works reasonably well, but is slower than single threaded.
            Win32/NVidia - works reasonably well, but is slower than single threaded.
            Win32/Intel - buggy; can crash.
            Win32/ATI - forget it - it just isn't reliable. I've seen incorrect textures rendered and/or random bits of memory shown on screen in place of correct texture maps.
            Windows XP/ATI - well you'll be lucky not to get a BSOD...

            This is essentially what I do in qt 4.7.3/4:

            1. Create an QGLWidget.
            2. Create a render thread, which has a pointer to the QGLWidget.
            3. call doneCurrent in the main thread.
            4. Start the thread, call makeCurrent() in the thread, run render thread.
              You still need to override the methods resizeEvent(), paintEvent(), initializeGL, resizeGL, updateGL(). resizeEvent() in particular should tell the render thread that it needs to resize.

            The render thread is roughly this (pseudo code):
            @
            nextFrameDueAt = NOW() + 16 milliseconds; // get the current time
            while (running):
            clear the buffer (if needed)
            resize viewport (if needed)
            renderAllObjects();

             while (pendingTextureUploadRequest() && (CURRENTTIME() < (nextFrameDueAt-2ms))):
                processNextTextureUploadRequest();
            
             swapBuffers()
            

            @
            Good luck.

            -bms

            Edit: Please wrap (pseudo)code in @ tags; mlong

            1 Reply Last reply Reply Quote 0
            • A
              awallin last edited by

              bms, thanks for your input.

              I've browsed the interwebs and one of the better explanations I found was by apple:
              http://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/OpenGL-MacProgGuide/opengl_threading/opengl_threading.html

              I will try to implement something like the "Worker Task" idea from that link. If anyone has some example code where a (double-buffered?) vertex-array or vertex-buffer-object is updated in a worker task I would be interested.

              Anders

              1 Reply Last reply Reply Quote 0
              • First post
                Last post