2013-06-18 8 views
8

Интересно, может ли вызов updateGL() в фиксированные интервалы таймера замедлять процесс рендеринга. Итак, я хочу попробовать сделать рендер в реальном времени. Я не выполняю функцию автоматически. Кто-нибудь это знает?Как сделать updateGL() в реальном времени в QT

Во-вторых, я прокомментировал updateGL() в своей программе, использование ЦП уменьшено до 1% и 0%. Теперь, когда я нажимаю на виджет дисплея, он перескакивает до 14%, почему? это не GPU, выполняющий всю работу по рендерингу? если да, то почему CPU перескакивает до 14? как я могу это решить?

+0

Для использования ЦП, нет, это не тот GPU, который выполняет * все * задание. ЦП еще должен выполнить команды для перехода на графический процессор, а иногда и ждать синхронизации (а также выполняет логику вашего приложения, если оно есть). Тем не менее, если ваша сцена действительно проста, 14% определенно не нормальное. Убедитесь, что вы не рисуете более 60 кадров в секунду, что не имеет смысла. – Boris

ответ

11

Да, вы можете сделать это в реальном времени, без разрыва (например, перерисовка ровно на 60 кадров в секунду, частота обновления вашего монитора).

Для этого вы должны включить V_sync, и с помощью QTimer timer; интервала 0. Включение V_sync сделает автоматически вызывается swapBuffers() команду CPU-ждать сигнала вертикальной развертки от монитора. Затем таймер будет фактически синхронизирован с частотой обновления монитора.

Связанная информация может быть найдена здесь: http://blog.qt.digia.com/blog/2010/12/02/velvet-and-the-qml-scene-graph/. Обратите внимание на QGLFormat::setSwapInterval(1), чтобы включить V_sync, если это не сделано автоматически в настройках драйвера:

class MyGLWidget: public QGLWidget 
{ 
    // ... 
private: 
    QTimer timer; 
} 

QGLFormat desiredFormat() 
{ 
    QGLFormat fmt; 
    fmt.setSwapInterval(1); 
    return fmt; 
} 

MyGLWidget::MyGLWidget() : 
    QGLWidget(desiredFormat()) 
{ 
    // Configure the timer 
    connect(&timer, SIGNAL(timeout()), this, SLOT(updateGL())); 
    if(format().swapInterval() == -1) 
    { 
     // V_blank synchronization not available (tearing likely to happen) 
     qDebug("Swap Buffers at v_blank not available: refresh at approx 60fps."); 
     timer.setInterval(17); 
    } 
    else 
    { 
     // V_blank synchronization available 
     timer.setInterval(0); 
    } 
    timer.start(); 
} 

Параллельно, вы можете запустить QElapsedTimer, чтобы определить, сколько времени прошло между двумя рисунок (обычно прибл 16.6ms), а также использование эта информация, например, для обновления вашей сцены.

+0

Я добавил this-> format(). SetSwapInterval (1); в конструкторе и swapbuffers() в конце функции paintGL(). но это не имело никакого эффекта. как сделать рендеринг 60 кадров в секунду? – Sam

+0

@ user1596226 Две вещи: вы не должны вызывать 'this-> format(). SetSwapInterval (1);' но вместо этого создайте QGLFormat с этим интервалом подкачки и передайте его конструктору вашего 'QGLWidget'. Затем вы не должны называть 'swapBuffers()' вообще: как я уже сказал, он вызывается автоматически после 'paintGL()' :). Можете ли вы измерить и отобразить время между каждым paintGL(), используя ' QElapsedTimer'? Это будет очень полезно, чтобы понять, что происходит. – Boris

+0

Не могли бы вы написать его для меня, я не знаю, как добавить этот флаг к конструктору. – Sam

Смежные вопросы