Results 1 to 20 of 25

Thread: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by hayati View Post
    If system is busy in doing someting you may never get timeout calls at all.
    That's exactly what I'm saying. After 10 times the timeout value you may get from 0 to 10 timeouts depending on what is happening in the system.

    and off course painting is a long operation but what is opengl is for.
    You mean you have only fully OpenGL applications in your system?

    The latency of the loop is obvious (it does "something", so it introduces a delay), but it is nothing compared to latency of the whole system. Try running a few "while(1);" applications and at the same time run a simple application with a timer triggering at 10Hz, regardless if you are using OpenGL or not.

    Bottom line is - without a real time operating system you may never trust any timers - it is a tool, not a panaceum.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  2. The following user says thank you to wysota for this useful post:

    ricardo (11th August 2009)

  3. #2
    Join Date
    Aug 2006
    Location
    istanbul, turkey
    Posts
    42
    Thanks
    2
    Thanked 4 Times in 4 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    i think second link of my previous post also discusses same issue. That's why i gave these links from trolls' side.

    At the end both side agrees on QTimer is not well suited for that kind of update triggering.

    Thanks

  4. The following user says thank you to hayati for this useful post:

    ricardo (11th August 2009)

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by hayati View Post
    At the end both side agrees on QTimer is not well suited for that kind of update triggering.
    It's fine, it just needs to be used properly. Using sleep() or any of its variants wouldn't change a thing.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. The following user says thank you to wysota for this useful post:

    ricardo (11th August 2009)

  7. #4
    Join Date
    Apr 2009
    Posts
    132
    Thanks
    67
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    @hayati: Are you telling I should use a thread? USually, common games only use a thread in their main loop.
    Useful links, Now I reading them, thanks.
    If I use a thread to update and render my game, does this create any multithreaded problem? I mean, shared variables... (I'm not an expert in MT apps)
    If I use a thread, can I have issues with keyboard and mouse events?



    @wysota: Evidently updating and rendering takes time, but I read this form docs: (constant intervals)
    "The QTimer class provides a high-level programming interface for timers. To use it, create a QTimer, connect its timeout() signal to the appropriate slots, and call start(). From then on it will emit the timeout() signal at constant intervals."
    Did you try your method? are you sure it works? I will try it tomorrow.

    "without a real time operating system you may never trust any timers - it is a tool, not a panaceum."
    I don't think I need that accuracy, just about 45 and 55 FPS would be nice to create a good simulation.




    What do you all thinks about http://www.libqglviewer.com/?
    I didn't use it, but reading some docs I read
    http://www.libqglviewer.com/features.htm
    "Possible animation of the scene at a given frame rate"

    Does anyone use that library?


    Thanks a lot for help.

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by ricardo View Post
    @wysota: Evidently updating and rendering takes time, but I read this form docs: (constant intervals)
    "The QTimer class provides a high-level programming interface for timers. To use it, create a QTimer, connect its timeout() signal to the appropriate slots, and call start(). From then on it will emit the timeout() signal at constant intervals."
    "Constant intervals" is an approximation. Timers are not guaranteed to fire under stress on non-realtime operating systems. There's really nothing to discuss.

    Did you try your method? are you sure it works?
    Why shouldn't it work? It's an adaptive timer which makes the frame rate more stable than using a non-adaptive timer.

    "without a real time operating system you may never trust any timers - it is a tool, not a panaceum."
    I don't think I need that accuracy, just about 45 and 55 FPS would be nice to create a good simulation.
    You can't get even that. There is no guarantee - the kernel might preempty your process at any time for any amount of time (like 10 minutes, if it felt like doing so - of course usually it doesn't). There is just no way you can get a timeout during that period.

    You have to stick with "most of the time in normal conditions you will get 20-60ms accuracy" (consider the difference between resolution and stability of the rate). But you can compensate for "lost frames" by using adaptive timers (and even skipping rendering frames to catch up) - in reality redrawing framerate is not important at all (as long as it's over 16fps so that your eye can perceive it as animation - the brain will interpolate properly) - it is important that the logic is updated fluently (to prevent the game from "lagging behind") which is completely enough in your case. You can even adapt the complexity of scene rendering to compensate lags. Remember that computer graphics is mostly about cheating.

    And to stress again - using another thread will only make things worse as the system will have to context-switch between threads thus losing more time (for a moment ignoring the fact you can't paint from worker threads in Qt) doing completely nothing from your application's point of view. You can use sleep/msleep/nanosleep in the main thread just as well but it won't change the fact that these functions only guarantee that you will not be woken before the given time elapses, nothing more.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    ricardo (12th August 2009)

  10. #6
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    I am interested in FPS when you don't use timer - just loop which will render as fast as it can. How many fps can you achieve in that way?
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

  11. The following user says thank you to faldzip for this useful post:

    ricardo (12th August 2009)

  12. #7
    Join Date
    Apr 2009
    Posts
    132
    Thanks
    67
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by wysota View Post
    "Constant intervals" is an approximation. Timers are not guaranteed to fire under stress on non-realtime operating systems. There's really nothing to discuss.


    Why shouldn't it work? It's an adaptive timer which makes the frame rate more stable than using a non-adaptive timer.


    You can't get even that. There is no guarantee - the kernel might preempty your process at any time for any amount of time (like 10 minutes, if it felt like doing so - of course usually it doesn't). There is just no way you can get a timeout during that period.

    You have to stick with "most of the time in normal conditions you will get 20-60ms accuracy" (consider the difference between resolution and stability of the rate). But you can compensate for "lost frames" by using adaptive timers (and even skipping rendering frames to catch up) - in reality redrawing framerate is not important at all (as long as it's over 16fps so that your eye can perceive it as animation - the brain will interpolate properly) - it is important that the logic is updated fluently (to prevent the game from "lagging behind") which is completely enough in your case. You can even adapt the complexity of scene rendering to compensate lags. Remember that computer graphics is mostly about cheating.

    And to stress again - using another thread will only make things worse as the system will have to context-switch between threads thus losing more time (for a moment ignoring the fact you can't paint from worker threads in Qt) doing completely nothing from your application's point of view. You can use sleep/msleep/nanosleep in the main thread just as well but it won't change the fact that these functions only guarantee that you will not be woken before the given time elapses, nothing more.
    Thanks, so in your opinion the only solution is to implement an adaptative timer. I will try it right now.

    By the way: What happens if render takes more than 20 ms? 20-now.elapsed() would be a negative value. Should I control that case and pass a 0 to 20-now.elapsed()?




    @faldżip: I don't understand you very well, what do you mean exactly? Maybe this:

    Qt Code:
    1. MyQGLWidget::doFPSTest() {
    2. ...
    3. // draw 1000 frames or so
    4. while (1000 frames not drawn)
    5. {
    6. this->updateScene(); // rotate, translate, etc.
    7. this->updateGL(); // eventually calls paintGL()
    8. // put your time measurement somewhere in between
    9. ...
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by ricardo; 12th August 2009 at 11:06.

  13. #8
    Join Date
    Jan 2008
    Location
    Poland
    Posts
    687
    Thanks
    4
    Thanked 140 Times in 132 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by ricardo View Post
    @faldżip: I don't understand you very well, what do you mean exactly? Maybe this:

    Qt Code:
    1. MyQGLWidget::doFPSTest() {
    2. ...
    3. // draw 1000 frames or so
    4. while (1000 frames not drawn)
    5. {
    6. this->updateScene(); // rotate, translate, etc.
    7. this->updateGL(); // eventually calls paintGL()
    8. // put your time measurement somewhere in between
    9. ...
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 
    That's what I meant :] Just to see how many FPS you can achieve when you start render of the frame just after you finish rendering prevoius one - so that's the while() what you wrote.
    I would like to be a "Guru"

    Useful hints (try them before asking):
    1. Use Qt Assistant
    2. Search the forum

    If you haven't found solution yet then create new topic with smart question.

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by ricardo View Post
    Thanks, so in your opinion the only solution is to implement an adaptative timer. I will try it right now.
    No, it's not a solution. But it will give better results than a static timeout timer.

    By the way: What happens if render takes more than 20 ms? 20-now.elapsed() would be a negative value. Should I control that case and pass a 0 to 20-now.elapsed()?
    Either use 0 or immediately calculate the next frame (and skip rendering it).

    But first see how many frames per second can your application obtain as faldżip suggested.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  15. #10
    Join Date
    Apr 2009
    Posts
    132
    Thanks
    67
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Smile Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Hi wysota.
    After implementing an adaptative timer as you told to me, I get some good results but also a strange result.


    3 Tests (3 times each one). 10 seconds every one:


    Code:
    Qt Code:
    1. void CEditor::TimerFired() {
    2. if (m_time.elapsed()>10000) {
    3. ChangeEditorState(EDITING);
    4. } else {
    5. QTime now;
    6. now.start();
    7. m_current_level->Update(0);
    8. m_gl_drawer->updateGL();
    9. m_rendered_frames++;
    10. int next_shot;
    11. if (SIMULATION_UPDATE_INTERVAL_IN_MS-now.elapsed()<0) {
    12. next_shot=0;
    13. } else {
    14. next_shot=SIMULATION_UPDATE_INTERVAL_IN_MS-now.elapsed();
    15. }
    16. QTimer::singleShot(next_shot, this, SLOT(TimerFired()));
    17. }
    18. }
    19.  
    20. // Start button
    21. m_time.start();
    22. m_rendered_frames=0;
    23. QTimer::singleShot(0, this, SLOT(TimerFired()));
    24.  
    25. // When ChangeEditorState(EDITING);
    26. float fps=m_rendered_frames/10.0;
    27. QString m=QString("FPS: %1. rendered frames: %2. Timer interval (ms): %3.").arg(fps).arg(m_rendered_frames).arg(SIMULATION_UPDATE_INTERVAL_IN_MS);
    28. QMessageBox::warning(this, "Warning", m);
    To copy to clipboard, switch view to plain text mode 


    Results under the same conditions (3 times each one, 9 tests):
    If SIMULATION_UPDATE_INTERVAL_IN_MS=10. FPS: 92.7. Expected 100 FPS.
    If SIMULATION_UPDATE_INTERVAL_IN_MS=20. FPS: 32. Expected 50 FPS.
    If SIMULATION_UPDATE_INTERVAL_IN_MS=30. FPS: 32. Expected 33.3 FPS.

    What is really strange is when SIMULATION_UPDATE_INTERVAL_IN_MS=20. I don't understand why I don't get 50 FPS.
    Any idea? Is my adaptative timer implemented properly? Should I use high res windows timer and round its result or QTime is fine?

    Thanks a lot, very helpful your help.


    EDIT: I realised (SIMULATION_UPDATE_INTERVAL_IN_MS-now.elapsed()<0) never happens, so I'm still more disconcerted about interval=20, and next_shot is usually 20, so my computer updates and render it ultra fast. My conclusion is that Qt is taking a lot of time for it. Does anyone know anything about this? Thanks.
    Last edited by ricardo; 12th August 2009 at 12:50.

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Does your application do anything apart from performing the animation at the same time?

    BTW. I'm afraid updateGL() only schedules a repaint, not performs it immediately, so your calculations are not really that precise. As for the 20ms problem - I have no idea... maybe there is some vblank issue related or something. Or maybe you simply didn't repeat the tests enough number of times.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Does your application do anything apart from performing the animation at the same time?

    BTW. I'm afraid updateGL() only schedules a repaint, not performs it immediately, so your calculations are not really that precise. As for the 20ms problem - I have no idea... maybe there is some vblank issue related or something. Or maybe you simply didn't repeat the tests enough number of times.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. The following user says thank you to wysota for this useful post:

    ricardo (12th August 2009)

  19. #13
    Join Date
    Apr 2009
    Posts
    132
    Thanks
    67
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by wysota View Post
    Does your application do anything apart from performing the animation at the same time?

    BTW. I'm afraid updateGL() only schedules a repaint, not performs it immediately, so your calculations are not really that precise. As for the 20ms problem - I have no idea... maybe there is some vblank issue related or something. Or maybe you simply didn't repeat the tests enough number of times.
    Nope. Just update my world and render it.

    I read on docs:
    "If you need to trigger a repaint from places other than paintGL() (a typical example is when using timers to animate scenes), you should call the widget's updateGL() function."
    From: http://doc.trolltech.com/4.5/qglwidget.html#paintGL

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Quote Originally Posted by ricardo View Post
    I read on docs:
    "If you need to trigger a repaint from places other than paintGL() (a typical example is when using timers to animate scenes), you should call the widget's updateGL() function."
    From: http://doc.trolltech.com/4.5/qglwidget.html#paintGL
    Which still doesn't determine when paintGL() will be called after a call to updateGL(). But I just checked in the code - the redraw is immediate.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  21. The following user says thank you to wysota for this useful post:

    ricardo (12th August 2009)

  22. #15
    Join Date
    Apr 2009
    Posts
    132
    Thanks
    67
    Thanked 6 Times in 5 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Wink Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Hi friends!

    I think I found a way. just a WHILE(1) and use qApp->processEvents() to avoid a blocked UI. This code is executed when PLAY is pressed. There are no timers.

    Qt Code:
    1. // simulate it for 10 seconds
    2. m_rendered_frames=0;
    3. m_time.start();
    4. while (m_time.elapsed()<=10000) {
    5. QTime now;
    6. now.start();
    7. qApp->processEvents();
    8. m_current_level->Update(0);
    9. m_gl_drawer->updateGL();
    10. m_rendered_frames++;
    11. // sleep a while
    12. if (SIMULATION_UPDATE_INTERVAL_IN_MS-now.elapsed()>0) {
    13. QTest::qSleep(SIMULATION_UPDATE_INTERVAL_IN_MS-now.elapsed());
    14. }
    15. }
    16. // info
    17. float fps=m_rendered_frames/10.0;
    18. QString m=QString("FPS: %1. rendered frames: %2. Timer interval (ms): %3.").arg(fps).arg(m_rendered_frames).arg(SIMULATION_UPDATE_INTERVAL_IN_MS);
    19. QMessageBox::warning(this, "Warning", m);
    To copy to clipboard, switch view to plain text mode 

    It works properly. What do you think?

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

    Default Re: How can I get a 30 or 60 frame rate when using QGLWidget? QTimer is not acurate

    Event processing is sparse, keys might not be responding or might respond with a delay. That's not a good way to do it. But if it suits your needs...
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Retrieval of frame rate in Phonon.
    By Theo Adams in forum Qt Programming
    Replies: 2
    Last Post: 6th July 2010, 19:00
  2. Replies: 1
    Last Post: 23rd April 2009, 09:05
  3. Frame rate problem
    By MrShahi in forum Qt Programming
    Replies: 1
    Last Post: 30th July 2008, 23:06
  4. Change frame rate
    By superutsav in forum General Programming
    Replies: 1
    Last Post: 3rd August 2006, 21:02

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
  •  
Qt is a trademark of The Qt Company.