Not very accidentally I also want to implement a correct and flexible main/ game loop.
- game logics/ phyics will run at a constant speed dT (for example 30fps)
-- aka, the game logics should result in the same, independent of the machine/ hardware (note: this doesn't mean rendering)
- enabling/ disabling vsync should not affect gameplay/ speed (both should be supported)
-- aka game logics should be updated in the same speed when rendering is done at 100fps, 60fps or 25fps etc.
- game shouldn't break when debugging (and a specific frame time hits the fan)
- there are quite some solutions to figure out a 'good' dT (DeltaT), a few that I've read about:
-- static, delta T is always 1/60th of a second for example (CPU dependent)
-- use last frame time and make this dT for next frame
-- average the last x frames and make this dT for next frame (catch 'spikes')
-- guarantee that a frame takes x time, i.e. 1/60 or 1/30 second
(sleep if frame is shorter then ideal, sleep ideal time - frame time of frame time exceed ideal frame time)
- is the following example/ statement correct when V-sync is enabled, with 60hz:
-- game logics/ non rendering take 5ms
-- rendering takes 5ms
-- 16 - 5 - 5 -> vsync makes the API/ present call wait 6ms before presenting
(basically guaranteeing the full loop takes 16ms, 1/60)
I had to read it quite a few times to get the terminology right, until I read the first article on phyics :)
And also that it will decouple physics from rendering, which sounds like a good thing to do.
I've tried to 'redo' the final solution from the article, in my own words/ syntax.
With the different that I don't pass a "State" (position + velocity) in my render function, since all updating is done in the update call/function.
- are my assumptions correct/ is this the way to go?
- what exactly is 'dt', here 0.01? (I took it from the article code sample)
- and to which update frequency is the 'physics' (update logics) part set to in this example?
double dt = 0.01
double accumulator = 0.0
double currTime
double totalTime
double lastTime
while(!quit)
{
// here time starts running for non-rendering stuff
while(peekmessage)
{
handle windows messages
}
lastTime = currtime
currTime = GetTime()
double frameTime = currTime - lastTime
if(frameTime > 0.25) frameTime = 0.25 // seconds?
accumulator += frameTime
// is this while loop the decoupled physics part?
while(accumulator >= dt) // dt being the set/ wanted frametime??
{
mGame->UpdateLogics(totalTime, dt)
totalTime += dt
accumulator -= dt
}
// here the non-rendering time has passed, rendering time starts
mGame->Render()
}