OpenGL编程指南第七章:显示列表

显示列表(Display List)是一组暂存起来的OpenGL命令序列,可以被反复执行。显示列表会被存储在server端,因此可以提高效率。

1、显示列表的设计

显示列表可以被视作是指令缓存,而不是一个数据结构, 它不可以被修改;

显示列表会对指令先做优化再存储,这种优化是随具体的OpengGL实现而定的,但一般来说肯定不会比“立即模式”更慢,可能被优化的地方有:1)变换矩阵计算;2)图像的光栅化,可能先转化成适合硬件的格式;3)光照相关的属性设置,这些属性会涉及到一些矩阵计算,可能被预先执行,只缓存结果;4)多边形点画模式;

显示列表还是有一些额外的开销的,因此显示列表不能太小,否则效率上的收益会低于这种开销;

显示列表执行的时候,还是依赖于上下文的,所以要注意上下文状态的影响;

2、API

要使用显示列表,先创建名字:GLuint glGenLists(GLsizei range);再把显示表的指令序列放置在glNewList(GLuint list, GLenum mode)和glEndList(void)之间,就创建好了一个显示列表;glIsList(GLuint list)可以判断一个名字是不是显示列表; glDeleteLists(GLuint list, GLsizei range)删除显示列表。要调用的时候,glCallList(GLUint name)。

显示列表是被存储在server端的,所以如果显示列表中间引用到客户端变量,变量的值会被缓存,之后变量的变化不会影响到显示列表。

并不是所有的Opengl指令可以被存储在显示列表中,那些和client状态有关的指令不可以,那些做状态查询的指令不可以(这些指令一般需要一个引用变量做传出参数),这些指令如果出现的显示列表的定义体中,会被立即执行。具体那些指令不可以,请参考手册。

显示列表可以嵌套调用,也即显示列表1的实现主体可以调用现实列表2,这个特性允许我们设计出“可修改”显示列表。比如我们可以动态地重新定义显示列表2,这样列表1的行为就会发生变化。

还可以一次调用多个显示类表,glListBase(GLuint base)设定一个base值,glCallLists(GLsizei n, GLenum type, const GLvoid *lists)执行数组list里面的n个显示列表,list里面的元素会加上base值得到显示列表的名字。例如,把字体存储为显示列表,这项技术就很有用了。

显示列表如果包含改变opengl state的代码,在执行完成后,这个改变不会自动恢复。有时候我们希望显示列表执行完之后能够把状态变量恢复到执行之前,注意显示列表不能使用glGet*这样的状态查询函数的,推荐的方式是在显示列表的起始处使用glPushAttrib()、glPushMatrix(),在末尾处使用glPopAttrib()、glPopMatrix()。

反过来,也可以使用显示列表来进行多组状态的管理,每个显示列表的职责就是设置一组状态。

 

 

原文地址:https://www.cnblogs.com/longhuihu/p/10423332.html