jMonkey和Nifty中的线程?

3

我最近了解到jMonkey只在一个单线程上执​​行,即其openGL渲染线程。然而,我无法完全理解它。我可以理解它在单个更新循环中执行所有更新和initialize()调用,但输入应独立于此更新循环,否则它将变成轮询机制。

  1. jMonkey应用程序启动时会发生什么?它需要完成三个任务:运行更新循环、一次运行app states的初始化方法、进行渲染并不断处理事件。它如何通过单个线程管理所有这些任务?
  2. 当我在另一个app state的initialize方法中添加一个新的app state时会发生什么?
  3. 在输入处理中,输入管理器会通知各种监听器有关事件的情况。例如onClick()等nifty callback事件是如何在同一渲染循环上处理的?
  4. 最后,这个listen-update-render循环以什么顺序运行,我们在哪里可以找到与之相关的代码?
1个回答

4

jME采用了许多游戏引擎常见的方法(也用于一些其他用户界面库,例如Swing)。

游戏引擎所做的一切都在一个线程中完成。这可以称为LWJGL线程,但由于jME可以使用替代LWJGL的方法,因此更通用的是将其称为Render线程或仅称为jME线程。

确实在Render线程上完成所有操作,并且确实使用轮询机制。例如,如果您按住“左”键,则每帧相关的控件或应用程序状态都将在Render线程上调用,并且将使您向左移动一定量(由tpf修改)。 tpf是每帧时间,对于保持平滑运动并使游戏系统独立于帧速率以相同速度运行非常重要。

jME3中唯一经常使用单独线程的是物理引擎。它具有用于执行物理更新的线程,然后通过适当的机制将更改推送到Render线程。系统会为您处理这个,因此不需要担心。

  1. 线程在游戏循环中运行。每次进入循环时,它检查需要做的事情(例如排队任务、初始化应用程序状态、渲染等),并调用每个活动控制器和控件的更新等操作。在完成所有更新后,它会执行渲染。所有这些都发生在每一帧中,但计算机非常快,仍然可以处理所有这些并以良好的帧率渲染游戏。

  2. 这是一个实现细节,你不需要担心,只需要知道它肯定有效。添加实际上被排队并在下一帧中处理,我想。

  3. 所有东西都从同一个循环中处理。jME通过调用Nifty来允许Nifty进行其处理。作为该过程的一部分,Nifty检测事件并触发回调。这意味着回调已经在渲染线程上产生,因此您可以安全地修改场景图。jME使用一些特别编写的集合,如SafeArrayList,使您可以在同时迭代场景图时修改场景图。

  4. 更新、渲染、更新、渲染等。事件触发通常发生在检测到更新时的更新过程中。要查找代码,请先从Application类开始,并通过跟踪start()调用来找到主游戏循环。

jME3线程教程涵盖了相当多的内容:

http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading


谢谢。我已经理解了大部分内容(尤其是Nifty与jME的交互),只有一个问题。在操作系统中,输入被捕获为中断。它们如何作为动作排队在jME中流动?涉及哪些步骤? - simar
@simar 这由输入管理器处理,我不熟悉细节,抱歉。 - Tim B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接