How to make a QGLWidget a real time game loop?
Page |
1 |
I am trying to make my runtime window a real time window,
I know that many demos use a timer to send and updates message to a WGLWdiget like this
- m_animationTimer.setSingleShot(false);
- connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(OnIdle()));
- m_animationTimer.start(2);
However the timer method has few short comings:
First the granularity is too course (milliseconds instead of microsecond).
Second it requires lots of management when you want to stop for example to do some other actions.
the timer keeps sending even to the update in the middle of other operations, and you end up with flags and other stuff
just to control the logic.
Usually other GUIs have an event that is called when the system have no more Event in the event Queue. So to set a Real time Update all the client application need to do is to trap the Idle Event and from there send the Update to the Gl window.
This automatically controls the event queue to never overflow and the also the update stop each time
any other message is send to the system.
I am assuming that QT also have to have and Idle Event that is call when no more message are pendim, but I cannot find it.
Can someone tell me how to do this, please?
16 replies
What I am doing is that I am setting my Own Even Handle
- {
- Q_OBJECT
- protected:
- };
- {
- // I want to know what code is the one for want the application is Idle so thar I can send one even to update my WGLWidget
- // what event to send to force a WGLWidget update?
- }
- }
- int main(int argc, char *argv[])
- {
- // Enable run-time memory check for debug builds.
- #ifdef _MSC_VER
- _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
- #endif
- // Set the memory allocation function before creation the newton world
- // this is the only function that can be called before the creation of the newton world.
- // it should be called once, and the the call is optional
- NewtonSetMemorySystem (newtonDemos::PhysicsAlloc, newtonDemos::PhysicsFree);
- newtonDemosEventFilter filter;
- newtonDemos demos;
- demos.show();
- aplication.installEventFilter(&filter);
- return aplication.exec();
- }
But I am stoked find the idle event.
I really do not understand what you want to do. Why would you want to paint whenever the event loop is empty?
I do understand a “paint after each event” or “paint x frames per second”, but why would you want to paint whenever the event queue is empty?
PS: How is ‘render whenever the event queue happens to be empty’ realtime?
Whent you are making an application like a video Game or a performace measuring tool, you need the application to update as fast as it can. That is why you draw after all events are processed.
It is a very standrad operation in all operating system and all GUIs I know.
A timer is a very, very bad Idea.
Try the aboutToBlock [doc.qt.nokia.com] signal.
for what I can see thsi si too low level, It is asking me to impelmnet all thsi funtions
1> due to following members:
1> ‘bool QAbstractEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(71) : see declaration of ‘QAbstractEventDispatcher::processEvents’
1> ‘bool QAbstractEventDispatcher::hasPendingEvents(void)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(72) : see declaration of ‘QAbstractEventDispatcher::hasPendingEvents’
1> ‘void QAbstractEventDispatcher::registerSocketNotifier(QSocketNotifier *)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(74) : see declaration of ‘QAbstractEventDispatcher::registerSocketNotifier’
1> ‘void QAbstractEventDispatcher::unregisterSocketNotifier(QSocketNotifier *)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(75) : see declaration of ‘QAbstractEventDispatcher::unregisterSocketNotifier’
1> ‘void QAbstractEventDispatcher::registerTimer(int,int,QObject *)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(78) : see declaration of ‘QAbstractEventDispatcher::registerTimer’
1> ‘bool QAbstractEventDispatcher::unregisterTimer(int)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(79) : see declaration of ‘QAbstractEventDispatcher::unregisterTimer’
1> ‘bool QAbstractEventDispatcher::unregisterTimers(QObject *)’ : is abstract
1> c:\newton-dynamics_new\packages\thirdparty\qt\4.7.1\include\qtcore\../../src/corelib/kernel/qabstracteventdispatcher.h(80) : see declaration of ‘QAbstractEventDispatcher::unregisterTimers’
1> ‘QList<T> QAbstractEventDispatcher::registeredTimers(QObject *) const’ : is abstract
1> with
I am lost here, this is so eassy to do in Windows and WxWidget,
there has to be a way to do this eassy in Qt.
so far everything else has being very eassy.
I saw that but when I do this
- m_animationTimer.setSingleShot(false);
- connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(OnIdle()));
- m_animationTimer.start(0);
From Qt’s documentation: A QTimer with a timeout interval of 0 will time out as soon as all the events in the window system’s event queue have been processed.
I saw that but this is what I was explaining above, the timer send events asynchronously even when other event are being proccesed, not when the queue is empty.
This is importnat because this application is running a sevral threads on teh background.
if for example I go to the menu and a Load a different scene, the render should stops,
but is does not so the mommnet I click I get all kind of rasing conditions.
I suppose I can fix that but tha was not nessesary before.
when I set it to this
- m_animationTimer.setSingleShot(false);
- connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(OnIdle()));
- m_animationTimer.start(0);
It update as fast as it can, but still have the problem that if you click on en menu for example the timer still update send even and it should stops, because there are other events with higher priority.
Basically I need the updates if and only if when the system has nothing else to do.
To Bradley I see it is a signal, I read the explanation of that signal and it is no clear to me by I will experiment with that,
I see that there are other signals as well.
connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(onAboutToBlock())); @</blockquote> That does part of what I want but still not exacty, because it does update as fas as it can however it still send the same sinal when I click on the menu. I need tha teh signal to be the lowest possible priority of all signals. Maybe I did it wrong, I implemenetd like this ... void newtonDemos::OnIdle() { m_canvas->update(); }is that how is supposet to be?
so I though somethomg liek this shopuld do it, but it does not
- void newtonDemos::OnIdle()
- {
- static bool updateCanvas;
- if (updateCanvas) {
- updateCanvas = true;
- m_canvas->update();
- updateCanvas = false;
- }
- }
what does “a funtion that coul block” means?
bq. This signal is emitted after the event loop returns from a function that could block.
Well I could not find a clean way to do it, but it does no matter, I can acomplishe the same in diffrnet way
I end up doing this
- void newtonDemos::OnIdle()
- {
- if (m_doVisualUpdates) {
- m_canvas->update();
- }
- }
and I set m_doVisualUpdates on and off on eh relvane Menu actions.
It is still better than using a timer, and I also learned a lot about trapping events wih Qt.
Thank every one for the help.
You must log in to post a reply. Not a member yet? Register here!




