帧率(FPS)计算的六种方法总结

帧率(FPS)计算是游戏编程中常见的一个话题。大体来说,总共有如下六种方法:

一、固定时间帧数法

帧率计算的公式为:

fps = frameNum / elapsedTime;

如果记录固定时间内的帧数,就可以计算出同步率。此种方法用得较多。

int fps()
{
    static int fps = 0;
    static int lastTime = getTime(); // ms
    static int frameCount = 0;

    ++frameCount;

    int curTime = getTime();
    if (curTime - lastTime > 1000) // 取固定时间间隔为1秒
    {
        fps = frameCount;
        frameCount = 0;
        lastTime = curTime;
    }
    return fps;
}

还有另一种写法:

int fps(int deltaTime)
{
    static int fps = 0;
    static int timeLeft = 1000; // 取固定时间间隔为1秒
    static int frameCount = 0;

    ++frameCount;
    timeLeft -= deltaTime;
    if (timeLeft < 0)
    {
        fps = frameCount;
        frameCount = 0;
        timeLeft = 1000;
    }
    return fps;
}

二、固定帧数时间法

帧率计算的公式为:

fps = frameNum / elapsedTime;

如果每隔固定的帧数,计算帧数使用的时间,也可求出帧率。此种方法使用得较少。

int fps()
{
    static int fps = 0;
    static int frameCount = 0;
    static int lastTime = getTime(); // ms

    ++frameCount;

    if (frameCount >= 100) // 取固定帧数为100帧
    {
        int curTime = getTime();
        fps = frameCount / (curTime - lastTime) * 1000;
        lastTime = curTime;
        frameCount = 0;
    }
    return fps;
}

三、实时计算法

实时计算法直接使用上一帧的时间间隔进行计算,结果具有实时性,但平滑性不好。

int fps(int deltaTime) // ms
{
    int fps = static_cast<int>(1.f / deltaTime * 1000); // 别忘了先转换为浮点数,否则会有精度丢失
    return fps;
}

四、总平均法

总平均法使用全局帧数除以全局时间,以求出帧率。

int beginTime = getTime();

int fps()
{
    static int frameCount = 0;

    ++frameCount;

    int deltaTime = getTime() - beginTime();
    return static_cast<int>(frameCount * 1.f / deltaTime * 1000); // 别忘了先转换为浮点数,否则会有精度丢失
}

五、精确采样法

精确采样法采样前N个帧,然后计算平均值。此种方法需要额外的内存空间,所以不常用。

int fps(int deltaTime) // ms
{
    static std::queue<int> q;
    static int sumDuration = 0; // ms

    int fps = 0;
    if (q.size() < 100) // 样本数设为100
    {
        sumDuration += deltaTime;
        q.push(deltaTime);
        fps = static_cast<int>(q.size() * 1.f / sumDuration * 1000.f); // 别忘了转换为浮点数,否则会有精度丢失
    }
    else
    {
        sumDuration -= q.front();
        sumDuration += deltaTime;
        sumDuration.pop();
        sumDuration.push(deltaTime);
        fps = static_cast<int>(100.f / sumDuration * 1000.f); // 别忘了转换为浮点数,否则会有精度丢失
    }
    return fps;
}

六、平均采样法

平均采样法利用上次的统计结果,克服了精确采样法需要使用额外空间的缺点。此种方法较常用。

int fps(int deltaTime) // ms
{
    static float avgDuration = 0.f;
    static alpha = 1.f / 100.f; // 采样数设置为100
    static int frameCount = 0;

    ++frameCount;

    int fps = 0;
    if (1 == frameCount)
    {
        avgDuration = static_cast<float>(deltaTime);
    }
    else
    {
        avgDuration = avgDuration * (1 - alpha) + deltaTime * alpha; 
    }

    fps = static_cast<int>(1.f / avgDuration * 1000);
    return fps;
}

你可能感兴趣的:(图形学,游戏编程,C++,FPS)