Анимация в QOpenGLWidget выглядит запаздывающей

У меня нет опыта в написании игры, и на этой неделе я пытаюсь написать для игрока карту музыкальной игры (наконец, может стать игрой?) В QT; встретил проблему, и я думаю, что мне нужна помощь.

Я хочу показать анимацию в 60 FPS на QOpenGLWidget. Это всего лишь несколько кругов в виджете, и загрузка процессора низкая. Но это выглядит запоздалым.

Я включил VSync, установив поведение свопинга по умолчанию для поверхностного формата по умолчанию: doublebuffer / triplebuffer и имеет интервал 1, который, я думаю, означает 60 FPS.
Я реализую метод paintGL () и рисую содержимое с помощью QPainter, как это делает пример 2D-рисования QT.
Шаг для вычисления позиций каждого круга размещается вне метода paintGL и будет выполняться до вызова paintGL.

Это поток выполнения программы:

  1. прочитать сценарий
  2. запустить таймер
  3. опубликуйте событие для вызова процедуры «галочка»
  4. запускается процедура «галочка» и запрашивается обновление окна.
  5. PaintGL работает, нарисуйте рамку
  6. перед выходом из метода paintGL публикуется событие для вызова «галочка»
  7. Я думаю, что теперь он ждет VSync и буфер подкачки
  8. «галочка» называется, перейдите к шагу 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. печатать текущее время с помощью qDebug () каждый раз при входе в метод paintGL.
    Кажется, иногда кадр опускается; это выглядит очень очевидным, и его интервал до последнего вызова составляет более 30 мс.
  2. переместите мышь внутрь / наружу анимации продолжительности окна. Это стало медленным в более высокой возможности.
  3. Собрать временные затраты в вычислительной позиции, кажется, очень короткое время.
  4. запустить эту программу в андроиде, точно такой же или даже более медленный.
  5. игра, которая намного сложнее, бегло бегает на моем компьютере. Я думаю, что оборудование достаточно быстрое. (i7-4800M, GTX 765M)
  6. перезапустите программу снова и снова. сейчас он бегло (меньше или вообще не происходило пропадание кадров), теперь запаздывает … Я не могу найти образец.

Кроме того, настройте анимацию на 30 кадров в секунду, потому что она всегда выглядит медленной.

Как я могу справиться с проблемой?
(p.s. Я надеюсь, что это может работать и на Android)

это полный исходный код

https://github.com/sorayuki/CGSSPlayer/releases (cgssplayer.zip, а не исходный код)
(cgss-fumen.cpp не имеет значения в этой проблеме, я думаю)

Он может встроить QTCreator (5.6) без других зависимостей.

(для QT 5.5 требуется добавить

CONFIG += c++11

в файл .pro)

2

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]