OpenGL学习笔记(五)

顶点数组

根据前面的介绍,OpenGL需要进行大量的函数调用才能完成对几何图元的渲染。如绘制一个20条边的多边形至少需要22个函数调用。首先调用1glBegine(),然后为每个顶点调用1次函数,最后调用1glEnd()。有时还需要额外的信息,也增加函数的调用。这样就成倍地增加渲染几何物体所需要的函数调用数量,直接影响到了应用程序的性能。

OpenGL提供了一些顶点数组函数,允许只用少数几个数组指定大量的与顶点相关的数据,并用少量函数调用访问这些数据。使用顶点数组,一个拥有20条边的多边形的20个顶点可以放在1个数组中,并且只通过1个函数进行调用。

使用顶点数组对几何图形进行渲染步骤:

 1) 激活(启用)最多可达8个数组,每个数组用于存储不同类型的数据:顶点坐标、表面法线、RGBA颜色、辅助颜色、颜色索引、雾坐标、纹理坐标以及多边形的边界标志。

 2) 把数据放入数组中。

 3) 用这些数据绘制几何图形。

 

步骤1.启用数组

void glEnableClientState(GLenum array);

指定了需要启用的数组。array参数列表如下:

GL_VERTEX_ARRAY                              顶点数组

GL_COLOR_ARRAY                                颜色数组

GL_SECONDARY_COLOR_ARRAY         辅助色数组

GL_INDEX_ARRAY                                索引数组

GL_NORMAL_ARRAY                      法向量数组

GL_FOG_COORDINATE_ARRAY             雾坐标数组

GL_TEXTURE_COORD_ARRAY              纹理坐标数组

GL_EDGE_FLAG_ARRAY                       边界标志数组

理论上说,最多可调用该函数8次,激活8个可用的数组。但在实践中,可以激活的数组最多只有6个,因为有些数组不能同时激活。

相应地,有启用函数就有禁用函数:

void glDisableClientState(GLenum array);

指定了需要禁用的数组,接受的参数与glEnableClientState()函数相同。

 

步骤2.指定数组的数据

共有8个不同的函数用来指定数组,每个函数用于指定一个不同类型的数组。

void glVertextPointer(Glint size,GLenum type,GLsizei stride,const void *pointer);

void glColorPointer(Glint size,GLenum type,GLsizei stride,const void *pointer);

void glTexCoordPointer(Glint size,GLenum type,GLsizei stride,const void *pointer);

void glSecondaryColorPointer(Glint size,GLenum type,GLsizei stride,const void *pointer);

void glIndexPointer(GLenum type,GLsizei stride,const void *pointer);

void glNormalPointer(GLenum type,GLsizei stride,const void *pData);

void glFlgCoordPointer(GLenum type,GLsizei stride,const void *pointer);

void glEdgeFlagPointer(GLenum type,GLsizei stride,const void *pointer);

参数size-是每个顶点的坐标数量,一般来说表示二维空间(x,y)则顶点的坐标数量为2

参数type-指定了数组中每个坐标的数据类型(GL_SHORTGL_INTGL_FLOATGL_DOUBLE)

参数stride-指定了每个数组元素之间以字节为单位的空隙。一般情况下,该值为0,也就是数组元素之间没有空隙。

参数pointer/pData-是指向数据数组的指针

 

步骤3.用数据绘图

在顶点数组的内容被解引用(即提取指针指向的数据)之前,数组一直保存在客户端,它们的内容很容易进行修改。在此步骤中,数组中的数据被提取,接着发送到服务器,然后发送到图形处理管线进行渲染。

解引用单个数组元素

void glArrayElement(Glint ith);

获取当前所有已启用数组的第ith个顶点的数据。使用glArrayElement的优点就是只要用一个函数调用就可以替代为一个特定顶点所有数据所需要的几个函数调用(glNormalglColorglVertex)

示例:一个具有颜色的三角形

glEnableClientState(GL_COLOR_ARRAY);

glEnableClientState(GL_VERTEX_ARRAY);

glColorPointer(3,GL_FLOAT,0,colors);  //colors是三角形顶点rgb颜色数组

glVertexPointer(2,GL_INT,0,vertices);   //vertices是三角形二维坐标数组

//绘制三角形

glBegin(GL_TRIANGLES);

glArrayElement(0);              //解引用第一个元素

glArrayElement(1);              //解引用第二个元素

glArrayElement(2);              //解引用第三个元素

glEnd();

上面代码最后5行与下面代码段具有相同的效果

glBegin(GL_TRIANGLES);

glColor3fv(colors);

glVertex2iv(vertices);

glColor3fv(colors + (1 * 3));

glVertex2iv(vertices + (1 * 2));

glColor3fv(colors + (2 * 3));

glVertex2iv(vertices + (2 * 2));

glEnd();

由于glArrayElement()对于每个顶点只调用1次,因此减少函数调用的数量,从而提高程序的总体性能。

解引用数组元素的一个列表

void glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid *indices);

使用count个元素定义一个几何图元序列,这些元素的索引值保存在indices数组中。Type必须是GL_UNSIGNED_BYTEGL_UNSIGNED_SHORTGL_UNSIGNED_INT,表示indices数组的数据类型。mode参数指定了被创建的是哪种类型的图元,它的值和glBegin()函数所接受的参数值相同。

glDrawElements(mode, count, type, indices)的效果几乎相当于下面代码:

glBegin(mode);

       for(i=0;i<count;i++)

              glArrayElement(indices[i]);

glEnd();

解引用一个数组元素序列

void glDrawArrays(GLenum mode,Glint first,GLsizei count);

创建一个几何图元序列,使用每个被启用的数组中从first开始,到first+count-1结束的数组元素。

glDrawArrays(mode,first,count)的效果几乎相当于下面代码:

glBegin(mode);

       for(i=0;i<count;i++)

              glArrayElement(first + i);

glEnd();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值