【发布时间】:2011-10-06 03:42:10
【问题描述】:
我目前正在开发一个 OpenGL 应用程序来向用户显示一些 3D 球体,他们可以旋转、移动等。话虽如此,这里的复杂性并不多,所以应用程序运行在相当高的帧率(~500 FPS)。
显然,这太过分了——即使 120 也足够了,但我的问题是,以全状态运行应用程序会消耗我的 CPU,导致过热、功耗等。我想做的是能够让用户设置 FPS 上限,以便在不需要时不会过度使用 CPU。
我正在使用 freeglut 和 C++,并且已经设置了动画/事件处理以使用计时器(使用 glutTimerFunc)。但是,glutTimerFunc 只允许设置整数毫秒数 - 所以如果我想要 120 FPS,我能得到的最接近的是(int)1000/120 = 8 ms 分辨率,相当于 125 FPS(我知道这是一个可以忽略不计的数量,但是如果我知道系统可以更快地渲染,我仍然只想设置 FPS 限制并获得准确的 FPS)。
此外,使用glutTimerFunc 来限制 FPS 始终无法正常工作。假设我将我的应用程序限制为 100 FPS,它通常永远不会高于 90-95 FPS。同样,我试图计算出渲染/计算之间的时间差,但它总是超出限制 5-10 FPS(可能是计时器分辨率)。
我想这里最好的比较是游戏(例如半条命 2)——你设置了你的 FPS 上限,它总是会达到这个精确的数值。我知道我可以在渲染每一帧之前和之后测量时间增量,然后循环直到我需要绘制下一帧,但这并不能解决我的 100% CPU 使用率问题,也不能解决时间分辨率问题。
有什么方法可以在我的应用程序中实现有效的、跨平台的、可变帧速率限制器/上限?或者,换句话说,是否有任何跨平台(和开源)库可以实现高分辨率计时器和睡眠功能?
编辑:我希望找到一个不依赖最终用户启用 VSync 的解决方案,因为我将让他们指定 FPS 上限。
编辑 #2:致所有推荐 SDL 的人(我确实最终将我的应用程序移植到 SDL),使用 glutTimerFunc 函数有什么区别触发平局,还是使用SDL_Delay 在平局之间等待?每个文档都提到了相同的警告,但我不确定其中一个是否比另一个更有效。
编辑#3:基本上,我想弄清楚是否有(简单的方法)在我的应用程序中实现准确的 FPS 限制器(再次,如半条命 2)。如果这不可能,我很可能会切换到 SDL(对我来说,使用延迟函数更有意义,而不是使用 glutTimerFunc 每 x 毫秒回调一次渲染函数)。
【问题讨论】:
标签: c++ opengl 3d cross-platform freeglut