Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QOpenGLWidget中的动画看起来很滞后_C++_Qt_Animation_Opengl_Vsync - Fatal编程技术网

C++ QOpenGLWidget中的动画看起来很滞后

C++ QOpenGLWidget中的动画看起来很滞后,c++,qt,animation,opengl,vsync,C++,Qt,Animation,Opengl,Vsync,我没有编写游戏的经验,本周我正在尝试用QT编写一个音乐游戏地图(最终可能成为游戏?)的播放器;遇到了问题,我想我需要一些帮助 我想在QOpenGLWidget上以每秒60帧的速度播放动画。只是一些圆圈在小部件中移动,CPU使用率很低。但它看起来很落后 我通过将默认surface格式的交换行为设置为doublebuffer/triplebuffer启用了VSync,并且间隔为1,我认为这意味着60 FPS 我实现了paintGL()方法,并使用QPainter绘制内容,QT的2D绘图示例就是这样做

我没有编写游戏的经验,本周我正在尝试用QT编写一个音乐游戏地图(最终可能成为游戏?)的播放器;遇到了问题,我想我需要一些帮助

我想在QOpenGLWidget上以每秒60帧的速度播放动画。只是一些圆圈在小部件中移动,CPU使用率很低。但它看起来很落后

我通过将默认surface格式的交换行为设置为doublebuffer/triplebuffer启用了VSync,并且间隔为1,我认为这意味着60 FPS
我实现了paintGL()方法,并使用QPainter绘制内容,QT的2D绘图示例就是这样做的
计算每个圆位置的步骤放置在paintGL方法之外,并将在调用paintGL之前运行

这是程序运行的流程:

  • 读剧本
  • 启动计时器
  • 发布事件以调用“勾选”过程
  • “勾选”过程运行,并请求更新窗口
  • 画图,绘制框架
  • 在退出paintGL方法之前,将发布一个调用“tick”的事件
  • 我想现在它需要等待VSync和swap缓冲区
  • 如果调用了“勾号”,请转至步骤4
  • 守则:

    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->Compute(&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, &playerContext);
    
        painter.end();
    
        QMetaObject::invokeMethod(this, "onTick", Qt::QueuedConnection);
    }
    
    我尝试了以下方法来获取更多信息:

  • 每次输入paintGL方法时,通过qDebug()打印当前时间
    看起来有时候框架会掉下来;这看起来很明显,他和上次通话的时间间隔超过了30毫秒
  • 将鼠标移入/移出窗口持续时间动画。它在更高的可能性中变得滞后
  • 在计算位置收集时间成本,似乎只是很短的时间
  • 在android上运行这个程序,和以前一样,甚至更落后
  • 更复杂的游戏在我的电脑上流畅地运行。我认为硬件足够快。(i7-4800M,GTX 765M)
  • 一次又一次地重新启动程序。它现在是流畅的(更少或没有发生掉帧),现在是滞后的。。。我找不到图案
  • 另外,将动画调整为30 FPS,因为它看起来总是很滞后

    我该如何处理这个问题
    (另外,我希望它也能在android上运行)

    这是完整的源代码

    (cgssplayer.zip,不是源代码)
    (我认为cgss-fumen.cpp在这个问题上没有区别)

    它可以在QTCreator(5.6)中构建,没有其他依赖项

    (对于QT 5.5,需要添加

    CONFIG += c++11
    

    进入.pro文件)

    您是如何绘制按钮的?有小部件吗?@Mykola没有,按钮和图标都是基本形状,如圆形、矩形和三角形奇怪,它一定不会导致perormance降级?我怀疑,您的性能问题可能是由不同于绘画的原因造成的。您是通过哪种方式更新OpenGL曲面的?@Mykola所有内容都是通过QPainter绘制的,交换缓冲区等的细节由QT确定。我不知道它是怎么降下来的。我决定尝试一下SDL,看看是否发生了同样的问题。您还可以尝试将重新绘制插槽连接到QTimer timeout()信号,以便连续时间重新绘制OpenGL曲面