PDA

View Full Version : [OpenGL + Qt] Implementing real time loop



phanyx
12th May 2011, 13:49
Hello,

I want to implement a "real-time" loop, which will check and execute pending events, and after that fire up my QGLWidget::updateGL(). In short, it should follow the common pattern for game engine loop, which looks somehow like this:



(...) // initialize qApp and my custom QGLWidget

while (application not closed) {
if (has pending events)
execute them;

w.updateGL();
}
return 0;


I've read lots of threads about this problem, but all of them either was outdated or not applicable.

[solution 1]
I found a solution with using a QTimer with timeout 0, which fires up every time the application is idle. It's very simple and attractive solution: I only need to create QTimer in my custom QGLWidget constructor and run the application with standard QApplication::exec() in main(). The problem is, that in this approach the gui is not "snappy", e.g. moving/resizing the application window is very "choppy", which is not very visual attractive. I've also read, that employing a QTimer (or using QObject::startTimer() / QObject::timerEvent() ) is not very efficient in this scenario.

[solution 2]
I tried to solve the problem in this way:



(...) // initialize qApp and my custom QGLWidget

while (true) {
if (app.hasPendingEvents())
app.processEvents();

w.updateGL();
}

return 0; // which is not really reachable


But I can't exit the application in nice way. I mean, when I click the X button, the app window is hid (closed?), but the process is still running (and consuming lots of cpu). I overridden the QGLWidget::closeEvent() so it calls qApp->quit(), but it doesn't seem to work (it seems to do nothing actually). I also set some window attributes in QGLWidget constructor: WA_QuitOnClose and WA_DeleteOnClose, but neither gives any result.

[solution 3]
I overcame the problem with a bool isFinished in my derived QGLWidget, which is set to "false" in the constructor, and to "true" in QGLWidget::closeEvent(). Now the main() looks like this:



(...) // initialize qApp and my custom QGLWidget

while (!w.finished()) {
if (app.hasPendingEvents())
app.processEvents();

w.updateGL();
}

return 0;


It does the job perfectly. But it doesn't seem to do the job "in the way it should be done".

Well, my question is: how to implement a real-time loop in nice and smooth way. The solution 1 is nice but not smooth and probably not efficient. The second one is somehow nice, but doesn't work perfectly. The last one doesn't seem nice, but works perfectly.

Thanks for any replies.

OS: Windows XP SP3, Qt 4.7.0

Regards,
phan

wysota
17th May 2011, 01:24
The game loop should fire at constant intervals and not "as often as possible". You should assume your loop spins at say... 10Hz and start a timer matching this frequency -- that is 100ms in this case. Then you'll know you'll have more or less 10 spins of the game loop per second. This has nothing to do with updateGL() though. The latter causes a redraw. You shouldn't do any computations in painting code as you never know if something else than the timer wouldn't cause a repaint of your window.