C++:计算移动FPS

7

我想计算游戏最后2-4秒的FPS。最好的方法是什么?

谢谢。

编辑:更具体地说,我只能使用每秒增量为1秒的计时器。


1
我认为首先你需要提供一些关于你的游戏架构的信息(代码)。 - William
就架构而言,没有太多的东西。我可以在主循环中每次递增一个计数器,并且我可以访问第二个计时器。 - user542687
你想解决什么问题?我不是故意玩弄文字,但从你的问题中隐晦的意思来看,似乎你可能正在用错误的方式去解决你想要解决的问题。 - David Titarenco
我并不是真的在解决什么问题。只是在寻找计算移动FPS最佳方式。 - user542687
我不明白为什么你没有一个更精确的计时器。根据游戏(或游戏运行速度如何),如果你只使用1秒精度,你无法得到任何接近准确FPS的东西。 - Mark
@Mark 当然可以准确。FPS = 每秒帧数。所以我仍然可以计算每秒的帧数。这就是FPS的意思。 - user542687
4个回答

16

刚刚发布的帖子差点就错过了。请参考我在那里关于使用指数加权移动平均值的回复。

C++:计算游戏中的总帧数

以下是示例代码:

最初:

avgFps = 1.0; // Initial value should be an estimate, but doesn't matter much.

每秒钟(假设上一秒中的总帧数为framesThisSecond):

// Choose alpha depending on how fast or slow you want old averages to decay.
// 0.9 is usually a good choice.
avgFps = alpha * avgFps + (1.0 - alpha) * framesThisSecond;

我正在寻找一些特定的代码,只是不确定最好的方法是什么。 - user542687
嗯,看起来很有道理。如果您将此代码添加到答案中,我可能会接受它。 - user542687
这个不错,使用alpha来计算移动平均值。在主循环中加入以下代码:framesThisSecond++;secnow=getseconds();if(secnow!=seclast){doJaysCode;framesThisSecond=0};seclast=secnow; 每次秒数发生变化时重新计算。 - david van brink

2
这里有一个可能适合你的解决方案。我将用伪代码/C语言编写,但你可以根据自己的游戏引擎来调整这个想法。
const int trackedTime = 3000; // 3 seconds
int frameStartTime; // in milliseconds
int queueAggregate = 0;
queue<int> frameLengths;

void onFrameStart()
{
    frameStartTime = getCurrentTime();
}

void onFrameEnd()
{
    int frameLength = getCurrentTime() - frameStartTime;

    frameLengths.enqueue(frameLength);
    queueAggregate += frameLength;

    while (queueAggregate > trackedTime)
    {
        int oldFrame = frameLengths.dequeue();
        queueAggregate -= oldFrame;
    }

    setAverageFps(frameLength.count() / 3); // 3 seconds
}

我没有精确的计时器,只有一个秒计时器。抱歉我在 OP 中没有更清楚地表达。 - user542687

1

可以保留最近100帧的时间,使用循环缓冲区并对它们进行平均处理吗?这将得到“最近100帧的FPS”(实际上是99帧,因为不会计算最新时间和最旧时间之间的差异)。

调用一些准确的系统时间,以毫秒为单位或更高精度。


我没有访问精确计时器的权限。我只使用了一个秒计时器。 - user542687
你不需要一个计时器来完成这个任务,只需要时间。这两个概念是不同的。例如,许多系统可以提供毫秒级别的计时器,但却无法提供纳秒级别的时间。 - MSalters
@MSalters 抱歉表述不够清晰,我是指时间 = 计时器,计时器 = 时间。 - user542687

0
你实际想要的是像这样的东西(在你的主循环中):
frames++;
if(time<secondsTimer()){
  time = secondsTimer();
  printf("Average FPS from the last 2 seconds: %d",(frames+lastFrames)/2);
  lastFrames = frames;
  frames = 0;
}

如果你知道如何处理结构体/数组,那么将这个示例扩展到4秒应该很容易。但是如果你需要更详细的帮助,你真的应该提到为什么你没有访问精确计时器(使用的架构、语言),否则一切都像猜测...


我不使用准确的计时器并不重要,但如果你想知道,那是因为我正在编写可移植代码。我正在使用Linux,并且我正在使用的库确实可以访问精确时间,但是,正如我所说,目前我想保持我的代码可移植性。 - user542687

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接