在 GLUT 中使用鼠标滚轮

Posted

技术标签:

【中文标题】在 GLUT 中使用鼠标滚轮【英文标题】:Using the mouse scrollwheel in GLUT 【发布时间】:2010-09-06 01:48:56 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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);

正如 OP 所说,它“非常简单”。他错了。

【讨论】:

不幸的是,使用固定按钮非常不可靠,因为哪个鼠标按钮对应于鼠标滚轮取决于您插入的设备。事实上,我认为最常见的是向上/向下按钮 4/5 ,而不是 3/4。对于任何可用的程序,您都希望用户能够轻松地对其进行修改。 在我的 Mac 上,3/4 对应于垂直上下滚动,5/6 对应于水平滚动(在我的触控板上)。 谢谢伙计,这个解决方案在我的测试场景中完美运行。【参考方案2】:

请注意,古老的 Nate Robin's GLUT 库不支持滚轮。但是,像FreeGLUT 这样的 GLUT 的后续实现会这样做。

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

声明一个回调函数,当滚轮滚动时调用该回调函数。这是原型:

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

使用(免费)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;

就是这样!

【讨论】:

令我烦恼的是,freeGLUT 似乎没有实现 glutMouseWheelFunc() 回调。颇具讽刺意味的是,张贴者抱怨这种发帖方式,而您自己发布的答案却是不正确的。 除此之外 - 即使有人使用 #include &lt;GL/freeglut.h&gt; 以便代码编译,似乎也没有调用 glutMouseWheelFunc(在 Ubuntu 10.04 x86_64 上测试过,它附带了 freeglut 2.6.0)。解决方案是使用常规的glutMouseFunc 回调并检查button == 3 是否向上,button == 4 是否向下。 glutMouseWheelFunc 回调是特定于 Windows 的,可能不适用于 Linux 和 MAC 系统 As of 2020 freeglut seems to implement glutMouseWheelFunc on X11,虽然我没有检查它是否有效。【参考方案3】:

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

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();

【讨论】:

以上是关于在 GLUT 中使用鼠标滚轮的主要内容,如果未能解决你的问题,请参考以下文章

鼠标滚轮不能滑动都有哪些解决办法

js中如何禁用鼠标滚轮事件?急,在线等!

如何禁用鼠标的滚轮?

如何禁用鼠标滚轮?

“鼠标中键滚轮向上滚动”这个用英语怎么说?

openGL按鼠标中键实现放大缩小