




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第1章OpenGL基础知识
☆掌握图形学编程的基本概念☆了解OpenGL基本功能与操作☆学习图形系统和模型的基本原理、结构1.1OpenGL概述
1.1.1直观的三维图形开发环境
OpenGL是美国SGI公司为图形工作站开发的一种功能强大的三维图形机制,其目的是将用户从具体的硬件系统和操作系统中解放出来,可以完全不去理解这些系统的结构和指令系统,只要按规定的格式书写应用程序就可以在任何支持该语言的硬件平台上运行。 OpenGL实际上是一种图形与硬件的接口。它包括了几百个指令和函数,开发者可以用这些函数来建立三维模型和进行三维实时交互。与其他图形程序设计接口不同,OpenGL提供了十分清晰明了的图形函数。1.1.2三维图形开发标准
许多计算机公司已经把OpenGL集成到各种窗口和操作系统中,其中操作系统包括UNIX、WindowsNT、DOS等,窗口系统有X窗口、Windows等。为了实现一个完整功能的图形处理系统,设计一个与OpenGL相关的系统结构为:其最底层是图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,第五层为应用软件。OpenGL是网络透明的,在客户—服务器(Client-Server)体系结构中,OpenGL允许本地和远程绘图。所以在网络系统中,OpenGL在X窗口、Windows或其它窗口系统下都可以以一个独立的图形窗口出现。1.1.3OpenGL基本功能与操作
OpenGL能够对整个三维模型进行渲染着色,从而绘制出与客观世界十分类似的三维景象。另外OpenGL还可以进行三维交互、动作模拟等。具体的功能主要有以下这些内容。(1)模型绘制(2)模型观察(3)颜色模式的指定(4)光照应用(5)图象效果增强(6)位图和图象处理OpenGL还提供了专门对位图和图象进行操作的函数。(7)纹理映射(8)实时动画(9)交互技术1.1.4OpenGL的体系结构
OpenGL是一个独立于硬件的高效接口,其中没有执行窗口任务或获取用户输入的函数,程序员必须通过窗口系统来控制硬件。因此在三维图形的绘制过程中,应用程序需要利用OpenGL与操作系统的基本指令,使窗口系统与操作系统进行交互控制,通过硬件驱动程序操作各个图形硬件,进而完成三维图形的绘制。应用软件OpenGL窗口系统操作系统图形硬件
网络下的OpenGL体系结构,在实际操作中,应用程序发出OpenGL命令,由动态链接库OpenGL32.dll接受打包后,发送到服务器端的WINSRV.DLL,然后由它通过DDI层发往视频显示驱动程序。如果系统安装了硬件加速器,则由硬件相关的DDI来处理。
应用程序OpenGL32.DLLGDI32.DLL可安装的客户端驱动程序WINSRV.DLL相关DDIWIN32.DDI视频显示驱动程序
1.1.5创建OpenGL控制台应用程序框架
1)OpenGL安装(以VisualStudio.Net2008为例)2)OpenGL工程配置与测试3)OpenGL程序测试
1.1.6VisualC++6.0环境下OpenGL单文档应用程序框架
1)OpenGL安装(以VisualStudio6.0为例)1、下载OpenGL类库/source/274113(这个是1.4版本的),也可以到OpenGL官网下载其他版本。将下载的文件解压到一个临时文件夹中。2、将解压文件中的所有.h头文件拷贝到C:\ProgramFiles\MicrosoftVisualStudio6.0\VC\include\GL目录中(没有GL目录就自己创建一个,这里的具体路径看电脑上VisualStudio6.0安装的位置而定);将.lib文件拷贝到C:\ProgramFiles\MicrosoftVisualStudio6.0\VC\lib目录中;将.dll文件拷贝到C:\Windows\System32目录中。2)OpenGL工程配置与测试启动VC6,新建一个Win32ConsoleApplication1、按照如下顺序选择:Project→Settings→Link选项卡然后,在Object/librarymodules下面的文本框的最前面添加如下库文件内容:Opengl32.libglut32.libGLAUX.LIBGlu32.lib最后,在ProjectOptions中修改subsystem:console修改为subsystem:windows。2、再按照如下顺序选择:Project→Settings→C/C++选项卡将Preprocessordefinitions中的_CONSOLE修改为_WINDOWS。这样可以进行OpenGL应用程序的测试了。1.2OpenGL图形的实现方式
1.2.1设备上下文DC与渲染上下文RC
OpenGL的绘图方式与Windows的一般的绘图方式是不同的,其区别主要表现在以下3个方面:①Windows采用的是GDI绘图。②OpenGL采用的是渲染上下文RC(RenderContext,又称渲染描述表)绘图。③OpenGL使用的是特殊的像素格式。在Windows中使用GDI绘图时必须指定在哪个设备上下文(DeviceContext,又称设备描述表)中绘制。同样地,在使用OpenGL函数时也必须指定一个所谓的渲染上下文。正如设备上下文DC要存储GDI的绘制环境信息如笔、刷和字体等,渲染上下文RC也必须存储OpenGL所需的渲染信息如像素格式等。
两种管理RC与DC的方法。
方法1:RC由WM_CREATE消息响应时创建,创建后立即释放DC;当WM_PAINT消息到来时,程序再获取DC句柄,并与RC关联起来,绘图完成后,立即解除RC与DC的关联,并释放DC;当WM_DESTROY消息到来时,程序只需简单地删除RC即可,如图1.9所示。
方法2:RC在程序开始时创建并使之成为现行RC。它将保持为现行RC直至程序结束。相应地,GetDC在程序开始时调用,ReleaseDC在程序结束时才调用。
1.2.3OpenGL图形处理流程
OpenGL的工作流程如图所示:1.2.4OpenGL图形绘制方式
OpenGL中的模型绘制过程就多种多样,内容十分丰富,OpenGL提供了以下的对三维物体的绘制方式:(1)线框绘制方式(Wireframe):绘制三维物体的网格轮廓线。(2)深度优先线框绘制方式(Depthcued):(3)反走样线框绘制方式(Antialiased):(4)平面明暗处理方式(Flatshading):(5)光滑明暗处理方式(Smoothshading):(6)加阴影和纹理的方式(ShadowandTexture):(7)运动模糊绘制方式(Motionblured):(8)大气环境效果(Atmosphereeffects):(9)深度域效果(Depthofeffects):1.2.5OpenGL程序的运行方式
运行OpenGL主要有以下3种方式:1)OpenGL硬件加速方式2)三维图形加速模式3)纯软件模式1.3OpenGL图形开发库
1.3.1开发库的组成
OpenGL函数库相关的API有核心库(gl)、实用库(glu)、辅助库(aux)、实用工具库(glut)、窗口库(glx、agl、wgl)和扩展函数库等。从图1可以看出,gl是核心,glu是对gl的部分封装。glx、agl、wgl是针对不同窗口系统的函数。glut是为跨平台的OpenGL程序的工具包,比aux功能强大。扩展函数库是硬件厂商为实现硬件更新利用OpenGL的扩展机制开发的函数。1.3.2基本数据类型
OpenGL是一个跨平台的API,数据类型的大小会随使用的编程语言以及处理器(64位,32位,16位)等的不同而不同,所以OpenGL定义了自己的数据类型。
1.3.3OpenGL库函数命名规则
所有OpenGL函数采用了以下格式:
<库前缀><根命令><可选的参数个数><可选的参数类型>
库前缀有gl、glu、aux、glut、wgl、glx等等,分别表示该函数属于OpenGL某开发库等,从函数名后面中还可以看出需要多少个参数以及参数的类型。I代表int型,f代表float型,d代表double型,u代表无符号整型。注意,有的函数参数类型后缀前带有数字2、3、4。2代表二维,3代表三维,4代表alpha值(以后介绍)。有些OpenGL函数最后带一个字母v,表示函数参数可用一个指针指向一个向量(或数组)来替代一系列单个参数值。1.4基于OpenGL的高层图形库
除了基于底层三维图形库的OpenGL之外,目前还出现了许多高层的三维图形开发库。当前支持实时三维图形开发的软件包包括IRISPerformer,MultiGen-ParadigmVega,CG2Vtree,SoftRealitySoftVR,CarmelAppliedTechnologyX-IG,Reality2Tiepolo,ThomsonTrainingSimulationSPACEMagic,LockedMartinSE/ViewQuantum3DOpenGVS等等。
1.5OpenGL应用程序框架
1、Window32控制台程序框架用OpenGL编写的程序结构类似于用其他语言编写的程序。实际上,OpenGL是一个丰富的三维图形函数库,编写OpenGL程序并非难事,只需在基本程序语言中调用这些函数,用法基本类似,但也有部分不同之处。对于简单的控制台程序,只需按以下步骤即可进行OpenGL编程:①创建一个新工程。②设置包含文件和库文件路径。③加入OpenGL库。2.Win32SDK程序框架Win32软件开发包(SDK)是在Windows32位机平台下的软件开发包,包含了各类API函数及其相关套件。Win32程序总是依托于窗口,采用事件驱动方式,基于消息机制。1)WM_CREATE消息的响应2)WM_PAINT消息响应3、MFC程序框架MFC是一套面向对象的函数库,以类的方式提供给开发者,它将WindowsAPI函数封装到类中。所以MFC的底层还是Win32程序。每个Win32应用程序都要完成固定的任务,MFC也不例外,比如要定义一个窗口类,注册窗口类,要创建窗口,进行消息循环、窗口过程定义等。但是MFC的工程代码里找不到这些明显的定义代码,因为MFC底层框架类中封装了这些部分,只有当程序编译链接时,由链接器将那些基本的函数链接到MFC程序中,同时,MFC基于消息映射机制,可能跟Win32程序的直接消息处理方法上有所不同,但是本质是一样的。
1.6开发实例:基本二维几何物体绘制
这个例子我们可以看到OpenGL可以做什么,当然这个例子只做了很简单的一件事--绘制一个彩色的三角形。除此以外,我们还可以看到典型的OpenGL程序结构及openGL的运行顺序。
1.7本章小结与习题
第2章OpenGL建模技术
☆图形显示控制☆点、线段、多边形的绘制☆规则三维物体绘制函数☆曲线、样条曲线、样条曲面、NURBS曲线和曲面绘制☆二次曲面☆显示列表概念、创建、执行、索引和嵌套
2.1基本图元及规则物体绘制
任何复杂的图形模型都是由基本的几何图元———点、线段和多边形组成的,基本几何图元的构造是OpenGL一切后续处理的基础。这一节讲述OpenGL中的基本图元操作,在这之前,必须熟悉OpenGL图形的基本显示控制。
2.1.1图形显示控制
1.刷新窗口在一般情况下,在绘制一幅图形之前,需要将计算机内存中的原始内容清除掉,用户可以自行设置清除的背景颜色值。OpenGL之所以提供清除窗口函数,是因为它要比绘制一个覆盖整个窗口的颜色矩形要更有效也更快;OpenGL允许用户设置坐标系统、视点和视角,而此时要给出相应覆盖窗口矩形的位置和大小比较困难;如果使用OpenGL的消隐技术(后面目标会被前面目标遮住),则当使用清除窗口多边形作为背景时,必须保证它处在其他物体的后面。这在任意坐标和视点的情况下很难保证;最后,大多数计算机上除了像素颜色缓存区外还有其他一些图形硬件支持的缓冲区,这些缓冲区也必须逐次清除。。
2.指定绘图颜色在OpenGL中的几何体和颜色是分开的。不论什么时候要绘制几何模型时,都使用当前指定的颜色来绘制,OpenGL程序首先设置颜色,然后绘制目标。除非重新设置了颜色,否则所有物体都将用该颜色来绘制。此方法与不存储当前颜色相比,可以获得更高的绘制效率。在OpenGL中,指定当前绘图颜色的函数原型如下:voidglColor3{b,d,f,s,i,ub,ui,us}(TYPEred,TYPEgreen,TYPEblue);voidglColor4{b,d,f,s,i,ub,ui,us}(TYPEred,TYPEgreen,TYPEblue,TYPEalpha);voidglColor3{b,d,f,s,i,ub,ui,us}v(constTYPE*v);voidglColor3{b,d,f,s,i,ub,ui,us}v(constTYPE*v);
3.强制绘图完成在高档体系结构中,每种操作是由图形硬件的不同部分分别执行的,CPU负责控制,这样才可以保证计算机资源的充分利用,提高作图质量和速度。在这个协调工作的计算机系统中,CPU并不是把命令一条一条地分送给作图硬件,而是把命令放在一个缓冲区中,成批成批地分送到执行硬件中。这就存在着一个如果缓冲区未满的情况下,强行让硬件操作的问题。在特殊的情况下,可以要求作图硬件系统完成某项操作后,CPU才可以继续做其他的事情。在OpenGL提供了两个解决这个问题的函数,函数的原型如下:voidglFinish(void)功能:在有限时间内强制执行OpenGL命令。
4.消隐在三维空间中,一些物体遮挡另一些物体是很自然的一件事情,而且这种遮挡关系随视点的不同而不同。清除一个物体被其他物体挡住的部分的操作称为消隐。OpenGL中,消隐操作是由深度buffer(Z-buffer)来实现的,深度buffer为窗口的每个点保留一个深度值,这个深度值记录了视点到占有该像素的目标的垂直距离,然后根据组成物体像素点的不同深度值,决定该点是否需要显示到屏幕上。在OpenGL中,设置深度缓存的清除值的函数原型如下:voidglClearDepth(Glclampddepth);功能:指定深度缓冲区的清除值。
5.构造图形在OpenGL中绘制一组顶点、线段或多边形,必须使用一个函数对glBegin()和glEnd()。传递给glBegin()函数的参数惟一确定了绘制哪些几何图元,在函数对gl-Begin()和glEnd()中给出了这些顶点的定义,该函数的原型如下:voidglBegin(GLenummode);voidglEnd(void);功能:指定一个或一组相似图元的顶点。参数说明:mode指定由函数对glBegin和gIEnd提供的顶点所要创建的图元类型。
2.1.2点的绘制
OpenGL中的点由一组数来定义的。在一般情况下,所有的内部计算均以三维方式进行的。当用户只定义(x,y)二维数据时,OpenGL会自动将z轴坐标赋值0。OpenGL运用三维投影坐标系进行计算时,x,y,z三者是均匀等比例的,因此在内部计算时,所有顶点用4个浮点来表示(x,y,z,w),如果w不为0,则该坐标对应于欧几里德三维点(x/w,y/w,z/w)。在程序中可以使用OpenGL命令指定w坐标,如果没有指定w坐标,则其默认值为1.0。在OpenGL中,对点这个基本图元有如下操作:
1.定义顶点坐标在OpenGL中,定义顶点坐标的函数是glVertex(),该函数的原型如下:voidglVertex{234}{sidf}[v](TYPEcoords);功能:指定一个顶点。参数说明:{234}指定顶点的维数,即点是二维的,或者是三维的或者是四维的。{sidf}指定点的数据类型,即点的数据是双精度的,或者是浮点精度的,或者是整形精度的,或者是短整形精度的。[v]是可选的,指定一个指向二元、三元或者是四元数组的指针。二元数组中包含的元素是x和y,三元数组中包含的元素是x,y和z,四元数组中包含的元素是x,y,z和w。2.设定点的大小在OpenGL中,设定点的大小的函数是glPointSize(),该函数的原型如下:voidglPointSize(GLfloatsize);功能:指定光栅化的点的直径。参数说明:size指定光栅化的点的直径,它的初始值是1。
2.1.3线段的绘制
OpenGL中的线段与几何中定义的略有不同,分为三种不同的类型:1.线段线段是由空间上两个点决定的一条直线,glBegin()函数中mode的取值为GLLINES。2.折线折线是由空间上一系列的点决定的,第一个点的坐标是折线和第一条线段的起点坐标,第二个点的坐标是第一条线段的终点坐标也是第二条线段的起点坐标,其后各点依次类推。3.封闭线除最后一个点自动与第一个点相连外,封闭线与折线没有其他的区别。(1)设定线宽在OpenGL中,设定线宽的函数是glLineWidth(),该函数的原型如下:voidglLineWidth(GLfloatwidth);功能:指定光栅化线的宽度。(2)设定线型在OpenGL中,设定线型的函数是glLineStipple(),该函数的原型如下:
voidglLineStipple(GLintfactor,GLushortpattern);功能:指定线的点画绘制模板。
2.1.4多边形的绘制
多边形是指封闭曲线围成的区域。在OpenGL中可以描述的多边形有两点限制:1、多边形的边和边除了多边形的顶点外不可以相交。2、多边形必须是凸多边形,所谓凸多边形是指多边形任意非相邻的两点的连线位于多边形的内部。在OpenGL中,多边形的绘制分为三角形、四边形、多边形、相连三角形、扇形三角形和相连四边形等6种。
2.1.5规则三维物体绘制函数
在OpenGL的辅助库中,提供了绘制11种基本几何图形的函数,每一种图形又包括线框体和实心体两种形式,因此共有22个函数.如:voidauxWireSphere(GLdoubleradius);
voidauxSolidSphere(GLdoubleradius);功能:绘制一个球体的线框图和实体图。参数说明:radius指定所绘制球体的半径。voidauxWireBox(GLdoublewidth,GLdoubleheight,GLdoubledepth);voidauxSolidBox(GLdoublewidth,GLdoubleheight,GLdoubledepth);功能:绘制一个长方体线框图和实体图。
2.1.6开发实例:基本三维几何物体绘制
下面介绍一个实例,通过它介绍如何绘制各种基本图元,以及如何设置绘图的颜色,其中有些函数目前还没有介绍,但是并不影响对程序的理解,这些函数将在后面的章节陆续介绍。规则三维物体如球体、圆锥等的绘制技术的实例,与基本图元的绘制技术类似,请读者自行参考第1章。该应用程序是基于控制台运行模式。
2.2曲线与曲面绘制
2.2.1曲线的基本理论
1)参数曲线最常用的曲线表现形式是显式参数形式,这也是OpenGL所使用的形式。还有其他一些表现形式,如隐含式和代数式等。2)多项式曲线曲线在数学上可以表示为多项式。下面的表达式表示x和y作为u的三次多项式函数。x(u)=a0+a1u1+a2u2+a3u3y(u)=b0+b1u1+b2u2+b3u3式中ai和bi称为参数。3)参数样条曲线将多个多项式合起来形成一个分段多项式,分段多项式使曲线的造型具有更大的灵活性,这样的分段多项式称为样条函数。样条函数的阶定义为各多项式中阶数最高的那个多项式的阶(阶=多项式次数+1)。一般情况下,样条函数中每个多项式都具有相同的界。多项式曲线段相连处的断点称为节点。4)B样条曲线B样条是分段多项式的一种简单表示。B样条曲线的节点是一个多项式线段结束而另一个多项式线段开始的地方。下面介绍B样条曲线的形状是如何控制的。(1)控制点(2)基函数基函数定义控制点对曲线的影响程度,哪些控制点影响曲线以及在什么地方曲线受哪个控制点的影响。(3)节点节点决定如何以及在什么地方定义基函数。(4)加权假定要使某个控制点对曲线的影响力大于其他控制点,可以为该节点赋予一个较大的权值以改变该点对曲线的影响力。(5)NURBS曲线NURBS曲线是由分段有理B样条多项式基函数定义的,具有许多有用的性质。例如,可以用NURBS准确地表示圆、抛物线、椭圆、双曲线等二次曲线。
2.2.2样条曲线的绘制
在OpenGL中,为了绘制一条样条曲线,必须先定义求值器,然后才能计算曲线上点的坐标并完成曲线的绘制。1)定义求值器在OpenGL中,定义一维求值器的函数是glMap1(),该函数的原型如下:
voidglMap1{fd}(GLenumtarget,GLfloatu1,GLfloatu2,GLintstride,GLintorder,constGLdouble*points);功能:定义一个一维求值器。参数说明:target指定由求值器所生成的值的种类。2)计算曲线坐标在OpenGL中,计算曲线坐标的函数是glEvalCoord1(),该函数的原型如下:voidglEvalCoord1{fd}[v](TYPEu);功能:求取有效的一维映射值。
参数说明:指定一个由函数glMap1定义的基础函数的域坐标u的值。此函数计算曲线上顶点的坐标,并将此坐标设置为该顶点的当前坐标。该函数每调用一次只产生一个顶点的坐标值。3)计算均匀间隔坐标在使用函数glEvalCoord1()时,由于u的取值可以是定义域中的任意值,因此得到的坐标也是任意的。在通常情况下,计算曲线坐标时,采用均匀分割定义域的方法。要得到均匀分割后的坐标值,OpenGL提供了两个函数glMapGrid1()和glE-valMesh1(),函数原型分别介绍如下:voidglMapGrid1{fd}(GLintun,TYPEu1,TYPEu2);
功能:定义一个一维的网格。
参数说明:un指定网格范围[u1,u2]之间的等份数。它必须是正整数。u1,u2指定整形网格域值i=0和i=un的映射值。
2.2.3样条曲面的绘制
样条曲面的绘制方法在原理上与样条曲线基本相同,所不同的是曲面使用二维求值器,并且控制点连接起来形成一个网格。1)定义求值器
对于曲面,求值器函数除了使用两个参数u和v外,其余与一维求值器基本相同。顶点坐标、颜色、法线矢量和纹理坐标都对应于曲面而不是曲线。在OpenGL中,定义二维求值器的函数是glMap2(),该函数的原型如下:voidglMap2{fd}(GLenumtarget,TYPEu1,TYPEu2,GLintus-tride,GLintuorder,TYPEv1,TYPEv2,GLintvstrideGLintvorder,constTYPE*points);功能:定义一个二维求值器。参数说明:target指定求值器所生成的值的种类,其取值及其意义与一维求值器类似。2)计算曲面坐标在OpenGL中,计算曲面坐标的函数是glEvalCoord2(),该函数的原型如下:voidglEvalCoord2{fd}[v](TYPEu,TYPEv);
功能:求取有效的二维映射值。参数说明:u,v指定已经由函数glMap2定义的基础函数的域坐标u和v的值。此函数计算曲面上顶点的坐标,并将此坐标设置为该顶点的当前坐标。3)计算均匀曲面坐标与一维曲线情况类似,对于二维情况,同样可以使用两个类似的函数自动生成等间隔的坐标值。在OpenGL中,计算均匀曲面坐标的函数是glMapGrid2()和glEvalMesh2(),两函数的原型如下:voidglMapGrid2{fd}(GLintnu,TYPEu1,TYPEu2,GLintnv,TYPEv1,TYPEv2);voidglEvalMesh2{fd}(GLenummode,GLinti1,GLinti2,GLintj1,GLintj2)功能:定义和计算二维网格的坐标值。参数说明:un,vn指定网格范围[u1,u2]和[v1,v2]之间的等份数。它们必须是正整数。
2.2.4NURBS曲线和曲面绘制
基于求值器的曲线和曲面绘制方法是OpenGL基本函数库中惟一直接绘制曲线和曲面的方法,可以得到硬件图形加速器的支持。OpenGL的实用函数库(GLU)提供了另外一种曲线、曲面绘图接口,即NURBS接口。这一接口同样是建立在求值器的基础上的,但更灵活,使用起来也更方便。1)NURBS的使用在OpenGL中,NURBS曲线和曲面的使用较简单,进行光照处理和纹理映射也很方便。NURBS曲线或曲面的绘制步骤如下:①如果要对曲面进行光照处理,首先要指定法线矢量。可以调glEnable(GL_AUTO_NORMAL)让OpenGL自动生成,也可以显式地指定。
②创建一个指向NURBS对象的指针,这个指针在创建NURBS曲线或曲面时要用到。
在OpenGL中,创建NURBS对象的函数是gluNewNurbsRenderer(),该函数的原型如下GLUnurbs*gluNewNurbsRenderer(void)
功能:该函数用来建立并返回一个指向新的NURBS对象的指针。
当调用NURBS的绘图和控制函数时,必须提供这个对象。当返回值是NUL时,表示没有足够的内存空间来存放这个对象
。
③设置NURBS对象的属性。
在OpenGL中,设置NURBS对象的函数是gluNurbsProperty(),该函数的原型如下:
voidgluNurbsProperty(GLUnurbs*nurb,GLenumproperty,GL-floatvalue);
功能:设置一条NURBS对象的属性。
参数说明:nurb指定NURBS对象。property指定要设置的属性。
2.2.5二次曲面
OpenGL实用函数库中提供了一些利用二次曲面技术绘制几何图形(如球体、圆柱体等)的函数,下面介绍几个比较常用的函数:1)创建二次曲面在OpenGL中,创建二次曲面的函数是gluNewQuadric(),该函数的原型如下:CLUquadric*gluNewQuadric(void);功能:创建一个二次曲面对象。该函数用来建立并返回一个指向新的二次曲面对象的指针。当调用二次曲面的绘图和控制函数时,必须提供这个对象。当返回值是NULL时,表示没有足够的内存空间来存放这个对象。该对象使用完成后应该调用gluDeleteQuadric()函数将其删除以便释放所占用的资源。2)二次曲面对象①绘制圆柱体。②绘制圆盘。③绘制盘形的圆弧。④绘制球体。
2.3显示列表
OpenGL的显示列表(DisplayList)是由一组预先定义并储存起来可以在以后执行的OpenGL函数组成。当调用这个显示列表时,显示列表中的函数被依次执行。另外一种绘图方式是立即方式,就是给出绘图命令后,OpenGL立即执行的方式。
2.3.1显示列表概念
OpenGL定义显示列表的目的是提高应用程序的运行性能,特别是网络的性能。显示列表被设计成高速的命令缓存,而不是动态的数据缓存。因此,显示列表一旦创建,就只能删除和运行,不能修改。从而减少了管理、搜索的开销,提高了运行的性能。采用显示列表方式,通常会比立即方式要快。
在网络环境下,由于创建好的显示列表驻留在服务器上,因此当应用程序调用显示列表时,对网络通讯的压力与立即方式相比要小得多。
在单机环境下,显示列表的优势同样明显。下列场合如果应用显示列表,将有可能充分发挥显示列表的优势:1)矩阵操作
2)光栅位图和图像3)光、材质和光照模型4)纹理5)多边形的图案填充模式
2.3.2显示列表的创建
显示列表必须在创建之后才能使用,这是和函数定义不一样的地方。函数只要声明和定义之后,在需要使用的地方调用它即可;而显示列表不仅需要定义绘制代码,而且在使用之前需要调用这段建立显示列表的程序。 OpenGL提供类似于描述基本图元的格式,即函数glBegin()和函数glEnd()的成对形式来创建显示列表。OpenGL创建显示列表使用的函数是glNewList()和glEndList(),相应的函数原型如下:voidglNewList(Gluintlist,GLenummode);功能:建立或替换一个显示列表。
2.3.3显示列表的执行
一旦成功地创建了一个显示列表,就可以在后续的程序中多调用该显示列表。调用显示列表的函数是glCallList(),该函数的原型如下:voidglCallList(Gluintlist);功能:执行一个显示列表。参数说明:list指定要执行的显示列表的名称。如果list所标识的显示列表没有定义,则不产生任何操作。
2.3.4多重显示列表
OpenGL提供了一种有效的机制来依次执行多个显示列表。这种机制需要将显示列表索引放入一个数组中,并调用glCallLists()函数。当显示列表索引与有意义的值相对应时,就可以使用多重显示列表来进行处理。
在创建多重显示列表时,需要知道不同显示列表的正确索引值。OpenGL提供了函数glListBase()来指定显示列表的初始索引,该函数的原型如下:voidglListBase(GLuintbase);功能:为函数glCallLists设置显示列表的基值。
2.3.5显示列表索引
如果需要删除某个特定的显示列表,则可以使用glDeleteLists()函数。函数的原型分别介绍如下:GLuintglGenLists(GLsizeirange);功能:建立一组连续的空显示列表。参数说明:range指定要产生的连续的空显示列表的数目。
2.3.6显示列表的嵌套
显示列表的嵌套,就是在一个显示列表中调用另一个显示列表,即在函数glNewList()与函数glEndList()之间,调用了函数glCallList()。显示列表的嵌套对于构造由多个元件组成的物体非常有用,尤其是某些元件需要重复使用的时候。为了避免陷入无限递归,显示列表的嵌套深度限制为64层(不同平台的定义略有不同),可以通过调用函数glGetIntegerv()来获取显示列表的最大嵌套深度。
2.3.7实例介绍
下面介绍一个如何使用显示列表的实例,该实例是基于控制台运行模式的,在该程序中首先利用显示列表绘制若干个三角形,然后绘制一条直线。
2.4位图、图像与文本绘制
在OpenGL中,除了基本图元(点、线段和多边形)外,还有另外两种图元类型:位图和图像。文本绘制基本上就是上述两种图元的扩展。这两种图元数据都是以像素矩阵的形式存储,即通过一个像素的矩阵数组来表示一个位图或图像。两者的不同之处在于,位图包含每个像素的一位信息,而图像数据一般包括每个像素的多位信息(例如:红、绿、蓝和alpha值);另外,位图类似于掩码,可用于遮掩其他的已经存在的图像,而图像数据则简单地覆盖原先已经存在的数据或者与之融合。
2.4.1位图
一幅位图是窗口上一块矩形区域中的像素,位图数据是一个由0和1组成的二维数组,每一位对应位图中一个像素。当位图数据中的某位为1时,窗口上相应位置的像素以当前颜色显示出来;当某位为0时,相应的像素不变。1)数据格式位图数据的格式使用OpenGL的像素存储格式,控制像素存储格式的函数是glPixelStore(),该函数的原型如下:voidglPixelStore{fi}(GLenumpname,TYPEparam);功能:设置像素存储模式。2)光栅坐标位图按光栅图像的方式绘制,其坐标为光栅坐标。为了使光栅坐标与屏幕上的像素相对应,OpenGL提供了最底层的函数glRasterPos(),该函数的原型如下:voidglRasterPos{234}{sifd}[v](TYPEx,TYPEy,TYPEz,TYPEw);功能:指定像素操作的光栅位置。3)绘制位图当设置了光栅位置后,就可以调用函数glBitmap()来显示位图,该函数的原型如下:glBitmap的函数原型如下: voidglBitmap(GLsizeiwidth,GLsizeiheight,GLfloatxorig,GLfloatyorig,GLfloatxmove,GLfloatymove,constGlubyte*bitmap);
功能:绘制一个位图。
参数说明:width,height指定一个位图的宽度和高度。
2.4.2图像
图像与位图的不同之处在于:图像的每一个像素不止用一位表示。例如,对于RGBA颜色模式下的彩色图像,其中的每一个像素都存储有完整的RGB信息。
在OpenGL中,可以直接操作帧缓冲区和内存中的图像数据。主要的操作有:从帧缓冲区中读取图像,向帧缓冲区中绘制图像,从帧缓冲区中复制图像以及缩放图像。1)像素读取OpenGL提供了函数glReadPixels()进行最基本的像素读取操作,该函数的原型如下:voidglReadPixels(GLintx,GLinty,GLsizeiwidth,GLsizeiheight,GLenumformat,GLenumtype,GLvoid*pixels);功能:从帧缓冲区中读出一个像素块。2)像素绘制OpenGL提供了函数glDrawPixels()进行最基本像素绘制操作,该函数的原型如下:voidglDrawPixels(GLsizeiwidth,GLsizeiheight,GLenumformat,GLenumtype,GLvoid*pixels);功能:向帧缓冲区写入一个像素块。参数说明:width,height指定要写入帧缓冲区中的像素矩形的尺寸。3)像素复制OpenGL提供了函数glCopyPixels()进行最基本像素复制操作,该函数的原型如下:voidglCopyPixels(GLintx,GLinty,GLsizeiwidth,GLsizeiheight,GLenumtype);功能:向帧缓冲区中拷贝像素。参数说明:x,y指定被拷贝的像素矩形区域的左下角的窗口坐标。4)像素缩放
一般情况下,图像中的每一个像素对应窗口中的一个点。也可以任意地缩小和放大图像。OpenGL提供了函数glPixelZoom()进行像素缩放操作,该函数的原型如下:voidglPixelZoom(GLfloatxfactor,GLfloatyfactor);功能:指定像素的缩放比例因子。参数说明:xfactor,yfactor指定对像素进行写操作时的x和y缩放比例因子。
2.4.3文本
在双颜色缓冲区模式下,不能在OpenGL绘图设备上使用Windows的GDI字体管理和文本输出函数,因此也就无法实现字符串的显示。为了解决这个问题,WGL提供了两个函数wglUseFontBitmaps()和wglUseFontOutlines()分别用于位图文本和轮廓文本的输出。由于这两个函数是Win32函数,必须使用Windows的窗口系统进行编程。1)位图文本
在双缓冲区模式下显示文本的方法是:将文本中的每一个字符当做一个普通的OpenGL物体看待和处理,显示字符之前,先为每个字符创建一个显示列表,然后通过执行显示列表完成字符的输出。OpenGL提供创建位图字符显示列表的函数是wglUseFontBitmaps()BOOLwglUseFontBitmaps(HDChdc,DWORDfirst,DWORDcount,DWORDlistBase);功能:为从first(字符编码)开始的count个字符分别创建一个显示列表。2)轮廓文本在双缓冲区模式下显示轮廓文本的方法与显示位图文本基本相同。与位图文本不同的是,轮廓文本是使用二次B样条曲线描述的。OpenGL提供创建轮廓字符显示列表的函数是wglUseFontOutlines(),该函数的原型如下:BOOLwglUseFontOutlines(HDChdc,DWORDfirst,DWORDcount,DWORDlistBase,FLOATdeviation,FLOATextrusion,intformat,LPGLYPHMETRICSFLOATlpgmf);功能:为从first(字符编码)开始的count个字符分别创建一个显示列表。3)实例介绍
利用轮廓文本很容易实现3d文本的显示,下面介绍一个简单的实例来显示一个3d的字符串,该程序是基于Win32运行模式的,这一部分代码的框架可以参考第1章的1.5.3节。
2.5本章小结与习题
2.5.1重点回顾图元是各类图形构成的基础。OpenGL中提供了各类基础图元构建的方法。通过实践掌握OpenGL图元各函数功能、作用及函数参数的意义。2.5.2课后练习1、OpenGL图形构建的方式有那些?2、OpenGL颜色控制模式及定义?2.5.3实训技能训练目的:进一步熟悉OpenGL的开发环境配置方法掌握OpenGL基础图元的构建模式熟悉VC/VC.net的程序框架与流程技能训练内容使用OpenGL绘制一个地球、月亮和太阳的模型。建议通过查资料用MFC来实现。
第3章
坐标变换
☆学习三维模型在绘制到二维屏幕之前如何进行变换。☆学习坐标系与坐标变换☆学习矩阵操作、平移变换、旋转变换、缩放变换、变换次序等☆学习控制这些变换的方法,显示模型的特定视图。
OpenGL提供了计算机图形学中最基本的三维变换,包括:视点变换、模型变换、投影变换、剪取变换(附加裁剪面)和视口变换等。同时OpenGL还有针对性地提供了一些特殊的变换和用法,如矩阵堆栈等。
3.1从三维图形到二维图像
3.1.1三维图形的输出过程
在现实世界中,观察到的所有物体对象都具有三维特征。但是在计算机屏幕上只能表现二维图像。那么,在三维图形到二维平面之间,需要什么样的变换,才能真实地反映现实世界呢?
3.1.2坐标系与坐标变换
为了能在计算机上显示三维图形,必须使其适应计算机。因为计算机只能处理数据,因此必须将三维图形与数据相联系。而将数据与三维图形联系在一起的惟一纽带,就是坐标。从现实三维世界中获取的三维对象,本身是包含了现实世界的坐标形式。这个坐标系称之为世界坐标系。而屏幕上的二维平面本身又定义了一个坐标系,称为屏幕坐标系。三维图形映射到二维平面上,最重要的一环就是投影。投影分为透视投影和正交投影两种。投影平面对应的三维空间称为三维视景体(ViewingVolume)。只有在视景体内的三维物体才可能投影到二维平面上。在屏幕坐标系中,可以定义一个矩形,称为视口,视景体投影后的图形就在视口中显示出来。视口的坐标系与物理设备的坐标系之间可能还存在差异,因此还需要做一些适应物理设备的坐标变换。物理设备的坐标系称为物理设备坐标系。
3.1.3矩阵操作
OpenGL提供了丰富的三维变换函数,用户可以运用这些三维变换函数自如地进行三维图形操作,同时OpenGL还提供了一系列矩阵操作函数,帮助用户自己定义变换。下面先介绍这些矩阵操作函数。1)设置矩阵类在OpenGL中,设置矩阵类型的函数是glMatrixMode(),该函数的原型如下:voidglMatrixMode(GLenummode);功能:设置当前矩阵。2)装入矩阵在OpenGL中,装入矩阵的函数是glLoadMatrix(),该函数的原型如下:voidglLoadMatrix{fd}(TYPE*m);功能:用指定的矩阵替换当前矩阵。3)装入单位矩阵在OpenGL中,装入单位矩阵的函数是glLoadIdentity(),该函数的原型如下:voidglLoadIdentity(void);功能:用单位矩阵替换当前的矩阵。4)矩阵相乘在OpenGL中,矩阵相乘的函数是glMultMatrix(),该函数的原型如下:voidglMultMatrix{fd}(TYPE*m);功能:用指定的矩阵乘以当前的矩阵。
3.2几何变换
几何变换是指三维场景中的物体运动姿态的变化,包括物体的平移、旋转和缩放。在OenGL中提供了3个命令函数来实现平移、旋转和缩放,它们是glTranslate(),glRotate(),glScale(),从而可以确定一个物体在场景中的位置、旋转角度和缩放比例。直接使用OpenGL中的矩阵操作函数可以实现几何变换,但是使用OpenGL中的变换函数,变换的速度要快得多。
3.2.1平移变换
为了便于建模,通常以物体坐标系缺省的原点作为模型的初始位置,建模完成后再将物体移至它在场景中应处的位置。在OpenGL中,物体的移动是用平移变换函数glTranslate()来完成的,函数原型如下:voidglTranslate{fd}(TYPEx,TYPEy,TYPEz);功能:把当前矩阵乘上一个平移矩阵。glTranslate()函数可以作用于几何矩阵、投影矩阵和纹理坐标变换矩阵。如果当前矩阵为几何矩阵,函数的功能则是将物体坐标系的原点移到(x,y,z)所指的位置,形成新的物体坐标系。调用此函数之后的所有顶点的坐标都以新的位置作为原点。换句话说,平移之后所画的几何物体都做了相同的平移。glTranslate()函数平移的是坐标系而不是物体,如图3.2所示。该函数仅影响在它被调用之后所绘的物体。如果使用(0,0,0)作为参数调用该函数,则不产生任何平移。
3.2.2旋转变换
在OpenGL中,进行旋转变换的函数是glRotate(),该函数的原型如下:voidglRotate{fd}(TYPEangle,TYPEx,TYPEy,TYPEz);功能:把当前矩阵乘上一个旋转矩阵。参数说明:angle指定旋转角度,其单位是“度”(°)。X,y,z分别指定一个向量的x,y和z坐标。函数glRotate()的作用是绕向量(x,y,z)产生一个angle角度的旋转。当前矩阵将被它与一个旋转矩阵相乘后所得的矩阵所替代。
3.2.3缩放变换
在OpenGL中,进行缩放变换的函数是glScale(),该函数的原型如下:voidglScale{fd}(TYPEx,TYPEy,TYPEz);功能:当前矩阵乘以一个普通的缩放矩阵。参数说明:x,y,z分别指定沿x,y和z轴方向的缩放因子。当前矩阵将被它与这个缩放矩阵相乘的结果所替换。
3.2.4变换次序
在OpenGL中,平移、旋转和缩放变换的组合使用会产生复杂的变换效果,但是必须注意变换的先后次序,因为不同的变换次序会导致不同的效果。
3.2.5实例介绍
下面介绍一个应用几何变换的例子,从该例子中可以清晰地分辨出,对一个三角形实施的平移变换、缩放变换和旋转变换的痕迹。
3.3投影变换投影变换的目的是将三维场景中的物体投影到二维平面上,这个二维平面就是显示窗口。投影变换定义一个取景器,该取景器决定物体是如何投影到窗口平面上的,并且它还定义了哪些对象或物体的哪些部分从最终的图像中剪切出去。投影变换同样是使用矩阵变换来实现的,与几何变换不同的是它使用投影矩阵,因此在进行投影变换之前必须调用glMatrixMode(GL_PROJECTION)函数将当前矩阵的类型设置为投影矩阵。投影变换有两种,一种是透视投影,这种投影得到的效果与人眼观察世界的效果相同;另一种是正交投影,它的最大特点是无论物体距离视点多远,投影后的尺寸不变。在执行投影变换命令之前,必须调用下面的函数,将变换矩阵设置为投影变换矩阵:glMatrixMode(GL_PROJECTION);//阵模式为投影变换矩阵glLoadIdentity();
3.3.1透视投影
透视投影的取景器被设计成一个被截去了顶的四面锥体,因此取景器又称为观察锥。落在取景器内的物体朝着观察锥的顶点的方向投影,观察锥的顶点就是视点,靠近视点的平面称为近剪切面,观察锥的底称为远剪切面。观察锥的底平行于xOy平面,并向z轴负方向延伸。同样尺寸的物体,离视点越近就显得越大,这是因为它们比那些远处的物体占据的取景器空间的比例更大。这种投影方式与人眼的工作方式相似,因此常被用于动画、视觉模拟等场合。在OpenGL中,定义取景器有2个函数:glFrustum()和gluPerspective()。1)glFrustum()在OpenGL中,glFrustum()的函数原型如下:voidglFrustum(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublezNear,GLdoublezFar);功能:用一个透视矩阵乘以当前的矩阵。参数说明:left,right指定左、右垂直剪切平面的坐标。bottom,top指定下、上水平剪切平面的坐标。zNear,zFar指定视点到最近和最远深度剪切平面的距离。二者必须是正数。2)gluPerspective()在OpenGL中,luPerspective()函数的原型如下:voidgluPerspective(GLdoublefovy,GLdoubleaspect,GLdoublezNear,GLdoublezFar);功能:立一个透视投影矩阵。参数说明:ovy指定y方向的取景区域的角度,值范围为[0°,180°]。aspect指定x方向的用来确定取景区域的高宽比。高宽比是x(宽度)与y(高度)的比率。zNear指定视点到最近的裁剪平面的距离(它必须是正数)。zFar指定视点到最远的裁剪平面的距离(它必须是正数)。
3.3.2正交投影
正交投影的取景器是一个封闭的平行六面体。与透视投影不同,从一端到另一端,取景器的大小不改变,因此同样尺寸的物体,距离视点近的物体与离视点远的物体经投影后,它们的大小仍然是相同的。这类投影通常用于CAD等领域。在OpenGL中设置正交投影的函数是glOrtho(),该函数的原型如下:voidglOrtho(GLdoubleleft,GLdoubleright,GLdoublebottom,GLdoubletop,GLdoublezNear,GLdoublezFar);功能:一个正交矩阵乘以当前矩阵。
3.4视窗变换视窗变换类似于照片冲洗过程中的照片裁剪。在计算机图形学中,视窗是绘制图像的矩形区域。视窗以窗口坐标来定义,它表示图像相对于窗口左下角的位置。进行视窗变换时,所有顶点都已经过几何变换和投影变换,并且位于取景器之外的图像已被剪切掉了。
3.4.1定义视窗
打开一个窗口时,系统自动地将视口设置为整个窗口的大小。在OpenGL中可以用glViewport()函数来设置一个较小的绘图区,该函数的原型如下:voidglViewport(GLintx,clinty,GLsizeiwidth,GLsizeiheight);功能:设置视口。视口的宽度和高度被默认地截断到一定的范围,具体范围值由所处环境决定。可调用函数glGet(GL_MAX_VIEWPORT_DIMS)查询这一范围值。视口的高宽比一般应与投影取景器的高宽比相同,否则会造成图像的变形。在程序的运行过程中,可能会改变窗口的大小,因此程序应该能够检测到这种变化,并作相应的处理。
3.4.2变换z坐标
在视口变换中,z坐标或深度坐标被编码并被存储起来。在OpenGL中可以使用glDepthRange()函数缩放z坐标的值,使它位于所要求的范围内。该函数的原型如下:voidglDepthRange(GLclampedzNear,GLclampedzFar);功能:指定一种从归一化深度坐标到窗口深度坐标的映射方法。
3.5附加裁剪面
附加裁剪面可用于显示物体的剖面图等情况。每个裁剪面是通过指定方程Ax+By+Cz+D=0中的系数来确定。裁剪面通过模型和视点变换自动进行相应的变换。最后的裁剪体成为视图体和附加裁剪面所定义的半空间的交集。OpenGL会适当地重建被自动剪切的多边形的边。在OpenGL中,定义附加裁剪面的函数是glClipPlane()。该函数的原型如下:voidglClipPlane(GLenumplane,constGLdouble*equation);功能:指定一个剪切几何体所用的平面。
3.6矩阵堆栈
堆栈在计算机中表示先入后出的内存区域。而OpenGL中的矩阵堆栈,也是以这种方式管理的,专门用于存储矩阵的内存区域,只不过该堆栈中存放的数据单元是矩阵。OpenGL中管理内存堆栈的函数是glPushMatrix()和glPopMatrix(),函数的原型如下:voidglPushMatrix(void);voidglPopMatrix(void);功能:压入和弹出当前矩阵堆栈。下面介绍一个3个齿轮相互啮合运动的实例,说明了矩阵堆栈的用法。该实例基于控制台运行模式,详细的源代码请参考本书,部分关键源代码介绍如下:1)齿轮绘制函数。该函数主要根据齿轮的参数,如内孔直径、最大外径和齿轮宽度进行齿轮的绘制。2)场景绘制函数。在该函数中主要通过调用显示列表的模式绘制出3个齿轮,为了控制不同齿轮的绘制位置,采用了压入和弹出矩阵堆栈的形式。3)空闲响应函数。在该函数中使齿轮的角度递增,从而产生动画效果。4)键盘响应函数。在该函数中主要处理了z和Z键以及LEFT,RIGHT,UP,DOWN键的响应代码。
第4章OpenGL颜色
☆RGBA显示模式☆颜色索引模式☆RGBA模式与颜色索引模式的对比☆抖动操作
☆指定阴影模型
OpenGL是用来描述真实三维世界的,没有了颜色也就不可能真实地再现现实世界。颜色是一门非常复杂的学科,涉及到数学、物理学、心理学和美学等多个领域。这里仅讨论与计算机图形学有关的部分。
物体的颜色不仅取决于物体本身,它还与光源、周围环境的颜色,以及观察者的视觉系统都有关系。
4.1RGBA模式与颜色索引模式
4.1.1RGBA模式与颜色索引模式的对比
在一台计算机彩色显示器上,电子枪使荧屏上的每个像素发出不同量的红、绿、蓝光,称为R,G,B值。这些值通常被组装在一起(有时加入第4个值,称为alpha),合起来称为RGB(或RGBA)值。每个像素的颜色信息,可以用RGB(或RGBA)方式存储,也可以用颜色索引方式存储。颜色索引方式指每个像素的颜色信息存储单个值(称为颜色索引)。每个颜色索引定义一组R,G,B值,作为表中的一项。这种表称为查色表,表中的值可以改变。准确地回忆颜色对于每个人来说都是很困难的,即使对非常了解的对象的颜色也是如此。光照的位置或强度不同时,颜色也会不同。为了清楚起见,一种颜色通常可以用它3种属性来描述:色调(hue)、饱和度(saturation)和亮度(lightness)。在OpenGL中通常使用2种颜色模式,即RGBA模式和颜色索引模式。在颜色索引模式下,对每个像素存储一定数量的颜色数据。这个量是由帧缓存中的位平面数所确定的,也就是通常说的多少位颜色。如果有8个颜色位平面,则每个像素有8个颜色位,从而对像素可以存储2=256种不同的颜色。现在的图形硬件,一般都支持高达32位颜色位面,通常对R,G,B,A都分配8位,但并非一定得如此。可以调用glGetIntegerv()函数,将参数分别设置为:GL_RED_BITS,GL_GREEN_BITS,GL_BLUE_BITS,GL_ALPHA_BITS,GL_INDEX_BITS,来查询有关R,G,B,A或颜色索引值的位面数。
4.1.2RGBA显示模式
在RGBA颜色模式中,每个像素的R,G,B,A分量被分别保存,其中A分量称为alpha,主要用于图像的融合和深度控制。为了适应不同的图形硬件,OpenGL使用浮点数表示RGBA各分量的值,取值范围从0.0或-1.0到1.0。这种表示方式的好处是不必考虑位面的数目,0.0表示该分量的最小强度,1.0表示最大强度。图形硬件系统只需简单地乘上位面数就可以将浮点数表示的强度值转换成电子束的强度值。在OpenGL中,系统时刻保存着系统使用的当前颜色,并且只使用当前颜色绘图。缺省的当前颜色为白色(1.0,1.0,1.0),可以使用glColor()函数改变当前的颜色,该函数的原型如下:voidglColor3{bsifdubusui}(TYPEred,TYPEgreen,TYPEblue);voidglColor4{bsifdubusui}(TYPEred,TYPEgreen,TYPEblue,TYPEalpha);voidglColor3{bsifdubusui}v(constTYPE*v);voidglColor4{bsifdubusui}v(constTYPE*v);功能:设置当前的绘图颜色。
4.1.3抖动操作
有些图形硬件使用抖动来增加可以显示的颜色数量。为了说明拉动的工作原理,假定系统分别只用1个位来表示RG和B。这样,它一共可以显示8种颜色:黑、白、红、蓝、绿、黄、青和洋红。为了一块粉红色的区域,图形硬件仍然采用前面那种棋盘模式的方法,用红色和白色交替对像素进行着色。如果眼睛距离屏幕足够远,不能看到单独的像素,这块区域看上去就是粉红色的,也就是红色和白色的均值。深一点的粉红色可以通过提高红色像素的比例来实现,淡一点的粉红色可以通过提高白色像素的比例来实现。
4.1.4颜色索引显示模式
在颜色索引模式中,每个像素只保存一个颜色索引号,系统有一张颜色索引表,该表保存每一个索引号和与之对应颜色的R,G,B值。这样的颜色索引表称为颜色映射(ColorMap)。在OpenGL中的颜色索引模式下,指定颜色的函数是glIndex(),该函数的原型如下:voidglIndex{sifdub}(TYPEc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电子商务教师资格证考试模拟题试题及答案
- 企业员工心理援助合同范本
- 冷链物流服务合同协议书
- 10我们不乱扔 (教学设计)统编版道德与法治二年级上册
- 初中语文衬托课件
- 《线段、直线、射线和角》(教学设计)-2024-2025学年四年级上册数学人教版
- 保险行业分析与展望
- 全员安全知识培训课件
- 小学防控疫情课件
- 2025商场租赁意向协议合同
- 新东方在国际教育领域的布局与市场机会
- 2025年上半年海口市美兰区水务局下属事业单位招考易考易错模拟试题(共500题)试卷后附参考答案
- 2025届高三化学二轮复习 化学反应原理综合 课件
- 2025年公务车辆租赁管理合同范本
- 2025年会计招聘的面试题及答案
- 9.3.2《设计简单装置制作酸奶》跨学科实践主题学习单元教学设计
- 2025年工程测量员(技师)职业技能鉴定理论考试指导题库(含答案)
- 盈浦街道村务工作者招聘真题2024
- 金属熔融岗位培训课件
- 2025年车驾管知识题库查验业务知识考试题(附答案)
- 2025年度高端养生按摩店合伙人合作协议
评论
0/150
提交评论