1
votes

So basically am learning OpenGL and the GLFW libraries from the tutorial on page: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboard-and-mouse/

My problems is with this less lesson showing the control of camera movement with mouse. Basicaly it makes the application to get "FPS" like camera, with disabled cursor being moved on center of screen with each frame. But the camera gets crazy when we lose focus on the window and then it regains. For example if we click on the window to regain focus away from the middle of view, the camera will be moved by big amount. I tried to fix this issue with adding window focus callback:

void window_focus_callback(GLFWwindow* window, int focused){
if (focused)
{
    //center mouse on screen
    int width, height;
    glfwGetWindowSize(window, &width, &height);
    glfwSetCursorPos(window, 1024 / 2, 768 / 2);
    windowFocused = true;
}
else
{
    windowFocused = false;
}

And in the main application loop:

if(windowFocused) computeMatricesFromInputs();

But for some reason this solution doesnt work. Is there any way to fix this issue using glfw?

1

1 Answers

2
votes

Question is a bit old, but I recently suffered a similar issue. So just sharing, more solutions exist. I use GLFW_CURSOR_DISABLED. In this mode the mouse position is not (yet) updated when you receive the 'on' focus event, so call to GetCursorPos delivers the previous value. The new cursor position arrives in the MouseMove callback AFTER the 'on' focus event. I solved it by keeping track of the regain of focus and use this int he OnMouseMove callback to either dispatch a MouseInit (to snap the cursor) or a regular MouseMove.

This way I can ALT+TAB out of my window and return with the cursor somewhere else without nasty jumps/rotations of the camera.

void InputManagerGLFW::Callback_OnMouseMove(
            GLFWwindow* window,
            double      xpos,               //
            double      ypos)               //
{
    if (!mFocusRegained)
    {
        mMouseBuffer.Move(xpos, ypos);
    }
    else
    {
        mFocusRegained = false;
        mMouseBuffer.Init(xpos, ypos);
    }
}

void InputManagerGLFW::Callback_OnFocus(
            GLFWwindow* window,
            int         focused)
{
    if (focused)
    {
        // The window gained input focus
        // Note: the mouse position is not yet updated
        //       the new position is provided by the mousemove callback AFTER this callback
        Log::Info("focus");

        // use flag to indicate the OnMouseMove that we just regained focus,
        // so the first mouse move must be handled differently
        mFocusRegained = true;

        // this will NOT work!!!
        // double x,y;
        // glfwGetCursorPos(window,&x,&y);
        // mMouseBuffer.Init(x,y);
    }
    else
    {
        // The window lost input focus
        Log::Info("focus lost");
    }
}