glfwSetCursorPos() 无法在 windows 上工作
glfwSetCursorPos() not working on windows
所以我使用 lwjgl 提供的 GLFW 绑定 java 在 java 中写了一个 window。它在 linux 上工作正常,但由于某些原因某些方法在 windows.
上不起作用
我已经注册了一个在 linux 和 windows 上都可以正常工作的键回调,但是一个字符回调例如只在 linux.
上工作
我遇到的另一个问题是 setCursorPos() 不起作用,因为我无法将鼠标居中以计算从那里的偏移量,这会破坏我的相机旋转。
这就是我创建 window 的方式:
public void init(int selectedMonitor, int glMajor, int glMinor, int windowHints) {
if (this.initialized) return;
GLFWErrorCallback.createPrint(System.err).set();
if (!GLFW.glfwInit())
throw new WindowCreationException("Unable to initialize GLFW.");
// Configure window hints
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, (windowHints & 1));
GLFW.glfwWindowHint(GLFW.GLFW_FOCUSED, (windowHints >> 1) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, (windowHints >> 2) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_DECORATED, (windowHints >> 3) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajor);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinor);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, (windowHints >> 7));
// Set video mode
PointerBuffer monitors = GLFW.glfwGetMonitors();
if (monitors == null)
throw new WindowCreationException("Could not create window, there are no monitors.");
if (selectedMonitor >= monitors.capacity() || selectedMonitor < 0) {
this.currentMonitor = GLFW.glfwGetPrimaryMonitor();
} else {
this.currentMonitor = monitors.get(selectedMonitor);
}
this.vidMode = GLFW.glfwGetVideoMode(this.currentMonitor);
// Create window handle
this.windowHandle = GLFW.glfwCreateWindow(this.width, this.height, this.title, this.isFullscreen ? this.currentMonitor : 0L, 0L);
if (this.windowHandle == 0L)
throw new RuntimeException("Failed to create GLFW Window.");
// Center window if configured
if (((windowHints >> 4) & 1) == 1) this.centerWindow();
// Set key callbacks
this.addKeyCallback((window, keyCode, scanCode, action, mods) -> Key.byKeyCode(keyCode).update(action));
this.addMouseButtonCallback((window, keyCode, action, mods) -> Key.byKeyCode(keyCode).update(action));
glfwSetKeyCallback(this.windowHandle, (window, keyCode, scanCode, action, mods) -> {
for (GLFWKeyCallbackI callback : this.keyCallbacks) callback.invoke(window, keyCode, scanCode, action, mods);
});
glfwSetCharCallback(this.windowHandle, (window, unicode) -> {
for (GLFWCharCallbackI callback : this.charCallbacks) callback.invoke(window, unicode);
});
glfwSetMouseButtonCallback(this.windowHandle, (window, keyCode, action, mods) -> {
for (GLFWMouseButtonCallbackI callback : this.mouseButtonCallbacks) callback.invoke(window, keyCode, action, mods);
});
glfwSetScrollCallback(this.windowHandle, (window, xOffset, yOffset) -> {
for (GLFWScrollCallbackI callback : this.scrollCallbacks) callback.invoke(window, xOffset, yOffset);
});
// Make the OpenGL context current
GLFW.glfwMakeContextCurrent(this.windowHandle);
if (((windowHints >> 5) & 1) == 1) GLFW.glfwSwapInterval(1);
// Configure cursor
this.mouseX = MemoryUtil.memAllocDouble(1);
this.mouseY = MemoryUtil.memAllocDouble(1);
if (((windowHints >> 6) & 1) == 1) this.hideCursor(true);
this.initialized = true;
}
当我执行这段代码时:
GLFW.glfwSetCursorPos(this.windowHandle, 0, 0);
GLFW.glfwGetCursorPos(this.windowHandle, this.mouseX, this.mouseY);
System.out.println("Mouse Pos: " + this.mouseX.get(0) + ", " + this.mouseY.get(0));
Windows 和 Linux 的结果不同。
Linux: 鼠标位置: 0, 0
Windows: 鼠标位置: 623.0, 367.0
我不知道为什么它在windows上不起作用,它甚至似乎与lwjgl版本完全无关,因为我试过3.1.6、3.2.1、3.2.2和3.2 .3-SNAPSHOT,所有这些版本都一样。
所以问题是我在创建 window 时忘记了一些东西,或者 windows 在某些更新中破坏了一些东西,因为几个月前当我用 lwjgl 3.1.6 制作一个项目时我 100% 确定 setCursorPos()当时正在研究 linux 和 windows。
好的,所以我找到了问题的解决方案:
出于某种原因,glfwSetCursorPos() 必须在创建 window 的同一个线程中调用 windows 而不是 linux.
这有点奇怪,因为它没有在 windows 上导致分段错误,但是从同一个线程调用该方法对 windows 和 linux 都有效。
所以我使用 lwjgl 提供的 GLFW 绑定 java 在 java 中写了一个 window。它在 linux 上工作正常,但由于某些原因某些方法在 windows.
上不起作用我已经注册了一个在 linux 和 windows 上都可以正常工作的键回调,但是一个字符回调例如只在 linux.
上工作我遇到的另一个问题是 setCursorPos() 不起作用,因为我无法将鼠标居中以计算从那里的偏移量,这会破坏我的相机旋转。
这就是我创建 window 的方式:
public void init(int selectedMonitor, int glMajor, int glMinor, int windowHints) {
if (this.initialized) return;
GLFWErrorCallback.createPrint(System.err).set();
if (!GLFW.glfwInit())
throw new WindowCreationException("Unable to initialize GLFW.");
// Configure window hints
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, (windowHints & 1));
GLFW.glfwWindowHint(GLFW.GLFW_FOCUSED, (windowHints >> 1) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, (windowHints >> 2) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_DECORATED, (windowHints >> 3) & 1);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, glMajor);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, glMinor);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, (windowHints >> 7));
// Set video mode
PointerBuffer monitors = GLFW.glfwGetMonitors();
if (monitors == null)
throw new WindowCreationException("Could not create window, there are no monitors.");
if (selectedMonitor >= monitors.capacity() || selectedMonitor < 0) {
this.currentMonitor = GLFW.glfwGetPrimaryMonitor();
} else {
this.currentMonitor = monitors.get(selectedMonitor);
}
this.vidMode = GLFW.glfwGetVideoMode(this.currentMonitor);
// Create window handle
this.windowHandle = GLFW.glfwCreateWindow(this.width, this.height, this.title, this.isFullscreen ? this.currentMonitor : 0L, 0L);
if (this.windowHandle == 0L)
throw new RuntimeException("Failed to create GLFW Window.");
// Center window if configured
if (((windowHints >> 4) & 1) == 1) this.centerWindow();
// Set key callbacks
this.addKeyCallback((window, keyCode, scanCode, action, mods) -> Key.byKeyCode(keyCode).update(action));
this.addMouseButtonCallback((window, keyCode, action, mods) -> Key.byKeyCode(keyCode).update(action));
glfwSetKeyCallback(this.windowHandle, (window, keyCode, scanCode, action, mods) -> {
for (GLFWKeyCallbackI callback : this.keyCallbacks) callback.invoke(window, keyCode, scanCode, action, mods);
});
glfwSetCharCallback(this.windowHandle, (window, unicode) -> {
for (GLFWCharCallbackI callback : this.charCallbacks) callback.invoke(window, unicode);
});
glfwSetMouseButtonCallback(this.windowHandle, (window, keyCode, action, mods) -> {
for (GLFWMouseButtonCallbackI callback : this.mouseButtonCallbacks) callback.invoke(window, keyCode, action, mods);
});
glfwSetScrollCallback(this.windowHandle, (window, xOffset, yOffset) -> {
for (GLFWScrollCallbackI callback : this.scrollCallbacks) callback.invoke(window, xOffset, yOffset);
});
// Make the OpenGL context current
GLFW.glfwMakeContextCurrent(this.windowHandle);
if (((windowHints >> 5) & 1) == 1) GLFW.glfwSwapInterval(1);
// Configure cursor
this.mouseX = MemoryUtil.memAllocDouble(1);
this.mouseY = MemoryUtil.memAllocDouble(1);
if (((windowHints >> 6) & 1) == 1) this.hideCursor(true);
this.initialized = true;
}
当我执行这段代码时:
GLFW.glfwSetCursorPos(this.windowHandle, 0, 0);
GLFW.glfwGetCursorPos(this.windowHandle, this.mouseX, this.mouseY);
System.out.println("Mouse Pos: " + this.mouseX.get(0) + ", " + this.mouseY.get(0));
Windows 和 Linux 的结果不同。
Linux: 鼠标位置: 0, 0
Windows: 鼠标位置: 623.0, 367.0
我不知道为什么它在windows上不起作用,它甚至似乎与lwjgl版本完全无关,因为我试过3.1.6、3.2.1、3.2.2和3.2 .3-SNAPSHOT,所有这些版本都一样。 所以问题是我在创建 window 时忘记了一些东西,或者 windows 在某些更新中破坏了一些东西,因为几个月前当我用 lwjgl 3.1.6 制作一个项目时我 100% 确定 setCursorPos()当时正在研究 linux 和 windows。
好的,所以我找到了问题的解决方案:
出于某种原因,glfwSetCursorPos() 必须在创建 window 的同一个线程中调用 windows 而不是 linux.
这有点奇怪,因为它没有在 windows 上导致分段错误,但是从同一个线程调用该方法对 windows 和 linux 都有效。