GLUT Tutorials 11: 切换菜单
博客转自:http://www.lighthouse3d.com/tutorials/glut-tutorial/swapping-menus/
上一个教程主要是一个菜单内的Item的切换,这个教程是在应用程序运行中直接切换整个菜单。两个功能函数是 glutSetMenu 和 glutGetMenu
void glutSetMenu(int menu); Parameters: menu – the index of a previously created menu
此函数的功能是根据菜单索引切换菜单。
int glutGetMenu(void);
此函数返回当前菜单的索引。接下来,我们呈现一个程序运行中,当用户按F1时候,两个菜单交换的例子。
完整代码如下
#include <stdio.h> #include <gl/glut.h> #define RED 1 #define GREEN 2 #define BLUE 3 #define WHITE 4 //所有的变量被初始化为1,表明三角形最开始是白色的。 float red = 1.0, blue = 1.0, green = 1.0; static float angle = 0.0, angleX = 0.0, ratio; //initially define the increase of the angle by 0.05; float deltaAngle = 0.05; int menu1,menu2; int flag = 1; void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(angle, 0.0, 1.0, 0.0); glRotatef(angleX, 1.0, 0.0, 0.0); glColor3f(red, green, blue); glBegin(GL_TRIANGLES); glVertex3f(-0.5, -0.5, 0.0); glVertex3f(0.5, 0.0, 0.0); glVertex3f(0.0, 0.5, 0.0); glEnd(); glPopMatrix(); // this is the new line // previously it was: angle++; angle += deltaAngle; glutSwapBuffers(); } void reShape(int w, int h) { // 防止被0除. if (h == 0) h = 1; ratio = 1.0f * w / h; //Reset the coordinate system before modifying glMatrixMode(GL_PROJECTION); glLoadIdentity(); //设置视口为整个窗口大小 glViewport(0, 0, w, h); //设置可视空间 gluPerspective(45, ratio, 1, 1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, -1.0, 0.0f, 1.0f, 0.0f); } void processMenuEvents(int option) { //option,就是传递过来的value的值。 switch (option) { case RED: red = 1.0; green = 0.0; blue = 0.0; break; case GREEN: red = 0.0; green = 1.0; blue = 0.0; break; case BLUE: red = 0.0; green = 0.0; blue = 1.0; break; case WHITE: red = 1.0; green = 1.0; blue = 1.0; break; } } void createGLUTMenus() { // 创建菜单并告诉GLUT,processMenuEvents处理菜单事件。 menu1 = glutCreateMenu(processMenuEvents); //给菜单增加条目 glutAddMenuEntry("Red", RED); glutAddMenuEntry("Blue", BLUE); glutAddMenuEntry("Green", GREEN); glutAddMenuEntry("White", WHITE); // 把菜单和鼠标右键关联起来。 glutAttachMenu(GLUT_RIGHT_BUTTON); menu2 = glutCreateMenu(processMenuEvents); glutAddMenuEntry("Blue", BLUE); glutAddMenuEntry("Green", GREEN); glutAddMenuEntry("Red", RED); } void processKeys(unsigned char c, int x, int y) { if (flag) { return; } int num = glutGet(GLUT_MENU_NUM_ITEMS); switch (c) { case 'a': glutChangeToMenuEntry(1, "Blue", BLUE); glutChangeToMenuEntry(3, "Red", RED); break; case 'b': glutChangeToMenuEntry(3, "Blue", BLUE); glutChangeToMenuEntry(1, "Red", RED); break; case 'c': if (num > 3) glutRemoveMenuItem(num); break; case 'd': if (num == 3) glutAddMenuEntry("White", WHITE); break; } glutSetMenu(menu1); } void processSpecialKeys(int c, int x, int y) { if (!flag) { if (c == GLUT_KEY_F1) { int x = glutGetMenu(); if (x == menu1) glutSetMenu(menu2); else glutSetMenu(menu1); // don't forget to attach the menu!!! glutAttachMenu(GLUT_RIGHT_BUTTON); } } } void processMenuStatus(int status, int x, int y) { if (status == GLUT_MENU_IN_USE) { printf("Menu is using\n"); flag = 1; } else { printf("Menu is not using\n"); flag = 0; } } void main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(100, 100); glutInitWindowSize(320, 320); glutCreateWindow("GLUT Tutorial Menu"); glutDisplayFunc(renderScene); glutIdleFunc(renderScene); glutReshapeFunc(reShape); glutKeyboardFunc(processKeys); glutSpecialFunc(processSpecialKeys); glutMenuStatusFunc(processMenuStatus); //调用我们的函数来创建菜单 createGLUTMenus(); glutMainLoop(); }
显示效果如下