Как наиболее эффективный способ сохранить постоянную частоту кадров с DirectX и C ++?

StackOverflow https://stackoverflow.com/questions/1583436

Вопрос

Я изучаю DirectX из книги о игровом программировании, и он использует следующий метод для игрового цикла:

long int start = GetTickCount();
while(true)
    GameRun();

void GameRun()
{
     if(GetTickCount() - start >= 30)
         //do stuff
}

Это делает start Равное, что бы ни было время (я предполагаю, что количество тиков дает количество «клещей» с момента начала программы), а затем, 30 клещей спустя, делает все ИИ, рендеринг и т. Д.

Мой вопрос: разве не было бы более эффективным делать весь ИИ и т. Д. Сначала, тогда, если останется время, подождите, пока кадр не будет изменен?

Итак, что было бы лучшим способом сохранить постоянную частоту кадров? (Предпочтительно используя только заголовки DirectX, которые я бы уже использовал для звука, изображений и Imput (например, d3d9.h))

И, по связанным примечанию, что именно делает GetTickCount (), и как долго - «тик»

Это было полезно?

Решение

Для вашего игрового петля читайте эта статья. Анкет Это подведите варианты и дает ваш выбор ясным.

Теперь для GetTickCount () это самый простой способ получить время в Windows (я не знаю, что для Unix Oses). QueryPerformanceFrecounts и QueryPerformanceCounter дает гораздо больше точности, но может быть трудно понять, как их правильно использовать.

Вы можете быть заинтересованы в чтении, как Ogre :: Timer Class работает (OGRE-известная библиотека 3D-рендеринга в реальном времени с открытым исходным кодом) Они добавили некоторый код для решения некоторых потенциальных проблем с этими функциями, и есть код для нескольких платформ.

Вы можете взять код и использовать его в своих приложениях.Лицензия грядущей версии OGRE - MIT

Таким образом, вы можете сосредоточиться на своем игре и коде игры.


Обновите точность времени: теперь, если вы можете использовать последнюю версию Boost, есть Boost.chrono которые обеспечивают высокую точность, steady_clock, то есть кросс -платформ и Использует QueryPerformanceFrequency и QueryPerformanceCounter в Windows. Анкет Фактически, Chrono является предложением для дополнения к стандартной библиотеке C ++.

Другие советы

Примерный код, который вы предоставили, является худшим способом реализации игрового цикла. Как вы заметили, это просто огромная трата, чтобы подождать, пока не придет время освежить.

Просто выберите произвольный временный шаг (например, одну секунду) и выразите все ваши меры относительно этого временного шага.

Это будет выглядеть:

while ( !done )
{
    float alphaTime = timeConstant / (currentTime - lastLoopTime);
    dispatchEvents();
    gameLogic( alphaTime );
}

void gameLogic( float alphaTime )
{
    movePlayer( playerSpeed * alphaTime );
}

Таким образом, вы не тратите время на ожидание кадров, вы можете позволить вашим сценариям ИИ работать, ... и все будет двигаться с той же скорости, поскольку движения умножаются к фактору времени.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top