使用 LWJGL 从 GLFW 的主线程调度

Dispatch from GLFW's main thread using LWJGL

我正在尝试在异步任务中调用 GLFW.glfwPollEvents(),每 滴答(在本例中为 1/30 秒)运行s。这个滴答计时器有效地控制了应用程序中每个动作的发生时间。

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
    @Override
    public void run(){
        //... more code ...

        GLFW.glfwPollEvents();

        //... more code ...
    }
}, 33, 33);

但是,这不起作用,因为

This function may only be called from the main thread.

(from the documentation)

如何在主线程上调用它?当主线程上没有 运行 时,应用程序崩溃。我正在寻找类似

的内容
GLFW.dispatchMainThread(new GLFWRunnable(){
    public void run(){
        //...
    }
});

这可以在 swingawt 中使用

EventQueue.invokeLater(new Runnable(){
    public void run(){
        //...
    }
});

但相同的代码不适用于 GLFW

如何使用 LWJGL 在 运行 的主线程上 运行 任务,而不是 在主线程上使用 while(true) 循环?

由于 GLFW 的主线程必须与应用程序的主线程相同(GLFW 中的一个限制;这就是它放置 OS 消息队列的地方,swing/awt 似乎以不同的方式处理它 - 请参阅我的回答 ) 我会反过来做。

我的主线程将有一个永远的循环(可能使用 glfwWaitEvents 以免不必要地消耗 CPU 时间)。然后我会 post 任何特定于应用程序的事件,这些事件是另一个执行处理的线程。您的消息处理现在与消息接收分离。

这样我就不必等待 1/30 秒来接收 OS 消息(当应用程序在打开菜单、注册点击或在列表)。

您的更新线程甚至可以休眠 1/30 秒(或更短时间,如果时间不够则再次休眠,或者如果第二个高优先级队列需要工作则不休眠)并且只醒来检查排队事件作为一种极其简单的调度方法。

我在上面 link 编辑的答案有一个 link 到一个 LWJGL Multithreaded Demo 做的事情非常相似。他们的 renderLoop 将是您的 updateLoop 并且会从队列中提取并在再次休眠之前进行处理,而不是更新和呈现图形。