5. Ogre3D: FrameListener

28.06.2012

Любая игра представляет из себя замкнутый цикл. Во времена DOSа программистам приходилось работать с прерываниями, чтобы обработать ввод, обновить механику и вывести изображение на экран. Если довольно сильно упростить, то игру можно представть следующим псевдокодом:

while ( true )
 
{
    readInput();
 
    calculateMechanics();
 
    drawGraphics();
 
}

Обычно, для подготовки следующего кадра, существует специальный метод update( float elapsed ), куда передается время, истекшее с момента предыдущего вызова. В этом методе и происходит обновление. Другой способ – запускать игровой цикл с константным временем между кадрами, такой метод может называться, например, tick(). Например, нам нужно считать игровую механику 15 раз в секунду. Мы обновляем графику 60 раз в секунду, а внутри вызовов update( float elapsed ) считаем сколько осталось до следующего вызова механики.

void update( float elapsed )
{
    timeToUpdateMechanics -= elapsed;
    if ( timeToUpdateMechanics <= 0 )
    { 
        timeToUpdateMechanics = 1000 / 15; // const
        tick();
    }
}

FrameListener.

В Ogre3d мы можем зарегистрировать специальный класс для того, чтобы получать обновления перед и после отрисовки кадра. Этот класс известен как FrameListener. Интерфейс FrameListener выглядит следующим образом:

virtual bool frameStarted(const FrameEvent& evt);
virtual bool frameRenderingQueued(const FrameEvent& evt);
virtual bool frameEnded(const FrameEvent& evt);

Нам необходимо перегрузить любые из этих функций, чтобы получать обновления.

frameStarted

Вызывается ровно перед началом отрисовки кадра

frameRenderingQueued

Вызывается после выполнения всех графических команд, но перед сменой графических буферов

frameEnded

вызывается после отрисовки кадра

Как Вы могли отметить каждый из методов возвращает булево значение. Фактически, цикл отрисовки идет бесконечно, пока любой из этих методов не вернет false. Для того, чтобы завершить работу Ogre3D Вам необходимо вернуть false из любого вызова. Каждый из этих методов принимает в качестве параметра ссылку на FrameEvent. Единственным полезным в FrameListener’е параметром является FrameEvent::timeSinceLastFrame. Эта переменная отслеживает количество времени, прошедшее с момента последнего вызова frameStarted. Обратите внимание – во frameEnded тоже придет время с момента frameStarted. Также необходимо отметить, что порядок обращения к frameListener ам не зависит от порядка регистрации. Т.е. если у вас зарегистрировано несколько FrameListener ов, какой из них будет вызван первым неизвестно. Нередко, основным frameListener ом регистрируют само приложение – в этом случае вы сами сможете определить в каком порядке обновлять ваши игровые объекты.

Регистрация FrameListener.

Для того, чтобы FrameListener получал обновления от Ogre3D, необходимо зарегистрировать его. Сделать это вы можете с помощью соответствующих методов Ogre::Root:

Ogre::Root::addFrameListener()
Ogre::Root::removeFrameListener()

Ogre::Root может быть найден среди protected членов базового приложения.

mRoot->addFrameListener( frameListener );

Заполнен: Ogre3D
Присвоен тэг:

avatar

Об Авторе ()

Коллективный разум нашей редакции. Все человеческое здесь заканчивается и начинается C++!

Комментирование закрыто.

Наверх