幀率(FPS)計算是遊戲程式設計中常見的一個話題。大體來說,總共有如下六種方法:
一、固定時間幀數法
幀率計算的公式為:
如果記錄固定時間内的幀數,就可以計算出同步率。此種方法用得較多。
int fps()
{
static int fps = ;
static int lastTime = getTime(); // ms
static int frameCount = ;
++frameCount;
int curTime = getTime();
if (curTime - lastTime > ) // 取固定時間間隔為1秒
{
fps = frameCount;
frameCount = ;
lastTime = curTime;
}
return fps;
}
還有另一種寫法:
int fps(int deltaTime)
{
static int fps = ;
static int timeLeft = ; // 取固定時間間隔為1秒
static int frameCount = ;
++frameCount;
timeLeft -= deltaTime;
if (timeLeft < )
{
fps = frameCount;
frameCount = ;
timeLeft = ;
}
return fps;
}
二、固定幀數時間法
幀率計算的公式為:
如果每隔固定的幀數,計算幀數使用的時間,也可求出幀率。此種方法使用得較少。
int fps()
{
static int fps = ;
static int frameCount = ;
static int lastTime = getTime(); // ms
++frameCount;
if (frameCount >= ) // 取固定幀數為100幀
{
int curTime = getTime();
fps = frameCount / (curTime - lastTime) * ;
lastTime = curTime;
frameCount = ;
}
return fps;
}
三、實時計算法
實時計算法直接使用上一幀的時間間隔進行計算,結果具有實時性,但平滑性不好。
int fps(int deltaTime) // ms
{
int fps = static_cast<int>( / deltaTime * ); // 别忘了先轉換為浮點數,否則會有精度丢失
return fps;
}
四、總平均法
總平均法使用全局幀數除以全局時間,以求出幀率。
int beginTime = getTime();
int fps()
{
static int frameCount = ;
++frameCount;
int deltaTime = getTime() - beginTime();
return static_cast<int>(frameCount * / deltaTime * ); // 别忘了先轉換為浮點數,否則會有精度丢失
}
五、精确采樣法
精确采樣法采樣前N個幀,然後計算平均值。此種方法需要額外的記憶體空間,是以不常用。
int fps(int deltaTime) // ms
{
static std::queue<int> q;
static int sumDuration = ; // ms
int fps = ;
if (q.size() < ) // 樣本數設為100
{
sumDuration += deltaTime;
q.push(deltaTime);
fps = static_cast<int>(q.size() * / sumDuration * ); // 别忘了轉換為浮點數,否則會有精度丢失
}
else
{
sumDuration -= q.front();
sumDuration += deltaTime;
sumDuration.pop();
sumDuration.push(deltaTime);
fps = static_cast<int>( / sumDuration * ); // 别忘了轉換為浮點數,否則會有精度丢失
}
return fps;
}
六、平均采樣法
平均采樣法利用上次的統計結果,克服了精确采樣法需要使用額外空間的缺點。此種方法較常用。
int fps(int deltaTime) // ms
{
static float avgDuration = ;
static alpha = / ; // 采樣數設定為100
static int frameCount = ;
++frameCount;
int fps = ;
if ( == frameCount)
{
avgDuration = static_cast<float>(deltaTime);
}
else
{
avgDuration = avgDuration * ( - alpha) + deltaTime * alpha;
}
fps = static_cast<int>( / avgDuration * );
return fps;
}