title: Animation looks laggy in QOpenGLWidget
body: <p>I have no experience in writing a game and this week I'm trying writing a player of a music game's map (finally may become a game?) in QT; met problem and I think I need some help.</p>
  
  <p>I want to show animation in 60 FPS on QOpenGLWidget. It's just some circles move in the widget, and CPU usage is low. But it looks laggy.</p>
  
  <p>I enabled VSync by set the default surface format's swap behavior to doublebuffer/triplebuffer and has an interval of 1 which I think it means 60 FPS. <br />
  I implement the paintGL() method and draw the content by QPainter which QT's 2D drawing example does. <br />
  The step to compute the positions of each circle is placed outsides the paintGL method, and will run before paintGL is called.</p>
  
  <p>This is the flow of the program runs:</p>
  
  <ol>
  <li>read the script</li>
  <li>start a timer</li>
  <li>post a event to call "tick" procedure</li>
  <li>"tick" procedure runs, and request update the window.</li>
  <li>paintGL runs, draw the frame</li>
  <li>before exit the paintGL method, a event to call "tick" is posted</li>
  <li>I think now it waits for VSync and swap buffer</li>
  <li>"tick" is called, go to step 4</li>
  </ol>
  
  <p>the code:</p>
  
  <pre><code>class CgssFumenPlayer : public QOpenGLWidget
  {
      Q_OBJECT
  
      ...
      bool Load();
  
  public slots:
      void onTick();
  
  protected:
      ....
      void paintGL() override;
      QElapsedTimer elapsedTimer;
  };
  
  int main(int argc, char *argv[])
  {
      QApplication a(argc, argv);
  
      QSurfaceFormat fmt;
      fmt.setSwapBehavior(QSurfaceFormat::TripleBuffer);
      fmt.setSwapInterval(1);
      QSurfaceFormat::setDefaultFormat(fmt);
  
      CgssFumenPlayer w;
      w.Load();
      w.setFixedSize(704, 396);
      w.show();
  
      return a.exec();
  }
  
  bool CgssFumenPlayer::Load()
  {
      ....
      elapsedTimer.start();
      QMetaObject::invokeMethod(this, "onTick", Qt::QueuedConnection);
  }
  
  void CgssFumenPlayer::onTick()
  {
      playerContext.currentTime = elapsedTimer.elapsed() / 1000.0;
      double f = playerContext.currentTime / (1.0 / 60);
      playerContext.currentTime = (int)f * (1.0 / 60);
  
      fumen-&gt;Compute(&amp;playerContext);
  
      update();
  }
  
  
  void CgssFumenPlayer::paintGL()
  {
      QPainter painter;
      painter.begin(this);
  
      painter.setRenderHint(QPainter::Antialiasing);
  
      painter.setWindow(0, 0, windowWidth, windowHeight);
      painter.fillRect(QRectF(0, 0, windowWidth, windowHeight), QColor().black());
      DrawButtons(painter);
      DrawIcons(painter, &amp;playerContext);
  
      painter.end();
  
      QMetaObject::invokeMethod(this, "onTick", Qt::QueuedConnection);
  }
  </code></pre>
  
  <p>I tried these ways to get more information:</p>
  
  <ol>
  <li>print current time by qDebug() each time entering the paintGL method. <br />
  It seems sometimes frame is dropped; it looks very obvious, and he interval to last time it's called is more than 30ms.</li>
  <li>move the mouse in/out the window duration animation. It became laggy in higher possibility.</li>
  <li>collect the time cost in compute position, seems only a very short time.</li>
  <li>run this program in android, just the same or even more laggy.</li>
  <li>game which are much more complex runs fluently on my computer. I think the hardware is fast enough. ( i7-4800M, GTX 765M )</li>
  <li>restart the program again and again. it's now fluent (less or no frame-dropping happened), now laggy... I can't find the pattern.</li>
  </ol>
  
  <p>Also, adjust the animation to 30 FPS cause it always looks laggy.</p>
  
  <p>How can I deal with the problem? <br />
  (p.s. I hope it can run on android as well)</p>
  
  <p>this is the full source code</p>
  
  <p><a href="https://github.com/sorayuki/CGSSPlayer/releases" rel="nofollow">https://github.com/sorayuki/CGSSPlayer/releases</a> (cgssplayer.zip, not the source code) <br />
  (cgss-fumen.cpp makes no difference in this problem I think)</p>
  
  <p>It can build in QTCreator (5.6) with no other dependency.</p>
  
  <p>(for QT 5.5, it require to add</p>
  
  <pre><code>CONFIG += c++11
  </code></pre>
  
  <p>into the .pro file)</p>