Lab 3 - GLUT Menus

How to make a mouse-click menu

Menu-related GLUT functions:

  • int glutCreateMenu(void (*func)(int)): creates a menu (internally) and returns an identifier; takes a pointer to menu-handling function as an argument
  • glutAddMenuEntry(char* text, int id): adds a textual entry to last-created menu, referred to by corresponding integer identifier (which is passed to the menu-handling function)
  • glutAttachMenu(int button): attaches the menu to a mouse button, overriding the event-handler for that mouse button's events
  • There are corresponding functions for destroying menus: glutDetachMenu(int button) and glutDestroyMenu(int menuID).

Here's an example of how to create a menu using these functions, based on the helloGL.cpp code.

First, let's make a function to handle the menu-creation:

 void CreateMenus()
 {
 	// Get a menu ID (use var with wider scope if you
 	// need to reference it later)
 	int main = glutCreateMenu(ProcessMainMenu);

 	// Add entries to menu
 	glutAddMenuEntry("Item 1", MAIN_ITEM_1);
 	glutAddMenuEntry("Item 2", MAIN_ITEM_2);

 	// Attach to the right mouse button
 	glutAttachMenu(GLUT_RIGHT_BUTTON);
 }

Next, we need to define some things referred to in CreateMenus(): the menu handler ProcessMainMenu(int), and the item ID macros.

 ...
 #define MAIN_ITEM_1 1
 #define MAIN_ITEM_2 2
 ...
 void ProcessMainMenu(int item)
 {
 	switch (item)
 	{
 		case MAIN_ITEM_1:
 			std::cout << "Item 1 selected\n"; break;
 		case MAIN_ITEM_2:
 			std::cout << "Item 2 selected\n"; break;
 	}
 }

Finally, we should call CreateMenus() in the main function:

 // In main()
 CreateMenus();

Compile and run the program, and verify that you see a menu when right-clicking in the window.

Sub-Menus

You can also create sub-menus easily in GLUT. The sub-menu is created with the same commands as a main menu, i.e. with glutCreateMenu() and glutAddMenuEntry(). However, instead of attaching the menu to a button, you add it as a sub-menu of another menu.

Consider this revised version of CreateMenus():

 void CreateMenus()
 {
	// Create sub-menu with 1 item
	int sub = glutCreateMenu(ProcessMainMenu);
	glutAddMenuEntry("Sub-item 1", SUB_ITEM_1);

	// Create main menu with 2 items
	int main = glutCreateMenu(ProcessMainMenu);
	glutAddMenuEntry("Item 1", MAIN_ITEM_1);
	glutAddMenuEntry("Item 2", MAIN_ITEM_2);

	// Add sub-menu to main menu
	glutAddSubMenu("Sub-menu", sub);

	// Attach main menu to a mouse button
	glutAttachMenu(GLUT_RIGHT_BUTTON);
 }

Now you'll see something like this when right-clicking in the window:

Further Reading: