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 都有效。