Breakout clone & smooth ball movement & fixed time step loop with varying framerate

Started by
14 comments, last by ddn3 15 years, 1 month ago
Your timer might be to blame then, if it's using HPC behind the scenes. See this page for discussion:

http://www.virtualdub.org/blog/pivot/entry.php?id=106

Try this code to see if it's possibly the case, I didn't test this, but its just your code running in infinite loop checking if the results from timeGetTime vs c.GetElapsedTime agree over a long running period. You can adjust the number of iteration of the loop to increase the step time.

{	sf::Clock c;	while (1) 	{		float a = 0.0f;		DWORD start = timeGetTime();		c.Reset();		for (int g=0; g<100000; g++)		{			float d = sqrtf(g);			a += d*d*d;		}		float dur =  c.GetElapsedTime();		float dur2 = (float)(timeGetTime()-start)/1000.0f;				if (abs(dur-dur2)>.01) 		{				char mess[256];			sprintf(mess, "detected anomalous time error greater than .01 sec");			MessageBox(NULL, mess, mess, MB_OK);		}	}}


Good Luck!

-ddn
Advertisement
Quote:Original post by ddn3
Your timer might be to blame then, if it's using HPC behind the scenes. See this page for discussion:

http://www.virtualdub.org/blog/pivot/entry.php?id=106

Try this code to see if it's possibly the case, I didn't test this, but its just your code running in infinite loop checking if the results from timeGetTime vs c.GetElapsedTime agree over a long running period. You can adjust the number of iteration of the loop to increase the step time.

*** Source Snippet Removed ***

Good Luck!

-ddn


Ran the code for a few minutes and there was no popup warning. Guess the timer's fine. The only problem is the variable framerate that introduces seldom big times between frames. I don't know how to deal with varying framerates in a fixed time step loop. :D
bump :D
Thinking about it I know the issue. Your updating way too much per frame. Normally games update 1x per tick. A tick is defined by the desired update rate, which in your case is probably 1/60 sec. So the code should be like this.

void CGameEngine::Update(){											const float updateRate = 60.0f;	const float tick = 1.0f/updateRate;  //note the new tick measure	static float accumulator = 0.0f;	accumulator += timer.GetTime();	timer.Reset();								// NOTE: you have to sleep off the excess time if your updating too fast for 	// ur desired update rate, otherwise you'll just burn CPU waiting to update a single tick. 	if (accumulator < tick)	{		//NOTE: we add 1 because a sleep value of 0, gives a non-deterministic sleep time, which isn't 		//desirable, time is converted into miliseconds, for Sleep.		float sleepTimeMs = ((tick-accumulator)*1000)+1.0f;		Sleep((int)sleepTimeMs);	}	else	{		//this should occur at a near constant rate of 1 update, occasionally spiking if the interval is 		//longer than a tick.		numUpdates = 0;		while (accumulator >= tick )		{			UpdateSimulation(amount);					accumulator -= amount;			numUpdates++;		}	}	interpolator = accumulator / interpolator;}


That should do it, this is untested but you should get the gist of it. Update at a desired update rate, sleep off excess time to give other threads CPU and reduce your own CPU usage. Your update rate affects all your simulation, so you might need to recalibrate forces and velocities to fit within the new update rate.

Good Luck!

-ddn
Quote:Original post by ddn3
Thinking about it I know the issue. Your updating way too much per frame. Normally games update 1x per tick.
-ddn


You are correct, that's what's happening.
The issue with your code though, is, presuming we are running single threaded, that Render() will also be called at updateRate, rate per second and this is undesirable. The interpolator would have no use now, his sole purpose was to predict what update will do next frame all this happening while update wasn't doing any updates(accumulator being < updateRate)
Yah you can decouple the rendering and update rates, that's fairly common. Games can render at floating rate ( anywhere from 60-15 fps ) while the simulator updates at a fixed rate of 10 ups for instance. Just adjust the sleep time to be your desired framerate vs update rate and that should do it. You still want to have a consistent framerate even though your game can run at 1000fps, it really doesn't matter when you have a vsync of 60hz. If you enable vsync you're application will be effectively blocked during the vsync and you're just burning CPU then which could be used otherwise, this might be a DirectX setting where it will return immediately from flush instead of blocking, I don't remember.

Good Luck!

-ddn

This topic is closed to new replies.

Advertisement