GLFW 3:如何使用 ScrollCallback 获取鼠标滚轮的增量(LWJGL 3)
GLFW 3: How to get delta of the mouse scroll wheel with ScrollCallback (LWJGL 3)
我正在关注 this tutorial 使用 LWJGL 和 OpenGL 进行 3D 游戏开发。在该系列中,讲师使用的是 LWJGL 2,而我使用的是 LWJGL 3 和 GLFW。并且在某个部分他使用了 LWJGL 的输入实现仅在 LWJGL 2 中可用,所以我不得不使用 GLFW 的回调系统。我能够为键输入、光标移动和鼠标按钮输入添加输入功能,但是当我尝试添加滚动回调时,似乎滚动方向的偏移量只有 return -1 和 1,并且添加时,(第三人称)相机无限期地向前和向后平移,其目的是为相机向前或向后平移一定距离的每次滚动运动。实际上,我期望获得每次滚动运动的增量值。以前我一直在胡思乱想,看看我是否可以为一定的延迟时间设置偏移值,然后将它们设置回 0,但无济于事。我尝试寻找答案,但没有找到与我的问题相关的任何内容。我可能很笨,但这是代码。
MouseScroll 回调class:
import org.lwjgl.glfw.GLFWScrollCallback;
public class MouseScroll extends GLFWScrollCallback {
private static float XScroll;
private static float YScroll;
private static float DXScroll;
private static float DYScroll;
@Override
public void invoke(long window, double xoffset, double yoffset) {
XScroll = (float) xoffset;
YScroll = (float) yoffset;
// Don't know how to achieve this here
}
/* Returns raw offset values */
public float getXScroll() {
return XScroll;
}
public float getYScroll() {
return YScroll;
}
/* Returns the rate of each scrolling movement */
public float getDXScroll() {
return DXScroll;
}
public float getDYScroll() {
return DYScroll;
}
}
Input中获取YScroll的方法class:
public static float getMouseYScroll() {
return mouseScroll.getYScroll(); // mouseScroll is reference to MouseScroll callback
}
方法使用Camera.java中的回调:
private void calculateZoom() {
float zoomLevel = Input.getMouseYScroll() * 0.1f;
distanceFromPlayer -= zoomLevel;
}
Camera.java中的更新方法:
public void move() {
calculateZoom();
calculatePitch();
calculateAngleAroundPlayer();
float horizontalDistance = calculateHorizontalDistance();
float verticalDistance = calculateVerticalDistance();
calculateCameraPosition(horizontalDistance, verticalDistance);
this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
}
最后 camera.move()
每次循环迭代都会被调用
只要用户产生一些滚动操作(向上或向下,甚至向左或向右),就会调用 GLFWScrollCallback。结果,您将 XScroll
/ YScroll
设置为 -1
或 1
并保持原样 直到下一个滚动事件发生。您需要实施某种方法将其重置为零。可能你可以做类似
public float getYScroll() {
float value = YScroll;
YScroll = 0.0f;
return value;
}
但这只有在每帧只调用一次 getYScroll
时才有效。目前还不清楚你想如何处理这些事件(即你想存储它们直到被消耗 - 可能不是每一帧),但很可能你通过简单地向 MouseScroll
添加一些重置方法来逃避你在每一帧结束时调用 - 因为你每帧都查询滚轮,所以不会丢失任何事件。
我正在关注 this tutorial 使用 LWJGL 和 OpenGL 进行 3D 游戏开发。在该系列中,讲师使用的是 LWJGL 2,而我使用的是 LWJGL 3 和 GLFW。并且在某个部分他使用了 LWJGL 的输入实现仅在 LWJGL 2 中可用,所以我不得不使用 GLFW 的回调系统。我能够为键输入、光标移动和鼠标按钮输入添加输入功能,但是当我尝试添加滚动回调时,似乎滚动方向的偏移量只有 return -1 和 1,并且添加时,(第三人称)相机无限期地向前和向后平移,其目的是为相机向前或向后平移一定距离的每次滚动运动。实际上,我期望获得每次滚动运动的增量值。以前我一直在胡思乱想,看看我是否可以为一定的延迟时间设置偏移值,然后将它们设置回 0,但无济于事。我尝试寻找答案,但没有找到与我的问题相关的任何内容。我可能很笨,但这是代码。
MouseScroll 回调class:
import org.lwjgl.glfw.GLFWScrollCallback;
public class MouseScroll extends GLFWScrollCallback {
private static float XScroll;
private static float YScroll;
private static float DXScroll;
private static float DYScroll;
@Override
public void invoke(long window, double xoffset, double yoffset) {
XScroll = (float) xoffset;
YScroll = (float) yoffset;
// Don't know how to achieve this here
}
/* Returns raw offset values */
public float getXScroll() {
return XScroll;
}
public float getYScroll() {
return YScroll;
}
/* Returns the rate of each scrolling movement */
public float getDXScroll() {
return DXScroll;
}
public float getDYScroll() {
return DYScroll;
}
}
Input中获取YScroll的方法class:
public static float getMouseYScroll() {
return mouseScroll.getYScroll(); // mouseScroll is reference to MouseScroll callback
}
方法使用Camera.java中的回调:
private void calculateZoom() {
float zoomLevel = Input.getMouseYScroll() * 0.1f;
distanceFromPlayer -= zoomLevel;
}
Camera.java中的更新方法:
public void move() {
calculateZoom();
calculatePitch();
calculateAngleAroundPlayer();
float horizontalDistance = calculateHorizontalDistance();
float verticalDistance = calculateVerticalDistance();
calculateCameraPosition(horizontalDistance, verticalDistance);
this.yaw = 180 - (player.getRotY() + angleAroundPlayer);
}
最后 camera.move()
每次循环迭代都会被调用
只要用户产生一些滚动操作(向上或向下,甚至向左或向右),就会调用 GLFWScrollCallback。结果,您将 XScroll
/ YScroll
设置为 -1
或 1
并保持原样 直到下一个滚动事件发生。您需要实施某种方法将其重置为零。可能你可以做类似
public float getYScroll() {
float value = YScroll;
YScroll = 0.0f;
return value;
}
但这只有在每帧只调用一次 getYScroll
时才有效。目前还不清楚你想如何处理这些事件(即你想存储它们直到被消耗 - 可能不是每一帧),但很可能你通过简单地向 MouseScroll
添加一些重置方法来逃避你在每一帧结束时调用 - 因为你每帧都查询滚轮,所以不会丢失任何事件。