第二章 使用OpenGL
一、设置OpenGL的坐标系
设置OpenGL坐标系的方式与Window GDI有所不同。在OpenGL当中通过设置视口来实现设置绘图范围(剪裁范围)的大小,通过调用
glutOrtho来设置坐标原点的位置以及坐标的范围。下面是一个设置坐标的程序片断:
glViewport(0,0,200,200);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glOrtho(-100,100,-100,100,-100,100);
在
第一个函数调用glViewport当中的前两个参数表示了窗口左下脚的坐标值,一般将其设置为0,0,而后两个参数表示了裁减范围的大小。在后面的
glutOrtho函数调用当中6个参数分别表示了窗口最左端最右端最上端最下端最前端最后端在坐标系上的值,由此确定了坐标原点的位置,以及逻辑坐标与
实际硬件象素之间的缩放比例。
值得注意的是,在调用函数设置坐标系之前必须调用glLoadIdentity()和
glMatrixMode(GL_PROJECTION)两个函数。
上面的程序片断将窗口的横纵方向同时设置为200个逻辑单位,在窗口是正方形的状态下,横纵方向一个逻辑单位的物理长度相同,但是如果窗口大小发生改变横
纵比不再是1时会导致画面的失真,这个时候必须要对坐标系做出相应的修改使得无论在横纵方向上单位逻辑长度表示的物理长度都相同。这个操作需要用GLUT
当中的glutReshapeFunc函数来设置回调函数,而回调函数的一般定义如下:
void Reshape(GLint x,GLint
y)
{
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glViewport(0,0,x,y);
if
(y == 0)
y = 1;
GLdouble nRange = 100.0;
if (x <= y)
glOrtho(-nRange,nRange,-
nRange * y / x,nRange * y / x,-1,1);
else
glOrtho(-nRange * x /
y,nRange * x / y,-nRange,nRange,-1,1);
}
二、在屏幕上绘图
1.绘制点
绘制点就是在屏幕上的一个或者多个象素设置为指定的颜色。绘制点的方式主要是使用glBegin(GL_POINTS)...glEnd()以及当中的一
些设置点位置的OpenGL函数的调用。点在屏幕上的大小可以通过调用glPointSize来设置。
2.绘制线
绘制线就是将屏幕上两个点之间的所有象素设置为指定的颜色。绘制点的方式主要是使用glBegin(GL_LINES)...glEnd()以及当中的一
些设置点位置的OpenGL函数的调用。绘制线的时候可以设置线的宽度以及线的线性。设置线的线性主要是通过调用glLineStippe函数,这个函数
包括两个参数,第一个参数表示重复的次数第二个用一个16位二进制数表示画线的方式。例如第二个参数片断位1011则表示在第一第二第四个逻辑单位上设置
颜色而第三个逻辑单位上保持空白,如果第一个参数设置为N那么第二个参数的每个二进制位表示N个逻辑单位。设置线宽主要使用glLineWidth函数,
这个函数唯一的一个参数表示线的宽度。
3.绘制多边形
多边形的绘制通过glBegin(GL_POLYGON)...glEnd()以及之间的一些定点设置来绘制,多边形当中的特殊情况矩形可以通过独立的
OpenGL函数glRect来绘制,三角型可以通过glBegin(GL_TRIANGEL)来绘制。
在绘制多边形时需要设置多边形的填充方式和填充颜色。设置多边形填充方式的函数有两个函数:glShadeModel和glPolygonMode;第一
个函数用来控制多边形当中填充颜色的控制,而第二个用来控制多边形当中的填充方式。第一个函数只有一个参数,这个参数是一个标志,如果为GL_FLAT则
使用多边形最后一个点的颜色来填充多边形;如果使用GL_SMOOTH则使用多边形所有顶点颜色的渐变色来填充多边形。第二个函数用来设置多边形的填充方
案,如不填充只留轮廓或者普通填充等等,这个函数需要两个参数,第一个表示设置的多边形的面(正面用GL_FRONT,反面用GL_BACK),第二个参
数表示填充方案(GL_FILL普通填充;GL_LINE只留轮廓)。另外如果用glEnable打开GL_POLYGON_STIPPLE标志则可以使
用一个32*32的位标志来对多边形做单色的填充,打开标志后需要调用glPolygonStipple函数。
在多边形的填充方式当中我们提到了多边形的正面和反面。在OpenGL的默认方式下多边形定点在glBegin...glEnd当中绘制的方向是逆时针的
则说明多边形是正面否则为反面。我们可以通过调用glFrontFace这个函数来改变这种默认的行为,这个函数需要一个标志值做为参数,如果该参数为
GL_CCW则为默认的方式,如果为GL_CW则被认为顺时针方向的面为正面。
4.绘制3D物体
绘制3D物体的实质就是用上面所说的绘图方法绘制一些2D图元,然后将其在笛卡儿坐标系当中组合到一起形成一个3D物体。3D物体当中最多使用到的图元为
多边形,而创建多边形有一个规则,即多边形的所有顶点必须在一个平面内,因此3D物体必须使用多个多边形来进行组合。而在3D物体当中最多使用的多边形是
三角形,一方面是因为图形硬件对三角形的处理做了优化较其他多边形要快;另一方面则是因为,无论程序员犯任何的错误只要顶点构成的三角形存在那么这个三角
形必然在一个平面当中。
绘制3D物体时我们必须注意的是靠近我们观测点的面必然会遮挡住离我们观测点较远的那些物体。这个时候如果之前2D的方式来绘图,那么会发生这样的一种状
况:后绘制的面无论是否在它的前面有没有其他的面必然会出现在屏幕上,这与客观事实不符。解决这一问题的方法是在使用OpenGL时打开深度缓冲区,方法
是在glutInitDisplayMode函数调用当中加入GL_DEPTH,并且在绘图之初用GL_DEPTH_BUFFER_BIT来清除深度缓冲
区当中原有的内容,然后用glEnable函数使用标志GL_DEPTH_TEST打开深度检测,这样就能使屏幕上的显示与事实相符合。
另外如果绘制的3D物体是封闭的,也就是说3D物体的内部各个面没有任何机会被显示,那么如果使用默认的方式OpenGL依旧会绘制内部的各个面,这在性
能上讲是一种浪费,我们可以使用GL_CULL_BACK标志来调用glEnable函数从而禁止OpenGL绘制物体的内部来达到提高性能的目的。 From:
http://phil2360.spaces.live.com/blog/cns!71CD456F35382A94!581.entry?wa=wsignin1.0&sa=73469406
阅读(2557) | 评论(0) | 转发(0) |