繁体   English   中英

经常检查LWJGL / JInput游戏手柄按钮或轴时滞后,如何解决?

[英]Lag when frequently checking LWJGL/JInput gamepad buttons or axis, how do I fix it?

我正在为Android / OUYA和PC在Java上创建多平台(但受OpenGL支持)游戏引擎的过程,并且PC平台适配器在快速检查游戏手柄状态时给了我一些问题。

我当前正在使用LWJGL / JInput编写PC适配器,并且每当我轮询游戏手柄状态的速度快于每秒30次左右(给与大约33ms的时间来进行轮询和更新状态)时,从游戏手柄获得的值都是false。 错误的意思是,操纵杆可以位于右侧的一半,但是getAxisValue返回0而不是1f中接近0.5f的值。 最重要的是,它似乎比33ms更长的时间,否则它将被要求更频繁地执行。 是什么赋予了?

简而言之,在典型的更新呼叫中发生的是,引擎会在活动玩家的控制器中扫描游戏中实际使用的特定按钮的状态,这些按钮均已提前设置并注册。 目前,在我的测试应用程序中,它包含两个按钮和一个轴。 因此,它要做的就是检查三个输入的当前状态,仅此而已。 在经过几层接口并进入交换块之后,最终将其称为:

return controller.isButtonPressed(map.A);

要么

return controller.getAxisValue(map.LS_H);

其中map包含最终int,这些int将名称链接到给定控制器的特定索引值。

我通过自己的测试发现了什么:

  • 这不是硬件问题,因为当每秒更新少于30到35次时,它仍然非常准确。
  • 当将速度提高到每秒更新约60次以匹配图形线程的60fps速率时,它只会在输入线程上造成巨大的延迟。 图形线程不受影响,这使我认为它也不是一般的性能问题。
  • 将isButtonPressed或getAxisValue更改为任意预设值可解决更新滞后问题,因此不是我的代码导致间歇性停止,绝对是isButtonPressed和getAxisValue。

有什么方法可以提高游戏手柄检查的速度,或者我错过的某个设置会禁用通过LWJGL / JInput不必要的输入例程的设置?

就性能而言,匹配60fps太多了吗?

轮询不是最好的方法,它是一个相对昂贵的操作。 看一下JInput上的事件接口,您应该能够快速检查事件队列的内容。

原来,我遇到的部分视觉滞后是由于循环的delta-t计算问题。 它是基于前一帧结束到新帧开始之间的时间,而不是花费在前一帧上执行计算所需的时间。 这导致花了更长的时间在框架上出现视觉停顿现象,使任何小的性能问题都显得十分严重。 修复此问题有助于视觉上的结结,但并不能改善游戏手柄的滞后性(移动轴与看到结果之间的时间)或输入读数的准确性(轴物理上为X,但读数为0或非X)。


解决问题的方法:

我缩小了导致浪费时间的一些问题:

  • Display.update()自动轮询输入,该输入已在逻辑线程中完成。 从渲染线程调用它可能导致线程之间的锁定问题,从而使逻辑线程等待渲染线程释放输入对象。 另一个考虑因素是,轮询现在发生的频率越来越高 使用Display.update(false)并让逻辑线程自己轮询可大大减少的问题。

  • Display.setVSyncEnabled(true)强制渲染线程在我的60hz监视器上使用其给定的整个渲染时间(对于60fps速率为13ms),这可能会加剧以前的锁定问题。 启用它总是会使逻辑线程的结结恶化,然后再从Display.update()中删除输入轮询。

  • (可选)使用Display.swapBuffers()代替Display.update(false)似乎对性能的影响很小。 在我的代码中,后者往往会导致间歇性帧延迟。

实施了这些更改之后,我还没有注意到游戏手柄读数的任何问题,并且引擎对轴的更改非常敏感。 我在硬件上测试时没有视觉卡顿的最高性能是60fps渲染和逻辑/输入线程上100cycles / second。


我认为从心态层面来看,问题的一部分是我试图独立于呈现过程来轮询输入硬件,由于Display.update()与输入轮询和屏幕缓冲区都相关,因此LWJGL似乎不鼓励这样做。 通过实现API的方式,在未建立显示的情况下不可能使用某些输入设备。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM