【问题标题】:What's the usual way of controlling frame rate?控制帧速率的常用方法是什么?
【发布时间】:2011-04-01 03:46:39
【问题描述】:

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

【问题讨论】:

标签: c++ graphics


【解决方案1】:

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

两者中的第一个和更多控制,通常是可选的,是 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();
}

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

【讨论】:

    【解决方案2】:

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

    算法

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

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

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

    提高可靠性的提示

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

    第一个很容易实现,可以隐藏在辅助函数中。第二个有点棘手,因为它要求您保留平均渲染速度的统计数据等。第三个很难实现,因为通常很难预测不同任务需要多长时间。它通常只在具有硬约束的实时系统中实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 1970-01-01
      • 2011-09-23
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      相关资源
      最近更新 更多