大家都知道,时间在程序中的重要性,几乎任何运算都可能跟时间有关;
在运算中,时间是作为一个系数;
系统每桢调用的时间间隔通常是变化的,
那么可以这样下结论,时间不光是一个系数,而且是一个经常变化的系数;
问题就出来了,平时我们在处理播放或者Camera操作的时候,如果时间系数经常变化,
必然会导致结果有闪烁的痕迹,
我们把这个变化过程放在坐标系上,可以明显的看到,线路图是由一条条不规律的直线构成;
解决办法是,把直线图变成平滑的曲线图就可以达到这个目的;
即把系统每桢调用的时间间隔做平滑处理,下面是实现模版:
在运算中,时间是作为一个系数;
系统每桢调用的时间间隔通常是变化的,
那么可以这样下结论,时间不光是一个系数,而且是一个经常变化的系数;
问题就出来了,平时我们在处理播放或者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 ;
}
}
};
#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 ;
}
}
};