0

我正在尝试使用 OpenGL 检测水平鼠标运动,因此,当检测到时,执行 glutPostRedisplay()。问题是场景也会在鼠标垂直移动时重绘。

这是注册回调的代码(注意 mouse_inix 和 mouse_iniy 是全局(双)变量):

void mouse(int button, int state, int x, int y)
{
    if (state == GLUT_DOWN)  {
            mouse_inix = (double)x;
            mouse_iniy = (double)y;
    }
}

void motion(int x, int y)
{

    if (((double)x) != mouse_inix) {
            angle += 20.0;
            glutPostRedisplay();
    } 
}
4

1 回答 1

0

Are you sure? It doesn't look like from the code you've posted that vertical mouse movement will trigger the glutPostRedisplay() call.

BUT, you've defined "horizontal mouse movement" very narrowly here. If you move the mouse up and down, you're almost sure to get a few pixels of horizontal movement. Maybe you could put a dead zone around the mouse to keep it from moving on every pixel. Something like:

void motion(int x, int y)
{
    if ((abs(x - (int)mouse_inix) > 10) {
        angle += 20.0;
        glutPostRedisplay();
    } 
}

That's one thing that's going on here. Another is the use of "double". Since glut is returning mouse coordinates as ints, you're better off sticking with that. Trying to compare "(double)x != mouse_inix" will almost certainly be true because of the precision issues with doubles. You generally don't want to compare for exactly equal to or not equal to using floating point numbers. The use of the dead zone will negate that issue, but still, why convert to doubles if you don't need them?

I don't know if "20" is degrees or radians, but it could result in some pretty jumpy moves either way. Consider scaling the size of the move to the size of the mouse move:

void motion(int x, int y)
{
    int deltaX = (abs(x - (int)mouse_inix);
    if (deltaX > 10) {
        angle += (double)deltaX;  // or "deltaX/scaleFactor" to make it move more/less
        glutPostRedisplay();
    } 
}

It will still only rotate one way. If you used the sign of "deltaX", you would be able to rotated both directions depending on how you moved the mouse.

于 2012-11-08T19:56:51.433 回答