计算机图形学实验一
利用glut创建一个菜单主要包括创建菜单,创建菜单项,制定选择菜单项的鼠标按键等步骤
1、菜单注册函数:glutCreateMenu(ProcessMenu);用于创建一个弹出式菜单,它指定ProcessMenu作为菜单回调函数,
void ProcessMenu(int value);value确定用户选择菜单项的ID值,以进行相应的处理。
2、使用函数在菜单中加入菜单项:void glutAddMenuEntry(char *name,GLint value);参数name指定菜单项显示的名称,value指定菜单项对应的ID,当这个菜单项被选中时,这个ID会传给菜单回调函数。
3、将菜单与某个鼠标按键关联起来:void glutAttachMenu(button);参数button用符号常量GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON和GLUT_RIGHT_BUTTON指定鼠标的左键、中键和右键。
本想利用菜单实现矩形的橡皮筋技术,但是由于第一次接触这个,搞不出来。。。
参考此报告,顺利解决问题:http://www.docin.com/p-848199424.html
#include"gl/glut.h" static GLsizei iMode=1; int ipointnum=0;//已确定点的数目 int x1=0,x2=0,y1=0,y2=0;//确定的点坐标 int winWidth=400,winHeight=300;//窗口的宽度和高度 int num=0,a[100],b[100],w1,h1,w2,h2; void Initial(void) { glClearColor(1.0f,1.0f,1.0f,1.0f);//设置窗口的背景颜色 } void ChangeSize(int w,int h) { winWidth=w;winHeight=h;//保存当前窗口的大小 glViewport(0,0,w,h);//指定窗口显示区域 glMatrixMode(GL_PROJECTION);//指定设置投影参数 glLoadIdentity();//调用单位矩阵,去掉以前的投影参数设置 gluOrtho2D(0.0,winWidth,0.0,winHeight);//设置投影参数 } void Display(void) { GLint i; glClear(GL_COLOR_BUFFER_BIT);//用当前背景色填充窗口 glColor3f(1.0f,0.0f,0.0f);//指定当前的绘图颜色 if(iMode==1) //绘制直线段 { glBegin(GL_LINES); glVertex2i(x1,y1); glVertex2i(x2,y2); glEnd(); } else if(iMode==2)//绘制折线 { glBegin(GL_LINE_STRIP); for(i=0;i<num;i++) { glVertex2i(a[i],b[i]); } glEnd(); glBegin(GL_LINES); glVertex2i(w1,h1); glVertex2i(w2,h2); glEnd(); } else if(iMode==3)//绘制矩形 { glBegin(GL_LINES);//通过给定两点坐标绘制矩形的四条边 glVertex2i(x1,y1); glVertex2i(x2,y1); glEnd(); glBegin(GL_LINES); glVertex2i(x1,y1); glVertex2i(x1,y2); glEnd(); glBegin(GL_LINES); glVertex2i(x2,y1); glVertex2i(x2,y2); glEnd(); glBegin(GL_LINES); glVertex2i(x1,y2); glVertex2i(x2,y2); glEnd(); } glutSwapBuffers();//交换缓冲区 } void MousePlot(GLint button,GLint action,GLint xMouse,GLint yMouse) { if(iMode==2){ if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN) { if(num==0) { w1=xMouse;h1=winHeight-yMouse;//确定直线段的第一个端点 a[num]=w1;b[num]=h1;num++; } else { w2=xMouse;h2=winHeight-yMouse;//确定直线段的第二个端点 a[num]=w2;b[num]=h2;num++; w1=w2;h1=h2; glutPostRedisplay();//指定窗口重新绘制 } } if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN) { num=0; glutPostRedisplay(); } } else if(iMode==3||iMode==1) { if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN) { if(ipointnum==0||ipointnum==2) { ipointnum=1; x1=xMouse;y1=winHeight-yMouse;//确定直线段的第一个端点 } else { ipointnum=2; x2=xMouse;y2=winHeight-yMouse;//确定直线段的第二个端点 glutPostRedisplay();//指定窗口重新绘制 } } if(button==GLUT_RIGHT_BUTTON&&action==GLUT_DOWN) { ipointnum=0; glutPostRedisplay(); } } } void PassiveMouseMove(GLint xMouse,GLint yMouse) { if(iMode==2) { if(num){ w2=xMouse; h2=winHeight-yMouse;//将当前鼠标位置指定为直线的未固定端点 glutPostRedisplay(); } } else if(iMode==3||iMode==1) { if(ipointnum==1) { x2=xMouse; y2=winHeight-yMouse; glutPostRedisplay(); } } } void ProcessMenu(int value) { iMode=value; glutPostRedisplay(); } int main(int argc,char *argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//使用双缓存及RGB模型 glutInitWindowSize(400,300);//指定窗口的大小 glutInitWindowPosition(100,100);//指定窗口在屏幕上的位置 glutCreateWindow("橡皮筋技术"); glutCreateMenu(ProcessMenu); glutAddMenuEntry("直线的橡皮筋绘制",1); glutAddMenuEntry("折线的橡皮筋绘制",2); glutAddMenuEntry("矩形的橡皮筋绘制",3); glutAttachMenu(GLUT_RIGHT_BUTTON); glutDisplayFunc(Display); glutReshapeFunc(ChangeSize);//指定窗口再整形回调函数 glutMouseFunc(MousePlot);//指定鼠标响应函数 glutPassiveMotionFunc(PassiveMouseMove);//指定鼠标移动响应函数 Initial(); glutMainLoop();//启动主GLUT时间处理循环 return 0; }