在GLUT中使用鼠标滚轮

34

我想在我的OpenGL GLUT程序中使用鼠标滚轮来缩放场景。我该怎么做?

3个回答

38

Freeglut的glutMouseWheelFunc回调函数在不同版本中会有差异,并且在X环境下不可靠。建议使用标准鼠标函数并测试3和4按键。

关于glutMouseWheelFunc,OpenGlut的说明如下:

由于缺乏有关鼠标的信息,在目前无法正确地在X上实现此功能。使用此函数限制了应用程序的可移植性。(该功能在X上确实可以工作,但不可靠。)建议您使用标准的、可靠的鼠标按钮报告,而非滚轮事件。

使用标准GLUT鼠标报告:

#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\n", (button == 3) ? "Up" : "Down", x, y);
   }else{  // normal button event
       printf("Button %s At %d %d\n", (state == GLUT_DOWN) ? "Down" : "Up", x, y);
   }
}

<snip...>

glutMouseFunc(mouse);

正如楼主所说,这很“死板简单”。但他是错的。


2
很不幸地,使用固定按钮是相当不可靠的,因为哪个鼠标按钮对应于鼠标滚轮取决于您插入了什么设备。事实上,我认为最常见的是按钮4/5用于上/下,而不是3/4。对于任何可用的程序,您都希望让用户轻松修改此设置。 - Chris Dodd
3
在我的Mac电脑上,使用免费的glut,3/4代表垂直上下滚动,而5/6代表水平滚动(在我的触控板上)。 - Alec Jacobson
谢谢伙计,这个解决方案在我的测试场景中完美运作。 - Maurizio Benedetti

26
注意,传统的Nate Robin的GLUT库不支持滚轮操作。但是,像FreeGLUT这样的后续实现则支持。
在FreeGLUT中使用滚轮非常简单。以下是方法:
声明一个回调函数,每当滚动鼠标滚轮时就会被调用。这是原型:
void mouseWheel(int, int, int, int);

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

glutMouseWheelFunc(mouseWheel);

定义回调函数。第二个参数表示滚动的方向。+1表示向前,-1表示向后。

void mouseWheel(int button, int dir, int x, int y)
{
    if (dir > 0)
    {
        // Zoom in
    }
    else
    {
        // Zoom out
    }

    return;
}

就是这样啦!


6
让我相当烦恼的是,freeGLUT 似乎没有实现 glutMouseWheelFunc() 回调函数。有趣的是,一些帖子在抱怨这种发帖风格,然而你为自己发布的答案却是不正确的。 - Rich
19
除了使用 #include <GL/freeglut.h> 让代码编译通过外,即使在 Ubuntu 10.04 x86_64 上测试(该系统附带 freeglut 2.6.0),glutMouseWheelFunc 回调函数似乎也没有被调用。解决方法是使用普通的 glutMouseFunc 回调函数并检查 button == 3 表示向上滚动鼠标轮,button == 4 表示向下滚动鼠标轮。 - Carlos Scheidegger
glutMouseWheelFunc回调函数是Windows特定的,可能不适用于Linux和MAC系统。 - AMCoded
截至2020年,freeglut似乎在X11上实现了glutMouseWheelFunc(https://sourceforge.net/p/freeglut/code/HEAD/tree/trunk/freeglut/freeglut/src/x11/fg_main_x11.c#l850),但我没有检查它是否有效。 - Yakov Galka

4
请观察鼠标单击回调函数中switch语句中的第三和第四个情况。
glutMouseFunc(mouseClick);

...

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 << ")\n";
      break;
    case GLUT_RIGHT_BUTTON:
      std::cout << "right click at: (" << x << ", " << y << ")\n";
      break;
    case GLUT_MIDDLE_BUTTON:
      std::cout << "middle click at: (" << x << ", " << y << ")\n";
      break;
    case 3:  //mouse wheel scrolls
      std::cout << "mouse wheel scroll up\n";
      break;
    case 4:
      std::cout << "mouse wheel scroll down\n";
      break;
    default:
      break;
    }
  }
  glutPostRedisplay();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接