Jumping Veiw

anonymous wrote on Monday, August 23, 2004:

This problem I am having is probably my fault, but I can’t see what I’m doing wrong, so I’ll ask here.

I have my Mouse Pos Callback function:

void GLFWCALL Ortho::MousePosCallback(int PosX, int PosY)
{
This->Center.X+=5.0*double(PosX)/double(This->Zoom);
This->Center.Y+=5.0*double(PosY)/double(This->Zoom);
glfwSetMousePos(0,0);
This->SetVeiw();
}

In this function Center is the center of my veiwscreen, Zoom is how much I am zoomed in, and SetVeiw() resets my veiw to take into account all of my changes. When I set this function at the beginning of my program, everything worked fine. But I wanted to only move the camera when I right-clicked, so I made this function:

void GLFWCALL Ortho::MouseButtonCallback(int Button, int Action)
{
if(Button==GLFW_MOUSE_BUTTON_RIGHT)
{
    switch(Action)
    {
        case GLFW_PRESS:
        {
        This->CameraMoveOn=true;
        glfwDisable(GLFW_MOUSE_CURSOR);
        glfwSetMousePosCallback(MousePosCallback);
        break;
        }
        case GLFW_RELEASE:
        {
        This->CameraMoveOn=false;
        glfwEnable(GLFW_MOUSE_CURSOR);
        glfwSetMousePosCallback(NULL);
        }
    }
}

Now, whenever I first right-click, the center of my screen jumps. I tried adding glfwSetMousePos(0,0); In the press case, but it didn’t help.

anonymous wrote on Monday, August 23, 2004:

Just in case you want to know, here is my SetVeiw function:

void Ortho::SetVeiw()
{
if(WindowSize.Y==0)
WindowSize.Y=1;

glViewport(0,0,WindowSize.X,WindowSize.Y);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(
Center.X-(double(WindowSize.X)/Zoom),
Center.X+(double(WindowSize.X)/Zoom),
Center.Y-(double(WindowSize.Y)/Zoom),
Center.Y+(double(WindowSize.Y)/Zoom),
-1.0f,1.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

anonymous wrote on Friday, September 17, 2004:

Anyone have anything? I stopped trying a while ago. Now I’ve come back to it, and I still can’t come up with anything. My solution so far has been to get rid of glfwDisable(GLFW_MOUSE_CURSOR);

case GLFW_PRESS:
{
This->CameraMoveOn=true;
glfwSetMousePos(This->WindowSize.X/2,This->WindowSize.Y/2);
glfwSetMousePosCallback(MousePosCallback);
break;
}

void GLFWCALL Ortho::MousePosCallback(int PosX, int PosY)
{
This->Center.X+=5.0*double(PosX-int(This->WindowSize.X/2))/double(This->Zoom);
This->Center.Y-=5.0*double(PosY-int(This->WindowSize.Y/2))/double(This->Zoom);
glfwSetMousePos(This->WindowSize.X/2,This->WindowSize.Y/2);
This->SetVeiw();
}

This works, but the mouse isn’t disabled…

marcus256 wrote on Monday, September 20, 2004:

Sorry for not replying. I haven’t had the time to look at this. Here is a hint though: you shouldn’t call GLFW functions from within callback functions, except for glfwGetXYZ (e.g. glfwGetKey, glfwGetMousePos etc).

This is not mentioned in the GLFW 2.4 docs, but I have added a section about it in the GLFW 2.5 reference manual.

Calling glfwSetMousePos from the mouse callback may disorient the internal GLFW mouse handling. You should be able to find another solution for this (e.g. delay the GLFW call(s) to after the event polling call).

marcus256 wrote on Monday, September 20, 2004:

Two more solutions (2nd solution is the preferred solution):

1) Always call glfwSetMousePos(0,0) after glfwPollEvents/glfwSwapBuffers

2) Store the old mouse position in a global variable, and form deltas manually, i.e.:

void GLFWCALL Ortho::MousePosCallback(int PosX, int PosY)
{
int dx,dy;
dx=PosX-OldPosX;
dy=PosY-OldPosY;
OldPosX=PosX;
OldPosY=PosY;
This->Center.X+=5.0*double(dx)/double(This->Zoom);
This->Center.Y+=5.0*double(dy)/double(This->Zoom);
This->SetVeiw();
}

Here, OldPosX and OldPosY are global variables.