GLFW_CURSOR_DISABLED模式下glfwGetCursorPos的Y坐标异常递减问题
问题现象
每帧调用glfwSetCursorPos将光标固定在屏幕中心,同时通过glfwGetCursorPos读取坐标时,Y坐标会每隔一帧精确减少172。无任何鼠标输入时该异常依然存在,初始几帧坐标显示正常,后续开始出现规律性跳动。
测试代码:
double testX, testY; glfwGetCursorPos(window, &testX, &testY); std::cout << testY << std::endl;
尝试将变量设为全局、调用前后手动置零等操作均无法解决问题。
触发条件定位
- 异常仅在光标隐藏场景下出现:
- 使用
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED)时必现坐标跳动 - 使用
GLFW_CURSOR_HIDDEN时,部分调用位置可正常运行(光标隐藏且坐标稳定),部分位置光标未真正隐藏,但坐标读取正常
- 使用
问题原因分析
GLFW的GLFW_CURSOR_DISABLED模式下,系统会接管光标位置管理:自动隐藏光标并持续重置其位置,以此提供纯粹的相对位移数据。此时手动调用glfwSetCursorPos会与GLFW内部的位置校准逻辑冲突,导致坐标计算出现固定偏移的累积,最终表现为每帧减少172的规律跳动(172的数值通常与屏幕分辨率、窗口布局或GLFW内部校准参数相关)。
而GLFW_CURSOR_HIDDEN仅隐藏光标视觉显示,不改变系统对光标位置的原生管理逻辑,所以手动设置位置不会触发冲突,但如果调用时机错误(比如在事件循环处理中频繁切换模式),会导致光标隐藏失效。
解决方案
禁用模式下放弃手动置光标:
若使用GLFW_CURSOR_DISABLED,直接通过glfwGetCursorPos返回的坐标差值获取鼠标相对移动量即可——该模式下GLFW会自动锁定光标并提供原生的相对位移数据,无需手动重置光标位置。修正
GLFW_CURSOR_HIDDEN调用时机:
确保在窗口初始化完成、进入主循环前调用glfwSetInputMode设置GLFW_CURSOR_HIDDEN,避免在帧渲染或事件处理过程中频繁切换光标模式。示例代码:// 窗口初始化完成后立即设置 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); // 主循环内逻辑 while (!glfwWindowShouldClose(window)) { double xpos, ypos; glfwGetCursorPos(window, &xpos, &ypos); // 计算光标偏移量 double deltaX = xpos - centre.x; double deltaY = ypos - centre.y; // 重置光标到屏幕中心 glfwSetCursorPos(window, centre.x, centre.y); // 渲染与事件处理 glfwSwapBuffers(window); glfwPollEvents(); }验证GLFW版本兼容性:
该异常可能是特定GLFW版本的bug,尝试升级到最新稳定版(如3.3.8及以上),或回退到之前验证过正常运行的版本。
内容的提问来源于stack exchange,提问作者JacobDev

