Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Owning the game loop
QtWS25 Last Chance

Owning the game loop

Scheduled Pinned Locked Moved Unsolved Game Development
gameevent loopevent-handlingloop
3 Posts 2 Posters 1.7k 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.
  • F Offline
    F Offline
    Flyverse
    wrote on 16 Nov 2019, 05:55 last edited by
    #1

    Hi,

    I have been trying to find a solution to this problem of mine on the internet, but to no avail.
    I am currently writing an OpenGL Game for a computer graphics class project. Since we have been using Qt for previous homeworks to create supporting UIs easily, we are required to use Qt as a base for the project as well.
    However, in the game I am writing, I'd like to implement my own game loop, and thus will have to take control of the event loop (otherwise my loop would be blocking it, and conversely.).
    I have a QApplication and wrote classes deriving from QMainWindow and QOpenGLWidget to render to.
    I know that I can make everything work by connecting a QTimer to my rendering/update function, but this is very suboptimal.
    Optimally, I would like to not have to call QApplication::exec, while still being able to poll for events. I thought I could bypass it by calling QCoreApplication::processEvents in my update function of my game loop, and just not calling app.exec -- however, this doesn't really work, as my UI just (1) takes forever to start up and (2) freezes and (3) doesn't respond to UI stuff such as terminating when closing etc.

    How am I able to take control of the main loop while still using Qt to create a basic window that I can render to using my opengl functionality?

    Thanks!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 16 Nov 2019, 07:37 last edited by
      #2

      Hi and welcome to devnet,

      What are you doing in your game loop ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • F Offline
        F Offline
        Flyverse
        wrote on 16 Nov 2019, 08:59 last edited by Flyverse
        #3

        @SGaist
        Thanks for answering.
        Basically, I am separating rendering and updating to have fixed-timestep updating (for physics etc) as well as as-fast-as-possible rendering with time interpolation. (Heavily heavily inspired from Gaffer on Games article)
        My code looks as follows (only slightly simplified):

        ... within my OpenGLContext
        void GLWindow::gameLoop()
        {
            const double delta = 1.0 / fixedUpdatesPerSecond;
            auto time = QDateTime::currentMSecsSinceEpoch();
            double accumulated = 0.0;
            while (! this->terminate)
            {
                auto newTime = QDateTime::currentMSecsSinceEpoch();
                double frameExecution = tdiff(time, newTime);
                time = newTime;
                accumulated += frameExecution;
                while (accumulated >= delta)
                {
                    // Handle user input / system polling
                        //However, since Qt has event driven polling, let's just call processEvents and then handle any input events by putting their results into a map.
                    QCoreApplication::processEvents();
                    // Update our states
                    this->updateState(delta);
                    accumulated -= delta;
                }
                this->render(accumulated / delta);
            }
        }
        

        In the same class, I have updateState and render:

        void MyGL::updateState(float delta)
        {
        //... Bunch of commented-out code to make sure base loop works first
            if(myKeys.at(Qt::Key_W)) {
                cam->translateAlongForward(delta * 3.0);
                cam->update();
            }
        }
        void MyGL::render(float aheadAlphaPercent)
        {
            this->update();
        }
        void MyGL::paintGL()
        {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            lambertShader->setViewProj(cam->matrix());
            // a lot of other drawing stuff
        }
        

        I know that my rendering code itself works because I initially tested it by just using a QTimer.

        Instead, I now do the following:

        ...in main...
        QApplication a(argc, argv);
        QSurfaceFormat::setDefaultFormat(format);
        MainWindow w;
        w.show();
        w.start();
        //return a.exec();
        // ^Dont^want^to^uncomment^this^
        ... MainWindow::start (MainWindow is QMainWindow subclass)...
        uiElements->glWindow->gameLoop(); //glWindow is subclass of OpenGLContext
        

        As you can see, I tried to avoid calling Qt's blocking event loop in QApplication::exec, but am still polling events. However, this doesn't work properly, as described in my first post.

        1 Reply Last reply
        0

        3/3

        16 Nov 2019, 08:59

        • Login

        • Login or register to search.
        3 out of 3
        • First post
          3/3
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved