2

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

我想在 QOpenGLWidget 上以 60 FPS 的速度显示动画。只是小部件中的一些圆圈移动,CPU使用率很低。但它看起来很滞后。

我通过将默认表面格式的交换行为设置为双缓冲区/三缓冲区来启用垂直同步,并且间隔为 1,我认为这意味着 60 FPS。
我实现了paintGL() 方法并通过QT 的2D 绘图示例所做的QPainter 绘制内容。
计算每个圆的位置的步骤放置在paintGL 方法之外,并且将在调用paintGL 之前运行。

这是程序运行的流程:

  1. 阅读脚本
  2. 启动计时器
  3. 发布事件以调用“tick”程序
  4. “tick”程序运行,并请求更新窗口。
  5. paintGL 运行,绘制框架
  6. 在退出paintGL方法之前,会发布一个调用“tick”的事件
  7. 我认为现在它等待 VSync 和交换缓冲区
  8. 调用“tick”,转到第 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);
}

我尝试了这些方法来获取更多信息:

  1. 每次进入paintGL方法时通过qDebug()打印当前时间。
    似乎有时会掉帧;看起来很明显,距离上次调用的间隔超过30ms。
  2. 将鼠标移入/移出窗口持续时间动画。它变得滞后的可能性更高。
  3. 收集计算位置的时间成本,似乎只有很短的时间。
  4. 在android中运行这个程序,一样甚至更慢。
  5. 更复杂的游戏可以在我的电脑上流畅运行。我认为硬件足够快。(i7-4800M, GTX 765M)
  6. 一次又一次地重新启动程序。它现在很流畅(很少或没有发生丢帧),现在很迟钝......我找不到模式。

此外,将动画调整为 30 FPS,因为它看起来总是滞后。

我该如何处理这个问题?
(ps我希望它也可以在android上运行)

这是完整的源代码

https://github.com/sorayuki/CGSSPlayer/releases(cgssplayer.zip,不是源代码)
(我认为cgss-fumen.cpp对这个问题没有影响)

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

(对于 QT 5.5,它需要添加

CONFIG += c++11

进入 .pro 文件)

4

0 回答 0