Re: Smooth animation
- From: Stephan Rose <ker-spam-mos@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Fri, 02 Dec 2005 14:46:50 +0100
On Thu, 1 Dec 2005 09:26:26 +0100, "Matt Jack" <mathieu_gdal@xxxxxxxx>
wrote:
>Superb explanations!
>I could understand all, despite my poor english; it proves it is clear!
>
>My App is "Time Based". At each render, I measure the time since the last
>render, and move the camera/the 3D object using this delay.
>
>I have just change my app to make it "Frame-based" (I have keep almost all
>my code, excepted that I apply a constant when I compute the camera/3D
>objects position) : Everything becomes *smooth* !!!
>
>I have found the reason : When I compute the time delay between 2 frames, I
>use the QueryPerformanceCounter win32 API, and this one is not bug-free.
>For example, often, when I compute the delay between 2 frames with this API,
>I get 0 millisecond. It makes my 3D objects "freeze" between 2 frames.
QueryPerformanceCounter is bug-free, I use it extensively in real-time
datalogging applications without any problems. If you get 0
milliseconds then its because your resolution is too low. Ie, the
delta time is LESS than 1 ms, and your are truncating it to 0
milliseconds. Work with doubles or floats, not with integers.
Frame-based animation, particularly with a constant = BAD!
This is why....
My system at home has 2 GeForce 7800 GTs operating in SLI mode.
My system here at work has a single GeForce 6700 if I remember
correctly
If I now write a frame-based app on this system until it looks good on
this computer, and say you achieve 40 FPS. My system at home may
easily obtain 80 FPS if not even more due to its significant higher
performance capabilities. I used 80 FPS because with your current
method, this would mean your app, and your animations, would run twice
as fast on my home system, then on my system here at work. On the same
thought, a slower system that would only get 20 FPS, your app would
now run at half this speed. In the old DOS days, there are quite a few
games that suffered from this problem.
The only solution with a frame-based system as stated by another
poster would to be to add or drop frames as necessary to achieve your
40 FPS reference in some way. But if you do that, you already have to
measure time....so you might as well use this measured time for your
animations and go time based and not have to worry about framerates
ever again (at least not as far as the speed of your animations and
object movement, etc. is concerned).
You have to keep in mind that not just animations, but also object
movements, physics, etc. everything is based on either that time
reference or frame reference.
That little tiger looks good on your machine now, and smooth with your
constant movement, because its running at high FPS. But try it with 10
FPS and then see what happens...(or just turn vsync on and see the
difference).
Use the time-based animation instead...you will be much much better
off. If you are having trouble using QueryPerformanceCounter and
getting 0 ms as stated, give my class a try that I use. This is almost
the identical class I use in my real-time datalogging apps....pretty
simple to use really.
Call init to initialize it..
QueryMs to query the elapsed time since the last call you did to
QueryMs.
QueryMsAbsolute to query the elapsed time since you initialized OR the
last call to QueryMs, whichever comes first.
Note that my class divides the frequency by 1000 to return the time in
actual ms since when I first wrote this, I needed to display the
timestamps in ms. For an animation engine, you would want the returned
values to not be in the 0-1000 range, but in the 0.0f to 1.0f range,
so for your purposes, take out the division by 1000 the Init function.
using System;
using System.Runtime.InteropServices;
namespace Rail
{
public class CpuTimer
{
private long frequency;
private long start;
private long current;
private double frequencyMs;
[DllImport("kernel32.dll")]
public static extern bool
QueryPerformanceFrequency(ref long frequency);
[DllImport("kernel32.dll")]
public static extern bool QueryPerformanceCounter(ref
long count);
public CpuTimer()
{
}
public void Init()
{
QueryPerformanceFrequency(ref frequency);
frequencyMs = ((double)frequency)/1000.0;
QueryPerformanceCounter(ref start);
}
public double QueryMs()
{
double elapsed =0;
QueryPerformanceCounter(ref current);
elapsed = (double)(current-start);
elapsed /= frequencyMs;
QueryPerformanceCounter(ref start);
return elapsed;
}
public double QueryMsAbsolute()
{
double elapsed = 0;
QueryPerformanceCounter(ref current);
elapsed = (double)(current - start);
elapsed /= frequencyMs;
return elapsed;
}
}
}
--
Stephan
2001 Yamaha YZF-R6 <--- Stolen
.
- References:
- Re: Smooth animation
- From: Matt Jack
- Re: Smooth animation
- Prev by Date: Re: cubes + clear black edges
- Next by Date: Sytem::Type blues
- Previous by thread: Re: Smooth animation
- Next by thread: Re: cubes + clear black edges
- Index(es):
Relevant Pages
|