第一部分 OpenGL 51.1概述 OpenGL是一个功能强大的图形库,用户可以很方便地利用它开发出有多种特殊视觉效果(如光照,纹 理,透明,阴影)的三维图形。 OpenGL的前身是SGl公司为其图形工作站设计的一个图形开发软件库R|s GL( Graphics Library),由于其性能优越,因此受到了用户的一致推崇。SGl公司有针对性地对GL进行 了改进,特别是扩展了GL的可移植性,使之成为一个跨平台的开放式图形编程接口,这就是 OpenGL ARB( Architecture review board体系结构评审委员会)批准了 OpengL1.1版本,这一版本的 OpenGL性能 得到了加强,并引入了一些新特征,其中包括:在增强元文件中包含 OpenGL调用,引进打印机支持,通过顶 点数组的新特征,提高了顶点位置、法向、颜色及色彩指数、纹理坐标、多边形边缘标志等的传输速度。现 在, OpenGL已经成为应用最为广泛的二维和三维图形编程接口。各种平台上利用 OpenGL开发的图形应用软 件大量地涌现出来。 OpenGL的主要版本有1.0、1.1、1.2和1.2.1,其中以1.1版最为常用。 Microsoft起先是把 OpenGL集成到 Windows NT中,后来又把它集成到新版本的 Windows950SR2中,而在 Windows98中, OpenGL已经成为标准组成部分之一,其执行性能也得到了相应的优化提高。 1.0penL的特点 从程序开发人员的角度来看, OpenGL是一组绘图命令的API集合。利用这些API能够方便地描述二维和三 维几何物体,并控制这些物体按某种方式绘制到显示缓冲区中。 OpenGL的API集提供了物体描述、平移、旋 转、缩放、光照、纹理、材质、象素、位图、文字、交互以及提高显示性能等方面的功能,基本涵盖了开发 隹图形程序所需的各个方面。与一般的图形开发工具相比,Open 具有以下几个突出特点 应用广 OpenGL是目前最主要的二、三维交互式图形应用程序开发环境,已成为业界最受推荐的图形应用编程接口。 自从1992年发表以来, OpenGL已被广泛地应用于CAD/CAM、三维动画、数字图象处理以及虚拟现实等领域 Kinetix公司的3 D Studio max就是突出的代表。无论是在PC机上,还是在工作站甚至是大型机和超级计算 机上, OpenGL都能表现出它的高性能和强大威力 ·跨平台性 0 penGL能够在几乎所有的主流操作系统上运行,包括UNIX、Mac0s、0s/2、 Windows nt、 Windows9x、 Linux 等:也能够与其中绝大多数的窗口系统一起工作 高质量和高性能 无论是在CAD/CAM、三维动画还是可视化仿真等领域, OpenGL高质量和高效率的图形生成能力都能得到充 分的体现。在这些领域中,开发人员可以利用 OpengL制作出效果逼真的二、三维图象来。 出色的编程特性 OpenGL体系结构评审委员会(ARB)独立负责管理 OpenGL的规范,这使得 OpenGL具有充分的独立性。 OpenGL在各种平台上已有多年的应用实践,加上严格的规范控制,因此 OpenGL具有良好的稳定性。 良好的前瞻性、伸缩性和易使用性等也是 OpenGL的突出编程特点。 建立在客户/服务器模型上的网络透明性是 OpenGL的固有特性,它允许一个运行在工作站上的进程在本机 或通过网络在远程工作站上显示图形。利用这种透明性能够均衡地共同承担图形应用任务的各工作站的负荷, 也能使得没有图形功能的服务器能够使用图形工具 2.0 penGL的API结构 图1-1(a)是Win32平台上 OpenGL API的结构简图:(b)是UNX平台上 OpenGL API的结构简图。其中“0 penGL 表示 OpenGL基本API,这类API的主要功能包括物体描述、平移、旋转、缩放、光照、纹理、材质、象素、 位图、文字处理等。“GL"表示实用API,其主要功能包括绘制二次曲面、 NURBS曲线曲面、复杂多边形以及 纹理、矩阵管理等。“GL"是Win32为支持 OpenGL而特别设计的一套编程接口:“LX是UNIX系统支持 OpenGl 的编程接口 为了实现与硬件平台无关, OpenGL不提供窗口管理、输入管理和事件响应机制,因此ω penGL程序必须使 用所在平台的用户接口(如GD和Ⅺlib)。 计算机图形学第五章第137页共36页
计算机图形学 第五章 第 137 页 共 36 页 第一部分 OpenGL 5.1.1 概述 OpenGL 是一个功能强大的图形库,用户可以很方便地利用它开发出有多种特殊视觉效果(如光照,纹 理,透明,阴影)的三维图形。OpenGL 的前身是 SGI 公司为其图形工作站设计的一个图形开发软件库 IRIS GL(Graphics Library),由于其性能优越,因此受到了用户的一致推崇。SGI 公司有针对性地对 GL 进行 了改进,特别是扩展了 GL 的可移植性,使之成为一个跨平台的开放式图形编程接口,这就是 OpenGL。 1992 年,OpenGL1.0 版正式发布,并立即得到了迅速的应用推广。1995 年 12 月,由 OpenGL ARB(Architecture Review Board—体系结构评审委员会)批准了 OpenGL1.1 版本,这一版本的 OpenGL 性能 得到了加强,并引入了一些新特征,其中包括:在增强元文件中包含 OpenGL 调用,引进打印机支持,通过顶 点数组的新特征,提高了顶点位置、法向、颜色及色彩指数、纹理坐标、多边形边缘标志等的传输速度。现 在,OpenGL 已经成为应用最为广泛的二维和三维图形编程接口。各种平台上利用 OpenGL 开发的图形应用软 件大量地涌现出来。OpenGL 的主要版本有 1.0、1.1、1.2 和 1.2.1,其中以 1.1 版最为常用。 Microsoft 起先是把 OpenGL 集成到 Windows NT 中,后来又把它集成到新版本的 Windows 95 OSR2 中,而在 Windows98 中,OpenGL 已经成为标准组成部分之一,其执行性能也得到了相应的优化提高。 1.OpenGL 的特点 从程序开发人员的角度来看,OpenGL 是一组绘图命令的 API 集合。利用这些 API 能够方便地描述二维和三 维几何物体,并控制这些物体按某种方式绘制到显示缓冲区中。OpenGL 的 API 集提供了物体描述、平移、旋 转、缩放、光照、纹理、材质、象素、位图、文字、交互以及提高显示性能等方面的功能,基本涵盖了开发 二、三维图形程序所需的各个方面。与一般的图形开发工具相比,OpenGL 具有以下几个突出特点: • 应用广泛 OpenGL 是目前最主要的二、三维交互式图形应用程序开发环境,已成为业界最受推荐的图形应用编程接口。 自从 1992 年发表以来,OpenGL 已被广泛地应用于 CAD/CAM、三维动画、数字图象处理以及虚拟现实等领域, Kinetix 公司的 3D Studio Max 就是突出的代表。无论是在 PC 机上,还是在工作站甚至是大型机和超级计算 机上,OpenGL 都能表现出它的高性能和强大威力。 • 跨平台性 OpenGL 能够在几乎所有的主流操作系统上运行,包括 UNIX、Mac OS、OS/2、Windows NT、Windows9x、Linux 等;也能够与其中绝大多数的窗口系统一起工作。 • 高质量和高性能 无论是在 CAD/CAM、三维动画还是可视化仿真等领域,OpenGL 高质量和高效率的图形生成能力都能得到充 分的体现。在这些领域中,开发人员可以利用 OpenGL 制作出效果逼真的二、三维图象来。 • 出色的编程特性 OpenGL 体系结构评审委员会(ARB)独立负责管理 OpenGL 的规范,这使得 OpenGL 具有充分的独立性。 OpenGL 在各种平台上已有多年的应用实践,加上严格的规范控制,因此 OpenGL 具有良好的稳定性。 良好的前瞻性、伸缩性和易使用性等也是 OpenGL 的突出编程特点。 • 网络透明性 建立在客户/服务器模型上的网络透明性是 OpenGL 的固有特性,它允许一个运行在工作站上的进程在本机 或通过网络在远程工作站上显示图形。利用这种透明性能够均衡地共同承担图形应用任务的各工作站的负荷, 也能使得没有图形功能的服务器能够使用图形工具。 2. OpenGL 的 API 结构 图 1-1(a)是Win32 平台上 OpenGL API 的结构简图;(b)是UNIX 平台上OpenGL API 的结构简图。其中“OpenGL” 表示 OpenGL 基本 API,这类 API 的主要功能包括物体描述、平移、旋转、缩放、光照、纹理、材质、象素、 位图、文字处理等。“GLU”表示实用 API,其主要功能包括绘制二次曲面、NURBS 曲线曲面、复杂多边形以及 纹理、矩阵管理等。“WGL”是 Win32 为支持 OpenGL 而特别设计的一套编程接口;“GLX”是 UNIX 系统支持 OpenGL 的编程接口。 为了实现与硬件平台无关,OpenGL 不提供窗口管理、输入管理和事件响应机制,因此 OpenGL 程序必须使 用所在平台的用户接口(如 GDU 和 Xlib)
Windows应用程序 UNX应用程序 GLU lllilllr GLU GDUd WGL)(OpenGL Ⅺ[Lx(opmL (a) Win32 OpenGL API D)UNIX OpenGL API+ 图5-1-10 penGL API结构图 3. OpenGL的工作顺序 OpenGL的工作顺序就是一个从定义几何要素到把象素段写入帧缓冲区的过程。在屏幕上显示图象的主要步 骤是以下3步 1).构造几何要素(点,线,多边形,图象,位图),创建对象的数学描述。在三维空间上 放置对象,选择有利的场景观察点。 2).计算对象的颜色,这些颜色可能直接定义,或由光照条件及纹理间接给出 光栅化,把对象的数学描述和颜色信息转换到屏幕的象素 5.1.2 OpenGL程序结构 1.基本语法 常用的程序设计语言,如C、C++、 Pascal、 Fortran和Java等,都支持 OpenGL的开发。这里只讨论 C版本下 OpenGL的语法 OpenGL基本函数均使用g作为函数名的前缀,如 glClearColoro:实用函数则使用gu作为函数名的 前缀,如 gluSphere0。 OpenGL基本常量的名字以GL_开头,如GL_ LINE LOOP;实用常量的名字以 GLU开头,如 GLU FILL。一些函数如 glColor*0(定义颜色值),函数名后可以接不同的后缀以支持不同 的数据类型和格式。如 glColor3b(…)、 glColor3d(.)、 glColor3f(-)和 glColor3bv(…)等,这几个函数在功 能上是相似的,只是适用于不同的数据类型和格式,其中3表示该函数带有三个参数,b、d、f分别表示参 OpenGL还定义了一些特殊常量,如 GLfloat, GLvoid。它们其实就是C中的foat和void。在glh文件 中可以看到以下定义 typedef foat GLfloat typedef void GLvoid 一些基本的数据类型都有类似的定义项。 2.状态机制 OpenGL的工作方式是一种状态机,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们 之前一直有效。例如,当前颜色就是一个状态变量,在这个状态改变之前,绘制的每个象素都将使用该颜色 直到当前颜色被设置为其它颜色为止。 OpenGL中大量地使用了这种状态机制,如颜色模式、投影模式、单 双显示缓存区的设置、背景色的设置、光源的位置和特性等等。许多状态变量可以通过 glEnable0, glDisable( 这两个函数来设置成有效或无效状态,如是否设置光照、是否进行深度检测等:在被设置成有效状态之后, 绝大部分状态变量都有一个缺省值。通常情况下,可以用下列四个函数来获取某个状态变量的值 glGetBooleanvo、 glGetDoubleo、 glGetFloatvo和 glGetIntegervo。究竟选择哪个函数应该根据所要获得 的返回值的数据类型来决定。还有些状态变量有特殊的查询函数,如 glGetLigh0、 glGetError(和 glPolygon Stipple0等。另外,使用 glPushAttrib和 glPopAttribo函数,可以存储和恢复最近的状态变量的 值。只要有可能,都应该使用这些函数,因为它们比其它查询函数的效率更高。 计算机图形学第五章第138页共36页
计算机图形学 第五章 第 138 页 共 36 页 图 5-1-1 OpenGL API 结构图 3. OpenGL 的工作顺序 OpenGL 的工作顺序就是一个从定义几何要素到把象素段写入帧缓冲区的过程。在屏幕上显示图象的主要步 骤是以下 3 步: 1). 构造几何要素(点,线,多边形,图象,位图),创建对象的数学描述。在三维空间上 放置对象,选择有利的场景观察点。 2). 计算对象的颜色,这些颜色可能直接定义,或由光照条件及纹理间接给出。 3). 光栅化,把对象的数学描述和颜色信息转换到屏幕的象素。 5.1.2 OpenGL 程序结构 1. 基本语法 常用的程序设计语言,如 C、C++、Pascal、Fortran 和 Java 等,都支持 OpenGL 的开发。这里只讨论 C 版本下 OpenGL 的语法。 OpenGL 基本函数均使用 gl 作为函数名的前缀,如 glClearColor();实用函数则使用 glu 作为函数名的 前缀,如 gluSphere()。OpenGL 基本常量的名字以 GL_开头,如 GL_LINE_LOOP;实用常量的名字以 GLU_开头,如 GLU_FILL。一些函数如 glColor*()(定义颜色值),函数名后可以接不同的后缀以支持不同 的数据类型和格式。如 glColor3b(...)、glColor3d(...)、glColor3f(...)和 glColor3bv(...)等,这几个函数在功 能上是相似的,只是适用于不同的数据类型和格式,其中 3 表示该函数带有三个参数,b、d、f 分别表示参 数的类型是字节型、双精度浮点型和单精度浮点型,v 则表示这些参数是以向量形式出现的。 OpenGL 还定义了一些特殊常量,如 GLfloat,GLvoid。它们其实就是 C 中的 float 和 void。在 gl.h 文件 中可以看到以下定义: …… typedef float GLfloat; typedef void GLvoid; …… 一些基本的数据类型都有类似的定义项。 2. 状态机制 OpenGL 的工作方式是一种状态机,它可以进行各种状态或模式设置,这些状态或模式在重新改变它们 之前一直有效。例如,当前颜色就是一个状态变量,在这个状态改变之前,绘制的每个象素都将使用该颜色, 直到当前颜色被设置为其它颜色为止。OpenGL 中大量地使用了这种状态机制,如颜色模式、投影模式、单 双显示缓存区的设置、背景色的设置、光源的位置和特性等等。许多状态变量可以通过 glEnable(),glDisable() 这两个函数来设置成有效或无效状态,如是否设置光照、是否进行深度检测等;在被设置成有效状态之后, 绝大部分状态变量都有一个缺省值。通常情况下,可以用下列四个函数来获取某个状态变量的值: glGetBooleanv()、glGetDouble()、glGetFloatv()和 glGetIntegerv()。究竟选择哪个函数应该根据所要获得 的返回值的数据类型来决定。还有些状态变量有特殊的查询函数,如 glGetLight*()、glGetError()和 glPolygonStipple()等。另外,使用 glPushAttrib()和 glPopAttrib()函数,可以存储和恢复最近的状态变量的 值。只要有可能,都应该使用这些函数,因为它们比其它查询函数的效率更高
命令 值 GL ALPH gIClipPlane gDepthFunc GL DEF gLightmModel、 alight GL LIGHT1 GL LIGHTING gILightModel- alight GL LIGHTING GL LINE SMOOTH glinestipple GL LINE S TIPPLE GL NORMALIZE gIPolygonMode GL POLYGON SMOTH 部分利用 glEnableo和 glDisable0的函数和设定值 3.程序的基本结构 OpenGL程序的基本结构可分为三个部分 第一部分是初始化部分,主要是设置一些 OpenGL的状态开关,如颜色模式(RGBA或 ALPHA)的选择, 是否作光照处理(若有的话,还需设置光源的特性),深度检验,裁剪等等。这些状态一般都用函数 geTable(???), glDisable(???)来设置,???表示特定的状态。 第二部分设置观察坐标系下的取景模式和取景框位置及大小。主要利用了三个函数 函数 void glViewport(left, top, right, bottom):设置在屏幕上的窗口大小,四个参数描述屏幕窗口四个角上 的坐标(以象素表示) 函数 void glortho( eft, right, bottom, top, near,fa):设置投影方式为正交投影(平行投影),其取景体积 是一个各面均为矩形的六面体 函数 void gluPerspective(owy, aspect, NEar,zFar):设置投影方式为透视投影,其取景体积是一个截头 锥体,在这个体积内的物体投影到锥的顶点 第三部分是 OpenGL的主要部分,使用 OpenGL的库函数构造几何物体对象的数学描述,包括点线面的 位置和拓扑关系,几何变换,光照处理等等。 以上三个部分是 OpenGL程序的基本框架,即使移植到使用MFC框架下的 Windows程序中,其基本 素还是这三个,只是由于 Windows自身有一套显示方式,需要进行一些必要的改动以协调这两种不同显示 简单的程序 程序5.1 #include include <Gu/glaux. h int main(int argc, char** argv) auxInit Display Mode(AUX_ SINGLE I Al auxInitPosition(0, 0, 500, 500) auxInitWindow(argv[o: gIClear Color(00,0.0.0.0,0.0);∥置背景色为黑色 glClear(GL_ COLOR BUFFER_BT;∥清除颜色缓冲区 glColor3f(1.0,1.0,1.0);∥设置象素颜色为白色 glMatrixMode(GL PROJECTION) glLoadldentityo glOrtho(-1.0,1.0,-1.0.1.0,-1.0.1.0) glBegin(GL POLYGON) glVertex2f(-0.5,-0.5); glVertex2f(-0.5, 0.5); gIVertex2f(0.5, 0.5) glVertex2f(0.5,-05 gIFlusho: 上面例子中,函数体内的前三条语句调用了 OpenGL辅助库( Auxiliary Library),其作用是一些初始化的 设置,具体的含义分别说明如下 void auxlnitWindow(GLbyte" title String); 计算机图形学第五章第139页共36页
计算机图形学 第五章 第 139 页 共 36 页 部分利用 glEnable()和 glDisable()的函数和设定值 3. 程序的基本结构 OpenGL 程序的基本结构可分为三个部分: 第一部分是初始化部分,主要是设置一些 OpenGL 的状态开关,如颜色模式(RGBA 或 ALPHA)的选择, 是否作光照处理(若有的话,还需设置光源的特性),深度检验,裁剪等等。这些状态一般都用函数 glEnable(???), glDisable(???) 来设置,???表示特定的状态。 第二部分设置观察坐标系下的取景模式和取景框位置及大小。主要利用了三个函数: 函数 void glViewport(left,top,right,bottom):设置在屏幕上的窗口大小,四个参数描述屏幕窗口四个角上 的坐标(以象素表示); 函数 void glOrtho(left,right,bottom,top,near,far):设置投影方式为正交投影(平行投影),其取景体积 是一个各面均为矩形的六面体; 函数 void gluPerspective(fovy,aspect,zNear,zFar):设置投影方式为透视投影,其取景体积是一个截头 锥体,在这个体积内的物体投影到锥的顶点。 第三部分是 OpenGL 的主要部分,使用 OpenGL 的库函数构造几何物体对象的数学描述,包括点线面的 位置和拓扑关系,几何变换,光照处理等等。 以上三个部分是 OpenGL 程序的基本框架,即使移植到使用 MFC 框架下的 Windows 程序中,其基本元 素还是这三个,只是由于 Windows 自身有一套显示方式,需要进行一些必要的改动以协调这两种不同显示 方式。 4. 一个简单的程序 程序 5.1.1 #include #include int main(int argc, char** argv) { auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); auxInitPosition (0, 0, 500, 500); auxInitWindow (argv[0]); glClearColor (0.0, 0.0, 0.0, 0.0); //置背景色为黑色 glClear(GL_COLOR_BUFFER_BIT); //清除颜色缓冲区 glColor3f(1.0, 1.0, 1.0); //设置象素颜色为白色 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glBegin(GL_POLYGON); glVertex2f(-0.5, -0.5); glVertex2f(-0.5, 0.5); glVertex2f(0.5, 0.5); glVertex2f(0.5, -0.5); glEnd(); glFlush(); } 上面例子中,函数体内的前三条语句调用了 OpenGL 辅助库(Auxiliary Library),其作用是一些初始化的 设置,具体的含义分别说明如下: void auxInitWindow(GLbyte* titleString);
该函数设置窗口的标题 title String为在标题条中出现的字符串名 void auxInit DisplayMode(GLbitfield mask 该函数设置窗口的特征 mask对下列值的按行逐位作“或”(OR)运算,或者按列作“与(AND)运算: AUX RGBAAUⅩNDEX颜色的RGBA模型还是索引模型 AUXS| NGLE AUX DOUBLE单、双显示缓冲区 以及激活以下任何缓冲,按列作“与AND)运算 AUX DEPTH深度缓存 AUX STENCIL模板缓存 AUX ACCUM累加缓存 例如,设置RGBA方式的双缓冲区及具有深度和模板缓存,则写成 AUX_DOUBLEJAUXRGBAJAUX_ DEPTHAUX STENCIL 缺省值是: AUX INDEXJAUX SINGLE 即是颜色索引方式的单缓存窗口。 void auxlnitPosition(GLint X, GLint y, GLsizei width, GLsize height 该函数设置程序窗口在屏幕上的位置和大小 x,y窗口左下角的位置。缺省值为(0,0) wdh, height窗口的大小(以象素为单位)。缺省值为(100,100) 下面为程序1的绘制效果 图5-1-2程序511的运行结果 5. OpenGL有关库 OpenGL本身是一个低层库,但在编程实践中还需要一些能简化编程任务、易于在窗口系统上执行的高层 库。SGl建立了四个库,前两个库对各种 OpenGL实现都提供,第三个库专为 OpenGL Programming Guide 编写的辅助库,第四个库是在 OpenGL之上开发的独立产品 1. OpenGL实用库(GLU) 利用较低层 OpenGL命令编写一些执行特殊任务的例程,如纹理映射、坐标变换、 NURBS曲线曲 面等。GLU库函数前缀都用gu 2. OpenGL的 X Window系统扩充(GLX) 在使用 X Window系统的机器上,提供一种建立 OpenGL现场( context),并把它与可绘( drawable) 窗口关联起来的方法。GLX作为 OpenGL的附件提供。GLX库函数前缀为g 3. OpenGL Programming Guide辅助库( Auxiliary Library) 这个库建立了一系列简单而又较完整的编程例子,例如初始化窗口、监控输入,以及绘制一些 三维几何体等函数。辅助库函数用前缀auX 在 Windows9598中,相关的库以动态链接库的形式存在, openg32mb、gu32lb、 glaux. ib分别表示 OpenGL库,实用库和辅助库,和它们相应的头文件是gh、guh及 glaux. he 计算机图形学第五章第140页共36页
计算机图形学 第五章 第 140 页 共 36 页 该函数设置窗口的标题。 titleString 为在标题条中出现的字符串名 void auxInitDisplayMode(GLbitfield mask); 该函数设置窗口的特征。 mask 对下列值的按行逐位作“或”(OR)运算,或者按列作“与”(AND)运算: AUX_RGBA AUX_INDEX 颜色的 RGBA 模型还是索引模型 AUX_SINGLE AUX_DOUBLE 单、双显示缓冲区 以及激活以下任何缓冲,按列作“与”(AND)运算 AUX_DEPTH 深度缓存 AUX_STENCIL 模板缓存 AUX_ACCUM 累加缓存 例如,设置 RGBA 方式的双缓冲区及具有深度和模板缓存,则写成: AUX_DOUBLE|AUX_RGBA|AUX_DEPTH|AUX_STENCIL 缺省值是: AUX_INDEX|AUX_SINGLE 即是颜色索引方式的单缓存窗口。 void auxInitPosition(GLint x,GLint y,GLsizei width, GLsize height); 该函数设置程序窗口在屏幕上的位置和大小。 x , y 窗口左下角的位置。缺省值为(0,0) width, height 窗口的大小(以象素为单位)。缺省值为 (100,100)。 下面为程序 1 的绘制效果: 图 5-1-2 程序 5.1.1 的运行结果 5. OpenGL 有关库 OpenGL 本身是一个低层库,但在编程实践中还需要一些能简化编程任务、易于在窗口系统上执行的高层 库。SGI 建立了四个库,前两个库对各种 OpenGL 实现都提供,第三个库专为 OpenGL Programming Guide 编写的辅助库,第四个库是在 OpenGL 之上开发的独立产品。 1. OpenGL 实用库(GLU) 利用较低层 OpenGL 命令编写一些执行特殊任务的例程,如纹理映射、坐标变换、NURBS 曲线曲 面等。GLU 库函数前缀都用 glu。 2. OpenGL 的 X Window 系统扩充(GLX) 在使用 X Window 系统的机器上,提供一种建立 OpenGL 现场(context),并把它与可绘(drawble) 窗口关联起来的方法。GLX 作为 OpenGL 的附件提供。GLX 库函数前缀为 glx。 3. OpenGL Programming Guide 辅助库(Auxiliary Library) 这个库建立了一系列简单而又较完整的编程例子,例如初始化窗口、监控输入,以及绘制一些 三维几何体等函数。辅助库函数用前缀 aux。 在 Windows95/98 中,相关的库以动态链接库的形式存在,opengl32.lib、glu32.lib、glaux.lib 分别表示 OpenGL 库,实用库和辅助库,和它们相应的头文件是 gl.h、glu.h 及 glaux.h
5.1.3基本几何元素 OpenGL的基本几何元素有点,线,多边形。从根本上看, OpenGL绘制的所有复杂三维物体都是由 定数量的基本图形元素构成的,曲线,曲面分别是由一系列直线段,多边形近似得到的 1.绘图准备和结束 在开始绘制新图形前,计算机屏幕上可能已有一些图形, OpenGL在显示缓冲区中存储了那些图形的绘图 信息,所以必须清除当前的这些内容,以免影响绘图的效果,可以用 void glClear Color( red, green, blue, alpha 给定当前屏幕的背景设置颜色,red, green,bue, alpha为RGBA颜色值, void glClear( mask ) 命令标志要清除的缓冲区。可以清除的缓冲区如下表所示: 名称 颜色缓冲区 GL COLOR BUFFER BIT 深度缓冲区 GL DEPTH BUFFER BIT 累加缓冲区 GL ACCUM BUFFER BIT 模板缓冲区 GL STENCIL BUFFER BIT 也可以使用 glClearColor(), glClear Depth0, glClearIndex0), glClear Stenci|O, glClearAccO为各自对 应的缓冲区赋值。若要同时清除多个缓冲区,使用上表中所列的mask位的”与'(AND)组合,在速度上要比 使用多次调用 glClear函数要快得多 在绘制图形前,同样通常要先设定颜色或颜色方式,这样有利于达到较高的绘图性能。设置颜色利用命令: glColor*O 在绘制完图形时,需要使用两个函数来结束绘图并返回: 函数 void glFlush0强制 OpenGL命令序列在有限的时间内完成执行 函数 void glFinish0使完成前面发出的全部 OpenGL命令的执行,即等到完全实现全部命令的结束后才 返回。 2.绘制 OpenGL的基本几何元素(几何要素) OpenGL的几何要素有点,线,多边形。 OpenGL中的点是三维的,用户设定二维坐标(X,y),此时z 自动置0:线是用一系列相连的顶点定义的:多边形是一个封闭的线段,通过选择属性,既可以得到填充的 多边形,也可以是轮廓线,或是一系列点,多边形的边不能交叉且应该是凸多边形,若要绘制的多边形不满 足这几个条件,则应调用GLU应用库函数,进行详细描述和镶嵌。光滑的曲线,曲面都是由一系列线段, 多边形近似得到的, OpenGL不直接提供绘制曲线,曲面的命令 总之,描述几何要素就是按一定的顺序给出几何要素的顶点, glVertexO命令指定一个顶点,并在生成顶 点后,把当前颜色,纹理坐标,法线等值赋给这个顶点 函数 void glVertex{234 HsifdHv( coords)按照指定的格式定义一个顶点,有时也用矢量形式定义顶点,执 行效率高,但是该函数只能在 glBegin0与gEnd0之间调用才有意义。 glBegin0标志几何要素定义的开始, gEnd0函数则标志结束一个几何要素的定义。 函数 void glBegin( Glenum mode)中的mode的值见下表。 表5-1-1:mode的取值 Mode的值 解释 GL POINTS 系列独立的点 GL LINES 每两点相连成为线段 GL POLYGON 简单,凸多边形的边界 GL TRIANGLES 三点相连成为一个三角形 GL QUADS 四点相连成为一个四边形 计算机图形学第五章第141页共36页
计算机图形学 第五章 第 141 页 共 36 页 5.1.3 基本几何元素 OpenGL 的基本几何元素有点,线,多边形。从根本上看,OpenGL 绘制的所有复杂三维物体都是由一 定数量的基本图形元素构成的,曲线,曲面分别是由一系列直线段,多边形近似得到的。 1. 绘图准备和结束 在开始绘制新图形前,计算机屏幕上可能已有一些图形,OpenGL 在显示缓冲区中存储了那些图形的绘图 信息,所以必须清除当前的这些内容,以免影响绘图的效果,可以用 void glClearColor ( red , green , blue , alpha ); 给定当前屏幕的背景设置颜色,red , green , blue , alpha 为 RGBA 颜色值, void glClear ( mask ); 命令标志要清除的缓冲区。可以清除的缓冲区如下表所示: 缓冲区 名称 颜色缓冲区 GL_COLOR_BUFFER_BIT 深度缓冲区 GL_DEPTH_BUFFER_BIT 累加缓冲区 GL_ACCUM_BUFFER_BIT 模板缓冲区 GL_STENCIL_BUFFER_BIT 也可以使用 glClearColor(),glClearDepth(),glClearIndex(),glClearStencil(),glClearAcc()为各自对 应的缓冲区赋值。若要同时清除多个缓冲区,使用上表中所列的 mask 位的”与”(AND)组合,在速度上要比 使用多次调用 glClear 函数要快得多。 在绘制图形前,同样通常要先设定颜色或颜色方式,这样有利于达到较高的绘图性能。设置颜色利用命令: glColor*()。 在绘制完图形时,需要使用两个函数来结束绘图并返回: 函数 void glFlush() 强制 OpenGL 命令序列在有限的时间内完成执行; 函数 void glFinish() 使完成前面发出的全部 OpenGL 命令的执行,即等到完全实现全部命令的结束后才 返回。 2. 绘制 OpenGL 的基本几何元素(几何要素) OpenGL 的几何要素有点,线,多边形。OpenGL 中的点是三维的,用户设定二维坐标(x , y),此时 z 自动置 0;线是用一系列相连的顶点定义的;多边形是一个封闭的线段,通过选择属性,既可以得到填充的 多边形,也可以是轮廓线,或是一系列点,多边形的边不能交叉且应该是凸多边形,若要绘制的多边形不满 足这几个条件,则应调用 GLU 应用库函数,进行详细描述和镶嵌。光滑的曲线,曲面都是由一系列线段, 多边形近似得到的,OpenGL 不直接提供绘制曲线,曲面的命令。 总之,描述几何要素就是按一定的顺序给出几何要素的顶点,glVertex()命令指定一个顶点,并在生成顶 点后,把当前颜色,纹理坐标,法线等值赋给这个顶点。 函数 void glVertex{234}{sifd}{v}(coords)按照指定的格式定义一个顶点,有时也用矢量形式定义顶点,执 行效率高,但是该函数只能在 glBegin()与 glEnd()之间调用才有意义。glBegin() 标志几何要素定义的开始, glEnd() 函数则标志结束一个几何要素的定义。 函数 void glBegin(Glenum mode)中的 mode 的值见下表。 表 5-1-1:mode 的取值 Mode 的值 解释 GL_POINTS 一系列独立的点 GL_LINES 每两点相连成为线段 GL_POLYGON 简单,凸多边形的边界 GL_TRIANGLES 三点相连成为一个三角形 GL_QUADS 四点相连成为一个四边形
GL LINE STRIP 顶点相连成为一系列线段 GL LINE LOOP 顶点相连成为一系列线段,连接 最后一点与第一点 GL TRIANGLE STRIP相连的三角形带 GL TRIANGLE FAN相连的三角形扇形 GL QUAD STRIP 相连的四边形带 例如下列程序语句定义如左图所示的图形。 glBegin(GL POLYGON) glVertex2f(0.0,0.0) glVertex2f(0.0, 3.0) glVertex2f(3.0, 3.0) 图51-3绘多边形或 GL POLYGON GL POINTS glVertex2f(4.0, 1.5) glVertex2f(3.0,0.0) lEndo 点、线和多边形在屏幕上绘制时,是有各自的缺省显示方式的。例如点绘成单个象素,线绘成一个象素宽 的实线,多边形绘成实的填充多边形。可以通过 OpenGL库提供的相应函数改变这些显示方式 点属性 void glPointSize(Glfloat size 以象素为单位设置点绘制的宽度 size点的宽度,必须大于0。缺省值为1.0。 注意,这里的点宽度可以不是整数。如果程序中没有设置反走样处理,那么非整数的宽度被截断为整数 例如宽度为10的点,在屏幕上显示的就是1×1象素的正方形。如果设置了反走样处理,点宽度不作取整运 算,此时表示点的象素群边界上的象素用较低亮度绘出,使边缘显得较平滑 ·线属性 void glLineWidth(Glfloat width) 以象素为单位设置线绘制的宽度。绘制线时的反走样处理与点的处理一样。 void glLineStipple(Glint factor, Glushort pattern) 指定点画模式(线型) factor指定线型模式中每位的乘数。 factor的值在[1255之间,缺省值为1 pattern用16位整数指定位模式。位为1时,指定要绘:位为0时,指定不绘。缺省时,全部为l。 位模式从低位开始。 例如:模式0×3f07,二进制表示为:0011111100000111,即是从低位起绘3个象素,不绘5个象素, 绘6个象素和不绘2个象素来连成一条线。设 factor为2,则绘或不绘的象素相应都乘上2。 利用如下命令定义上述线型: glLineStipple (2, 0x3f07) glEnable(GL LINE STIPPLE 在定义线型后,必须用 glEnableo命令激活线型。下图表示用不同的模式和重复因子绘线。 当不激活线型时: pattern factor 去活线型时调用 diSable(GL_ LINE STIPPLE)。 计算机图形学第五章第142页共36页
计算机图形学 第五章 第 142 页 共 36 页 GL_LINE_STRIP 顶点相连成为一系列线段 GL_LINE_LOOP 顶点相连成为一系列线段,连接 最后一点与第一点 GL_TRIANGLE_STRIP 相连的三角形带 GL_TRIANGLE_FAN 相连的三角形扇形 GL_QUAD_STRIP 相连的四边形带 例如下列程序语句定义如左图所示的图形。 glBegin(GL_POLYGON); glVertex2f(0.0,0.0); glVertex2f(0.0,3.0); glVertex2f(3.0,3.0); 图 5-1-3 绘多边形或一 组点 glVertex2f(4.0,1.5); glVertex2f(3.0,0.0); glEnd(); 3. 设置几何要素的属性 点、线和多边形在屏幕上绘制时,是有各自的缺省显示方式的。例如点绘成单个象素,线绘成一个象素宽 的实线,多边形绘成实的填充多边形。可以通过 OpenGL 库提供的相应函数改变这些显示方式。 • 点属性 void glPointSize(Glfloat size); 以象素为单位设置点绘制的宽度。 size 点的宽度,必须大于 0。缺省值为 1.0。 注意,这里的点宽度可以不是整数。如果程序中没有设置反走样处理,那么非整数的宽度被截断为整数。 例如宽度为 1.0 的点,在屏幕上显示的就是 象素的正方形。如果设置了反走样处理,点宽度不作取整运 算,此时表示点的象素群边界上的象素用较低亮度绘出,使边缘显得较平滑。 • 线属性 void glLineWidth(Glfloat width); 以象素为单位设置线绘制的宽度。绘制线时的反走样处理与点的处理一样。 void glLineStipple(Glint factor,Glushort pattern); 指定点画模式(线型)。 factor 指定线型模式中每位的乘数。factor 的值在[1,255]之间,缺省值为 1。 pattern 用 16 位整数指定位模式。位为 1 时,指定要绘;位为 0 时,指定不绘。缺省时,全部为 1。 位模式从低位开始。 例如:模式 0x3f07,二进制表示为:0011 1111 0000 0111,即是从低位起绘 3 个象素,不绘 5 个象素, 绘 6 个象素和不绘 2 个象素来连成一条线。设 factor 为 2,则绘或不绘的象素相应都乘上 2。 利用如下命令定义上述线型: glLineStipple(2,0x3f07); glEnable(GL_LINE_STIPPLE); 在定义线型后,必须用 glEnable()命令激活线型。下图表示用不同的模式和重复因子绘线。 当不激活线型时: pattern factor 0xffff 1 去活线型时调用 glDisable(GL_LINE_STIPPLE)
PATTERN FACTOR OXOOFF OXOOFF OXOCOF OXOCOF OXAAAA OXAAAA 213123 OXAAAA 二 OXAAAA 图5-1-4各种参数下的线型 多边形属性 通常多边形用实模式填充,但也可以利用下面命令 glPolygonStippleo指定某种点画模式(图案)来填 充。多边形也存在反走样,而且较点和线更复杂。 void glPolygonStipple(const Glubyte *mask) 该函数指定多边形点画模式。 mask指定32X32点画模式(位图)的指针,当值为1时绘:当值为0时不绘。 指定多边形点画模式需要利用 glEnablet激活,也利用 glDisableO去活。 glEnable(GL POLYGON STIPPLE glDisable(GL POLYGON STIPPLE 下面的程序运行结果为三个矩形区域,其中第一个矩形只使用了实模式,第二和第三个矩形使用了点画模 程序5.1.2多边形的填充 include #include #include void display(void) GLubyte fly={∥第二个矩形点画模式的mask值 0x00.0X00.0X00.0x00.0X00.0X00.0X00.0x00 0X03,0x80,0x01,0xC0,0x06,0xC0,0x03,0x60 0×04,0x60,0x06,0x20,0x04,0x30,0x0C,0x20, 0x04,0x18,0x18,0x20,0x04,0x0C,0x30,0x2〔 0x04,0x06,0×60,0x20,0x44,0x03,0XC0,0x22 0×44,0x01,0x80,0x22,0x44,0x01,0x80,0X22 0x44,0x01,0x80,0x22,0x44,0x01,0x80,0x22 0×44,0x01,0x80,0x22,0x44,0x01,0X80,0x22, 0x66,0x01,0x80,0x66,0x33,0x01,0x80,0CC, 0x19,0x81,0x81,0x98,0xOC,0xC1,0Xx83,030, 0x07,0xe1,0x87,0xe0,0x03,0x3f,0xftc,0xc0 00a080ga0 0x18,0Xcc,0×33,0x18,0x10,0xc4,0x23,0x08 0x10,0x63,0x6,0x08,0x10,0x30,0x0c,0x08 0x10,0x18,0X18,0x08,0x10,0x00,0x00,0x08 } GLubyte halftone]={第三个矩形点画模式的mask值 OXAA. OXAA. OXAA. OXAA 0x 550X55 0X550x55 0xAA,OxAA,0xAA,0xAA,0x55,0x55,0×55,0x55, OXAA. OXAA. OXAA. OXAA. 0X55 0X55 0X55 0X55 OXAA. OXAA. OXAA. OXAA. 0x55. 0X55. 0x55 0X55 OXAA, OXAA, OXAA, OXAA, 0X55, 0X55, 0X55, 0x55 OXAA, OXAA, OXAA, OXAA, 0X55, 0x55, 0X55, 0X55 OXAA, OXAA, OXAA, OxAA, 0x55, 0X55, 0X55, 0x55 OXAA, OXAA, OXAA, OXAA, 0X 55, 0X55, 0X55, 0x55 0xAA,0xAA,OXAA,0xAA,0x55,0×55,055,0×55, 计算机图形学第五章第143页共36页
计算机图形学 第五章 第 143 页 共 36 页 图 5-1-4 各种参数下的线型 • 多边形属性 通常多边形用实模式填充,但也可以利用下面命令 glPolygonStipple()指定某种点画模式(图案)来填 充。多边形也存在反走样,而且较点和线更复杂。 void glPolygonStipple(const Glubyte* mask); 该函数指定多边形点画模式。 mask 指定 点画模式(位图)的指针,当值为 1 时绘;当值为 0 时不绘。 指定多边形点画模式需要利用 glEnable()激活,也利用 glDisable()去活。 glEnable(GL_POLYGON_STIPPLE); glDisable(GL_POLYGON_STIPPLE); 下面的程序运行结果为三个矩形区域,其中第一个矩形只使用了实模式,第二和第三个矩形使用了点画模 式。 程序 5.1.2 多边形的填充 #include #include #include void display(void) { GLubyte fly[] = { //第二个矩形点画模式的 mask 值 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x06, 0xC0, 0x03, 0x60, 0x04, 0x60, 0x06, 0x20, 0x04, 0x30, 0x0C, 0x20, 0x04, 0x18, 0x18, 0x20, 0x04, 0x0C, 0x30, 0x20, 0x04, 0x06, 0x60, 0x20, 0x44, 0x03, 0xC0, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x44, 0x01, 0x80, 0x22, 0x66, 0x01, 0x80, 0x66, 0x33, 0x01, 0x80, 0xCC, 0x19, 0x81, 0x81, 0x98, 0x0C, 0xC1, 0x83, 0x30, 0x07, 0xe1, 0x87, 0xe0, 0x03, 0x3f, 0xfc, 0xc0, 0x03, 0x31, 0x8c, 0xc0, 0x03, 0x33, 0xcc, 0xc0, 0x06, 0x64, 0x26, 0x60, 0x0c, 0xcc, 0x33, 0x30, 0x18, 0xcc, 0x33, 0x18, 0x10, 0xc4, 0x23, 0x08, 0x10, 0x63, 0xC6, 0x08, 0x10, 0x30, 0x0c, 0x08, 0x10, 0x18, 0x18, 0x08, 0x10, 0x00, 0x00, 0x08 }; GLubyte halftone[] = { //第三个矩形点画模式的 mask 值 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55
0xAA,OxAA,0xAA,0xAA,0x55,0x55,0×55,0x55, OXAA, OXAA, OXAA, OXAA, 0X55, 0X55, 0X55, 0X55 OXAA, OxAA, OxAA, 0XAA, 0x55, 0X55, 0x 55, 0X55 OXAA, OXAA, OXAA, OXAA, 0X 55, 0X55, 0X55, 0x55 OXAA,0xAA,0xAA,0xAA,0x55,0×55,0×55,0x55 0xAA,0xAA,0xAA,OxAA,0x55,0X55,0×55,0x55, OXAA, OXAA, OxAA, OXAA, 0x55, 0x55, 0x 55, 0X55 glClear(GL COLOR BUFFER BIT) glColor3f(1.0,1.0,1.0) glRectf(25.0,25.0,125.0.1250); glEnable(GL POLYGON STIPPLE); glPolygon Stipple(fly) glRectf(125.0,25.0,225.0,1250) pOlygon Stipple(halftone) Rect(225.0,25.0,3250,12 glDisable(GL POLYGON STIPPLE) glFlush (: void myinit (void gIClearColor(0.0,0.0,0.0,0.0) glShadeModel (GL FLAT } int main(int argc, char"*argv) auxInitDisplay Mode(AUX SINGLE AUX RGBA); auxInitPosition(0, 0, 350, 150) auxInitWindow(argv[oD; myinit o auxMainLoop(display) 图5-1-5程序51.2的运行结果 上图中第二个矩形的苍蝇图形比较复杂,下面具体给出它的设置说明: 计算机图形学第五章第144页共36页
计算机图形学 第五章 第 144 页 共 36 页 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55 }; glClear (GL_COLOR_BUFFER_BIT); glColor3f (1.0, 1.0, 1.0); glRectf (25.0, 25.0, 125.0, 125.0); glEnable (GL_POLYGON_STIPPLE); glPolygonStipple (fly); glRectf (125.0, 25.0, 225.0, 125.0); glPolygonStipple (halftone); glRectf (225.0, 25.0, 325.0, 125.0); glDisable (GL_POLYGON_STIPPLE); glFlush (); } void myinit (void) { glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_FLAT); } int main(int argc, char** argv) { auxInitDisplayMode (AUX_SINGLE | AUX_RGBA); auxInitPosition (0, 0, 350, 150); auxInitWindow (argv[0]); myinit (); auxMainLoop(display); } 图 5-1-5 程序 5.1.2 的运行结果 上图中第二个矩形的苍蝇图形比较复杂,下面具体给出它的设置说明:
18643168421128解32168421126431684211264316842 128643216842 缺省时,毎个字节的最高位在先。位的次序可调用 glPixelStore O加以改变。 图5-1-6构成多边形点画模式 计算机图形学第五章第145页共36页
计算机图形学 第五章 第 145 页 共 36 页 图 5-1-6 构成多边形点画模式
4.控制多边形绘制 多边形的绘制通常是在多边形闭合边界内填充全部象素,但也可以只绘多边形边框,或只绘多边形顶点。 由于多边形面存在正面和背面,所以需要控制反转多边形面和剔除不绘的面。此外,有时多边形还需控制边 界线的绘制。 ·选择绘制多边形的方式 利用下面函数可以选择绘多边形的方式 oid glPolygonMode(GLenum face, GLenum mode) face控制多边形的正面和背面的绘图方式 GL FRONT AND BACK正面和反面都画 L FRONT只画正面 GL_BACK只画反面 mode控制绘点、线框或填充多边形。 GL POINT用有一定间隔的点填充 GL_LINE只画多边形的边框 FIL填充多边形 缺省值: glPolygonMode( GL FRONT AND BACK. GL FILL 即多边形的正、背面都用填充绘制。 例如,下面两个函数的调用,多边形正面是填充的和背面是线框的。 glPolygonMode(GL_ FRONT, GL_FILL) glPolygonMode(GL BACK, GL LINE) 反转多边形面 在 OpenGL中,每个多边形被认为是由两个面组成的:正面和反面。缺省时,在屏幕上以逆时针方向出现 顶点的多边形称为正面,反之为背面。用户也可以利用函数 gl FrontFace自行设置多边形的正面方向 void glFront Face(Glenum mode) 该函数定义多边形的正面方向 mode GL Cw(顺时针方向为正面) GL_Cw(逆时针方向为正面,缺省值) ·裁减多边形面 由一致方向的多边形构成完全闭合的曲面,其背面多边形总是被正面多边形所遮挡。因此,通过 OpenGl 确定为背面时剔除这些多边形,可以极大地提高几何体的绘制速度。同样,如果处在几何对象内部,只是背 面多边形是可见时,则剔除正面多边形。利用函数 glCullFace0,选择剔除(cul1)正面或背面多边形,在这 之前需利用 glEnbleo激活剔除处理 void glCullFace(GLenum mode) 指定剔除正面或背面多边形 mode L front剔除正面 GL FRONT AND BACK剔除全部 利用下面函数激活或去活多边形剔除 glEnable(GL CULL FACE) glDisable(GL CULL FACE) 5.法向量 法向量是垂直于面的方向上点的向量。在平展的面上,各个点有同一个方向:在弯曲的面上,各个点具有 不同的法向量 几何对象的法向量定义了它在空间中的方向。在进行光照处理时,法向量是一项重要的参数,因为法向量 决定了该对象可以接收多少光照。 ·指定法向量 利用下面函数 gINorma0设置当前法向量。 void glNormal3 (bsidt(TYPE nx, TYPE ny, TYPE nz) void gINormal3 bsdf/v(const TYPE V); nx, ny, nz指定法向量的xy和z坐标。法向量的缺省值为(0,0,1) V指定当前法向量的xy和z三元组(即矢量形式)的指针 用 gNormal'O指定的法向量不一定为单位长度。如果利用命令 glEnable( GL NORMALIZ日激活自动规 格化法向量,则经过变换后,就会自动规格化 gINorma0所指定的法向量。 计算机图形学第五章第146页共36页
计算机图形学 第五章 第 146 页 共 36 页 4. 控制多边形绘制 多边形的绘制通常是在多边形闭合边界内填充全部象素,但也可以只绘多边形边框,或只绘多边形顶点。 由于多边形面存在正面和背面,所以需要控制反转多边形面和剔除不绘的面。此外,有时多边形还需控制边 界线的绘制。 • 选择绘制多边形的方式 利用下面函数可以选择绘多边形的方式。 void glPolygonMode(GLenum face,GLenum mode); face 控制多边形的正面和背面的绘图方式。 GL_FRONT_AND_BACK 正面和反面都画 GL_FRONT 只画正面 GL_BACK 只画反面 mode 控制绘点、线框或填充多边形。 GL_POINT 用有一定间隔的点填充 GL_LINE 只画多边形的边框 GL_FILL 填充多边形 缺省值:glPolygonMode(GL_FRONT_AND_BACK,GL_FILL) 即多边形的正、背面都用填充绘制。 例如,下面两个函数的调用,多边形正面是填充的和背面是线框的。 glPolygonMode(GL_FRONT,GL_FILL); glPolygonMode(GL_BACK,GL_LINE); • 反转多边形面 在 OpenGL 中,每个多边形被认为是由两个面组成的:正面和反面。缺省时,在屏幕上以逆时针方向出现 顶点的多边形称为正面,反之为背面。用户也可以利用函数 glFrontFace()自行设置多边形的正面方向。 void glFrontFace(Glenum mode); 该函数定义多边形的正面方向。 mode GL_CW(顺时针方向为正面) GL_CCW(逆时针方向为正面,缺省值) • 裁减多边形面 由一致方向的多边形构成完全闭合的曲面,其背面多边形总是被正面多边形所遮挡。因此,通过 OpenGL 确定为背面时剔除这些多边形,可以极大地提高几何体的绘制速度。同样,如果处在几何对象内部,只是背 面多边形是可见时,则剔除正面多边形。利用函数 glCullFace(),选择剔除(cull)正面或背面多边形,在这 之前需利用 glEnble()激活剔除处理。 void glCullFace(GLenum mode); 指定剔除正面或背面多边形。 mode GL_FRONT 剔除正面 GL_BACK 剔除背面(缺省值) GL_FRONT_AND_BACK 剔除全部 利用下面函数激活或去活多边形剔除: glEnable(GL_CULL_FACE); glDisable(GL_CULL_FACE); 5. 法向量 法向量是垂直于面的方向上点的向量。在平展的面上,各个点有同一个方向;在弯曲的面上,各个点具有 不同的法向量。 几何对象的法向量定义了它在空间中的方向。在进行光照处理时,法向量是一项重要的参数,因为法向量 决定了该对象可以接收多少光照。 • 指定法向量 利用下面函数 glNormal*()设置当前法向量。 void glNormal3{bsidf}(TYPE nx,TYPE ny,TYPE nz); void glNormal3{bsidf}v(const TYPE* v); nx,ny,nz 指定法向量的 x,y 和 z 坐标。法向量的缺省值为(0,0,1)。 v 指定当前法向量的 x,y 和 z 三元组(即矢量形式)的指针。 用 glNormal*()指定的法向量不一定为单位长度。如果利用命令 glEnable(GL_NORMALIZE)激活自动规 格化法向量,则经过变换后,就会自动规格化 glNormal*()所指定的法向量