在openGL中设置每秒最大帧数

Rav*_*ven 8 c++ opengl performance

有没有办法计算应该达到多少更新以达到所需的帧速率,而不是系统特定的?我发现对于windows,但我想知道openGL本身是否存在这样的东西.它应该是某种计时器.

或者我怎样才能防止FPS急剧下降或上升?这次我正在测试它在线上绘制大量顶点,并且使用fraps我可以看到帧速率从400到200 fps,并且绘制它的速度明显减慢.

Edi*_*enz 11

您有两种不同的方法来解决此问题:

  1. 假设您有一个名为的变量maximum_fps,其中包含您要显示的最大帧数.

    然后你测量在最后一帧上花费的时间(一个计时器会做)

    现在假设您说您的应用程序最多需要60FPS.那么你希望测量的时间不低于1/60.如果测量的时间降低,则调用sleep()以达到帧的剩余时间.

  2. 或者你可以有一个名为的变量tick,它包含应用程序的当前"游戏时间".使用相同的计时器,您将在应用程序的每个主循环中递增它.然后,在绘图程序中,您可以根据tickvar 计算位置,因为它包含应用程序的当前时间.

    选项的最大优点2是您的应用程序将更容易调试,因为您可以tick随时随地使用变量,前进和后退.这是一个很大的优点.

  • 第一个仅用于减慢FPS,并且依赖于睡眠间隔的准确性是危险的. (7认同)

you*_*ung 11

规则1.不要使update()或loop()类函数依赖于它被调用的频率.

你无法真正得到你想要的FPS.您可以尝试通过跳过一些昂贵的操作来增强它,或者通过调用sleep()类函数来减慢它.但是,即使使用这些技术,FPS也几乎总是与您想要的精确FPS不同.

解决此问题的常用方法是使用上次更新所用的时间.例如,

// Bad
void enemy::update()
{
  position.x += 10; // this enemy moving speed is totally up to FPS and you can't control it.
}

// Good
void enemy::update(elapsedTime)
{
  position.x += speedX * elapsedTime; // Now, you can control its speedX and it doesn't matter how often it gets called.
}
Run Code Online (Sandbox Code Playgroud)


Sig*_*erm 5

有没有办法计算应该进行多少更新才能达到所需的帧速率,而不是特定于系统的?

不。

无法精确计算应调用多少次更新以达到所需的帧率。

但是,您可以测量自上一帧以来经过了多少时间,根据它计算当前帧率,将其与所需帧率进行比较,然后引入一点Sleep将当前帧率降低到所需值。不是一个精确的解决方案,但它会起作用。

我发现对于 Windows,但我想知道 openGL 本身是否存在这样的东西。它应该是某种计时器。

OpenGL 只关心渲染的东西,与定时器无关。此外,使用 Windows 计时器也不是一个好主意。使用 QueryPerformanceCounter、GetTickCount 或 SDL_GetTicks 来测量已经过去了多长时间,然后睡眠以达到所需的帧率。

或者我还能如何防止 FPS 大幅下降或提高?

您可以通过睡眠来防止 FPS 提高。

至于防止FPS掉...

这是一个非常广泛的话题。让我们来看看。它是这样的:使用顶点缓冲区对象或显示列表,配置文件应用程序, 不要使用非常大的纹理,不要使用太多的 alpha 混合,避免使用“RAW”OpenGL (glVertex3f),不要渲染不可见的对象(即使没有绘制多边形,处理它们也需要时间),考虑学习 BSP或用于渲染复杂场景的 OCTrees,在参数化曲面和曲线中,不要不必要地使用太多图元(如果您将使用一百万个多边形渲染一个圆,没有人会注意到差异),禁用 vsync。简而言之 - 减少到绝对可能的最小渲染调用次数、渲染多边形数量、渲染像素数量、读取的纹素数量,从 NVidia 阅读所有可用的性能文档,您应该会获得性能提升。

  • @Raven:“glutTimerFunc”这不是 OpenGL 函数 - glut 不是 OpenGL 的一部分。“仅在 Windows 上可用”是的,它们仅适用于 Windows。如果您需要跨平台解决方案,请使用 SDL_GetTicks。 (3认同)