#include
#include
#include
#include
#include
int menu=0,submenu1=0,submenu2;
//画一个绿色多边形
void draw(){
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0,1,0);
glOrtho(-1,1,-1,1,-1,1);
glBegin(GL_POLYGON);
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glutSwapBuffers();
}
//点击某个条目时,输出该条目属于哪个菜单
void getcurrentmenu(){
int nmenu;
nmenu = glutGetMenu();
if(nmenu == menu)
printf("current is main menu.\n");
else if(nmenu == submenu1)
printf("current is sub menu 1.\n");
else if(nmenu == submenu2)
printf("current is sub menu 2.\n");
}
//第一个子菜单
void submenufunc1(int data){
getcurrentmenu();
switch(data){
case 1:
printf("sub menu 1's item 1 is triggered.\n");
break;
case 2:
printf("sub menu 1's item 2 is triggered.\n");
break;
case 3:
printf("sub menu 1's item 3 is triggered.\n");
break;
}
}
//第二个子菜单
void submenufunc2(int data){
getcurrentmenu();
switch(data){
case 1:
printf("sub menu 2's item 1 is triggered.\n");
break;
case 2:
printf("sub menu 2's item 2 is triggered.\n");
break;
case 3:
printf("sub menu 2's item 3 is triggered.\n");
break;
}
}
//主菜单
void menufunc(int data){
getcurrentmenu();
switch(data){
case 1:
printf("menu's item 1 is triggered.\n");
break;
case 2:
printf("menu's item 2 is triggered.\n");
break;
case 3:
printf("menu's item 3 is triggered.\n");
break;
}
}
int main(int argc,char *argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(0,0);
glutInitWindowSize(512,512);
glutCreateWindow("test");
glutDisplayFunc(draw);
//构建子菜单1的内容
submenu1 = glutCreateMenu(submenufunc1);
glutAddMenuEntry("1's item 1",1);
glutAddMenuEntry("1's item 2",2);
glutAddMenuEntry("1's item 3",3);
glutAttachMenu(GLUT_LEFT_BUTTON);
//构建子菜单2的内容
submenu2 = glutCreateMenu(submenufunc2);
glutAddMenuEntry("2's item 1",1);
glutAddMenuEntry("2's item 2",2);
glutAddMenuEntry("2's item 3",3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
//构建主菜单的内容
menu = glutCreateMenu(menufunc);
glutAddMenuEntry("item 1",1);
glutAddMenuEntry("item 2",2);
glutAddMenuEntry("item 3",3);
//将两个菜单变为另一个菜单的子菜单
glutAddSubMenu("sub1",submenu1);
glutAddSubMenu("sub2",submenu2);
//点击鼠标右键时显示菜单
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}
名词解释:
菜单:
菜单条目:菜单中的某一选项。
和
都是菜单条目。
int glutCreateMenu( void (* func) (int value) )
参数说明:func 与将要创建的这个菜单相关联的函数。这个函数的作用:点击菜单中的某一选项时,控制系统做出对应的反应。
value 传递给回调函数func的数值,由所选择的菜单条目对应的整型数值确定。
通俗点说,在创建每一个菜单条目时,都会被赋予一个唯一的值。点击某个条目时,该条目对应的值就会被传递给func函数,func函数根据传入的值得知用户点击了哪个条目,然后进行对应的操作。
下面的代码应该对你理解这个函数会有一点帮助。
void menufunc(int data){
getcurrentmenu();
switch(data){
case 1:
printf("menu's item 1 is triggered.\n");
break;
case 2:
printf("menu's item 2 is triggered.\n");
break;
case 3:
printf("menu's item 3 is triggered.\n");
break;
}
}
int main(){
menu = glutCreateMenu(menufunc);
//构建菜单内容
glutAddMenuEntry("item 1",1);
glutAddMenuEntry("item 2",2);
glutAddMenuEntry("item 3",3);
}
void glutAddMenuEntry(char * name, int value)
参数说明:char *name 菜单条目的内容,比如示例结果图中的item 1和item 2.(这里的name没理解错的话,是地址指针)。
value,菜单条目的值(索引 )。在一个菜单中,每个条目都有唯一的数值用以区分。
该函数在上面已经有过初次见面了。
glutAddMenuEntry("item 1",1);
glutAddMenuEntry("item 2",2);
glutAddMenuEntry("item 3",3);
void glutAttachMenu(int button)
参数说明:button 指明在窗口中按哪种按键会使得菜单出现。可选择的符号常数为:GLUT_LEFT_BUTTON、GLUT_MIDDLE_BUTTON和 GLUT_RIGHT_BUTTON,分别表示鼠标左、中、右键。
示例代码的最后一行表示单机鼠标右键时会出现菜单。(键盘按键下一节会讲)
void glutAddSubMenu(char * name, int menu)
参数说明: name 与glutAddMenuEntry中的name类似,这里是子菜单的名称,比如实际结果图中的 sub1和sub2。
代码示例:
本文开头示例代码的main函数里最后几行。
void glutDetachMenu(int button)
参数说明:button 与上一个相同
使用该代码后,会断开鼠标按键和菜单间的联系。点击鼠标按键,对应的菜单将不会再出现(就像游戏里已经被你放生的宠物)。
参数说明:entry 菜单条目的索引,最顶层的为1,向下依次递增。比如示例中item1,item2, item3,sub1,sub2条目的索引分别为1、2、3、4、5.
name 新的字符串
value 新的值,也就是glutAddMenuEntry(char *name, int value)中的value
这里可以理解为改变当前菜单条目的名字。
比如在示例代码的最后加上一行代码:
menu = glutCreateMenu(menufunc);
glutAddMenuEntry("item 1",1);
glutAddMenuEntry("item 2",2);
glutAddMenuEntry("item 3",3);
glutChangeToMenuEntry(1,"item",1);//增加的代码
glutAddSubMenu("sub1",submenu1);
glutAddSubMenu("sub2",submenu2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}
运行结果如下:
item1 被改变为 item
不仅菜单条目可以改变,子菜单条目也可以改变,也就是示例中的sub1和sub2
将当前菜单指定的菜单条目更改为子菜单触发条目
参数说明:entry 与6.4的entry相同,为菜单项的索引
name,menu 与glutAddSubMenu(char *name, int menu)中的参数对应相同
entry与6.4的entry相同,为菜单项的索引。