C++ QOpenGLWidget中的动画看起来很滞后
我没有编写游戏的经验,本周我正在尝试用QT编写一个音乐游戏地图(最终可能成为游戏?)的播放器;遇到了问题,我想我需要一些帮助 我想在QOpenGLWidget上以每秒60帧的速度播放动画。只是一些圆圈在小部件中移动,CPU使用率很低。但它看起来很落后 我通过将默认surface格式的交换行为设置为doublebuffer/triplebuffer启用了VSync,并且间隔为1,我认为这意味着60 FPSC++ 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绘图示例就是这样做
我实现了paintGL()方法,并使用QPainter绘制内容,QT的2D绘图示例就是这样做的
计算每个圆位置的步骤放置在paintGL方法之外,并将在调用paintGL之前运行 这是程序运行的流程:
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);
}
我尝试了以下方法来获取更多信息:
看起来有时候框架会掉下来;这看起来很明显,他和上次通话的时间间隔超过了30毫秒
(另外,我希望它也能在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曲面