OpenGL基本图元

OpenGL的辅助库可以提供一些较为复杂的几何体的绘制函数,如auxSolidTeapot可以绘制一个茶壶,如果用OpenGL基本库中的函数实现就困难的多。但是,除了教学等简单的环境外,在大型的OpenGL应用中,辅助库中的这些函数基本是没有任何用处的。而且,这些函数也因为受限于平台,很少被使用。在一些基于OpenGL的3D引擎中可以看到,仅仅使用OpenGL基本库中的图元函数就可以了。

OpenGL的基本图元有点(Point)、线段(Line)、多边形(Ploygon)、三角形(Triangle)、四边形(Quadrangle)。线段又分为独立线段、不闭合的线(Line Strip)和首尾闭合的线(Line Loop)。三角形分为独立三角形、三角形链(Triangle Strip)和三角扇形(Triangle Fan)。四边形则分为独立的四边形和四边形链(Quadrangle Strip)。

 

1.1.1        点

在OpenGL中,点称为顶点(Vertex),用一个形如(x, y, z)的三维坐标值表示,是最基本的图元,其他的图元都是由顶点组合构成的。如果采用齐次坐标表示,就是一个形如(x, y, z, w)的四元组,其中w是比例因子,(x, y, z, w)表示的就是(x/w, y/w, z/w)坐标点。如果w为0,则表示方向为(x, y, z)的无穷远点。

OpenGL表示顶点的函数为glVertex{[2][3][4]}{[d][f][i][s]}[v],其中{ }里面表示函数必须包含的部分,[ ]里面表示函数可选的部分,以下相同,不再赘述。

从glVertex函数的说明可以看到,表示一个顶点的方式可以有24种。当没有明确的指明z或w的值时,z的值缺省为0.0,w的值缺省为1.0。

下面举例说明绘制点的代码:

 

GLshort v[]={3, 6, 9, 3};

 

glBegin(GL_POINTS);

    glVertex2f(1.0f, 2.0f);         //点(1, 2, 0)

    glVertex3i(1, 2, 1);                //点(1, 2, 1)

    glVertex4sv();                  //点(1, 2, 3)

glEnd();

 

其中glBegin和glEnd需要成对使用,两者之间是绘图语句,glBegin的参数就是需要绘图的图元类型,使用GL_POINTS生成的都是离散的点。

1.1.2        线

线段是由两个顶点连接起来形成的图元。glBegin的图元参数是GL_LINES、GL_LINE_STRIP和GL_LINE_LOOP时分别表示绘制独立的线段、首尾相连但不闭合的折线段及首尾相连闭合的折线段。

我们再来看一下绘制线段的例子。

 

glBegin(GL_LINES);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(1.0f, -1.0f,0.0f);       //从点(-1, 1, 0)到(1, -1, 0)的一条线段

 

    glVertex3f(1.0f, 1.0f, 0.0f);

    glVertex3f(-1.0f, -1.0f, 0.0f);     //从点(1, 1, 0)到(-1, -1, 0)的一条线段

glEnd();

 

在独立的线段中,每一对相邻的顶点决定一条线段,2n个顶点确定的是n条线段。

 

glBegin(GL_LINE_STRIP);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(1.0f, -1.0f,0.0f);       //从点(-1, 1, 0)到(1, -1, 0)的一条线段

    glVertex3f(1.0f, 1.0f, 0.0f);  //从点(1, -1, 0)到(1, 1, 0)的一条线段

    glVertex3f(-1.0f, -1.0f, 0.0f);     //从点(1, 1, 0)到(-1, -1, 0)的一条线段

glEnd();

 

在折线段中,从第一个顶点开始按顺序连接每一个顶点,n+1个顶点共产生n条线段。

 

glBegin(GL_LINE_LOOP);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(1.0f, -1.0f,0.0f);       //从点(-1, 1, 0)到(1, -1, 0)的一条线段

    glVertex3f(1.0f, 1.0f, 0.0f);  //从点(1, -1, 0)到(1, 1, 0)的一条线段

    glVertex3f(-1.0f, -1.0f, 0.0f);     //从点(1, 1, 0)到(-1, -1, 0)的一条线段

                            //从点(-1, -1, 0)到(-1, 1, 0)一条线段

 

glEnd();

 

在闭合折线段中,从第一个顶点开始按顺序连接每一个顶点,直到最后一个顶点,然后再回到第一个顶点,这样,n个顶点就产生n条线段。图1-3给出了三种线段的图示。

 

图1-3   三种线段图元

 

1.1.3        三角形

顶点是和线段还不能构成一个实体,因为点是0维的,线段是1维,平面才是二维的。一个三角形就表示了一个平面,因此,三角形是表示物体的基础。实际上,在如Quake这样的游戏中,对场景的渲染就是对三角形的渲染。

OpenGL分别用GL_TRANGLES、GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN作为glBegin的参数来绘制独立的三角形、三角形链和三角扇形。

下面举例说明这些三角形的不同。

 

glBegin(GL_TRIANGLES);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(-1.0f, -1.0f, 0.0f);

glVertex3f(1.0f, -1.0f,0.0f);       //第一个三角形

 

    glVertex3f(1.0f, 1.0f, 0.0f);

    glVertex3f(3.0f, -1.0f, 0.0f);     

glVertex3f(3.0f, 1.0f, 0.0f);       //第二个三角形

 

glEnd();

 

当绘制独立三角形时,每三个顶点为一组,生成一个三角形,共3n个顶点生成n个三角形。

 

glBegin(GL_TRIANGLE_STRIP);

    glVertex3f(-1.0f, -1.0f, 0.0f);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(1.0f, -1.0f,0.0f);       //第一个三角形

    glVertex3f(1.0f, 1.0f, 0.0f);       //第二个三角形

    glVertex3f(3.0f, -1.0f, 0.0f);      //第三个三角形

    glVertex3f(3.0f, 1.0f, 0.0f);       //第四个三角形

 

 

glEnd();

 

当绘制三角形链图元时,n+2个顶点按顺序生成的是n个三角形。当i为奇数时,第i、i+1、i+2个顶点生成第i个三角形。当i为偶数时,第i+1、i、i+2个顶点生成第i个三角形。

 

glBegin(GL_TRIANGLE_FAN);

    glVertex3f(-1.0f, -1.0f, 0.0f);

    glVertex3f(-1.0f, 1.0f, 0.0f);

    glVertex3f(1.0f, 1.0f, 0.0f);

    glVertex3f(3.0f, 1.0f, 0.0f);

    glVertex3f(3.0f, -1.0f, 0.0f);

    glVertex3f(1.0f, -2.0f,0.0f);

glEnd();

 

当绘制三角扇形图元时,也是n+2个顶点共生成n个三角形,只是第1个顶点是公共顶点,和i+1、i+2个顶点生成第i个三角形。图1-4是几种三角形生成的图示。

 

 

图1-4   三种三角形图元

 

1.1.4        四边形

四边形是由四个顶点构成的,可能不在一个平面,因此实际应用中通常将一个四边形分解成两个三角形来渲染。四边形也有独立四边形和四边形链两种方式。

独立四边形使用4个顶点为一组,生成一个四边形,4n个顶点生成n个四边形。

在四边形链中,每两个顶点为一对,相邻两对顶点生成一个四边形,2n+2个顶点共生成n个四边形。

 

图1-5   两种四边形图元

 

1.1.5        多边形

多边形也是一种常用的渲染方式。多边形有凸多边形和凹多边形两种。如果将一个多边形的任意两个顶点连接起来形成的线段都在多边形的内部,该多边形就是凸多边形,反之就是凹多边形。这两种多边形OpenGL都可以处理,但是,如果给一个凹多边形贴上纹理,会出现意料不到的结果,完全和预期不一致。因此,我们要求使用的多边形都是凸多边形。绘制多边形时,glBegin的参数应该是GL_POLYGON。图1-6是两种多边形的区别。

 

 

 

图1-6   凸多边形和凹多边形-------------------------------------------------------------------------------------------------
声明:本文可在网络媒体自由传播,但必须保留作者的声明信息及来源,平面媒体的引用必须征得作者的同意。

 

转!
另外,作者也欢迎同仁进行交流。
QQ: 851473402
Email: LotusRachel@gmail.com

posted on 2010-12-15 19:03  minggoddess  阅读(3142)  评论(0编辑  收藏  举报