关于opengl:在GLUT中使用鼠标滚轮

关于opengl:在GLUT中使用鼠标滚轮

Using the mouse scrollwheel in GLUT

我想在OpenGL GLUT程序中使用鼠标滚轮来放大和缩小场景吗? 我怎么做?


Freeglut的glutMouseWheelFunc回调与版本有关,在X中不可靠。使用标准鼠标功能并测试按钮3和4。

OpenGlut关于glutMouseWheelFunc状态的注释:

Due to lack of information about the mouse, it is impossible to
implement this correctly on X at this time. Use of this function
limits the portability of your application. (This feature does work on
X, just not reliably.) You are encouraged to use the standard,
reliable mouse-button reporting, rather than wheel events.

使用标准的GLUT鼠标报告:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <GL/glut.h>

<snip...>

void mouse(int button, int state, int x, int y)
{
   // Wheel reports as button 3(scroll up) and button 4(scroll down)
   if ((button == 3) || (button == 4)) // It's a wheel event
   {
       // Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP
       if (state == GLUT_UP) return; // Disregard redundant GLUT_UP events
       printf("Scroll %s At %d %d
", (button == 3) ?"Up" :"Down", x, y);
   }else{  // normal button event
       printf("Button %s At %d %d
", (state == GLUT_DOWN) ?"Down" :"Up", x, y);
   }
}

<snip...>

glutMouseFunc(mouse);

正如OP所说,这是"死法简单"。他只是错了。


请注意,古老的Nate Robin的GLUT库不支持滚轮。但是,像FreeGLUT这样的GLUT更高版本的实现就可以了。

在FreeGLUT中使用滚轮非常简单。方法如下:

声明一个回调函数,只要滚动滚轮就应调用该回调函数。这是原型:

1
void mouseWheel(int, int, int, int);

使用(Free)GLUT函数glutMouseWheelFunc()注册回调。

1
glutMouseWheelFunc(mouseWheel);

定义回调函数。第二个参数给出滚动方向。值+1为正向,-1为反向。

1
2
3
4
5
6
7
8
9
10
11
12
13
void mouseWheel(int button, int dir, int x, int y)
{
    if (dir > 0)
    {
        // Zoom in
    }
    else
    {
        // Zoom out
    }

    return;
}

而已!


在下面的mouseClick回调中的switch语句中观察情况3和4

1
glutMouseFunc(mouseClick);

...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void mouseClick(int btn, int state, int x, int y) {
  if (state == GLUT_DOWN) {
    switch(btn) {
    case GLUT_LEFT_BUTTON:
      std::cout <<"left click at: (" << x <<"," << y <<")
";
      break;
    case GLUT_RIGHT_BUTTON:
      std::cout <<"right click at: (" << x <<"," << y <<")
";
      break;
    case GLUT_MIDDLE_BUTTON:
      std::cout <<"middle click at: (" << x <<"," << y <<")
";
      break;
    case 3:  //mouse wheel scrolls
      std::cout <<"mouse wheel scroll up
";
      break;
    case 4:
      std::cout <<"mouse wheel scroll down
";
      break;
    default:
      break;
    }
  }
  glutPostRedisplay();
}


推荐阅读