多线程 LWJGL 键盘延迟
Multithreaded LWJGL Keyboard Delay
在我制作的 LWJGL 游戏中,我有 3 个线程 - 一个用于图形,一个用于 processing/physics,另一个用于提供世界访问和处理多人连接。
我遇到的问题是,当我在物理线程中调用 Keyboard.isKeyDown() 时,有时我必须按住它半秒左右才能发生任何事情。这不是因为线程 运行 缓慢 - 它是目前循环中唯一的东西,并且 println 调用显示它正在更新。
我想知道这是否与图形线程中存在 OpenGL 上下文以及我从物理线程调用键盘调用这一事实有关?如果我在图形线程中进行检查,它工作正常,但是从那里获取输入并将它们发送到另一个线程在某种程度上违背了拥有单独线程的意义。
我的键盘检查目前是这样的:
boolean escPressed = false;
private void process(){
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
if(!escPressed){
escPressed = true;
GameStateManager.pauseUnpause();
}
}
else{
escPressed = false;
}
}
我的线程设置就是这样
public class Client {
public static GraphicsThread graphics;
public static PhysicsThread physics;
public static ConnectionThread server;
public static void main(String[] args) {
GameStateManager.setState(GameStateManager.EnumState.MENU);
graphics = new GraphicsThread();
physics = new PhysicsThread();
server = new ConnectionThread();
physics.start();
graphics.start();
server.start();
}
}
所以谁能告诉我为什么从不同线程调用方法时会出现延迟?
更新
我做了一个快速测试,对键盘的任何调用似乎都需要很长时间才能完成。
while(true){
start = System.currentTimeMillis();
Keyboard.isKeyDown(Keyboard.KEY_ESCAPE);
end = System.currentTimeMillis();
System.out.println(end-start);
}
运行 该测试显示结果高达 1100 毫秒,高得离谱。当 运行 在图形线程中时,它会在不到一毫秒的时间内完成并打印 0。不确定这里发生了什么。
LWJGL 2 还是 3?真的不重要..
不过,据我所知,在其他线程上调用此方法应该没有问题,尽管在 OpenGL 上下文绑定到的线程上调用它是一个好主意。
对于我的设置,我有一个专用于所有 OpenGL 上下文相关内容的线程。 (例如,仅限 openGL 调用)。因此,在您的情况下,我将检查图形线程中的 keyPressed 状态,该状态将提示传递给执行所有繁重工作的物理线程(如果有的话)。虽然细节当然取决于你。
希望对您有所帮助
编辑:
我在处理这个问题时也遇到了 this post ,基本上是不可能的,因为 LWJGL 的设计选择。您可以通过提示(如上所述)手动将其分开,或者跟踪您从其他线程检查的每个输入设备的状态(在图形线程中更新),而不是使用 Keyboards
class.
在我制作的 LWJGL 游戏中,我有 3 个线程 - 一个用于图形,一个用于 processing/physics,另一个用于提供世界访问和处理多人连接。 我遇到的问题是,当我在物理线程中调用 Keyboard.isKeyDown() 时,有时我必须按住它半秒左右才能发生任何事情。这不是因为线程 运行 缓慢 - 它是目前循环中唯一的东西,并且 println 调用显示它正在更新。 我想知道这是否与图形线程中存在 OpenGL 上下文以及我从物理线程调用键盘调用这一事实有关?如果我在图形线程中进行检查,它工作正常,但是从那里获取输入并将它们发送到另一个线程在某种程度上违背了拥有单独线程的意义。
我的键盘检查目前是这样的:
boolean escPressed = false;
private void process(){
if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
if(!escPressed){
escPressed = true;
GameStateManager.pauseUnpause();
}
}
else{
escPressed = false;
}
}
我的线程设置就是这样
public class Client {
public static GraphicsThread graphics;
public static PhysicsThread physics;
public static ConnectionThread server;
public static void main(String[] args) {
GameStateManager.setState(GameStateManager.EnumState.MENU);
graphics = new GraphicsThread();
physics = new PhysicsThread();
server = new ConnectionThread();
physics.start();
graphics.start();
server.start();
}
}
所以谁能告诉我为什么从不同线程调用方法时会出现延迟?
更新 我做了一个快速测试,对键盘的任何调用似乎都需要很长时间才能完成。
while(true){
start = System.currentTimeMillis();
Keyboard.isKeyDown(Keyboard.KEY_ESCAPE);
end = System.currentTimeMillis();
System.out.println(end-start);
}
运行 该测试显示结果高达 1100 毫秒,高得离谱。当 运行 在图形线程中时,它会在不到一毫秒的时间内完成并打印 0。不确定这里发生了什么。
LWJGL 2 还是 3?真的不重要..
不过,据我所知,在其他线程上调用此方法应该没有问题,尽管在 OpenGL 上下文绑定到的线程上调用它是一个好主意。
对于我的设置,我有一个专用于所有 OpenGL 上下文相关内容的线程。 (例如,仅限 openGL 调用)。因此,在您的情况下,我将检查图形线程中的 keyPressed 状态,该状态将提示传递给执行所有繁重工作的物理线程(如果有的话)。虽然细节当然取决于你。
希望对您有所帮助
编辑:
我在处理这个问题时也遇到了 this post ,基本上是不可能的,因为 LWJGL 的设计选择。您可以通过提示(如上所述)手动将其分开,或者跟踪您从其他线程检查的每个输入设备的状态(在图形线程中更新),而不是使用 Keyboards
class.