计算机图形学要用到的主要工具就是:OPENGL
一:图形编程入门
1.窗口的设置
glutInitWindowPosition(int x, int y);//为窗口指定初始位置,窗口左上角在屏幕上的位置为(x,y),如果不写该函数,默认为(0,0)
glutInitWindowSize(int width, int height); //设置窗口大小,如果不写该函数,表示窗口的大小为默认大小300*300
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB); //设置显示模式;
//GLUT_DOUBLE:双缓冲(绘制图形指令在一个缓冲区完成,速度非常快,在绘图指令完成之后,再通过交换指令把完成的图形即 显示在屏幕上,这样避免了图形的不完整,同时效率很高)
//GLUT_SINGLE:单缓冲(直接在窗口绘制图形,效率低,如果电脑慢,会出现闪烁)
//GLUT_DEPTH:窗口使用深度缓存
//一般opnegl绘图都用双缓冲,单缓冲一般只用于显示单独的非动态的图形。
2.背景色的设置
glClearColor(r,g,b,alpha);//设置背景颜色,此函数放在display()中,并且放在glClear(GL_COLOR_BUFFRT_BIT);语句的前面
glClear(GL_COLOR_BUFFRT_BIT);//刷新颜色缓冲区;
3.基本图形的绘制
绘制函数一般放置在清屏语句
glClear(GL_COLOR_BUFFER_BIT); //刷新颜色缓冲区;
和刷新语句之间
glFlush(); //用于刷新命令队列和缓冲区,使所有尚未被执行的OpenGL命令得到执行;
矩形绘制:glRectf(x1,y1,x2,y2);//画矩形,x1,y1和x2,y2分别为矩形对角线顶点坐标
绘制直线:
glBegin(GL_LINES);//画线命令,x1,y1和x2,y2分别为直线段端点坐标
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();
画三角形:
glBegin(GL_TRIANGLES);//画三角形命令,x1,y1,x2,y2和x3,y3分别为三角形顶点坐标
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glVertex2f(x3,y3);
glEnd();
点绘制:
glPointSize(2.0) //点的大小设置
glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);//分别设置不同的颜色
glVertex2f(-0.5,-0.5);
glColor3f(1.0,0.0,1.0);
glVertex2f(-0.5,0.5);
glEnd()
直线/三角形/四边形绘制:
glLineWidth(2.0);
glBegin(GL_LINES);
glBegin(GL_LINE_STRIP);
glBegin(GL_LINE_LOOP);
glBegin(GL_TRIANGLES);
glBegin(GL_TRIANGLE_STRIP);
glBegin(GL_TRIANGLE_FAN);
glBegin(GL_QUADS);
glBegin(GL_TRIANGLE_STRIP);
glEnd();
多边形:
glBegin(GL_POLYGON);
glVertex2f(-0.5,0.5);
glVertex2f(-0.5,-0.5);
glColor3f(1.0,1.0,1.0);
glVertex2f(0,-0.5);
glColor3f(1.0,1.0,0.0);
glVertex2f(0.5,-0.5);
glVertex2f(0.5,0.5);
glEnd();
圆盘绘制:
GLUquadricObj *disk; //定义二次曲面对象
disk=gluNewQuadric(); //生成二次去面对像
gluDisk(disk,0.8,1,50,50); //内径0.8,外径1,盘心在原点
球的绘制:
glutSolidSphere(1,80,80); //半径为1的球,球心在原点
绘图色的设置:
glColor3f(r,g,b);//设置绘图色r,g,b,取值范围:[0,1],可以为浮点数。如果想单独为某个图形指定颜色就要放在glBegin()和glEnd()之间
二:OPENGL简单的动画
2.添加线宽语句:
glLineWidth(2.0); //设置线宽 想要对每个图形分别设置线宽,放在每个图形的glBegin()函数前面即可,值不能设置太大,否则看不出效果
void glutIdleFunc((*f) (void))//注册闲置响应函数,用于后台处理,当其他的事情处于挂起时,就可以执行函数f,通常利用它可实现简单动画。
glutPostRedisplay(); //重画函数,相当于重新调用Display(),改编后的变量得以传给绘制函数
三:简单的键盘交互
1.在主函数里添加键盘注册回调函数
glutKeyboardFunc(mykeyboard);//mykeyboard函数是自己定义的函数
此函数可放在 glutDisplayFunc(display);后面。
2.在main函数里添加注册窗口变化函数
glutReshapeFunc(myreshape);//myreshape函数自己定义
(放在glutMainLoop()之前)
3.裁剪窗口设置函数:
gluOrtho2D(xwmin,xwmax,ywmin,ywmax);
// xwmin,xwmax,ywmin,ywmax为裁剪窗口在世界坐标系的位置,分别为x最小,x最大,y最小,y最大。其实就是绘图的坐标
4.视区设置函数:
glViewport(startx,starty,viewport_width,viewport_height);
绘图区在显示窗口中的位置,以屏幕坐标系为参考
startx,starty,viewport_width,viewport_height分别为绘图区在显示窗口的起点位置, 以及绘图区的宽度和高度
四:鼠标交互
1.在主程序注册鼠标响应和鼠标移动子函数
glutMouseFunc(mymouse);
glutMotionFunc(mymotion);
放在display注册之后和mainloop之前
五:图形变换
1.gltranslatef(x,y,z)//x,y,z分别代表x,y,z方向的平移量,对于2D图形,z=0
2、glrotatef(Q,x,y,z)//Q为逆时针方向旋转的角度度数(0~360),(x,y,z)为旋转轴的方向矢量
//(x,y,z)=(0,0,1)时代表沿Z轴方向旋转;(x,y,z)=(1,0,0)代表沿x轴方向旋转
//(x,y,z)=(0,1,0)代表沿y轴方向旋转
//默认绕原点旋转
3、glscalef(x,y,z)//x,y,z分别表示x,y,z方向的比例因子。对于2D图形,z=0。比例因子取-1时,产生对称变换
代码示例:
1.某图形沿水平方向垂直方向分别平移Tx,Ty段距离:
清屏
glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下
glLoadIdentity(); //将当前矩阵设置为单位矩阵
glTranslatef(Tx,Ty,0);
DrawSomeShape();
刷新
2.某图形绕任意点(cx,cy)旋转ALPHA://如果不是绕原点旋转,就要进行三部曲
清屏
glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下
glLoadIdentity(); //将当前矩阵设置为单位矩阵
glTranslatef(cx,cy,0); //平移回去
glRotatef(ALPHA,0,0,1); //绕原点旋转ALPHA角度
glTranslatef(-cx,-cy,0); //平移回原点
DrawSomeShape();
刷新
//总而言之,就两种情况,就是绕原点旋转或者绕任意点旋转
//而要绕任意点旋转就要进行三部曲,三部曲中的cx,cy就是你所要旋转的点
//如果不进行三部曲,默认情况下就是整个图形绕着原点旋转
//具体是自转还是公转,就要看你所绕的点和你所画的图形的想对位置了
3.某图形绕任意点(cx,cy)缩放Sx,Sy比例因子//如果不是绕原点缩放,也要进行三部曲
清屏
glMatrixMode(GL_MODELVIEW);//设置矩阵模式为模型变换模式,表示在世界坐标系下
glLoadIdentity(); //将当前矩阵设置为单位矩阵
glTranslatef(cx,cy,0); //平移回去
glScalef(Sx,Sy,1); //绕原点水平缩放系数Sx,垂直缩放系数Sy
glTranslatef(-cx,-cy,0); //平移回原点
DrawSomeShape();
刷新
//当需要对单独的图像进行变换的时候,应该把画图函数,转换函数全部都放在glPushMatrix(void)和glPopMatrix(void)之间。
4.void glPushMatrix(void)
功能:把当前操作矩阵压入矩阵堆栈,记住当前所在的位置。
复制活动栈顶的当前矩阵并将其存入第二个栈位置
5.void glPopMatrix(void)
功能:当前操作矩阵出栈,它下面的矩阵作为当前矩阵,返回到以前所在的位置。
破坏栈顶矩阵,栈的第二个矩阵成为当前矩阵。如果要弹出栈顶,栈内至少要有2个矩阵,否则就会出错。