Java openGL中的帧速率和绘制流程
我似乎无法理解帧图形如何与缓冲区交换同步 问题如下: 1.由于大多数OpenGL调用是非阻塞(或缓冲)的,您如何知道gpu是否使用当前帧完成 2.OpenGL是否处理它,以便未完成的帧不会被交换到窗口缓冲区 3.如何计算帧速率?我的意思是,确定每帧绘制的帧数或所用时间的依据是什么?Java openGL中的帧速率和绘制流程,java,c++,opengl,3d,Java,C++,Opengl,3d,我似乎无法理解帧图形如何与缓冲区交换同步 问题如下: 1.由于大多数OpenGL调用是非阻塞(或缓冲)的,您如何知道gpu是否使用当前帧完成 2.OpenGL是否处理它,以便未完成的帧不会被交换到窗口缓冲区 3.如何计算帧速率?我的意思是,确定每帧绘制的帧数或所用时间的依据是什么? 问题1和2:调用而不是glFlush(): 说明 glFinish在所有以前调用的GL命令的效果完成之前不会返回。此类效果包括对GL状态的所有更改、对连接状态的所有更改以及对帧缓冲区内容的所有更改 问题3:开始一
- 问题1和2:调用而不是
:glFlush()
- 问题3:开始一次并计算在一秒钟内执行了多少次对
的调用glFinish()
- 问题1和2:调用而不是
:glFlush()
- 问题3:开始一次并计算在一秒钟内执行了多少次对
的调用glFinish()
glFinish()。如果正确使用同步对象,则可以完全避免这两种情况
您只需在感兴趣的任意点向GL命令流中插入围栏同步,然后可以在完成之前检查所有命令,或者您可以等待完成(而您仍然可以让更多命令排队)
请注意,对于帧速率估计,您不需要任何明确的同步方法。只要使用SwapBuffers()
就足够了。gpu可能会提前排队几帧(nvidia驱动程序甚至对此进行了设置),但这不会干扰fps计数,因为只有前n帧排队。只需计算每秒发出的SwapBuffer()
调用数,就可以了。如果用户已启用同步到vblank,帧速率将限制为监视器的刷新速率,并且不会出现撕裂
如果您需要更详细的GPU定时统计信息(但对于帧速率计数器,您不需要),您应该看看。与GL同步的现代方法是使用。使用glFinish()。如果正确使用同步对象,则可以完全避免这两种情况
您只需在感兴趣的任意点向GL命令流中插入围栏同步,然后可以在完成之前检查所有命令,或者您可以等待完成(而您仍然可以让更多命令排队)
请注意,对于帧速率估计,您不需要任何明确的同步方法。只要使用SwapBuffers()
就足够了。gpu可能会提前排队几帧(nvidia驱动程序甚至对此进行了设置),但这不会干扰fps计数,因为只有前n帧排队。只需计算每秒发出的SwapBuffer()
调用数,就可以了。如果用户已启用同步到vblank,帧速率将限制为监视器的刷新速率,并且不会出现撕裂
如果您需要更详细的GPU定时统计信息(但对于帧速率计数器,您不需要),您应该查看
一般来说,你不会。我想不出一个很好的理由让你在实际应用中担心它。如果你真的想知道,使用同步对象(正如@derhass在回答中所建议的那样)是现代OpenGL中最好的选择。但是你应该确保你清楚地理解为什么你需要它,因为这对我来说是不寻常的
对。虽然OpenGL中调用的处理大部分是异步的,但调用的顺序仍然保持不变。因此,如果您进行SwapBuffers
调用,它将保证您在SwapBuffers
调用之前进行的所有调用都将在交换缓冲区之前完成
没有好的简单方法来测量单个帧所用的时间。最实用的方法是渲染足够长的时间(至少几秒钟似乎是合理的)。计算这段时间内渲染的帧数以及经过的挂钟时间。然后将帧数除以获得帧速率所需的时间
上面的一些内容稍微简化了,因为这打开了一些可能非常广泛的领域。例如,您可以使用计时器查询来测量GPU处理给定帧所需的时间。但是你必须小心你从中得出的结论
作为一个假设的示例,假设您以60 fps的速度渲染,但受到vsync的限制。您在一个帧上放置了一个计时器查询,它告诉您GPU渲染该帧花费了15毫秒。这是否意味着你在维持60 fps的极限上是正确的?使渲染/内容更复杂会使其低于60 fps吗?不一定。除非您还跟踪GPU时钟频率,否则您不知道GPU是否真的在其极限运行。电源管理可能会降低成本