logo资料库

OpenGL的简单动画与交互.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
void glutTimerFunc(unsigned int msecs, void (*Func
实验三 OpenGL 的简单动画与交互 一、实验目的 1、掌握 OpenGL 鼠标交互功能及其简单应用。 2、掌握 OpenGL 的闲置函数与简单动画。 二、实验环境 硬件要求: PC 机,主流配置,最好为独立显卡,显存 512M 以上。 软件环境: 操作系统:Windows XP。 语言开发工具:Microsoft Visual studio 2008,Visual C++。 三、实验内容与要求 1、闲置函数的使用与简单动画。 (1) 旋转的六边形,如图 3-1 所示 阅读 OpenGL 旋转的六边形样本框架程序,分析程序的实现步骤: //样本程序: 旋转的六边形 #include "stdafx.h" #include #include #define PI 3.14159 int n=6, R=10; //设置圆周率 //多边形变数,外接圆半径 float theta=0.0; //旋转初始角度值 void Keyboard(unsigned char key, int x, int y); void Display(void); void Reshape(int w, int h); void myidle(); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR int lpCmdLine, nCmdShow) { 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库; glutInitWindowSize(700,700); //设置显示窗口大小 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //设置显示模式;(注意双缓冲) glutCreateWindow("A Rotating Square"); // 创建显示窗口 glutDisplayFunc(Display); glutReshapeFunc(Reshape); //注册显示回调函数 //注册窗口改变回调函数
glutIdleFunc(myidle); glutMainLoop(); //进入事件处理循环 //注册闲置回调函数 return 0; } void Display(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,0,0); //设置红色绘图颜色 glBegin(GL_POLYGON); //开始绘制六边形 for (int i=0;i=2*PI) theta-=2*PI; glutPostRedisplay(); //重画,相当于重新调用Display(),改编后的变量得以传给绘制函数 } void Reshape(GLsizei w,GLsizei h) { glMatrixMode(GL_PROJECTION); //投影矩阵模式 glLoadIdentity(); //矩阵堆栈清空 gluOrtho2D(-1.5*R*w/h,1.5*R*w/h,-1.5*R,1.5*R); //设置裁剪窗口大小 glViewport(0,0,w,h); //设置视区大小 glMatrixMode(GL_MODELVIEW); //模型矩阵模式 } 运行该程序,观察旋转动画效果。 思考: 如果要调整旋转速度,旋转更快或更慢,应该如何修改程序?
(2) 六边形静止,直线单独旋转,如图 3-2 所示。 图 3-1 要求: 1)修改前面的程序,使得六边形保持静止,以六边形中心为起点画 一条直线,终点为六边形某一顶点,使得直线不停绕中心点旋转。 代码保存下来备用。 思考:如果需要直线保持与机器时钟的秒针节拍吻合,应该如何修改?
2、鼠标交互。 (1) 鼠标画线 图 3-2 阅读 OpenGL 鼠标画线程序,能够实现在绘制窗口用鼠标交互 绘制若干条直线,鼠标左键首先按下,确定直线的起始点,鼠标左 键按下同时移动,看到画线过程,鼠标左键松开时,确定直线的终 点,可重复画多条直线。 实现主要思路: 1) 写出画静止若干条直线程序框架,坐标用变量替代; 2) 在主函数里注册鼠标按钮响应函数和鼠标移动响应函数; 3) 在鼠标按钮响应子函数里,给出鼠标按钮响应事件; 4) 在鼠标移动响应子函数里,给出鼠标移动响应事件; 5) 读懂程序并分析程序,保留程序。 //鼠标画线小程序 #include "stdafx.h" #include #define N 1000 //maximum line numbers int ww,hh; int line[N][4], k=0; //for line's endpoint coordinates and line number // for display window width and height void Myinit(void) { glClearColor(0.0,0.0,0.0,0.0); glLineWidth(3.0); }
//鼠标按钮响应事件.. void myMouse(int button,int state,int x,int y) { if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN) { line[k][0]=x; line[k][1]=hh-y; //线段终点y坐标 //线段起点x坐标 } if(button==GLUT_LEFT_BUTTON&&state==GLUT_UP) { line[k][2]=x; line[k][3]=hh-y; k++; //线段起点x坐标 //线段终点y坐标 glutPostRedisplay(); } } //鼠标移动时获得鼠标移动中的坐标----------------------------------------------------- void myMotion(int x,int y) { //get the line's motion point line[k][2]=x; line[k][3]=hh-y; //动态终点的y坐标 //动态终点的x坐标 glutPostRedisplay(); } //画线子程序 void drawlines() { for(int i=0;i<=k;i++) //******** { } } glBegin(GL_LINES); glVertex2f(line[i][0],line[i][1]); glVertex2f(line[i][2],line[i][3]); glEnd(); //渲染绘制子程序-------------------------------------------------------------------------- void Display(void) { glClear(GL_COLOR_BUFFER_BIT); drawlines(); //画线子程序; glutSwapBuffers(); //双缓冲的刷新模式; //刷新颜色缓冲区; } //----------------------------------------------- void Reshape(int w, int h) //窗口改变时自动获取显示窗口的宽w和高h { //矩阵堆栈清空 glMatrixMode(GL_PROJECTION); //投影矩阵模式 glLoadIdentity(); glViewport(0, 0, w, h); gluOrtho2D(0, w, 0, h); ww=w; hh=h; //设置视区大小 //设置裁剪窗口大小
} int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR int lpCmdLine, nCmdShow) { } 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库; glutInitWindowSize(800, 600); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); //设置显示模式;(注意双缓冲) glutCreateWindow("鼠标画线小程序演示"); // 创建显示窗口 //设置显示窗口大小 Myinit(); glutDisplayFunc(Display); //注册显示回调函数 glutMouseFunc(myMouse); //注册鼠标按钮回调函数 glutMotionFunc(myMotion); //注册鼠标移动回调函数 glutReshapeFunc(Reshape); //注册窗口改变回调函数 glutMainLoop(); //进入事件处理循环 return 0; 鼠标画线程序运行后,程序效果如图 3-3 所示。 图 3-3
(2) 鼠标绘制矩形 修改鼠标画线程序,要求:能够实现在绘制窗口用鼠标交互绘制若 干矩形,鼠标左键首先按下,确定矩形对角线的起始点,鼠标左键 按下同时移动时,看到画矩形过程,鼠标左键松开,确定矩形对角 线的另一点,可重复画多个矩形。如图 3-4 所示。 图 3-4 参考函数: 1、void glutIdleFunc((*f) (void)) //注册闲置响应函数 用于后台处理,当其他的事情处于挂起时,就可以执行函数 f。 如果将函数的参数设为 NULL 或 0,将取消该函数的执行。 该函数调用放在主程序 main()中,通常利用它可实现简单动画。 2、void myidle() //闲置响应回调函数 { } //当时间空闲时系统要做的事情 3、注册鼠标按钮响应函数 glutMouseFunc(void(*f)(int button,int state,int x,int y)) 该函数在主程序中调用。 参数 button: GLUT_LEFT_BUTTON,GLUT_MIDDLE_BUTTON,GLUT_RIGHT_BUTTON 参数 state: GLUT_UP,GLUT_DOWN x,y:返回鼠标在窗口的位置(原点在左上角)。 4、鼠标按钮响应回调函数
mymousebutton(int button, int state, int x, int y) { ··· } 5、注册鼠标移动响应函数 void glutMotionFunc(void (*f) (int x,int y)) 该函数在主程序中调用。(x,y)鼠标的位置,原点在左上角 6、4、鼠标移动响应回调函数 mymousemotion(int x,int y) { } ··· 5、多边形线框模型设置: glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); 6、时间函数的使用 void glutTimerFunc(unsigned int msecs, void (*Func)(int value), int value); 注册一个回调函数,当指定时间值到达后,由 GLUT 调用注册的函数一次 msecs 是等待的时间,单位 Func 是注册的函数 value 是指定的一个数值,用来传递到回调函数 Func 中 这个函数注册了一个回调函数,当指定的毫秒数到达后,这个函数就调用注册的 函数,value 参数用来向这个注册的函数中传递参数. 四、思考题:程序合成 要求将以上 4 个小程序集成在一起,实现: 按下数字 1 键:清屏实现显示旋转的六边形 按下数字 2 键:清屏实现显示静止的六边形+旋转的直线 按下数字 3 键:清屏实现显示鼠标画线 按下数字 4 键:清屏实现显示鼠标绘制矩形 程序如何实现? 提示:1、增加 keyboard()函数,同时在 display()函数中添加 switch 语句,实现每个数字键的不同功能。
分享到:
收藏