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. Multithreaded opengl
QtWS25 Last Chance

Multithreaded opengl

Scheduled Pinned Locked Moved General and Desktop
5 Posts 3 Posters 7.7k 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.
  • A Offline
    A Offline
    awallin
    wrote on last edited by
    #1

    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
    0
    • D Offline
      D Offline
      dangelog
      wrote on last edited by
      #2

      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
      0
      • A Offline
        A Offline
        awallin
        wrote on last edited by
        #3

        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
        0
        • B Offline
          B Offline
          bms20
          wrote on last edited by
          #4

          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
          0
          • A Offline
            A Offline
            awallin
            wrote on last edited by
            #5

            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
            0

            • Login

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