Friday, May 11, 2012

GLUT Tutorial - Creating Menus and Submenus in GLUT

GLUT supports simple cascading pop-up menus. They are designed to let a user select various modes within a program. The functionality is simple and minimalistic and is meant to be that way. Do not mistake GLUT’s pop-up menu facility with an attempt to create a full-featured user interface. glutCreateMenu creates a Menu in GLUT. The syntax of glutCreateMenu is

int glutCreateMenu(void (*func)(int value));

This function defines the callback that has to be called when a menu item was selected. This callback function has one parameter, the value. This function returns an int, this is the menu identifier. This identifier is needed when you would want to attach this menu as a submenu. This is illustrated in sample example later.


void glutAddMenuEntry(char *name, int value);

This adds an entry to the menu with the label defined by name and the second parameter is the value that will be passed to the callback function. The menu is being added to the current menu. Each menu entry that is being added is added at the bottom of the current menu.

void glutAddSubMenu(char *name, int menu);

This adds the menu identified by the menu identifier as submenu with a given name to the current menu. The program won’t work if it contains an infinite loop of menus.

void glutAttachMenu(int button);

This attaches the current menu to a certain (mouse) event, you can let a menu listen to a specified mouse button, button can be one of the following:GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, and GLUT_RIGHT_BUTTON. You can also detach the menu using void glutDetachMenu(int button);.

Source code of sample example
#include <windows.h>
#include <GL/glut.h> 
static int window;
static int menu_id;
static int submenu_id;
static int value = 0; 
void menu(int num){
  if(num == 0){
    glutDestroyWindow(window);
    exit(0);
  }else{
    value = num;
  }
  glutPostRedisplay();
} 
void createMenu(void){     submenu_id = glutCreateMenu(menu);
    glutAddMenuEntry("Sphere", 2);
    glutAddMenuEntry("Cone", 3);
    glutAddMenuEntry("Torus", 4);
    glutAddMenuEntry("Teapot", 5);     menu_id = glutCreateMenu(menu);
    glutAddMenuEntry("Clear", 1);
    glutAddSubMenu("Draw", submenu_id);
    glutAddMenuEntry("Quit", 0);     glutAttachMenu(GLUT_RIGHT_BUTTON);
} 
void display(void){
  glClear(GL_COLOR_BUFFER_BIT);   if(value == 1){
    return; //glutPostRedisplay();
  }else if(value == 2){
    glPushMatrix();
    glColor3d(1.0, 0.0, 0.0);
    glutWireSphere(0.5, 50, 50);
    glPopMatrix();
  }else if(value == 3){
    glPushMatrix();
    glColor3d(0.0, 1.0, 0.0);
    glRotated(65, -1.0, 0.0, 0.0);
    glutWireCone(0.5, 1.0, 50, 50);
    glPopMatrix();
  }else if(value == 4){
    glPushMatrix();
    glColor3d(0.0, 0.0, 1.0);
    glutWireTorus(0.3,0.6,100,100);
    glPopMatrix();
  }else if(value == 5){
    glPushMatrix();
    glColor3d(1.0, 0.0, 1.0);
    glutSolidTeapot(0.5);
    glPopMatrix();
  }
  glFlush();
} 
int main(int argc, char **argv){     glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    window = glutCreateWindow("Menus and Submenus - Programming Techniques");
    createMenu();     glClearColor(0.0,0.0,0.0,0.0);
    glutDisplayFunc(display);     glutMainLoop();
    return EXIT_SUCCESS;
} 

5 comments:

  1. Hello
    i copied your code and complie ,but when running ,right click ,i recvied error Segmentation fault why?

    ReplyDelete
  2. You should replace "GlutPostRedisplay();" in the display function for "return;", otherwise you will enter a infinite loop.

    ReplyDelete
  3. I'm a newbie here, and I've tried to run this test case. It builds under my environment (gcc under SuSE Linux 12.2), but I simply can't get any response from the menu - it just doesn't appear. With no error messages, it's hard to know where to begin to look. Has anybody out there any ideas?

    ReplyDelete
  4. Thankyou so much this code helped me alot to understand functioning of menus ...

    zak

    ReplyDelete