您的位置:首页 > 运维架构

OpenGL中显示列表的简介

2011-10-14 10:52 211 查看
(一)定义显示列表。

  前面所举出的例子都是瞬时给出函数命令,OpenGL瞬时执行相应的命令,这种绘图方式叫做立即或瞬时方式(immediate mode)。OpenGL显示列表(Display List)是由一组预先存储起来的留待以后调用的OpenGL函数语句组成的,当调用显示列表时就依次执行表中所列出的函数语句。显示列表可以用在以下场合:

  1)矩阵操作

  大部分矩阵操作需要OpenGL计算逆矩阵,矩阵及其逆矩阵都可以保存在显示列表中。

  2)光栅位图和图像

  程序定义的光栅数据不一定是适合硬件处理的理想格式。当编译组织一个显示列表时,OpenGL可能把数据转换成硬件能够接受的数据,这可以有效地提高画位图的速度。

  3)光、材质和光照模型

  当用一个比较复杂的光照环境绘制场景时,因为材质计算可能比较慢。若把材质定义放在显示列表中,则每次改换材质时就不必重新计算了,因此能更快地绘制光照场景。

  4)纹理

  因为硬件的纹理格式可能与OpenGL格式不一致,若把纹理定义放在显示列表中,则在编译显示列表时就能对格式进行转换,而不是在执行中进行,这样就能大大提高效率。

  5)多边形的图案填充模式,即可将定义的图案放在显示列表中。

  OpenGL提供类似于绘制图元的结构即类似于glBegin()与glEnd()的形式创建显示列表,其相应的函数为:

void glNewList(GLuint list,GLenum mode);

void glEndList(void);
  glNewList()函数说明一个显示列表的开始,其后的OpenGL函数存入显示列表中,直至调用结束表的函数glEndList(void)。glNewList()函数中的参数list是一个正整数,它标志唯一的显示列表;参数mode的可能值有GL_COMPILE和GL_COMPILE_AND_EXECUTE;若要使列表中函数语句只存入而不执行,则用GL_COMPILE;若要使列表中的函数语句存入表中且按瞬时方式执行一次,则用GL_COMPILE_AND_EXECUTE。

  注意:并不是所有的OpenGL函数都可以在显示列表中存储且通过显示列表执行。一般来说,用于传递参数或返回数值的函数语句不能存入显示列表,因为这张表有可能在参数的作用域之外被调用;如果在定义显示列表时调用了这样的函数,则它们将按瞬时方式执行并且不保存在显示列表中,有时在调用执行显示列表函数时会产生错误。以下列出的是不能存入显示列表的OpenGL函数:

glDeleteLists()    glIsEnable()

  glFeedbackBuffer()   glIsList()

  glFinish()       glPixelStore()

  glGenLists()      glRenderMode()

  glGet*()        glSelectBuffer()
  在建立显示列表以后就可以调用执行显示列表的函数来执行它,并且允许在程序中多次执行同一显示列表,同时也可以与其它函数的瞬时方式混合使用。显示列表执行的函数形式如下:

  void glCallList(GLuint list);

  参数list指定被执行的显示列表。显示列表中的函数语句按它们被存放的顺序依次执行;若list没有定义,则不会产生任何事情。

  (二)管理显示列表

  在实际应用中,一般调用函数glGenList()来创建多个显示列表,这样可以避免意外删除,产生一个没有用过的显示列表。此外,在管理显示列表的过程中,还可调用函数glDeleteLists()来删除一个或一个范围内的显示列表。

  1)GLuint glGenList(GLsizei range)

  该函数分配range个相邻的未被占用的显示列表索引。这个函数返回的是一个正整数索引值,它是一组连续空索引的第一个值。返回的索引都标志为空且已被占用,以后再调用这个函数时不再返回这些索引。若申请索引的指定数目不能满足或range为0则函数返回0。

  2)GLboolean glIsList(GLuint list)

  该函数询问显示列表是否已被占用的情况,若索引list已被占用,则函数返回TURE;反之,返回FAULSE。

  3)void glDeleteLists(GLuint list,GLsizei range)

  该函数删除一组连续的显示列表,即从参数list所指示的显示列表开始,删除range个显示列表,并且删除后的这些索引重新有效。

  (三)多级显示列表

  多级显示列表的建立就是在一个显示列表中调用另一个显示列表,也就是说,在函数glNewList()与glEndList()之间调用glCallList()。多级显示列表对于构造由多个元件组成的物体十分有用,尤其是某些元件需要重复使用的情况。但为了避免无穷递归,显示列表的嵌套深度最大为64(也许更高些,这依赖于不同的OpenGL实现),当然也可调用函数glGetIntegerv()来获得这个最大嵌套深度值。OpenGL也允许用一个显示列表包含几个低级的显示列表来模拟建立一个可编辑的显示列表。

  下面的一段代码使用了列表嵌套来显示一个三角形:

glNewList(1,GL_COMPILE);

  glVertex3fv(v1);

  glEndList();

  glNewList(2,GL_COMPILE);

  glVertex3fv(v2);

  glEndList();

  glNewList(3,GL_COMPILE);

  glVertex3fv(v3);

  glEndList();

  glNewList(4,GL_COMPILE);

  glBegin(GL_POLYGON);

  glCallList(1);

  glCallList(2);

  glCallList(3);

  glEnd();

  glEndList();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: