Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GLFW to capture mouse dragging? [C++]

Tags:

c++

opengl

glfw

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.

like image 481
Mettalknight Avatar asked Mar 12 '23 08:03

Mettalknight


2 Answers

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`
}
like image 53
linxx Avatar answered Mar 20 '23 08:03

linxx


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).

like image 44
Ivan Aksamentov - Drop Avatar answered Mar 20 '23 08:03

Ivan Aksamentov - Drop