控制帧速率的常用方法是什么?

时间:2011-04-01 03:46:39

标签: c++ graphics

我是图形新手,所以我不知道人们通常如何控制帧率来渲染事物。 我的意思是,你如何设置应用程序以30fps渲染? 可能有很多API提供这样的东西,但我需要从头开始编写代码。

2 个答案:

答案 0 :(得分:20)

“控制”帧率有两种“常用”方式,两者都不那么简单。

两者的第一个和更多控制,以及通常是可选的,是VSync。当显示器刷新完成时,这会强制视频卡仅推出新帧。许多显示器以60 Hz的频率刷新,因此您可以获得60 FPS。

这对于 cap 帧率来说非常有效,可以监视刷新率,但是当帧速率降到刷新以下时,它会被强制转换到下一个倍数。因此,当帧速率开始下降时,你会失去相当多的潜在渲染时间,因为它被强制为60,然后是30,然后是20,等等。

(有关DirectXOpenGL中的vsync的一些信息)

常用的第二种方法(可选择添加vsync)不限制帧速率。相反,请调整代码以处理差异。从长远来看,这更灵活,通常更好的编码,IMO,并且比试图强制特定的FPS计数简单得多。

假设你有一个简单的渲染循环,它开始看起来像:

while ( gameloop )
{
    float framedelta = ( timeNow - timeLast )
    timeLast = timeNow;

    for each ( GameObject object in World )
    {
        object->Animate(framedelta);
        object->Move(speed * framedelta)
    }

    render();
}

你想看看时差/时间/ delta,并从那里开始工作。允许帧速率根据硬件和设置进行缩放(有太多变化可供您预测或处理甚至一半),并让您的游戏使用它而不是控制它。对您来说更容易,在实践中更加灵活和稳定。

答案 1 :(得分:6)

以下伪代码描述了产生可预测(如果不是常量)帧速率(使用视频或3D图形)的典型方法。

<强>算法

  1. 准备下一帧(在后台缓冲区中渲染);
  2. 在剩余的时间片段中休眠;
  3. 询问框架是否显示(交换前后缓冲区)。
  4. 注意睡眠操作的位置。它夹在同一帧的准备和显示之间。这是恒定帧速率的主要关键!您希望帧的准备计入显示帧的总时间片

    关于如何实现这些步骤(根据它的分辨率,可靠性等选择睡眠操作)有很多变种,但核心就在那里。

    提高可靠性的提示

    • 在整个时间间隔内不要调用一次睡眠功能。使用您准备接受的最大误差定义一些常数,并在此间隔期间重复睡眠,直到剩余时间小于或等于此数量。
    • 当您知道无法及时准备下一帧时,不要害怕偶尔丢帧。跳过一个帧在视觉上比产生可变帧速率更有吸引力。
    • 如果您可以避免单处理器系统上的后台线程,请避免使用它们。使用工作线程会破坏睡眠功能的可靠性。最好的方法是将你的背景工作分成小块,然后执行这项工作而不是睡觉。

    第一个易于实现,可以隐藏在辅助函数中。第二个更加敏感,因为它需要你保持平均渲染速度的统计数据等等。第三个很难实现,因为通常很难预测不同任务需要多长时间。它通常只在具有严格约束的实时系统中实现。