views:

104

answers:

1

I'm using GLUT and developing a FPS game. I need a way to trap the mouse so that the camera continues to move because right now when the mouse position exceeds the monitor limit, there is no way to calculate change in X or change in Y. How can I 'trap' the mouse with GLUT?

Thanks

+2  A: 

I'd recommend using a ready-made engine like OGRE 3D instead, but if you really want to reinvent the wheel, here's how...

In all cases I'm aware of, PC FPS games "trap" the pointer by registering a mouse motion callback, noting the relative motion, and then warping the pointer back to the center of the window.

Here's some code I wrote to add mouse input to a sample ping-pong table in an OpenGL with C++ course a year or two ago:

void resetPointer() {
    glutWarpPointer(TABLE_X/2, TABLE_Y/2);
    lastMousePos = TABLE_Y/2;
}

void mouseFunc(int sx, int sy) {
    if (!started) { return; }
    int vertMotion = lastMousePos - sy;
    lastMousePos = sy;
    player1.move(vertMotion);

    // Keep the pointer from leaving the window.
    if (fabs(TABLE_X/2 - sx) > 25 || fabs(TABLE_Y/2 - sy) > 25) {
        resetPointer();
    }
}

// This goes in with your "start new game" code if you want a menu
resetPointer();
glutSetCursor(GLUT_CURSOR_NONE);
glutPassiveMotionFunc(mouseFunc);

It only tracks vertical motion, but adding horizontal is trivial.

ssokolow
What's the point of "if (fabs(TABLE_X/2 - sx) > 25 || fabs(TABLE_Y/2 - sy) > 25)" ? Why not recenter the mouse every frame ?
Calvin1602
Technically, frames and mouse movement events aren't the same thing. Anyway, I can't remember exactly, but I think that's to prevent overhead in XWarpPointer (which glutWarpPointer uses on Linux) from becoming an issue. The interval-based timing the sample code came with greatly amplified any performance issues present and I didn't have time to rewrite it fully.
ssokolow