GLFW Window 轮询事件滞后

GLFW Window poll events lag

我在处理 GLFW 轮询事件时遇到问题。据我所知,所有用户输入事件都是通过回调或通过不断检查键盘/鼠标状态来处理的。后者效率不高,甚至会导致丢失某些输入(例如,当按下按钮然后在检查状态之间释放时)。更重要的是,一些事件如 window resizing 无法在没有回调的情况下处理。

因此,问题是每当用户开始调整 window 大小时(按下鼠标按钮但不移动鼠标),应用程序似乎会冻结。这是假设调整大小回调已启用并有效定义(即使直接从 GLFW API 复制)。问题 不是 window 不重绘。可以通过在回调函数中创建和调用自己的 render() 函数来完成回调重绘。

实际问题是,即使我正确处理调整大小事件并在回调时重绘,仍然存在一些延迟。这种滞后是在鼠标按下修饰的 window 边框之后,当鼠标没有移动时。这是一个演示(按钮点击以绿色突出显示):

抱歉弄乱了 GIF。 GLFW API 中列出的所有回调都已启用和处理(window-、输入-、操纵杆-和监视器-回调),并且在每个回调中调用重绘。看来我缺少一些回调或者 GLFW 就是这样工作的。

根据 this 的回答,没有线程就无法完成:

That only works when the user moves the mouse while holding - just holding left-click on the resize window part still stalls. To fix that, you need to render in a separate thread in addition to this. (No, you can't do that without threading. Sorry, this is how GLFW works, no one except them can change it.)

所以,问题是:

  1. 如何在没有线程的情况下解决这个问题?如果我不能,我想我可以用不同的光标形状和调整区域或类似的东西来模拟调整大小...
  2. 如果这在 GLFW 中仍然无法解决,其他 GLFW 替代方案是否存在此问题?
  3. GLFW有类似这个的问题吗?

GLFW 在这里没有错。这就是操作系统如何处理某些用户输入事件,例如鼠标按下 window 的装饰器调整大小句柄或移动整个 window.

查看此答案以获得更详尽的细节:Win32: My Application freezes while the user resizes the window

GLFW uses the standard Windows PeekMessage -> TranslateMessage/DispatchMessage loop 可以在 any GUI Windows 应用程序中找到。这将在您调用 glfwPollEvents() 时被调用,并且它会处理 OS 迄今为止在此过程中为所有 windows 积累的所有 Window 事件消息。到目前为止处理完所有消息后,对 glfwPollEvents() 的调用将 return 并允许您自己的 window/game 循环继续。

发生的情况是,一旦用户点击 window 装饰的调整大小手柄,实际上对 glfwPollEvents() 的调用将在 OS 本身内阻塞,以便 OS / window-manager 拦截鼠标和键盘消息来做它的 window resizing/reshaping 事情。

恐怕即使 Windows 会通知进程有关 window 调整大小或移动操作的开始(之后 OS 将控制 window 消息处理)和 GLFW already handling these events internally,现在 GLFW 不会将此通知客户端应用程序。 可能 尽管 GLFW 向应用程序提供适当的事件回调,以便应用程序可以仅在 window resize/move 动作发生(在链接的其他 Whosebug 答案中也提到)。

因此,为了在用户按住调整大小手柄或用户移动 window 时继续渲染,您唯一可以做的就是在单独的线程中渲染。