來源:http://zhandinggen.spaces.live.com/blog/cns!fb9e1552d67bc103!357.entry 大家都知道,時間在程序中的重要性,幾乎任何運算都可能跟時間有關;
在運算中,時間是作為一個系數;
系統每楨調用的時間間隔通常是變化的,
那么可以這樣下結論,時間不光是一個系數,而且是一個經常變化的系數;
問題就出來了,平時我們在處理播放或者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;
}
}
};