在 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 <GL/freeglut.h>
以便代码编译,似乎也没有调用 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 中使用鼠标滚轮的主要内容,如果未能解决你的问题,请参考以下文章