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

hst*_*fan 13 c++ graphics

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

ssu*_*ube 22

"控制"帧率有两种"常用"方式,两者都不那么简单.

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

这可以很好地限制帧速率来监视刷新率,但是当帧速率降到刷新以下时,它会被强制到下一个倍数.因此,当帧率开始下降时,你会失去相当多的潜在渲染时间,因为它被强制为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();
}
Run Code Online (Sandbox Code Playgroud)

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


And*_*ron 8

在下面的伪代码中描述了产生可预测(如果不是恒定的)帧速率(具有视频或3D图形)的典型方式.

算法

  1. 准备下一帧(在后台缓冲区中渲染);
  2. 在剩余的时间片段中休眠;
  3. 要求显示框架(交换前后缓冲区).

注意睡眠操作的位置.它夹在同一帧的准备和显示之间.这是恒定帧速率的主要关键!您希望帧的准备计入显示帧的总时间片.

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

提高可靠性的提示

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

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