我们现在来学习如何利用GLUT添加弹出式菜单,直接看示例:
#include <Gl/glut.h>
#include <stdio.h>
const GLint pickBuffsize = 32;
GLsizei winWidth = 400, winHeight = 400;
GLfloat red = 1.0, green = 1.0, blue = 1.0;
GLenum fillMode = GL_SMOOTH;
void init()
{
glClearColor(0.6, 0.,0.6, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 300.0, 0.0, 300.0);
}
void fillOption(GLint selectedOption)//菜单消息响应函数
{
switch (selectedOption)
{
case 1:
fillMode = GL_FLAT;//同色填充
break;
case 2:
fillMode = GL_SMOOTH;//顶点颜色插值
break;
default:
break;
}
glutPostRedisplay();//消息响应后必须被重绘
}
void displayTriangle()
{
glClear(GL_COLOR_BUFFER_BIT);
glShadeModel(fillMode);//多边形填充方式
glColor3f(red, green, blue);
glBegin(GL_TRIANGLES);//两个白点
glVertex2i(280, 20);
glVertex2i(160, 280);
glColor3f(red, 0.0, 0.0);//一个红点
glVertex2i(20, 100);
glEnd();
glFlush();
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayTriangle);
glutCreateMenu(fillOption);//创建菜单并绑定回调函数
glutAddMenuEntry("Solid-Color Fill", 1);//第一个菜单项
glutAddMenuEntry("Color-Interpolation Fill", 2);//第二个菜单
glutAttachMenu(GLUT_RIGHT_BUTTON);//指定鼠标右键来弹出菜单项
glutReshapeFunc(winReshapeFcn);
glutMainLoop();//启动主循环,等待消息
}
程序默认显示的是一个插值变化的三角形,当我们点击鼠标右键时,在光标位置出现弹出式菜单可以改变插值方式,当我们选择第一个选项时,三角形变为红色。下面我们来讲解下相应菜单函数。
以下语句创建一个弹出式菜单;
glutCreateMenu(menuFcn);
其参数是一个回调函数:
void menuFcn(GLint menuItemNumber)
函数的整型参数对应于选中项的位置。我们用下面的函数来设定每个菜单项的名称和位置:
glutAddMenuEntry("First Menu Item",1);
glutAddMenuEntry("Second Menu Item",2);
然后,我们必须通过以下函数指定来选择菜单项的鼠标键
glutAttachMenu(button);
button即鼠标键的符号常量。
非常简单地我们也可以在菜单项中添加子菜单。
#include <Gl/glut.h>
#include <stdio.h>
const GLint pickBuffsize = 32;
GLsizei winWidth = 400, winHeight = 400;
GLfloat red = 1.0, green = 1.0, blue = 1.0;
GLenum fillMode = GL_SMOOTH;
void init()
{
glClearColor(0.6, 0.,0.6, 1.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 300.0, 0.0, 300.0);
}
void mainMenu(GLint selectedOption)
{
switch (selectedOption)
{
case 1:
fillMode = GL_FLAT;
break;
case 2:
fillMode = GL_SMOOTH;
break;
default:
break;
}
glutPostRedisplay();
}
void colorSubMenu(GLint colorOption)
{
switch (colorOption)
{
case 1:
red = 0.0, green = 0.0, blue = 1.0;
break;
case 2:
red = 0.0, green = 1.0, blue =0.0;
break;
case 3:
red = 1.0, green = 0.0, blue = 0.0;
break;
default:
break;
}
glutPostRedisplay();
}
void displayTriangle()
{
glClear(GL_COLOR_BUFFER_BIT);
glShadeModel(fillMode);
glColor3f(red, green, blue);
glBegin(GL_TRIANGLES);
glVertex2i(280, 20);
glVertex2i(160, 280);
glColor3f(red, 0.0, 0.0);
glVertex2i(20, 100);
glEnd();
glFlush();
}
void winReshapeFcn(GLint newWidth, GLint newHeight)
{
glViewport(0, 0, newWidth, newHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, GLdouble(newWidth), 0.0, GLdouble(newHeight));
winWidth = newWidth;
winHeight = newHeight;
}
void main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(winWidth, winHeight);
glutCreateWindow("An Example OpenGL Program");
init();
glutDisplayFunc(displayTriangle);
GLint subMenu = glutCreateMenu(colorSubMenu);//子菜单项和普通菜单项创建一样
glutAddMenuEntry("Blue", 1);
glutAddMenuEntry("Green", 2);
glutAddMenuEntry("Red", 3);
glutCreateMenu(mainMenu);//主菜单项
glutAddMenuEntry("Solid-Color Fill", 1);
glutAddMenuEntry("Color-Interpolation Fill", 2);
glutAddSubMenu("color", subMenu);//给主菜单添加子菜单项
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutReshapeFunc(winReshapeFcn);
glutMainLoop();//启动主循环,等待消息
}
可以看到整个过程是非常简单的,只是利用glutAddSubMenu将一菜单项添加到了另一菜单项下面作为子菜单项。