1、 UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); char *argv = hello , ; int argc = 2; / must/should match the number of strings in argv glutInit(&argc, argv); /初始化GLUT库; glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); /设置显示模式;(缓冲,颜色类型) glutInitWindowSize(500, 500); glutInitWin
2、dowPosition(1024 / 2 - 250, 768 / 2 - 250); glutCreateWindow(Hello); /创建窗口,标题为“hello”; glutDisplayFunc(display); /用于绘制当前窗口; glutMainLoop(); /表示开始运行程序,用于程序的结尾; return 0; void display(void) glClear(GL_COLOR_BUFFER_BIT); /刷新颜色缓冲区 glRectf(-0.5,-0.5,0.5,0.5); glFlush(); /用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执
3、行 2、在实验一的基础上添加键盘交互,按W键绘制的矩形上移,按S键矩形下移,按A键矩形左移,按D键矩形右移,如图2-2。参考步骤如下:(1)在主函数里添加注册键盘回调函数 glutKeyboardFunc(mykeyboard);此函数可放在 glutDisplayFunc(display);后面。 并在程序头部声明添加键盘回调函数: void mykeyboard(unsigned char key, int x, int y);(2)在display()绘制函数中修改绘制矩形代码,用变量代替数值参数。 例如: glRectf(-0.5,-0.5,0.5,0.5)改为glRectf(x1,y
4、1,x2,y2); 程序前面加上变量声明和初始值,如:float x1=-0.5,y1=-0.5,x2=0.5,y2=0.5; 注意语句的位置。 (3)在程序中增加mykeyboard键盘子函数,可放在display()函数之后。并在如下代码中进行修改,实现键盘控制矩形移动,运行程序自行测试。 void mykeyboard(unsigned char key, int x, int y) switch(key) case W: case w/ 矩形对角坐标变量修改使得矩形上移 y1+=0.1; y2+=0.1; break;case S case s/矩形对角坐标变量修改使得矩形下移 y1-
5、=0.1;y2-=0.1;A case a/矩形对角坐标变量修改使得矩形左移 x1-=0.1; x2-=0.1;Dd/矩形对角坐标变量修改使得矩形右移 x1+=0.1; x2+=0.1; /参数修改后调用重画函数,屏幕图形将发生改变 glutPostRedisplay();图2-2 3、设置窗口改变函数,使得矩形的长度和宽度等于100,程序启动时矩形仍在窗口中央,当显示窗口最大化时,绘制矩形也随之增大,如图2-3。 (1)在main函数里添加注册窗口变化函数glutReshapeFunc(myreshape); (放在glutMainLoop()之前)并在程序头部声明添加窗口变换函数: voi
6、d myreshape(GLsizei w, GLsizei h);(2)在程序中添加窗口改变子函数,参数w,h为当前显示窗口的宽和高 void myreshape(GLsizei w, GLsizei h) glViewport(0,0,w,h); /设置视区位置 glMatrixMode(GL_PROJECTION);/设置投影变换模式 glLoadIdentity(); /调单位矩阵,清空当前矩阵堆栈 gluOrtho2D(0,300,0,300); 3) 此时,矩形的初始变量经重新计算后为: float x1=100,x1=100,x2=200,y2=200; 注意:请同学们自己思考为
7、什么矩形初始的初始变量由原来的(-0.5,-0.5,0.5,0.5)变为(100,100,200,200) ?裁剪窗口设置函数gluOrtho2D(xwmin,xwmax,ywmin,ywmax); 和视区设置函数 glViewport(startx,starty,viewport_width,viewport_height)的设置有何规律? 此时,按下键盘“WADS”键进行交互移动,矩形的移动距离较之前有什么变化?要保持以前的移动频率,程序应该如何修改? a) 显示窗口改变前 b)显示窗口变大后图2-3 4、在矩形中间添加字符,观察结果;然后将字符改为自己名字的拼音或英文名字。如图2-4所示
8、。提示:在绘制矩形后添加如下代码:glColor3f(1,0,0); glRasterPos2i(x1+x2)/2,(y1+y2)/2); /定位当前光标 glutBitmapCharacter(GLUT_BITMAP_9_BY_15,H /写字符H glutBitmapCharacter(GLUT_BITMAP_9_BY_15,eelloo注意:运行程序,效果如图2-4所示。但是如果此时,按下键盘“WADS”键进行交互移动,程序会发生什么变化?要保持矩形白色,字符红色,程序应该如何修改?如果字符颜色设置语句glColor3f(1,0,0);放在定位光标语句glRasterPos2i(x1+x
9、2)/2,(y1+y2)/2); 之后,运行又会发生什么变化?请同学自己总结设置字符颜色语句的顺序规律。图2-45、 自己参照讲义或教材按照自己的构思画二维平面图形,将上面的矩形替换成自己构思的二维平面图形实现交互功能,注意顶点的顺序。并在画面上标注自己的姓名。3.2 鼠标交互(1) 鼠标画线 阅读OpenGL鼠标画线程序,能够实现在绘制窗口用鼠标交互绘制若干条直线,鼠标左键首先按下,确定直线的起始点,鼠标左键按下同时移动,看到画线过程,鼠标左键松开时,确定直线的终点,可重复画多条直线。实现主要思路: 1) 写出画静止若干条直线程序框架,坐标用变量替代;2) 在主函数里注册鼠标按钮响应函数和鼠
10、标移动响应函数;3) 在鼠标按钮响应子函数里,给出鼠标按钮响应事件;4) 在鼠标移动响应子函数里,给出鼠标移动响应事件;5) 读懂程序并分析程序,保留程序。/鼠标画线小程序#define N 1000 /maximum line numbersint ww,hh; / for display window width and heightint lineN4, k=0; /for lines endpoint coordinates and line numbervoid Myinit(void);void Reshape(int w, int h);void myMouse(int butt
11、on,int state,int x,int y);void myMotion(int x,int y);void Display(void);void drawlines();int APIENTRY _tWinMain(HINSTANCE hInstance, glutInitWindowSize(800, 600); /设置显示窗口大小 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);(注意双缓冲)鼠标画线小程序演示 / 创建显示窗口 Myinit(); glutDisplayFunc(Display); /注册显示回调函数 glutMouseFu
12、nc(myMouse); /注册鼠标按钮回调函数 glutMotionFunc(myMotion); /注册鼠标移动回调函数 glutReshapeFunc(Reshape); /注册窗口改变回调函数 /进入事件处理循环void Myinit(void)glClearColor(0.0,0.0,0.0,0.0);glLineWidth(3.0);/渲染绘制子程序-void Display(void) /刷新颜色缓冲区; drawlines(); /画线子程序; glutSwapBuffers(); /双缓冲的刷新模式;/-void Reshape(int w, int h) /窗口改变时自动获
13、取显示窗口的宽w和高h /投影矩阵模式 /矩阵堆栈清空 glViewport(0, 0, w, h); /设置视区大小 gluOrtho2D(0, w, 0, h); /设置裁剪窗口大小 ww=w; hh=h;/鼠标按钮响应事件.void myMouse(int button,int state,int x,int y) if(button=GLUT_LEFT_BUTTON&state=GLUT_DOWN) linek0=x; /线段起点x坐标 linek1=hh-y; /线段终点y坐标state=GLUT_UP) linek2=x; linek3=hh-y; k+;/鼠标移动时获得鼠标移动中
14、的坐标-void myMotion(int x,int y) /get the lines motion point linek2=x; /动态终点的x坐标 linek3=hh-y; /动态终点的y坐标 glutPostRedisplay();/画线子程序void drawlines() for(int i=0;i=k;i+) /* glBegin(GL_LINES); glVertex2f(linei0,linei1); glVertex2f(linei2,linei3); glEnd(); 鼠标画线程序运行后,程序效果如图3-3所示。图3-3 (2) 鼠标绘制矩形(将此修改代码贴到实验报告
15、中) 修改鼠标画线程序,要求:能够实现在绘制窗口用鼠标交互绘制若干矩形,鼠标左键首先按下,确定矩形对角线的起始点,鼠标左键按下同时移动时,看到画矩形过程,鼠标左键松开,确定矩形对角线的另一点,可重复画多个矩形。如图3-4所示。图3-4四、思考题:按下列步骤操作,并分析裁剪窗口、视区和显示窗口的关系。 (1)修改视区大小为原来的一半。如图2-5(a)。 (2)修改裁剪窗口的大小原来的一半;视区保持不变。如图2-5(b)。 图2-5(a) 图2-5(b)(3)修改以上程序使得按数字1键 实现矩形用WSAD键控制上下左右移动,按2键 显示自己构思的其他2D图形(三角形,点或多边形等)用WSAD键控制
16、上下左右移动五、参考函数:1、 裁剪窗口设置函数:gluOrtho2D(xwmin,xwmax,ywmin,ywmax); xwmin,xwmax,ywmin,ywmax为裁剪窗口在世界坐标系的位置,分别为x最小,x最大,y最小,y最大2、 视区设置函数:glViewport(startx,starty,viewport_width,viewport_height); 绘图区在显示窗口中的位置,以屏幕坐标系为参考 startx,starty,viewport_width,viewport_height分别为绘图区在显示窗口的起点位置, 以及绘图区的宽度和高度 3、 键盘响应相关函数:3.1 g
17、lutKeyboardFunc(void*f(unsigned char key,int x,int y)注册键盘响应函数, 按下键盘中某键,程序将key值作为字符返回给函数f,用户可决定下一步的行动。该函数调用放在主程序main()中 例如,当用户按下q 或 Q 或 Esc键 (ASCII27)时,程序退出。 glutKeyboardFunc(mykey); /主函数注册键盘响应函数 void mykey(unsigned char key,int x,int y) /键盘响应函数 if (key=q|key=Q|key=27) exit(0); 3.2 特殊键响应void glutSpec
18、ialFunc(void (*f) (int key,int x,int y)当用户按下一个特殊键时,调用函数f响应用户需求。使用方法同glutKeyboardFunc(void*f(unsigned char key,int x,int y)例, if (key=GLUT_KEY_F1) . if (key=GLUT_KEY_UP) .非ASCII键回调参数值Fi(i=1,2,12)GLUT_KEY_FiPage UpGLUT_KEY_PAGE_UPPage DownGLUT_KEY_PAGE_DOWN左方向键GLUT_KEY_LEFT右方向键GLUT_KEY_RIGHT上方向键GLUT_K
19、EY_UP下方向键GLUT_KEY_DOWNHomeGLUT_KEY_HOMEEndGLUT_KEY_END3.3 组合键 int glutGetModifers() 在键盘响应事件中当键盘按下时返回GLUT_ACTIVE_SHIFT, GLUT_ACTIVE_CTRL,或GLUT_ACTIVE_ALT值例, if(glutGetModifers()= GLUT_ACTIVE_CTRL)&(key=c)|(key=C) exit(0);4、 鼠标按钮响应相关函数 void glutMouseFunc(void (*f) (int button, int state, int x, int y)
20、 Mouse callback function。在主程序中调用。 button: GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON,GLUT_RIGHT_BUTTON state: GLUT_UP,GLUT_DOWN x,y:返回鼠标在窗口的位置(原点在左上角)。例如,主程序注册: glutMouseFunc(mymouse); void mymouse(int x,int y,int button,int state) if (state=GLUT_DOWN &button=GLUT_LEFT_BUTTON) exit(); /按下左键退出5、 注册鼠标移动响应函数v
21、oid glutMotionFunc(void (*f) (int x,int y)该函数在主程序中调用。(x,y)鼠标的位置,原点在左上角 move event:鼠标按钮按下时的鼠标移动 glutMotionFunc(mymousemotion);mymousemotion(int x,int y)/鼠标移动时触发的事件代码 passive move event:鼠标按钮松开时的鼠标移动 glutPassveMotionFunc(mymousepmotion); entry event: 鼠标进入或离开窗口时的事件 glutEntryFunc(mymouseentry); void glut
22、EntryFunc(void(*f) (int state) x,y-鼠标的位置,原点在左上角 state: GLUT_ENTERED or GLUT_LEFT 例,鼠标绘制折线代码 鼠标按下时开始画折线,鼠标按钮松开时结束。 glutMotionFunc(mymotion); void mymotion(int x,int y) 。 if(first_time_called) glBegin(GL_LINE_STRIP); glVertex2f(sx*(GLfloat)x,sy*(GLfloat)(h-y); 。 注意:鼠标按钮松开时产生glEnd()六、实验演示录像 1 win32_lab3_interactive.exe
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1