您好,欢迎访问三七文档
任何复杂的三维模型都是由基本的几何图元:点、线段和多边形组成的,有了这些图元,就可以建立比较复杂的模型。因此这部分内容是学习OpenGL编程的基础。一、基本图元的描述及定义OpenGL图元是抽象的几何概念,不是真实世界中的物体,因此须用相关的数学模型来描述。所有的图元都是由一系列有顺序的顶点集合来描述的。OpenGL中绘制几何图元,必须使用glBegain()和glEnd()这一对函数,传递给glBegain()函数的参数唯一确定了要绘制何种几何图元,同时,在该函数对中给出了几何图元的定义,函数glEnd()标志顶点列表的结束。例如,下面的代码绘制了一个多边形:glBegin(GL_POLYGON);glVertex2f(0.0,0.0);glVertex2f(0.0,3.0);glVertex2f(3.0,3.0);glVertex2f(4.0,1.5);glVertex2f(3.0,0.0);glEnd();函数glBegin(GLenummode)标志描述一个几何图元的顶点列表的开始,其参数mode表示几何图元的描述类型,具体类型见表一:类型说明GL_POINTS单个顶点集GL_LINES多组双顶点线段GL_POLYGON单个简单填充凸多边形GL_TRAINGLES多组独立填充三角形GL_QUADS多组独立填充四边形GL_LINE_STRIP不闭合折线GL_LINE_LOOP闭合折线GL_TRAINGLE_STRIP线型连续填充三角形串GL_TRAINGLE_FAN扇形连续填充三角形串GL_QUAD_STRIP连续填充四边形串表一、几何图元类型说明部分几何图元的示意图:图一、部分几何图元示意图在glBegin()和glEnd()之间最重要的信息就是由函数glVertex*()定义的顶点,必要时也可为每个顶点指定颜色(只对当前点或后续点有效)、法向、纹理坐标或其他,即调用相关的函数:函数函数意义glColor*()设置当前颜色glIndex*()设置当前颜色表glNormal*()设置法向坐标glEvalCoord*()产生坐标glCallList(),glCallLists()显示列表glTexCoord*()设置纹理坐标glEdgeFlag*()控制边界绘制glMaterial*()设置材质表二、在glBegin()和glEnd()之间可调用的函数需要指出的是:OpenGL所定义的点、线、多边形等图元与一般数学定义不太一样,存在一定的差别。一种差别源于基于计算机计算的限制。OpenGL中所有浮点计算精度有限,故点、线、多边形的坐标值存在一定的误差。另一种差别源于位图显示的限制。以这种方式显示图形,最小的显示图元是一个象素,尽管每个象素宽度很小,但它们仍然比数学上所定义的点或线宽要大得多。当用OpenGL进行计算时,虽然是用一系列浮点值定义点串,但每个点仍然是用单个象素显示,只是近似拟合。二、点(Point)用浮点值表示的点称为顶点(Vertex)。所有顶点在OpenGL内部计算时都使用三维坐标(x,y,z)来处理,用二维坐标(x,y)定义的点在OpenGL中默认z值为0。顶点坐标也可以用齐次坐标(x,y,z,w)来表示,如果w不为0.0,这些齐次坐标表示的顶点即为三维空间点(x/w,y/w,z/w),一般来说,w缺省为1.0。可以用glVertex{234}{sifd}[V](TYPEcords)函数来定义一个顶点。例如:glVertex2f(2.0f,3.0f);//二维坐标定义顶点;OpenGL中定义的点可以有不同的尺寸,其函数形式为:voidglPointSize(GLfloatsize);参数size设置点的宽度(以象素为单位),必须大于0.0,缺省时为1.0。三、线(Line)在OpenGL中,线代表线段(LineSegment),它由一系列顶点顺次连结而成。具体的讲,线有独立线段、条带、封闭条带三种,如图二所示:图二、线段的三种连结方式OpenGL能指定线的宽度并绘制不同的虚点线,如点线、虚线等。相应的函数形式如下:1、voidglLineWidth(GLfloatwidth);设置线宽(以象素为单位)。参数width必须大于0.0,缺省时为1.0。2、voidglLineStipple(GLintfactor,GLushortpattern);设置当前线为虚点模式。参数pattern是一系列的16位二进制数(0或1),它重复地赋给所指定的线,从低位开始,每一个二进制位代表一个象素,1表示用当前颜色绘制一个象素(或比例因子指定的个数),0表示当前不绘制,只移动一个象素位(或比例因子指定的个数)。参数factor是个比例因子,它用来拉伸pattern中的元素,即重复绘制1或移动0,比如,factor为2,则碰到1时就连续绘制2次,碰到0时连续移动2个单元。factor的大小范围限制在1到255之间。在绘制虚点线之前必须先启动虚点模式,即调用函数glEnable(GL_LINE_STIPPLE);结束时,调用glDisable(GL_LINE_STIPPLE)关闭。下面代码绘制了一个点线:voidline2i(GLintx1,GLinty1,GLintx2,GLinty2){glBegin(GL_LINES);glVertex2f(x1,y1);glVertex2f(x2,y2);glEnd();}glLineStipple(1,0x1C47);/*虚点线*/glEnable(GL_LINE_STIPPLE);glColor3f(0.0,1.0,0.0);line2i(450,250,600,250);三、多边形(Polygon)(一)凸、凹多边形。OpenGL定义的多边形是由一系列线段依次连结而成的封闭区域,多边形可以是平面多边形,即所有顶点在一个平面上,也可以是空间多边形。OpenGL规定多边形中的线段不能交叉,区域内不能有空洞,也即多边形必须是凸多边形(指多边形任意非相邻的两点的连线位于多边形的内部),不能是凹多边形,否则不能被OpenGL函数接受。凸多边形和凹多边形见图三。图三、凸凹多边形(二)边界标志问题。实际应用中,往往需要绘制一些凹多边形,通常解决的办法是对它们进行分割,用多个三角形来替代。显然,绘制这些三角形时,有些边不应该进行绘制,否则,多边形内部就会出现多余的线框。OpenGL提供的解决办法是通过设置边标志命令glEdgeFlag()来控制某些边产生绘制,而另外一些边不产生绘制,这也称为边界标志线或非边界线。这个命令的定义如下;voidglEdgeFlag(GLbooleanflag);voidglEdgeFlag(PGLbooleanpflag);(三)多边形绘制模式。多边形的绘制模式包含有:全填充式、轮廓点式、轮廓线式、图案填充式及指定正反面等。下面分别介绍相应的OpenGL函数形式。1)多边形模式设置。其函数为:voidglPolygonMode(GLenumface,GLenummode);参数face为GL_FRONT、GL_BACK或GL_FRONT_AND_BACK;参数mode为GL_POINT、GL_LINE或GL_FILL,分别表示绘制轮廓点式多边形、轮廓线式多边形或全填充式多边形。在OpenGL中,多边形分为正面和反面,对这两个面都可以进行操作,在缺省状况下,OpenGL对多边形正反面是以相同的方式绘制的,要改变绘制状态,必须调用PolygonMode()函数,2)设置图案填充式多边形。其函数为:voidglPolygonStipple(constGLubyte*mask);参数mask是一个指向32x32位图的指针。与虚点线绘制的道理一样,某位为1时绘制,为0时什么也不绘。注意,在调用这个函数前,必须先启动glEnable(GL_POLYGON_STIPPLE);不用时用glDisable(GL_POLYGON_STIPPLE)关闭。下面举出一个多边形扩展绘制实例:voidCALLBACKdisplay(void){/*填充模式定义(32x32)*/GLubytepattern[]={0x00,0x01,0x80,0x00,0x00,0x03,0xc0,0x00,0x00,0x07,0xe0,0x00,0x00,0x0f,0xf0,0x00,0x00,0x1f,0xf8,0x00,0x00,0x3f,0xfc,0x00,0x00,0x7f,0xfe,0x00,0x00,0xff,0xff,0x00,0x01,0xff,0xff,0x80,0x03,0xff,0xff,0xc0,0x07,0xff,0xff,0xe0,0x0f,0xff,0xff,0xf0,0x1f,0xff,0xff,0xf8,0x3f,0xff,0xff,0xfc,0x7f,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xfe,0x3f,0xff,0xff,0xfc,0x1f,0xff,0xff,0xf8,0x0f,0xff,0xff,0xf0,0x07,0xff,0xff,0xe0,0x03,0xff,0xff,0xc0,0x01,0xff,0xff,0x80,0x00,0xff,0xff,0x00,0x00,0x7f,0xfe,0x00,0x00,0x3f,0xfc,0x00,0x00,0x1f,0xf8,0x00,0x00,0x0f,0xf0,0x00,0x00,0x07,0xe0,0x00,0x00,0x03,0xc0,0x00,0x00,0x01,0x80,0x00};glClear(GL_COLOR_BUFFER_BIT);/*绘制一个指定图案填充的三角形*/glColor3f(0.9,0.86,0.4);glPolygonStipple(pattern);glBegin(GL_TRIANGLES);glVertex2i(310,310);glVertex2i(220,80);glVertex2i(405,80);glEnd();glDisable(GL_POLYGON_STIPPLE);glFlush();}(三)指定多边形的正反面。其函数为:voidglFrontFace(GLenummode);在正常情况下,OpenGL中的多边形的正面和反面是由绘制的多边形的顶点顺序决定的,逆时针绘制的面是多边形的正面,但是,在OpenGL中使用该函数可以自定义多边形的正面。该函数的参数mode指定了正面的方向。它可以是CL_CCW和CL_CW,分别指定逆时针和顺时针方向为多边形的正方向。四、法向量的计算及指定法向量是几何图元的重要属性之一。几何对象的法向量是垂直与曲面切面的单位向量,它定义了几何对象的空间方向,特别定义了它相对于光源的方向,决定了在该点上可接受多少光照。OpenGL本身没有提供计算法向量的函数(计算法向量的任务由程序员自己去完成),但它提供了赋予当前顶点法向的函数。(一)平面法向的计算方法。在一个平面内,有两条相交的线段,假设其中一条为矢量W,另一条为矢量V,平面法向为N,则平面法向就等于两个矢量的叉积(遵循右手定则),即N=WxV。例如:一个三角形平面三个顶点分别为P0、P1、P2,相应两个向量为W、V,则三角平面法向的计算方式如下列代码所示:voidgetNormal(GLfloatgx[3],GLfloatgy[3],GLfloatgz[3],GLfloat*ddnv){GLfloatw0,w1,w2,v0,v1,v2,nr,nx,ny,nz;w0=gx[0]-gx[1];w1=gy[0]-gy[1];w2=gz[0]-gz[1];v0=gx[2]-gx[1];v1=gy[2]-gy[1];v2=gz[2]-gz[1];nx=(w1*v2-w2*v1);ny=(w2*v0-w0*v2);nz=(w0*v1-w1*v0);nr=sqrt(nx*nx+ny*ny+n
本文标题:第2讲基本图元
链接地址:https://www.777doc.com/doc-2192400 .html