So i'm trying to capture mouse dragging in my OpenGL application. I've done the following so far:
glfwSetMouseButtonCallback(window, mouse_callback);
static void mouse_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT) {
double x;
double y;
glfwGetCursorPos(window, &x, &y);
if (previous_y_position - y > 0)
{
camera_translation.y -= 1.0f;
previous_y_position = y;
}
else
{
camera_translation.y += 1.0f;
previous_y_position = y;
}
}
}
The problem with this though is if I would like to zoom in I need to move my mouse upwards and then click repeatedly. For some reason if I press down on the left mouse button and drag upwards it does nothing.
In cursor_pos_callback, just confirm if the button is pressed, and that works.
void mouse_cursor_callback( GLFWwindow * window, double xpos, double ypos)
{
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE)
{
return;
}
// `write your drag code here`
}
mouse_callback
is stateless. It receives events, momentary "actions".
You need to make your program to "remember" that mouse button is pressed. So that when button is pressed in a frame 1, you can refer to this information in all the frames after that and before mouse button is released.
The simple way is to flip a boolean flag on press/release:
static void mouse_callback(GLFWwindow* window, int button, int action, int mods)
{
if (button == GLFW_MOUSE_BUTTON_LEFT) {
if(GLFW_PRESS == action)
lbutton_down = true;
else if(GLFW_RELEASE == action)
lbutton_down = false;
}
if(lbutton_down) {
// do your drag here
}
}
Schematically:
state released pressed released
timeline -------------|------------------------------|---------------
^ ^
mouse_callback calls GLFW_PRESS GLFW_RELEASE
The hard way is to use a state machine (especially if you need more complicated combinations of states of input controllers).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With