Using the mouse scrollwheel in GLUT
Asked Answered
T

3

34

I want to use the mouse scrollwheel in my OpenGL GLUT program to zoom in and out of a scene? How do I do that?

Treasonable answered 18/8, 2008 at 9:29 Comment(0)
T
26

Note that venerable Nate Robin's GLUT library doesn't support the scrollwheel. But, later implementations of GLUT like FreeGLUT do.

Using the scroll wheel in FreeGLUT is dead simple. Here is how:

Declare a callback function that shall be called whenever the scroll wheel is scrolled. This is the prototype:

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

Register the callback with the (Free)GLUT function glutMouseWheelFunc().

glutMouseWheelFunc(mouseWheel);

Define the callback function. The second parameter gives the direction of the scroll. Values of +1 is forward, -1 is backward.

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

    return;
}

That's it!

Treasonable answered 18/8, 2008 at 9:29 Comment(4)
Much to my annoyance, freeGLUT doesn't seem to implement the glutMouseWheelFunc() callback. Rather ironic that posters were complaining about this style of posting, yet the answer you posted for yourself was incorrect.Viscose
Adding to that - even when one uses #include <GL/freeglut.h> so that the code compiles, glutMouseWheelFunc does not seem to be called (as tested on Ubuntu 10.04 x86_64, which ships freeglut 2.6.0). The solution is to use the regular glutMouseFunc callback and check for button == 3 for wheel up, and button == 4 for wheel down.Irmine
glutMouseWheelFunc callback is windows specific might not in Linux and MAC systemsCling
As of 2020 freeglut seems to implement glutMouseWheelFunc on X11, though I didn't check if it works.Lucretialucretius
B
38

Freeglut's glutMouseWheelFunc callback is version dependant and not reliable in X. Use standard mouse function and test for buttons 3 and 4.

The OpenGlut notes on glutMouseWheelFunc state:

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.

Using standard GLUT mouse reporting:

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

As the OP stated, it is "dead simple". He was just wrong.

Billfish answered 25/10, 2011 at 7:8 Comment(3)
Unfortunately using fixed buttons is pretty unreliable as WHICH mouse buttons correspond to the mouse wheel depends on what device you have plugged in. In fact, I think the most common is button 4/5 for up/down, not 3/4. For any usable program, you want to make it easy for the user to modify this.Inevasible
On my Mac with free glut, 3/4 correspond to vertical up and down scrolling and 5/6 correspond to horizontal scrolling (on my trackpad).Crossman
Thanks mate, this solution works perfectly in my testing scenario.Cresting
T
26

Note that venerable Nate Robin's GLUT library doesn't support the scrollwheel. But, later implementations of GLUT like FreeGLUT do.

Using the scroll wheel in FreeGLUT is dead simple. Here is how:

Declare a callback function that shall be called whenever the scroll wheel is scrolled. This is the prototype:

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

Register the callback with the (Free)GLUT function glutMouseWheelFunc().

glutMouseWheelFunc(mouseWheel);

Define the callback function. The second parameter gives the direction of the scroll. Values of +1 is forward, -1 is backward.

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

    return;
}

That's it!

Treasonable answered 18/8, 2008 at 9:29 Comment(4)
Much to my annoyance, freeGLUT doesn't seem to implement the glutMouseWheelFunc() callback. Rather ironic that posters were complaining about this style of posting, yet the answer you posted for yourself was incorrect.Viscose
Adding to that - even when one uses #include <GL/freeglut.h> so that the code compiles, glutMouseWheelFunc does not seem to be called (as tested on Ubuntu 10.04 x86_64, which ships freeglut 2.6.0). The solution is to use the regular glutMouseFunc callback and check for button == 3 for wheel up, and button == 4 for wheel down.Irmine
glutMouseWheelFunc callback is windows specific might not in Linux and MAC systemsCling
As of 2020 freeglut seems to implement glutMouseWheelFunc on X11, though I didn't check if it works.Lucretialucretius
S
4

observe case 3 and 4 in the switch statement below in the mouseClick callback

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();
}
Showily answered 14/11, 2018 at 16:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.