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. How to make a QGLWidget a real time game loop?
QtWS25 Last Chance

How to make a QGLWidget a real time game loop?

Scheduled Pinned Locked Moved General and Desktop
17 Posts 4 Posters 17.1k 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.
  • J Offline
    J Offline
    julio jerez
    wrote on last edited by
    #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?

    1 Reply Last reply
    0
    • J Offline
      J Offline
      julio jerez
      wrote on last edited by
      #2

      What I am doing is that I am setting my Own Even Handle
      @class newtonDemosEventFilter: public QObject
      {
      Q_OBJECT
      protected:
      bool eventFilter(QObject *obj, QEvent *ev);
      };

      bool newtonDemosEventFilter::eventFilter(QObject *obj, QEvent *ev)
      {
      // 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
      if (ev->type() == QEvent::What_is_the_Idle_Evene?) {
      // what event to send to force a WGLWidget update?
      }

      return QObject::eventFilter(obj, ev);
      }

      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);

      QApplication aplication(argc, argv);
      newtonDemosEventFilter filter;

      newtonDemos demos;
      demos.show();

      aplication.installEventFilter(&filter);
      return aplication.exec();
      }@
      But I am stoked find the idle event.

      1 Reply Last reply
      0
      • T Offline
        T Offline
        tobias.hunger
        wrote on last edited by
        #3

        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?

        1 Reply Last reply
        0
        • J Offline
          J Offline
          julio jerez
          wrote on last edited by
          #4

          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.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            baysmith
            wrote on last edited by
            #5

            Try the "aboutToBlock":http://doc.qt.nokia.com/4.7/qabstracteventdispatcher.html#aboutToBlock signal.

            Nokia Certified Qt Specialist.

            1 Reply Last reply
            0
            • J Offline
              J Offline
              julio jerez
              wrote on last edited by
              #6

              I see that class QAbstractEventDispatcher seems to have what I look for,
              but hwo do I use that class
              I do not see a single example using a class like tha in the demos.

              I tryed this
              @//class newtonDemosEventFilter: public QObject
              class newtonDemosEventFilter: public QAbstractEventDispatcher
              {
              Q_OBJECT
              protected:
              bool eventFilter(QObject *obj, QEvent *ev);
              };@

              but all I get is a bunch of errors.

              1 Reply Last reply
              0
              • J Offline
                J Offline
                julio jerez
                wrote on last edited by
                #7

                for what I can see thsi si too low level, It is asking me to impelmnet all thsi funtions

                bq. 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.

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  kkrzewniak
                  wrote on last edited by
                  #8

                  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.

                  Me, Grimlock, not "nice dino". ME BASH BRAINS!

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    baysmith
                    wrote on last edited by
                    #9

                    @
                    connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()),
                    this, SLOT(onAboutToBlock()));
                    @

                    Nokia Certified Qt Specialist.

                    1 Reply Last reply
                    0
                    • J Offline
                      J Offline
                      julio jerez
                      wrote on last edited by
                      #10

                      I saw that but when I do this

                      @m_animationTimer.setSingleShot(false);
                      connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(OnIdle()));
                      m_animationTimer.start(0);@
                      [quote author="kkrzewniak" date="1297960472"]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.[/quote]
                      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.

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        julio jerez
                        wrote on last edited by
                        #11

                        [quote author="Bradley" date="1297960977"]@ connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(onAboutToBlock())); @[/quote]

                        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

                        @connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(OnIdle()));

                        ...

                        void newtonDemos::OnIdle()
                        {
                        m_canvas->update();
                        }@

                        is that how is supposet to be?

                        1 Reply Last reply
                        0
                        • B Offline
                          B Offline
                          baysmith
                          wrote on last edited by
                          #12

                          You are probably causing a cycle. The update() call will probably post an UpdateRequest event, and after it is processed (and any other events), the aboutToBlock signal will be sent again, which will cause another update() call.

                          Nokia Certified Qt Specialist.

                          1 Reply Last reply
                          0
                          • J Offline
                            J Offline
                            julio jerez
                            wrote on last edited by
                            #13

                            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.

                            1 Reply Last reply
                            0
                            • J Offline
                              J Offline
                              julio jerez
                              wrote on last edited by
                              #14

                              For what I can see the only way I can do this is by having a bool that is toggled on each action/slot,
                              and that does not sound like an elegant or atractive solution.

                              I can not beleive this is not a trivial operation in Qt.
                              This is the default behavior in window

                              1 Reply Last reply
                              0
                              • J Offline
                                J Offline
                                julio jerez
                                wrote on last edited by
                                #15

                                I can upload the two application to my server and post a link to it maybe some one can
                                take a look and tell me how to do what I want.
                                the window and the QT.

                                1 Reply Last reply
                                0
                                • J Offline
                                  J Offline
                                  julio jerez
                                  wrote on last edited by
                                  #16

                                  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.

                                  1 Reply Last reply
                                  0
                                  • J Offline
                                    J Offline
                                    julio jerez
                                    wrote on last edited by
                                    #17

                                    Hello I am here again with the same problem but this time in different OS.

                                    If you remember you told me that adding this action will make my display to refresh perpetually as fast as the system can

                                    In my init window I added this
                                    @// create the render window
                                    m_canvas = new DemoEntityManager (this, glFormat);
                                    setCentralWidget(m_canvas);

                                    connect(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()), this, SLOT(OnIdle())); @

                                    The idle function is this

                                    @void newtonDemos::OnIdle()
                                    {
                                    if (m_doVisualUpdates) {
                                    m_canvas->update();
                                    }
                                    }@

                                    m_doVisualUpdates is set to true.
                                    This works beatifully on all windows systems and all Linux 32 and 64 system a tested,
                                    But on the Mac it fails to call OnIdle.
                                    OnIdle is only called once and after that only whne some event happens, like moving the mouce or touching a key.

                                    Is there something different on the Mac that does not refresh like is does on other OS?
                                    If so how do I make a Game loop on a Mac running OS X?

                                    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