Lesson2 、Lesson 3 和Lesson 4 是关于多边形绘制的内容,程序结构和第一课完全一样,只是在 int DrawGLScene(GLvoid) 这个函数中添加了绘图的内容。绘制的是基本图形三角形和正方形。绘制图形的过程如下。
一、 初始化
首先通过 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 和 glLoadIdentity() 这两个函数将整个屏幕初始化成一片漆黑的状态,此时绘图点在屏幕中央,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。OpenGL屏幕中心的坐标值是X和Y轴上的0.0f点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。移入屏幕深处是负值,移出屏幕则是正值。
二、绘图
接下来就要开始绘图了,首先要把绘图点移动到指定位置。
1、移动绘图点
我们想象在OpenGL空间中有一个很大的立体网格框架,每个点都有对应坐标,那么使用函数 glTranslatef(x, y, z) 就可以将绘图点移动到坐标(x,y,z)的位置,比如glTranslatef(-1.5f,0.0f,-6.0f) 就实现了“左移 1.5 单位,并移入屏幕 6.0”这一操作。注意在glTranslatef(x, y, z)中移动的时候,并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
2、设置旋转
旋转是通过函数 glRotatef(Angle, Xvector, Yvector, Zvector) 来实现的,这个函数的作用并不是说让物体沿某个方向以某个速度不停旋转,而是让物体由正面沿某个方向旋转到一个角度,这个角度一点点增加,这就使得每次绘图时图形的角度都不一样,看起来就是图形在不停地旋转了。因此只有这个函数是无法实现不停旋转的效果,还要在 DrawGLScene 这个函数结束时加一句Angle += XXX f ,比如在例子里是rtri += 0.2f 和 rquad -= 0.15f 。
关于旋转要注意的是,OpenGL里的旋转不是物体绕轴转,而是轴绕物体转,每次无论是移动还是旋转,坐标轴都在变动,相当于物体始终在原点,而坐标轴即我们的观察视角在不停的动。虽然看起来结果一样,但操作起来完全不同。这就导致同时有多个物体时,每画一个物体要考虑是否加 glLoadIdentity() 。
比如例子里面,先是三角形,glRotatef(rtri, 0.0f, 1.0f, 0.0f) ,绕Y轴旋转,然后是正方形,glRotatef(rquad, 1.0f, 0.0f, 0.0f) ,绕X轴旋转,可以想得到,两个物体应该是各自绕各自的轴旋转,而不是共用一套坐标轴,因此,在画正方形时要加一句 glLoadIdentity() ,这样就给正方形重新设置了坐标轴空间。
试着注释掉 glLoadIdentity() ,结果正方形在整个空间里乱飞,因为三角形的坐标轴已经旋转了,而正方形没有重置坐标轴,正方形就只能绕那个不停旋转的X轴旋转,看起来就是乱飞了。
3、开始绘制基本图形
移动坐标点并设置好旋转以后,就可以开始画基本图形了,在这里,使用 glBegin() 和 glEnd() 两个组合在一起的函数来实现三角形和四边形。
使用时如下:
glBegin(参数)
function1;
function2;
function3;
… …
function N;
glEnd();
参数
glBegin() 中可以添加的参数如下:
1、GL_POINTS:把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制N个点
2、GL_LINES:把每一个顶点作为一个独立的线段,顶点2n-1和2n之间共定义了n条线段,总共绘制N/2条线段
3、GL_LINE_STRIP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制n-1条线段
4、GL_LINE_LOOP:绘制从第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点和第一个顶点相连,第n和n+1个顶点定义了线段n,总共绘制n条线段
5、GL_TRIANGLES:把每个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
6、GL_TRIANGLE_STRIP:绘制一组相连的三角形,对于奇数n,顶点n、n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1、n和n+2定义了第n个三角形,总共绘制N-2个三角形
7、GL_TRIANGLE_FAN:绘制一组相连的三角形,三角形是由第一个顶点及其后给定的顶点确定,顶点1、n+1和n+2定义了第n个三角形,总共绘制N-2个三角形
8、GL_QUADS:绘制由四个顶点组成的一组单独的四边形。顶点4n-3、4n-2、4n-1和4n定义了第n个四边形。总共绘制N/4个四边形
9、GL_QUAD_STRIP:绘制一组相连的四边形。每个四边形是由一对顶点及其后给定的一对顶点共同确定的。顶点2n-1、2n、2n+2和2n+1定义了第n个四边形,总共绘制N/2-1个四边形
10、GL_POLYGON:绘制一个凸多边形。顶点1到n定义了这个多边形。
针对这十种参数,我写了一个小程序,可以通过空格逐个切换,直观地看出每一个参数对应的图形。 ( http://download.csdn.net/detail/u014420201/8453639 )
要注意从第五个参数(三角形)开始,绘制出的形状都是颜色填充的,如果没有设置颜色,就是白色。
函数
glBegin() 和 glEnd() 之间可调用的函数如下:
1、glVertex*() 设置顶点坐标
2、glColor*() 设置当前颜色
3、glIndex*() 设置当前颜色表
4、glNormal*() 设置法向坐标
5、glEvalCoord*() 产生坐标
6、glCallList(),glCallLists() 执行显示列表
7、glTexCoord*() 设置纹理坐标
8、glEdgeFlag*() 控制边界绘制
9、glMaterial*() 设置材质
在第二课中,学习glVertex*() 。
这个函数在使用时是glVertex3f() 。glVertex3f()表示了该函数属于 gl库,参数是三个float型参数指针。我们用glVertex*()来表示这一类函数。
在用glVertex3f()设置坐标点时要注意顺序,否则会影响到以后的材质纹理内容。
在第三课中,学习glColor3f()。
和glVertex3f()一样,这个函数也有三个0到1之间的参数,分别是r、g、b值。RGB颜色值是0到255,因此这里是要进行比例换算,参数为1.0f就代表了255。要注意这个颜色是指顶点的颜色。在这里有一个小方法,颜色可以通过随机数产生,因为主函数中是在while循环中不停地循环画图这一函数,因此颜色会随即改变。
在设置顶点位置之前设置顶点颜色,那么从顶点出发的一定范围的图形区域就都是这个颜色,并且如果不再改变颜色,那么接下来就一直是这个颜色,就好比用刷子沾了颜料如果不洗掉换颜色的话接下来的就都是一个颜色。
因此,在设置的时候要注意是否要预设颜色等问题。
4、结束
到这里就差不多结束了,简单的绘制几何图形还是很容易的。