hyde
路人甲
路人甲
  • 注册日期2003-09-24
  • 发帖数555
  • QQ
  • 铜币1457枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:1269回复:0

OpenGL系列讲座(24)

楼主#
更多 发布于:2004-03-21 11:10
第六章 OpenGL显示列表
 

OpenGL显示列表(Display List)是由一组预先存储起来的留待以后调用的OpenGL函数

语句组成的,当调用这张显示列表时就依次执行表中所列出的函数语句。前面内容所举出的

例子都是瞬时给出函数命令,则OpenGL瞬时执行相应的命令,这种绘图方式叫做瞬时方式

(immediate mode)。本章将详细地讲述显示列表的基本概论、创建、执行、管理以及多级显

示列表的应用等内容。

 

6.1  显示列表概论
6.1.1 显示列表的优势

 

OpenGL显示列表的设计能优化程序运行性能,尤其是网络性能。它被设计成命令高速

缓存,而不是动态数据库缓存。也就是说,一旦建立了显示列表,就不能修改它。因为若显

示列表可以被修改,则显示列表的搜索、内存管理的执行等开销会降低性能。

采用显示列表方式绘图一般要比瞬时方式快,尤其是显示列表方式可以大量地提高网络

性能,即当通过网络发出绘图命令时,由于显示列表驻留在服务器中,因而使网络的负担减

轻到最小。另外,在单用户的机器上,显示列表同样可以提高效率。因为一旦显示列表被处

理成适合于图形硬件的格式,则不同的OpenGL实现对命令的优化程度也不同。例如旋转矩阵

函数glRotate*(),若将它置于显示列表中,则可大大提高性能。因为旋转矩阵的计算并不

简单,包含有平方、三角函数等复杂运算,而在显示列表中,它只被存储为最终的旋转矩阵,

于是执行起来如同硬件执行函数glMultMatrix()一样快。一般来说,显示列表能将许多相邻

的矩阵变换结合成单个的矩阵乘法,从而加快速度。

 

 

6.1.2显示列表的适用场合

 

并不是只要调用显示列表就能优化程序性能。因为调用显示列表本身时程序也有一些开

销,若一个显示列表太小,这个开销将超过显示列表的优越性。下面给出显示列表能最大优

化的场合:

    一、矩阵操作。大部分矩阵操作需要OpenGL计算逆矩阵,矩阵及其逆矩阵都可以保存在

显示列表中。

二、光栅位图和图像。程序定义的光栅数据不一定是适合硬件处理的理想格式。当编译

组织一个显示列表时,OpenGL可能把数据转换成硬件能够接受的数据,这可以有效地提高画

位图的速度。

三、光、材质和光照模型。当用一个比较复杂的光照环境绘制场景时,可以为场景中的

每个物体改变材质。但是材质计算较多,因此设置材质可能比较慢。若把材质定义放在显示

列表中,则每次改换材质时就不必重新计算了。因为计算结果存储在表中,因此能更快地绘

制光照场景。

四、纹理。因为硬件的纹理格式可能与OpenGL格式不一致,若把纹理定义放在显示列表

中,则在编译显示列表时就能对格式进行转换,而不是在执行中进行,这样就能大大提高效

率。

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

 6.2  创建和执行显示列表
 

6.2.1 创建显示列表

 

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

应的函数为:

 

void glNewList(GLuint list,GLenum mode);

 

说明一个显示列表的开始,其后的OpenGL函数存入显示列表中,直至调用结束表的函

数(见下面)。参数list是一个正整数,它标志唯一的显示列表。参数mode的可能值有

GL_COMPILE和GL_COMPILE_AND_EXECUTE。若要使后面的函数语句只存入而不执行,则用

GL_COMPILE;若要使后面的函数语句存入表中且按瞬时方式执行一次,则用GL_COMPILE_AND_EXECUTE。

 

void glEndList(void);

 

    标志显示列表的结束。

 

注意,并不是所有的OpenGL函数都可以在显示列表中存储且通过显示列表执行。一般来

说,用于传递参数或返回数值的函数语句不能存入显示列表,因为这张表有可能在参数的作

用域之外被调用;如果在定义显示列表时调用了这样的函数,则它们将按瞬时方式执行并且

不保存在显示列表中,有时在调用执行显示列表函数时会产生错误。以下列出的是不能存入

显示列表的OpenGL函数:

 

    glDeleteLists()                glIsEnable()

    glFeedbackBuffer()             glIsList()

    glFinish()                     glPixelStore()

    glGenLists()                   glRenderMode()

    glGet*()                       glSelectBuffer()

 

 

6.2.2 执行显示列表

 

在建立显示列表以后就可以调用执行显示列表的函数来执行它,并且允许在程序中多次

执行同一显示列表,同时也可以与其它函数的瞬时方式混合使用。显示列表执行的函数形式

如下:

 

void glCallList(GLuint list);

 

执行显示列表。参数list指定被执行的显示列表。显示列表中的函数语句按它们被存放

的顺序依次执行;若list没有定义,则不会产生任何事情。

 

    下面举出一个应用显示列表的简单例子 displist.c:

 

例3-19  显示列表例程 displist.c

 

#include "glos.h"

 

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

 

void myinit(void);

void drawLine (void);

void CALLBACK display(void);

void CALLBACK myReshape(GLsizei w, GLsizei h);

 

GLuint listName = 1;

 

void myinit (void)

{

    glNewList (listName, GL_COMPILE);

    glColor3f (1.0, 0.0, 0.0);

    glBegin (GL_TRIANGLES);

    glVertex2f (0.0, 0.0);

    glVertex2f (1.0, 0.0);

    glVertex2f (0.0, 1.0);

    glEnd ();

    glTranslatef (1.5, 0.0, 0.0);

    glEndList ();

    glShadeModel (GL_FLAT);

}

 

void drawLine (void)

{

    glColor3f(1.0,1.0,0.0);

    glBegin (GL_LINES);

    glVertex2f (0.0, 0.5);

    glVertex2f (5.0, 0.5);

    glEnd ();

}

 

void CALLBACK display(void)

{

    GLuint i;

 

    glClear (GL_COLOR_BUFFER_BIT);

    glColor3f (0.0, 1.0, 0.0);

    glPushMatrix();

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

        glCallList (listName);

    drawLine ();

    glPopMatrix();

    glFlush ();

}

 

void CALLBACK myReshape(GLsizei w, GLsizei h)

{

    glViewport(0, 0, w, h);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    if (w <= h)

        gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w,

                1.5 * (GLfloat) h/(GLfloat) w);

    else

        gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, -0.5, 1.5);

    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

}

 

void main(void)

{

    auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);

    auxInitPosition (10, 200, 400, 50);

    auxInitWindow ("Display List");

    myinit ();

    auxReshapeFunc (myReshape);

    auxMainLoop(display);

}

 

    以上程序运行结果是显示五个显示列表中定义的红色三角形,然后再绘制一条非表

中的黄色线段。

 

  

 

图 3-6-1 显示列表

 



 

喜欢0 评分0
夜落了,风静了,我喜欢一本书,一杯茶,一粒摇曳的烛光...
游客

返回顶部