大家都知道,时间在程序中的重要性,几乎任何运算都可能跟时间有关;
在运算中,时间是作为一个系数;
系统每桢调用的时间间隔通常是变化的,
那么可以这样下结论,时间不光是一个系数,而且是一个经常变化的系数;
问题就出来了,平时我们在处理播放或者Camera操作的时候,如果时间系数经常变化,
必然会导致结果有闪烁的痕迹,
我们把这个变化过程放在坐标系上,可以明显的看到,线路图是由一条条不规律的直线构成;
解决办法是,把直线图变成平滑的曲线图就可以达到这个目的;
即把系统每桢调用的时间间隔做平滑处理,下面是实现模版:
#define USE_HIGH_FREQUENCY
#define FILTER_SIZE 16
class TIMER
{
float filter[FILTER_SIZE];
long filter_index;
public:
TIMER()
{
long n;
for (n=0;n<FILTER_SIZE;n++) filter[FILTER_SIZE] = 20.0f;
filter_index = 0;
#ifdef USE_HIGH_FREQUENCY
LARGE_INTEGER liFreq;
QueryPerformanceFrequency( &liFreq );
fSecondsPerTick = 1.0f / liFreq.QuadPart;
QueryPerformanceCounter(&liPrevTime);
#else
Previous_Time = GetTickCount();
#endif
Delta_Time = 20;
rDelta_Time = Delta_Time;
fps = 0; fps_count = 0; fps_time = 0;
Ring = false;
FixedDelta = false;
ADT = 1;
ADT_ON = true;
ADT_val = 10;
};
bool FixedDelta;
DWORD FixedDeltaValue;
bool Ring;
#ifdef USE_HIGH_FREQUENCY
float fSecondsPerTick;
LARGE_INTEGER liPrevTime;
#endif
DWORD Previous_Time;
DWORD Delta_Time;
DWORD rDelta_Time;
DWORD fps;
DWORD fps_count;
DWORD fps_time;
DWORD ADT;
float ADT_val;
bool ADT_ON;
DWORD Run()
{
long n;
#ifdef USE_HIGH_FREQUENCY
LARGE_INTEGER liCurTime;
QueryPerformanceCounter( &liCurTime );
float fDeltaTime = 1000.0f * (liCurTime.QuadPart - liPrevTime.QuadPart) * fSecondsPerTick;
Delta_Time = long(fDeltaTime);
#else
DWORD Current_Time;
Current_Time = GetTickCount();
Delta_Time = Current_Time - Previous_Time;
rDelta_Time = Delta_Time;
#endif
if(Delta_Time > 100)
{
Delta_Time = 100;
fDeltaTime = 100.f;
}
filter[filter_index] = (float)Delta_Time;
filter_index++;
if (filter_index >= FILTER_SIZE) filter_index = 0;
ADT_val = 0;
for (n=0;n<FILTER_SIZE;n++) ADT_val += filter[n];
ADT_val = ADT_val/FILTER_SIZE;
fps_time += Delta_Time;
ADT += Delta_Time;
fps_count++;
if (fps_time >= 1000)
{
//ADT_val = ADT/fps_count;
ADT = 1;
fps_time = fps_time - 1000;
fps = fps_count;
fps_count = 0;
Ring = true;
} else Ring = false;
#ifdef USE_HIGH_FREQUENCY
liPrevTime = liCurTime;
#else
Previous_Time = Current_Time;
#endif
if (ADT_ON) Delta_Time = (DWORD)ADT_val;
if (Delta_Time == 0) Delta_Time = 1;
if (FixedDelta) return FixedDeltaValue;
return Delta_Time;
};
void SetDelta(long DeltaTime)
{
if (DeltaTime < 0)
{
FixedDelta = false;
}
else
{
FixedDeltaValue = DeltaTime;
FixedDelta = true;
}
}
};