Time based rendering/movement/animations?

Started by
8 comments, last by dario_s 20 years, 11 months ago
Hi, Im wondering about how to make the time based rendering... I have successfully implented timebased movement (even though Im sure I havent done it "the right way" so I appreciate feedback on this too). I wanna make my game run at the same speed on most (hopefully all) computers. Any ideas?
Advertisement
What is the main idea behind this?
Do you want the same framerate on every system?
Why??

Do you want a value which can be multiplyed with any speed related operant like movement, rotation.... ect.?

Whats your aim?

Dark

McNugget next time...
DarkMcNugget next time... ;)
For timebased movement and any other equal calculation the following function should be the best way to do this:

Write a function like this (copy and paste) and call it once per frame:
void Val2Proc(){    static double       time_elapsed;   	static __int64      pc1, pc2;	static __int64      pf;        QueryPerformanceCounter((LARGE_INTEGER*)&pc2);		time_elapsed = double(pc2-pc1) / double(pf);        QueryPerformanceFrequency((LARGE_INTEGER*)&pf);        QueryPerformanceCounter((LARGE_INTEGER*)&pc1);    procPower = time_elapsed*50;} 

''procPower'' should be global so that you can use it anywhere in your program.
Note that the first time you call this function ''procPower'' has a bad value! Maybe it is better to set it to zero when calling it the first time (!danger when having divisions).

Dark

McNugget next time...
DarkMcNugget next time... ;)
DarkKiller: your function will lose time if the time to do:
time_elapsed = double(pc2-pc1) / double(pf);QueryPerformanceFrequency((LARGE_INTEGER*)&pf);QueryPerformanceCounter((LARGE_INTEGER*)&pc1); 

is greater than one tick of the performance counter.

Also there is no need to repeatedly call QueryPerformanceFrequency - it won''t change - see here.

A better system would be (for c++):

  class Timer{   private:      __int64 frequency;      __int64 time;   public:      Timer(){         if (!QueryPerformanceFrequency((LARGE_INTEGER*)&frequency)){            //throw exception or set fail flag;         }         QueryPerformanceCounter((LARGE_INTEGER*)&time);      }      int getTimeElapsed(){         __int64 newTime;         QueryPerformanceCounter((LARGE_INTEGER*)&newTime);         int elapsed = (newTime - time) / frequency;         time = newTime;         return elapsed;      }};  


Enigma
Thanks a lott!

The code looks good!
I'll use your code!

Dark

McNugget next time...

[edited by - DarkKiller on April 30, 2003 4:55:07 PM]
DarkMcNugget next time... ;)
My aim is that I want the animations on my md2''s to be the same as the velocity of the models...

You see, on a baaad computer my engine has a framerate of ~30fps whilst on a decent computer with a gf2 32mb MX it runs at >100fps... That makes my characters to move really wierd.

Im not sure on how the theory works behind all this, so if you want, you''re welcome to explain it for me...

I really dont understand how those codes will smooth things out?
Thats maybe easy to explain.

ok, you have a cube you want to move.
So you translate it every frame a bit more.


  static float moveX;moveX += 0.5 * procPower;glTranslate3f(moveX,0,0);DrawCube();SwapBuffer();   


Now it doesn't matter how fast a computer is the cube will allways move with the same speed. If you have 120fps moveX will be very small and with 10fps it would be much greater!

So it you multiply your transformations and rotations of your model with this value 'procPower' you should get smooth animations that have allways the same speed.

But you may have to modify 'procPower = time_elapsed*50;' a bit.
The factor '50' is just a value I've set for myself, because it seems good for me.

I get a good '1.0f' at 10 fps...


Dark

McNugget next time...

[edited by - DarkKiller on May 1, 2003 5:18:18 AM]
DarkMcNugget next time... ;)
Or you could define an ''optimal fps'', and do like this:

float optimalFPS = 60.0f; // Or some any other number...
moveX += 0.5f / optimalFPS * currentFPS;
glTranslatef(moveX, 0.0f, 0.0f);


This will give a good result, and always move it just as much as you want...
Will this work?


    LARGE_INTEGER TimerFrequency, LastTime;unsigned int FPS, softFPS;int computer_time, game_time, delta_time;void calculate_framerate(void){    if(!TimerFrequency.QuadPart)    {        QueryPerformanceFrequency(&TimerFrequency);    }    else	{		LARGE_INTEGER Time;		QueryPerformanceCounter(&Time);				if(LastTime.QuadPart != 0 && (Time.QuadPart-LastTime.QuadPart) != 0)			FPS = ((int)(TimerFrequency.QuadPart/(Time.QuadPart-LastTime.QuadPart)));			        if(!softFPS)        {            softFPS = FPS;        }		else        {            if(softFPS > FPS)                softFPS--;            else if(softFPS < FPS)                softFPS++;        }				// Time stuff		if (!computer_time)		{			// Computer uptime in ms            computer_time = (int)(Time.QuadPart/(TimerFrequency.QuadPart / 1000));		}		else		{			// Delta time in ms			delta_time = (int)((Time.QuadPart - LastTime.QuadPart)/(TimerFrequency.QuadPart / 1000));		}				// Game uptime in ms		game_time  = (int)((Time.QuadPart/(TimerFrequency.QuadPart / 1000)) - computer_time);				LastTime.QuadPart = Time.QuadPart;	}}  


and then I do:

percent = 0.1f;p1xpos +=percent*delta_time; 


It seems alright on my computer, but I havent had the chance to test it on another computer...

[edited by - dario_s on May 1, 2003 8:40:00 AM]
Well, for me this works perfectly:


  void spinDisplay(void) {								// Rotiraj svijet i racunaj fps	static float max=0.0f;	FILE *out;	static float framesPerSecond = 0.0f;						// fps    	static float lastTime = 0.0f;							// Kad smo posljednji put crtali	static float frameTime = 0.0f;	float currentTime = timeGetTime() * 0.001f;			g_FrameInterval = currentTime - frameTime;	frameTime = currentTime;	++framesPerSecond;	if(currentTime-lastTime>1.0f) {		lastTime = currentTime;		if(framesPerSecond>max) {						// Ako imamo najveci fps zapisi ga u frames.dat			out=fopen("frames.dat", "wt");			fprintf(out, "Frames Per Second: %.3f", framesPerSecond);			fclose(out);			max=framesPerSecond;		}		framesPerSecond=0;							// Reset fps        	}	spin+=SpeedFactor*g_FrameInterval;						// Izracunaj kut vrtnje(Zemlja je osnova)	}  


Sorry for non-english comments. Too lazy to translate them.

This topic is closed to new replies.

Advertisement