ПрограммированиеФорумОбщее

Игровой цикл

Страницы: 1 2 3 4 Следующая »
#0
19:43, 1 мар 2017

Тема вроде широко известная, но есть впечатление, что самоочевидным и общеизвестным является далеко не всё.

Поэтому видится смысл поговорить вслух.

Подобные темы были, ну вот будет тема обновлённая.

Чтиво:
http://gafferongames.com/game-physics/fix-your-timestep/
http://www.koonsolo.com/news/dewitters-gameloop/
http://gameprogrammingpatterns.com/game-loop.html
http://www.gamedev.ru/community/gamedev_lecture/articles/game_orhetecture
https://www.wired.com/2013/02/john-carmacks-latency-mitigation-strategies/

В качестве затравки набросок:

// There is some argument about double vs. fixed-point:
// https://twitter.com/ID_AA_Carmack/status/418158611664097280
// https://tomforsyth1000.github.io/blog.wiki.html ( A matter of precision )
double update_dt=1.0/50.0; // Game logic updates 50 times per second.
double max_fps=250.0; // FPS limiter.
double max_lag=0.125;
double t0,t1=get_time();
double t_render=t1;
double delta=0.0; // Time to next update.
while(!quit)
{
    t0=t1;
    t1=get_time();
    delta-=(t1-t0);
    if(delta>2.0*update_dt)
    {
        // Something weird happened.
        // Maybe time got reset.
        delta=0.0; // Whatever.
        t_render=t1;
    }
    if(delta<-max_lag)
    {
        // We are lagging behind.
        // Prevent unbound delta accumulation (maybe update() takes more than update_dt).
        delta=-max_lag;
    }
    while(delta<=0.0)
    {
        update(world);
        delta+=update_dt;
    }
    if((t1-t_render)*max_fps>=1.0)
    {
        t_render=t1;
        double time_since_update=(get_time()-t1)+(update_dt-delta);
        render(world,time_since_update); // For extrapolation.
        if(vsync) wait_for_vsync();
        swap_buffers();
    }
    else
    {
        // Do not render too often: see http://www.teamliquid.net/forum/starcraft-2/139794-blizzard-confirms-sc2-overheating-bug .
        sleep(0.001);
    }
}

Можно критиковать.

Вопросы:
1. Мысль из http://www.gamedev.ru/community/gamedev_lecture/articles/game_orhetecture о эффективности порядка Render(); Update(); Present(); - ещё актуальна?
2. VSync здесь вообще внятно сделан?

#1
19:58, 1 мар 2017

Если игровой цикл правильно организован, то всё шелестит очень быстро.

Ну сделал так чувак wait_for_vsync(); Мы же не видим что там внутри делается.

Что беспокоит-то ?

У Rastertek всё неплохо разобрано про это дело - игровой цикл.

Лучше по порядку про плюсы и минусы, а не сумбурно кучей.

Что не так с : Render(); Update(); Present(); ? 

О каких конкретно "ошибках" речь ?

#2
22:09, 1 мар 2017

bykabak
> О каких конкретно "ошибках" речь ?
видимо о распространенной херне, когда кто-то делает update где попало, а потом у него объекты начинают о камеры отставать.

#3
22:15, 1 мар 2017

> Что не так с : Render(); Update(); Present(); ?
Ну мы вроде как прошлый кадр рендерим таким способом.
Т. е. поинт, видимо - ценой latency улучшить throughput т. к. зависимость односторонняя (update->render).
Ну и вопрос - акутально ли? Дейстительно улучшает?

#4
22:46, 1 мар 2017

FordPerfect
Т. е. поинт, видимо - ценой latency улучшить throughput т. к. зависимость односторонняя (update->render).

Я не знаю, вас в школе не учили выражать свои мысли ?  ( Я ничего не понял )

Если честно, код в старте топика какой-то необычный. :)  Зачем вы его притянули сюда ?  Чем он вас зацепил ?

Вот у Rastertek так vsync сделан :  http://www.rastertek.com/dx11tut03.html

#5
23:43, 1 мар 2017

Развёрнутее:
в порядке Render(); Update(); Present(); (по сравнению с интуитивным Update(); Render(); Present();) latency выше:

// .....
Render();
Update();  // Нажали клавишу.
Present(); // ...
Render();  // ...
Update();  // ...
Present(); // Увидели реакцию на нажатие.
Render();
Update();
Present();
// .....

против

// .....
Update();  // Нажали клавишу.
Render();  // ...
Present(); // Увидели реакцию на нажатие.
Render();
Update();
Present();
Render();
Update();
Present();
// .....

Но throughput может быть лучше, т. к. update() в идеале не зависит от render() и не обязан дожидаться того, что render() ну например данный на GPU зальёт. Т. е. они могут работать более внахлёст. В обратной ситуации это более проблематично, т. к. render() зависит от update() - пока не обновились - непонятно, что рисовать.

#6
23:46, 1 мар 2017

Код в старте - мой. Как пример "как бы я сейчас делал"; ну и для затравки разговора.

#7
9:10, 2 мар 2017

Я полагаю, что всё должно идти по порядку, и, возможно, что-то не каждый кадр выполняется.  Что именно - решает разработчик, исходя из его видения как должно работать.

Вы видите решение с vsync так, как вы решили. Ссылку на альтернативный вариант я вам дал.
Из вашей темы непонятно, что конкретно вас беспокоит ?

#8
9:38, 2 мар 2017

По винду цикл должен быть таким:

while (true) {
  while (UpdateStep()) {};
  if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
    if (msg.message == WM_QUIT)
      break;
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}

Апдейт степ, в котором физика/логика должен быть каким-то таким:

bool UpdateStep() {
  bool Out = World->Time() + World->TimeStep() <= get_time();
  if (Out) World->DoUpdateStep();
  return Out;
}

А рендер мира должен быть в оконной функции в обработчике WM_PAINT

#9
10:53, 2 мар 2017

MrShoor
если update будет занимать больше времени чем World->TimeStep, то приложение перестанет реагировать на события?

#10
10:59, 2 мар 2017

kipar
> если update будет занимать больше времени чем World->TimeStep, то приложение
> перестанет реагировать на события?
А смысл реагировать? Ну ок, можно переделать, но оно как было не играбельно, так и останется.

void Update() {
  long long NewTime = get_time();
  int UpdateCount = (NewTime - World->Time()) / World->TimeStep();
  for (int i = 0; i < UpdateCount; i++)
    World->DoUpdateStep();
  return;
}

А оконый цикл такой:

while (true) {
  Update();
  if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
    if (msg.message == WM_QUIT)
      break;
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
}
#11
11:10, 2 мар 2017

MrShoor
ну хотя бы чтоб выйти можно было. Да и вообще, по-моему лучше если игра тормозить начинает чем если она совсем виснет. Против исправленной версии ничего не имею.
—-
а, в исправленном еще остаток дельты с прошлого шага не учитывается. Но в общем суть ясна. учитывается

#12
11:30, 2 мар 2017

А не лучше ли вынести в 2 разных потока Update и Render?

#13
12:11, 2 мар 2017

FordPerfect
> Игровой цикл

Пытаюсь от него уйти. Запустить по крайней мере три процесса отдельно: графика, физика и логика.

#14
12:16, 2 мар 2017

dave
И потом все это синхронизировать.

Страницы: 1 2 3 4 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.