【问题标题】:C++: Calculating Moving FPSC++:计算移动 FPS
【发布时间】:2011-01-14 02:27:54
【问题描述】:

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

谢谢。

编辑:更具体地说,我只能访问以一秒为增量的计时器。

【问题讨论】:

  • 我认为首先你必须提供一些关于你的游戏架构的信息(代码)..
  • 就架构而言并不多。我可以每次通过主循环增加一个计数器,并且我可以访问第二个计时器。
  • 你想解决什么问题?我的意思不是听起来很腼腆,但从你问题的深奥意思来看,你似乎在用错误的方式来解决你想要解决的问题。
  • 我并没有真正尝试解决任何问题。只是在寻找计算移动 FPS 的最佳方法。
  • 我不明白您为什么无法使用更准确的计时器。根据游戏(或游戏的快慢),如果您只处理 1 秒的精度,您将无法获得相当接近准确 FPS 的任何东西。

标签: c++ frame-rate


【解决方案1】:

差点错过最近的一篇帖子。请参阅我对使用指数加权移动平均线的回复。

C++: Counting total frames in a game

这里是示例代码。

最初:

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;

【讨论】:

  • 我正在寻找一些特定的代码,我只是不确定最好的方法。
  • 嗯,似乎有道理。如果您将此代码添加到答案中,我可能会接受。
  • 这个很好,使用 alpha 作为移动平均线。主循环中的内容如下: framesThisSecond++;secnow=getseconds();if(secnow!=seclast){doJaysCode;framesThisSecond=0};seclast=secnow;每次秒数看起来发生变化时重新计算。
【解决方案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 中没有更清楚。
【解决方案3】:

可以为最后 100 帧保留一个帧时间的循环缓冲区,并对它们进行平均吗?那将是“最后 100 帧的 FPS”。 (或者,更确切地说,99,因为您不会区分最新时间和最旧时间。)

调用一些准确的系统时间,毫秒或更好。

【讨论】:

  • 我无法使用精确的计时器。我只使用第二个计时器。
  • 您不需要为此设置计时器。只是时间。这是两个不同的东西。例如。很多系统都可以提供毫秒定时器,但是纳秒时间。
  • @MSalters 抱歉我没说清楚,我的意思是时间 = 计时器,计时器 = 时间。
【解决方案4】:

你真正想要的是这样的(在你的 mainLoop 中):

frames++;
if(time<secondsTimer()){
  time = secondsTimer();
  printf("Average FPS from the last 2 seconds: %d",(frames+lastFrames)/2);
  lastFrames = frames;
  frames = 0;
}

如果您知道如何处理结构/数组,您应该很容易将此示例扩展到 4 秒而不是 2 秒。但是如果您需要更详细的帮助,您应该真正提及为什么您没有访问到一个精确的计时器(哪种架构,语言) - 否则一切都像猜测......

【讨论】:

  • 我为什么不使用准确的计时器并不重要,但如果您想知道,那是因为我此时正在编写可移植代码。我正在使用 Linux,并且我正在使用的库确实可以访问精确的时间,但是,就像我说的,我希望此时我的代码保持可移植性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
相关资源
最近更新 更多