How to move around camera using mouse in OpenGL?

11,422

You may want to use glutPassiveMotionFunc with a custom callback to handle the mouse position deltas:

void handlerFunc(int x, int y) 
{ 
    /* code to handle mouse position deltas */ 
}

int main()
{
     /* [...] */

     glutPassiveMotionFunc(handlerFunc);  // before glutMainLoop.

     /* [...] */

     return 0;
}

Documentation: glutPassiveMotionFunc

-

Moreover, I believe there's something wrong with your delta calculation. You should be calculating the difference between the current cursor position and the center of the window (where the cursor will be set after each frame).

mouseDisplacement = mouseX - centerWindowX;

Here's some code I use in my engine to get a FPS camera (feel free to adapt accordingly):

void update(float delta)  // delta is usually 1.0/60.0
{
    // Mouse.
    MouseState mouse = InputDevices.get_mouse_state();

    // - Movement
    camera->yaw += camera->speed * mouse.dx * delta;
    camera->pitch -= camera->speed * mouse.dy * delta;

    // Regular FPS camera.
    // TODO(Clem): Move this to a class.

    // Clamp.
    if (camera->pitch > math::PI_OVER_TWO) {
        camera->pitch = math::PI_OVER_TWO - 0.0001f;
    }
    else if (camera->pitch < -math::PI_OVER_TWO) {
        camera->pitch = -math::PI_OVER_TWO + 0.0001f;
    }

    float pitch = camera->pitch;
    float yaw = camera->yaw;

    // Spherical coordinates (r=1).
    camera->forward.x = -sin(yaw) * cos(pitch);
    camera->forward.y = -sin(pitch);
    camera->forward.z = -cos(yaw) * cos(pitch);

    camera->right.x = -cos(yaw);
    camera->right.y = 0.0;
    camera->right.z = sin(yaw);

    camera->up = cross(camera->forward, camera->right);

    camera->forward = normalize(camera->forward);
    camera->right = normalize(camera->right);
    camera->up = normalize(camera->up);
}
Share:
11,422
Bazinga
Author by

Bazinga

Fourth year computer science student. Love to help others as much as I can :) SOreadytohelp

Updated on June 04, 2022

Comments

  • Bazinga
    Bazinga almost 2 years

    I realize this question has been asked before on stackoverflow, but I have yet to find an answer that I understand completely so I thought I'd get some help specific to my situation.

    I basically want to be able to use the mouse to rotate around the y-axis. Following is the function I'm using for the actual rotation (angles are in degrees).

    void CCamera::RotateY (GLfloat Angle)
    {
        RotatedY += Angle;
    
        //Rotate viewdir around the up vector:
        ViewDir = Normalize3dVector(ViewDir*cos(Angle*PIdiv180)
                        - RightVector*sin(Angle*PIdiv180));
    
        //now compute the new RightVector (by cross product)
        RightVector = CrossProduct(&ViewDir, &UpVector);
    }
    

    Since I'm using GLUT, I use the passive function to get the x,y coordinates of the cursor. And then in my display I have the following:

    void display(void) {
        ...
        mouseDisplacement = mouseX - oldMouseX;
    
        if (mouseDisplacement > 0) Camera.RotateY(-1.0*abs(mouseDisplacement));
        else if (mouseDisplacement < 0) Camera.RotateY(1.0*abs(mouseDisplacement));
    
        oldMouseX = mouseX;
        glutWarpPointer(centerWindowX, centerWindowY);  // move the cursor to center of window
        ...    
    }
    

    Now the problem is pretty obvious, since the display function runs 60 times a second, the mouse cursor just gets stuck in the middle whenever I try to move it. If I don't have the display function loop, the rotation is really laggy and stuff. So what is the proper way of doing this?

    Note again, I'm only looking to have the camera move around in right/left direction using the mouse. Although it'd be awesome if I could get it working like a proper fps, it's not really essential.

    Any help is greatly appreciated.

  • Bazinga
    Bazinga over 8 years
    My bad for not being clear. I already am using the glutPassiveMotionFunc(...) to update the global variable which is mouseX. The issue comes when I want to move around the camera while keeping the mouse centered in the window.
  • Mr_Pouet
    Mr_Pouet over 8 years
    Ok gotcha. I believe the problem comes from your delta calculation. You should be calculating the difference between the current cursor position and the center of the window (where the cursor will be set after each frame).
  • Bazinga
    Bazinga over 8 years
    Thank you for taking the time to help me. I also tried what you said above, by taking displacement with respect to center coordinate. However, since I update the cursor to stay in the middle, the displacement becomes always 0 or very close to 0. Thereby not moving the camera like it should be.
  • Sahas
    Sahas over 2 years
    Guys, A Basic question: How to run this code? Can you comment on the libraries to include?