LWJGL 3 get cursor position
Asked Answered
C

1

6

How do I get the position of a cursor? I looked in the documentation of GLFW, and there is a method glfwGetCursorPos(window, &xpos, &ypos) but Java does not have pointers so when I tried this method in Java there were DoubleBuffers as the arguments. Now when I write something like this:

public static double getCursorPosX(long windowID){
    DoubleBuffer posX = null;
    DoubleBuffer posY = null;
    glfwGetCursorPos(windowID, posX, posY);
    return posX != null ? posX.get() : 0;
}

posX is null and I can't figure out why (yes, I am setting up the callback in my display class).

Chavey answered 8/11, 2015 at 9:26 Comment(0)
L
9

Java does not directly support pointers, so LWJGL uses buffers as a workaround. These just wrap a memory address that can be read from and written to through methods on the object. This allows you to pass buffers to functions which write values into them, so you can then read these values.

The key point here is that you actually have to create a buffer beforehand for storing the value.

public static double getCursorPosX(long windowID) {
    DoubleBuffer posX = BufferUtils.createDoubleBuffer(1);
    glfwGetCursorPos(windowID, posX, null);
    return posX.get(0);
}

BufferUtils.createDoubleBuffer(length) is a utility function that creates a buffer. There are different buffers for different primitives, like int, long, char, float, double etc. In this case we need a buffer that can store doubles. The number (1) we pass to the method is the number of values the buffer should be able to store. We can use a buffer with a larger size for storing multiple values like in an array, but here we only want a single value.

The get(index) method returns the value at the given index. We only want to read the first value so we specify 0. You can also use put(index, value) to store values in a buffer.

Note: It might be tempting to do something like the following if you want to get both x and y values:

DoubleBuffer coords = BufferUtils.createDoubleBuffer(2);
glfwGetCursorPos(windowID, coords, coords);
double x = coords.get(0);
double y = coords.get(1);

However, this will not work as intended: It will write the y value to index 0 and leave a garbage (read: random) value at index 1. If you want to get both coords, you have to create a separate buffer for each.

DoubleBuffer xBuffer = BufferUtils.createDoubleBuffer(1);
DoubleBuffer yBuffer = BufferUtils.createDoubleBuffer(1);
glfwGetCursorPos(windowID, xBuffer, yBuffer);
double x = xBuffer.get(0);
double y = yBuffer.get(0);
Leatheroid answered 8/11, 2015 at 20:32 Comment(2)
thx man been searching for this for ages :p so DoubleBuffer is something like a Array? if I understood your sentence correctly?Chavey
Yes. The difference is that while arrays are managed by the Java Virtual Machine, buffers are just memory blocks like you would use them in C. You can also only store primitives (int, double, char, etc) in buffers, no objects (at least not directly). One drawback is that they take time to get used to and if you handle them incorrectly you will probably crash the program. However, reading and writing values is a lot faster than with arrays, so they are useful if you really need every bit of performance you can get.Leatheroid

© 2022 - 2024 — McMap. All rights reserved.