Results 1 to 8 of 8

Thread: QT + OpenGL + Thread => aaaahhhhh !

  1. #1
    Join Date
    Jul 2008
    Posts
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default QT + OpenGL + Thread => aaaahhhhh !

    Hi, I've got a problem with threads and OpenGL in QT.
    Could you help me please ?

    I'm currently using QT 4.4 with C++.
    In my program, I've got a class which is subclassing the GL widget : " class gldrawer : public QGLWidget ".
    Everything works well : i'm drawing a cloud of points, the maximum number i tried with my program was 31 000 000
    See attached file interface.jpg to get an idea...

    I'm a student with not enough experience in the QT domain but I managed to implement a free fly camera, into my class gldrawer.
    That is probably not the best way to do it but it was easier for me to do it that way to begin with Qt + opengl.

    The surface is updated ONLY when a user interact, for example when the user push the forward button or change colors... => CPU is at 0% most of the time.
    To have a fluid animation during moving phases (user keeps pushing forward for example), I managed to draw the scene indefinitely => CPU at 100% on one core.
    I did that with a timer and a 0ms delay : " qTimerRedraw.start(0); ". The main reason was in fact my lack of knowledge with QThread at the time (I was just beginning with Qt!).

    The job is done, user can interact with opengl & GUI buttons in the same time, the event is just add to the event list so its sometimes a little lagging, but at least it's no crashing.
    (I've got more lags with QSliders when the opengl scene is huge and long to render...). I know this is not perfect, but it kinda works.


    Now I'm trying to launch an automated animation : you click a button and the camera have to follow a list of points, indefinitely. You reclick and it stops the camera.
    My idea was to create a thread to run to the points and replace the camera at each step ; this way the loop is not in the same thread than the GUI => no freeze, can reclick to stop the camera.

    As you know, QT + OpenGL + Threads = complex situation !
    Moreover the Qt documentation isn't enough clear about that, just a word about makeCurrent() but no example... I don't know how to separate my classes...


    Whatever I did some tests and this is the best I've come to :
    -I launch a thread when I click on the button, the thread is corerctly terminated when I reclick
    -Inside this thread, the loop is correctly executed, calculations for the camera are OK :
    I've got a pointer to my gldrawer object and i call a public method of it with the new camera coordinates : this->mygl->setPosition(current, cible); where this->mygl is a gldrawer * obtain in the constructor.

    As you notice, setPosition can be called from 2 different thread at the same time.... And guess what, setPosition is calling this->updateGL()...


    The code compile and run... But nothing happend when I click the button to launch the 'camera' thread. Well in fact the code is executed (new thread, loop, setposition, ...) , values are updated, ... but the screen is not refreshed

    Why ?

    I tried to lock the GL Context with makeCurrent(); and a mutex, like in the following code, but without success.

    //-------------
    I've found a multithreaded opengl + qt example right there : http://apsy.gse.uni-magdeburg.de/mai...e/threadedcube
    It's a great example, it works well. Very interesting.
    //-------------

    Thanks for taking time.
    Attached Images Attached Images

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    You don't need threads nor a 0 timeout timer. Decide how many frames per second you want to draw and set a timer to that frequency (for instance 25fps would give you a 40ms timer period). Connect the timer to a slot that will update your scene (including processing input events) and call updateGL() when it's done. This way you'll have a fluent animation with limited CPU usage and a single thread.

  3. #3
    Join Date
    Jul 2008
    Posts
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    Yes i know that, and that's what i did with my "qTimerRedraw".
    I chose a 0 ms delay because I wanted to have as much fps as i could when in animation mode. But I don't care because I know how to deal with this.

    I said this might not be the best way because it's putting events in the queue and that's bad for the gui because my glwidget is in the same thread than my mainwindow.
    =>You could tell me to increase the timer to 40ms ; but it doesn't matter : the draw instructions are way too long ! (remember : 30M points!)

    My problem is to call a method of my gldrawer from another thread : the call is done (in which updateGL() is also called), but the screen is not updated wtf?

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    updateGL has to be called in the main thread. And of course you realize that by using threads you slow down your application, right?

  5. #5
    Join Date
    Jul 2008
    Posts
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    Quote Originally Posted by wysota View Post
    updateGL has to be called in the main thread.
    Flashbang !
    Ok, that is the thing !
    So stupid it was not clear for me...

    I absolutely know i'm slowing my application by using mutex.
    But i really don't care here, it's just for launching a camera motion move and having the ability to play/pause that.

    //------------------------------------

    This morning I did a test : using a timer into gldrawer, with all the code into the gldrawer `thread`. It did works.
    But... I can't stop the animation until it's finished.
    Qt Code:
    1. void gldrawer::moveCamera()
    2. {
    3. int nb = number of key points (BIG)
    4. for(int i=0; i < nb; i++)
    5. {
    6. go to the next point
    7. draw()
    8. }
    9. }
    10.  
    11.  
    12. connect(&qMoveRedraw, SIGNAL(timeout()), this, SLOT(moveCamera()));
    13. qMoveRedraw.start(30);
    To copy to clipboard, switch view to plain text mode 
    i simplify the moveCamera() code but the idea is here... takes time !
    as soon as i resize or even click in the window : crash, and that's normal...


    //------------------------------------

    ok back to the beginning of my message :
    i just did some tests and i manage to get what i need

    In fact i just tell my gldrawer to draw continously meanwhile the second thread do stuff !

    I also did some tests with mutex & QWaitCondition but i think i will use sleep rather than mutex.

    Thanks again for your help !

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    Quote Originally Posted by anthibug View Post
    I absolutely know i'm slowing my application by using mutex.
    No, by using threads... Contrary to what people think threads tend to slow down execution of code, not speed it up. Unless of course you have more processing units than threads in your application and no other cpu consuming task is running.


    But i really don't care here, it's just for launching a camera motion move and having the ability to play/pause that.
    What do you use threads for, anyway?

    In fact i just tell my gldrawer to draw continously meanwhile the second thread do stuff !
    Why should it draw all the time? It doesn't make sense as the movement (not redrawing) depends on the other tasks running on your machine. You should first run a benchmark to determine how fast you can draw and then adjust the timer so that you have a constant frequency of the "game loop" and redraw as often as you know is possible.

  7. #7
    Join Date
    Jul 2008
    Posts
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    Quote Originally Posted by wysota View Post
    No, by using threads... Contrary to what people think threads tend to slow down execution of code, not speed it up. Unless of course you have more processing units than threads in your application and no other cpu consuming task is running.
    I completely agree, you misunderstand me !
    Re-read what i said : i'm slowing my application
    Not solving, slowing ! Sorry for my english...



    Quote Originally Posted by wysota View Post
    Quote Originally Posted by TiTi
    But i really don't care here, it's just for launching a camera motion move and having the ability to play/pause that.
    What do you use threads for, anyway?
    Yep that was not really explicit, give me another chance :
    -my gldrawer is in the same thread than the gui
    -i want to launch a processing to take screenshots from A point to B point into the cloud points scene
    -if i do that from the `main` thread, i'm freezeing my application : no buttons anymore, no resize, etc... or crash
    I've to wait until the end of animation and cross finger that a crash doesn't happend cause of events.

    => so my idea was to create a second thread from which the translation of the camera is done in an infinite loop


    Quote Originally Posted by wysota View Post
    Why should it draw all the time? It doesn't make sense as the movement (not redrawing) depends on the other tasks running on your machine. You should first run a benchmark to determine how fast you can draw and then adjust the timer so that you have a constant frequency of the "game loop" and redraw as often as you know is possible.
    -it's not a game but i think you know that
    -why draw all the time : because, as you said : "updateGL has to be called in the main thread"
    =>with the second thread looping and moving the camera, the only way to refresh the screen was to draw from the first thread.
    I'm also re-saying : i don't care to use a timer with a 0ms delay that take 100% of one core of my CPU.

    -in the latest modifications, i'm using a QMutex and a QWaitCondition* in a way that the second thread wait that the first thread do all the painting [wakeAll() after updateGL()]

    Of course the animation is not perfectly fluid, but i don't care because i just need to take the screenshot of the gl surface at every frame , i'm going to recompose a video from the captures. (I'm doing that because the scene is huuuuuuuuuuuge). [yes i know i didn't clearly explain all of that, but i aldready said a lot...]

    So this way i'm minimazing the call in terms of 'redrawing'...


    Sure it appears pretty messed up from your eye, and i'm far from beeing a pro at QT+OpenGL+Huge scenes... Even more far from beeing a good teller..
    So as a novice, who knew nothing a few weeks ago, it was hard to figure it out and explain my problem(s) but I manage to resolve them.

    I'm assuring you this thread animation thing is just one of the functionnalities ; it's not impacting the viewer in itself, with the free fly camera.



    *about that i can't find QWaitCondition in the assistant, only found here : http://doc.trolltech.com/4.4/qwaitcondition.html

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QT + OpenGL + Thread => aaaahhhhh !

    Quote Originally Posted by anthibug View Post
    -i want to launch a processing to take screenshots from A point to B point into the cloud points scene
    -if i do that from the `main` thread, i'm freezeing my application : no buttons anymore, no resize, etc... or crash
    I've to wait until the end of animation and cross finger that a crash doesn't happend cause of events.
    It won't freeze as long as you let the application process its events from time to time. Make a single shot at a time instead of trying to make all at once in one long loop.

    -it's not a game but i think you know that
    It's still called a game loop.

    -why draw all the time : because, as you said : "updateGL has to be called in the main thread"
    But why all the time? If nothing changes, what's the point of redrawing the screen? If the content is already stale, drop the frame and continue calculations, no need to redraw the display again.

    You surely have some function that changes the position of the camera that you call periodically - that's the "game loop". To have a steady movement it is important that you call the loop in regular intervals, otherwise your animation will get messed up. So call the loop every 40ms or so to get 25 frames per second, recalculate the position there, call updateGL if you want to redraw the display and make a shot. After you do that, return the flow to the event loop and let the timer timeout again 40ms-<time you spent on calculations/redrawing/snapshotting> later. All that in one thread and in one function call. If your computer cannot keep up, slow down the loop (have less fps but increase the step to compensate the animation).

Similar Threads

  1. QTimer ->start(0) + OpenGL + resize/move window => crash
    By anthibug in forum Qt Programming
    Replies: 5
    Last Post: 8th July 2008, 11:01
  2. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  3. Replies: 10
    Last Post: 20th March 2007, 22:19
  4. Problem closing a QMainWindow in Qt4.2
    By ian in forum Qt Programming
    Replies: 11
    Last Post: 17th October 2006, 00:49

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.