Archived

This topic is now archived and is closed to further replies.

dario_s

Time based rendering/movement/animations?

Recommended Posts

dario_s    123
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?

Share this post


Link to post
Share on other sites
DarkKiller    122
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...

Share this post


Link to post
Share on other sites
DarkKiller    122
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...

Share this post


Link to post
Share on other sites
Enigma    1410
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

Share this post


Link to post
Share on other sites
dario_s    123
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?

Share this post


Link to post
Share on other sites
DarkKiller    122
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]

Share this post


Link to post
Share on other sites
James Trotter    432
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...

Share this post


Link to post
Share on other sites
dario_s    123
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]

Share this post


Link to post
Share on other sites
pleja    122
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.

Share this post


Link to post
Share on other sites