




已阅读5页,还剩33页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1.Windows操作系统对OpenGL的支持 具有Windows编程经验的人都知道,在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数;用OpenGL作图也是类似,OpenGL函数是通过渲染上下文(RenderingContext简写RC)完成三维图形的绘制。Windows下的窗口和设备上下文支持位图格式(PIXELFORMAT)属性,和RC有着位图结构上的一致。只要在创建RC时与一个DC建立联系(RC也只能通过已经建立了位图格式的DC来创建),OpenGL的函数就可以通过RC对应的DC画到相应的显示设备上。创建RC的过程如下: 获取一个DC 选择并且设置DC的像素格式 通过API:wglCreateContext(DC)创建一个RC 设置当前的RC,通过API:wglMakeCurrent(RC, DC)来设置.实现释放或者选择其它RC: 调用API:wglMakeCurrent(NULL, NULL)使DC不再有RC。 调用API:wglMakeCurrent(AnotherRC, DC)选择其他RC为当前RC,一般情况下,我们都是一个RC对应一个DC,当然,在某些场合里面是可以有多个RC。 调用API:wglDeleteContent(RC) 直接删除,这个方法比较直截了当。 这里还有以下需要注意的方面: 1.一个线程只能拥有一个渲染上下文(RC),也就是说,用户如果在一个线程内对不同设备作图,只能通过更换与RC对应的DC来完成,而RC在线程中保持不变。(当然,删除旧的RC后再创建新的是可以的)与此对应,一个RC也只能属于一个线程,不能被不同线程同时共享。 2.设定DC位图格式等于设定了相应的窗口的位图格式,并且DC和窗口的位图格式一旦确定就不能再改变。这一点只能期望以后的Windows版本改进了。 3.一个RC虽然可以更换DC,在任何时刻只能利用一个DC(这个DC称为RC的当前DC),但由于一个窗口可以让多个DC作图从而可以让多个线程利用多个RC在该窗口上执行OpenGL操作。 4.现在的Windows下的OpenGL版本对OpenGL和GDI在同一个DC上作图有一定的限制。当使用双缓存用OpenGL产生动画时,不能使用GDI函数向该DC作图。 5.不建议用ANSIC在Windows下编写OpenGL程序。这样的程序虽然具有跨平台的可移植性(比如很多SI的例子程序),但是它们不能利用 Windows操作系统的很多特性,实用价值不大。2.用VC来编写OpenGL程序经过上面的分析,用VC来调用OpenGL作图的方法就很显然了。步骤如下: 1.先设置显示设备DC的位图格式(PIXELFORMAT)属性。这通过填充一个PIXELFORMATDESCRIPTOR的结构来完成(关于PIXELFORMATDESCRIPTOR中 各项数据的意义,请参照VC的帮助信息),该结构决定了OpenGL作图的物理设备的属性,比如该结构中的数据项dwFlags中PFD_DOUBLEBUFFER位如果没有设置(置1),通过该设备的DC上作图的OpenGL命令就不可能使用双缓冲来做动画。有一些位图格式(PIXELFORMAT)是DC支持的,而有一些DC就不支持了。所以程序必须先用ChoosePixelFormat来选择DC所支持的与指定位图格式最接近的位图格式,然后用SetPixelFormat设置DC的位图格式。 2.利用刚才的设备DC建立渲染上下文RC(wglCreateContext),使得RC与DC建立联系(wglMakeCurrent)。 3.调用OpenGL函数作图。由于线程与RC一一对应,OpenGL函数的参数中都不指明本线程RC的句柄(handle) 4.作图完毕以后,先通过置当前线程的RC为NULL(:wglMakeCurrent(NULL,NULL);),断开当前线程和该渲染上下文的联系,由此断开与DC的联系。此时RC句柄的有效性在微软自己的文档中也没有讲清楚,所以在后面删除RC的时候要先判断以下RC句柄的有效性(f(m_hrc):wglDeleteContext(m_hrc);)。再根据情况释放(ReleaseDC)或者删除(DeleteDC)DC 。3.一些说明 1.一旦设定了一个DC的位图格式,该DC所联系的窗口的位图格式随之设定。该窗口若含有子窗口或者有兄弟窗口,这些兄弟/子窗口的位图格式没有设成与对应RC一致的格式,OpenGL在它们上面作图就容易出错。故而OpenGL作图的窗口必须具有WS_CLIPCHILDREN和WS_CLIPSIBLINGS风格,程序中在主框窗的构造函数中用LoadFrame(IDR_MAINFRAME,WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,NULL,NULL);指定了主窗口的风格。 2.在ANSIC的OpenGL编程中,由auxReshapeFunc定义设置OpenGL视口大小和作图尺寸的回调函数。在MFC中应该由WM_SIZ消息的处理函数来完成。在ANSIC的OpenGL编程中,由EauxMainLoop定义作图的回调函数。在MFC中应该由WM_PAINT消息的处理函数来处理。相应的,由OpenGL定义的键盘、鼠标处理函数都应该由相应的Windows处理函数来响应。 3.OpenGL自己有刷新背景的函数glClear,故而应禁止Windows刷新窗口背景。否则,当窗口需要重画时,Windows会自动先发送WM_ERASEBKGND ,而缺省的处理函数使用白色的背景刷。当OpenGL使用的背景颜色不是白色时,作图时有一帧白色的闪烁。这种现象在做动画时特别明显。程序中只需要在WM_ERASEBKGND的消息处理函数中禁止父窗口类的消息处理,简单的返回一个TRUE即可。 4.由于OpenGL的跨平台性,它必须用操作系统的调色板。所以如果GL_INDEX_MODE作图时,必须用VC自己定义调色板。不过一般情况下,用GL_RGBA_MODE模式比较方便,很少用到GL_INDEX_MODE模式。 5.在OpenGL作图期间,RC对应的DC不能删除或者释放。 6.由于OpenGL作图时需要长时间占用DC,所以最好把作图窗口类设成CS_OWNDC。MFC缺省的窗口类风格中没有设这一属性,程序中在主窗口C+ 类的PreCreateWindow方法中自己注册了一个窗口类,除了设定了CS_OWNDC属性以外,还设定了CS_HREDRAW、CS_VREDRAW和CS_SAVEBITS。设定CS_HREDRAW、CS_VREDRAW是为了让窗口缩放时产生WM_PAINT消息,修正OpenGL视口和作图尺寸;由于OpenGL作图需要很多计算,设定CS_SAVEBITS是为了在OpenGL窗口被遮盖后显现出来时,不产生WM_PAINT消息,用内存存储的图象来填充,从而用空间消耗换取计算时间。 7.本程序中没有对OpenGL函数的出错情况作出处理。OpenGL出错后返回错误码,不会抛出异常;而且在某一个函数出错以后,后继函数也一般不会出现异常,只是返回错误码,一不小心就可能忽略某些错误。而对每一个OpenGL函数都做出错与否的判断比较麻烦,所以编程序时对OpenGL的函数应当非常小心。4.像素格式像素格式是OpenGL窗口的重要属性,它包括是否使用双缓冲,颜色位数和类型以及深度位数等。像素格式可由Windows系统定义的所谓像素格式描述子结构来定义(PIXELFORMATDESCRIPTOR),该结构定义在windows.h中。在该结构中包含有26个属性信息,其形式为:typedef struct tagPIXELFORMATDESCRIPTORWORD nSize;WORD nVersion;DWORD dwFlags; /如果使用了双缓冲,则需要在绘制代码结束后使用SwapBuffers(HDC hDc)换页BYTE iPixelType;BYTE cColorBits;BYTE cRedBits;BYTE cRedShift;BYTE cGreenBits;BYTE cGreenShift;BYTE cBlueBits;BYTE cBlueShift;BYTE cAlphaBits;BYTE cAlphaShift;BYTE cAccumBits;BYTE cAccumRedBits;BYTE cAccumGreenBits;BYTE cAccumBlueBits;BYTE cAccumAlphaBits;BYTE cDepthBits;BYTE cStencilBits;BYTE cAuxBuffers;BYTE iLayerType;BYTE bReserved;DWORD dwLayerMask;DWORD dwVisibleMask;DWORD dwDamageMask; PIXELFORMATDESCRIPTOR;各变量的含义如下:nSize:该结构所占内存空间。nVersion:版本号,当前为1。dwFlags:指定像素格式属性,可选参量如表1.1所示。 像素格式属性标识符 解释PFD_DRAW_TO_BITMAP 支持内存中绘制位图PFD_DRAW_TO_WINDOW 支持屏幕绘图PFD_DOUBLEBUFFER 支持双缓冲PFD_CENERIC_FORMAT 指定选择GDI支持的像素格式PFD_NEED_PALETTE 指定需要逻辑调色板PFD_NEED_SYSTEM_PALETTE 指定需要硬件调色板PFD_STEREO NT不支持PFD_SUPPORT_OPENGL 支持OpenGLPFD_SUPPORT_GDI 支持GDI,此时不可使用PFD_DOUBLEBUFFERiPixelType:像素颜色模式,可选项为PFD_TYPE_RGBA或PFD_TYPE_INDEX,分别对应于RGBA模式和颜色索引模式。cColorBits:指定颜色的位数。cRedBits:采用RGBA模式时,红色组分占用位数。cRedShift:采用RGBA模式时,红色组分偏移量。cGreenBits:采用RGBA模式时,绿色组分占用位数。cGreenShift:采用RGBA模式时,绿色组分偏移量。cBlueBits:采用RGBA模式时,蓝色组分占用位数。cBlueShift: 采用RGBA模式时,蓝色组分偏移量。cAlphaBits:采用RGBA模式时,Alpha组分占用位数。cAlphaShift:采用RGBA模式时,Alpha组分偏移量。cAccumBits:指定累积缓冲区表示一个像素所用位数。cAccumRedBits:指定累积缓冲区表示红色组分占用位数。cAccumGreenBits:指定累积缓冲区表示绿色组分占用位数。cAccumBlueBits:指定累积缓冲区表示蓝色组分占用位数。cAccumAlphaBits:指定累积缓冲区表示Alpha组分占用位数。cDepthBits:指定深度缓冲区表示一个像素所用位数。cStencilBits:指定模板缓冲区表示一个像素所用位数。cAuxBuffers:指定辅助缓冲区,Windows9x、NT不支持。iLayerType:Windows9x、NT下只能是PFD_MAIN_PLANE。bReserved:0。dwLayerMask:指定覆盖层的屏蔽,Windows9x、NT不支持。dwVisibleMask:Windows9x、NT不支持。dwDamageMask:Windows9x、NT不支持。Windows提供了四个像素格式管理函数,分别介绍如下:(1) int ChoosePixelFormat(HDC hdc,PIXELFORMATDESCRIPTOR *ppdf)该函数比较传过来的像素格式描述和OpenGL支持的像素格式,返回一个最佳匹配的像素格式索引。该索引值可传给SetPixelFormat为DC设置像素格式。返回值为0表示失败。在比较像素格式时,匹配优先级顺序为像素格式描述子结构中的下述各域:dwFlagscColorBitscAlphaBitscAccumBitscDepthBitscStencilBitscAuxBuffersiLayerType硬件支持的像素格式优先。(2) int DescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes,LPPIXELFORMATDESCRIPTOR *ppfd)该函数用格式索引iPixelFormat说明的像素格式来填写由ppfd所指向的像素格式描述子结构,利用该函数可以枚举像素格式。(3) int GetPixelFormat(HDC hdc)该函数用于获取hdc的格式索引。(4) BOOL SetPixelFormat(HDC hdc, int iPixelFormat,LPPIXELFORMATDESCRIPTOR *ppfd)该函数用格式索引iPixelFormat来设置hdc的像素格式。在使用该函数之前应该调用ChoosePixelFormat来获取像素格式索引。另外,OpenGL窗口风格必须包含WS_CLIPCHILDREN和WS_CLIPSIBLINGS类型,否则设置失败。应该注意的是ChoosePixelFormat函数并不一定返回一个最佳的像素格式值,可以利用DescribePixelFormat来枚举系统所支持的所有像素格式。OpenGL的通常支持24种不同的像素格式,如果系统安装了OpenGL硬件加速器,它可能会支持其它的像素格式。人们对三维图形技术的研究已经经历了一个很长的历程,而且涌现了许多三维图形开发工具,其中SGI公司推出的GL(Graphics Library)三维图形库表现尤为突出,它易于使用且功能强大。随着计算机技术的迅速发展,GL已经进一步发展成为OpenGL,现在OpenGL被认为是高性能图形和交互式视景处理的标准。OpenGL(即开放性图形库Open Graphics Library),是一个三维的计算机图形和模型库,最初是美国SGI公司为图形工作站开发的一种功能强大的三维图形机制(或者说是一种图形标准)。它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。SGI在1992年7月发布1.0版,后成为工业标准,由成立于1992年的独立财团OpenGL Architecture Review Board (AR控制。SGI等ARB成员以投票方式产生标准,并制成规范文档(Specification)公布,各软硬件厂商据此开发自己系统上的实现。只有通过了ARB规范全部测试的实现才能称为OpenGL。1995年12月ARB批准了1.1版本,最新版规范是1999年5月通过的1.2.1。OpenGL被设计成独立于硬件,独立于窗口系统,在运行各种操作系统的各种计算机上都可用,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库。它低端应用上的主要竞争对手是MS-Direct3D,该图形库是以COM接口形式提供的,所以极为复杂,稳定性差,另外微软公司拥有该库版权,目前只在Windows平台上可用。Direct3D的优势在速度上,但现在低价显卡都能提供很好的OpenGL硬件加速,所以做3D图形开发使用Direct3D已没有特别的必要,在专业图形处理特别是高端应用方面目前还没有出现以Direct3D技术为基础的例子,而游戏等低端应用也有转向OpenGL的趋势。微软在Windows NT对OpenGL的支持始于3.51,在Windows9x中的支持始于Win95 OEM Service Release 2。Windows下常用的OpenGL库有两种,MS实现的和SGI实现的,MS-OpenGL调用会自动检测是否存在显示卡制造商提供的ICD(Installable Client DeviceDriver)驱动程序,有则调用ICD中的例程,否则使用CPU进行计算,所以能利用显示卡的OpenGL加速能力。对开发者来说使用方法并没有区别,只是有ICD驱动时更快些。SGI的版本是纯软件实现,不能利用硬件加速并且SGI已经在1999年宣布停止支持,但这套图形库便于调试程序,仍有不少开发者使用。近日SGI宣布与Intel联手针对当前及未来IA体系的Internet流化SIMD扩展优化OpenGL。这显然意味着OpenGL未来在intel体系及internet应用领域将大放光彩。SGI曾经宣布研发OpenGL+,该图形库最大的特点是面向对象,提供了树形场景支持,大大节省了使用OpenGL处理复杂场景的工作量。1999年SGI宣布与MS合作开发Ferihant,即Windows的下一代图形处理体系,包括DirectX与OpenGL的低级图形处理接口和以场景图支持为特点的高级接口,并且就此停止对其在Windows下的OpenGL实现的支持以示决心。此举令世人瞩目,大家都以为Windows图形处理快要过上幸福生活了,然而,不久,SGI宣布中止合作,并撤回派出的科学家,Ferihant基本上夭折。SGI 称终止合作的原因是MS不肯积极合作,光想把SGI 的技术合并进DirectX,但是真正内幕不详。不过以SGI在图形处理界的老大地位来说,还是有几分可信度的,因为MS最初支持OpenGL就不积极。利用OpenGL可以创作出具有照片质量的、独立于窗口系统(Windowing System)、操作系统(Operating System)和硬件平台的三维彩色图形和动画。OpenGL的核心库包括100多个用于3D图形操作的函数,主要负责处理对象外形描述、矩阵变换、灯光处理、着色、材质等和三维图形图像密切相关的事情。OpenGL工具库所包含的辅助函数是OpenGL基本函数的补充。这些函数的功能相对高级,可以用于处理坐标变换、错误处理、绘制球体、锥体、柱体、曲线、曲面等图形实体。计算机硬件性能的提高和OpenGL本身的不断发展,使得OpenGL不再只属于专用图形工作站。如今,开发人员可以在各种硬件平台利用OpenGL进行图形软件开发。OpenGL可以运行在当前各种流行操作系统之上,如Mac OS、Unix、Windows 95/98、Windows NT/2000、Linux、OPENStep、Python、BeOS等。各种流行的编程语言都可以调用OpenGL中的库函数,如C、C+、Fortran、Ada、Java。OpenGL完全独立于各种网络协议和网络拓扑结构。目前,Microsoft公司、SGI公司、ATT公司的Unix软件实验室、IBM公司、DEC公司、SUN公司、HP公司等几家在计算机市场占主导地位的大公司都采用了OpenGL图形标准。值得一提的是,由于Microsoft公司在Windows NT和Windows 95/98中提供OpenGL标准,使得OpenGL在微机中得到了广泛应用。尤其是在OpenGL三维图形加速卡和微机图形工作站推出后,人们可以在微机上实现CAD设计、仿真模拟、三维游戏等,从而使得应用OpenGL及其应用软件来创建三维图形变得更有机会、更为方便。二、OpenGL的基本特点在计算机发展初期,人们就开始从事计算机图形的开发,但直到20世纪80年代末、90年代初,三维图形才开始迅速发展。于是各种三维图形工具软件包相继推出,如GL,RenderMan等。这些三维图形工具软件包有些侧重于使用方便,有些侧重于绘制效果或与应用软件的连接,但没有一种软件包能在交互式三维图形建模能力和编程方便程度上与OpenGL相比拟。OpenGL作为一个性能优越的图形应用程序设计界面(API),适用于广泛的计算机环境。从个人计算机到工作站和超级计算机,OpenGL都能实现高性能的三维图形功能。由于许多在计算机界具有领导地位的计算机公司纷纷采用OpenGL作为三维图形应用程序设计界面,所以OpenGL应用程序具有广泛的移植性。因此,OpenGL已成为目前的三维图形开发标准,是从事三维图形开发工作的技术人员所必须掌握的开发工具。OpenGL应用领域十分宽广,如军事、电视广播、CAD/CAM/CAE、娱乐、艺术造型、医疗影像、虚拟世界等。它具有以下特点:l 工业标准OARB(OpenGL Architecture Review Board)联合会领导OpenGL技术规范的发展,OpenGL有广泛的支持,它是业界唯一的真正开发的、跨平台的图形标准。2 可靠度高利用OpenGL技术开发的应用图形软件与硬件无关,只要硬件支持OpenGL API标准就行了,也就是说,OpenGL应用可以运行在支持OpenGL API标准的任何硬件上。3 可扩展性OpenGL是低级的图形API,它具有充分的可扩展性。如今,许多OpenGL开发商在OpenGL核心技术规范的基础上,增强了许多图形绘制功能,从而使OpenGL能紧跟最新硬件发展和计算机图形绘制算法的发展。对于硬件特性的升级可以体现在OpenGL扩展机制以及OpenGL API中,一个成功的OpenGL扩展会被融入在未来的OpenGL版本之中。4 可伸缩性基于OpenGL API的图形应用程序可以运行在许多系统上,包括各种用户电子设备、PC、工作站以及超级计算机。5 容易使用OpenGL的核心图形函数功能强大,带有很多可选参数,这使得源程序显得非常紧凑;OpenGL可以利用已有的其它格式的数据源进行三维物体建模,大大提高了软件开发效率;采用OpenGL技术,开发人员几乎可以不用了解硬件的相关细节,便可以利用OpenGL开发照片质量的图形应用程序。6 灵活性尽管OpenGL有一套独特的图形处理标准,但各平台开发商可以自由地开发适合于各自系统的OpenGL执行实例。在这些实例中,OpenGL功能可由特定的硬件实现,也可用纯软件例程实现,或者以软硬件结合的方式实现。客观世界和各种事物的形状虽然千变万化,但用计算机将之描述出来却只需要把一系列基本操作组合起来。OpenGL提供了以下基本操作:l 绘制物体真实世界里的任何物体都可以在计算机中用简单的点、线、多边形来描述。OpenGL提供了丰富的基本图元绘制命令,从而可以方便地绘制物体。2 变换可以说,无论多复杂的图形都是由基本图元组成并经过一系列变换来实现的。OpenGL提供了一系列基本的变换,如取景变换、模型变换、投影变换及视口变换。3 光照处理正如自然界不可缺少光一样,绘制有真实感的三维物体必须做光照处理。4 着色OpenGL提供了两种物体着色模式,一种是RGBA颜色模式,另一种是颜色索引模式。5 反走样在OpenGL绘制图形过程中,由于使用的是位图,所以绘制出的图像的边缘会出现锯齿形状,称为走样。为了消除这种缺陷,OpenGL提供了点、线、多边形的反走样技术。6 融合为了使三维图形更加具有真实感,经常需要处理半透明或透明的物体图像,这就需要用到融合技术。7 雾化正如自然界中存在烟雾一样,OpenGL提供了fog的基本操作来达到对场景进行雾化的效果。8 位图和图像在图形绘制过程中,位图和图像是非常重要的一个方面。OpenGL提供了一系列函数来实现位图和图像的操作。9 纹理映射在计算机图形学中,把包含颜色、alpha值、亮度等数据的矩形数组称为纹理。而纹理映射可以理解为将纹理粘贴在所绘制的三维模型表面,以使三维图形显得更生动。l0 动画出色的动画效果是OpenGL的一大特色,OpenGL提供了双缓存区技术来实现动画绘制。OpenGL并没有提供三维模型的高级命令,它也是通过基本的几何图元-点、线及多边形来建立三维模型的。目前,有许多优秀的三维图形软件(如3DMAX)可以较方便地建立物体模型,但又难以对建立的模型进行控制,若把这些模型转化为OpenGL程序,则可随心所欲地控制这些模型来制作三维动画,实现仿真数据的可视化和虚拟现实。三、讲 OpenGL体系结构OpenGL是一套图形标准,它严格按照计算机图形学原理设计而成,符合光学和视觉原理,非常适合可视化仿真系统。首先,在OpenGL中允许视景对象用图形方式表达,如由物体表面顶点坐标集合构成的几何模型,这类图形数据含有丰富的几何信息,得到的仿真图像能充分表达出其形体特征;而且在OpenGL中有针对三维坐标表示的顶点的几何变换,通过该变换可使顶点在三维空间内进行平移和旋转,对于由顶点的集合表达的物体则可以实现其在空间的各种运动。其次,OpenGL通过光照处理能表达出物体的三维特性,其光照模型是整体光照模型,它把顶点到光源的距离、顶点到光源的方向向量以及顶点到视点的方向向量等参数代入该模型,计算顶点颜色。因此,可视化仿真图像的颜色体现着物体与视点以及光源之间的空间位置关系,具有很强的三维效果。另外,为弥补图形方法难于生成复杂自然背景的不足,OpenGL提供了对图像数据的使用方法,即直接对图像数据读、写和拷贝,或者把图像数据定义为纹理与图形方法结合在一起生成视景图像以增强效果。为增强计算机系统三维图形的运算能力,有关厂家已研制出了专门对OpenGL进行加速的三维图形加速卡,其效果可与图形工作站相媲美。一个完整的窗口系统的OpenGL图形处理系统的结构为:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,第五层为应用软件。见图1.1所示。图1.1 OpenGL图形处理系统的层次结构OpenGL是网络透明的,在客户机/服务器体系结构中,允许本地或远程调用OpenGL。所以在网络系统中,OpenGL在X窗口、Windows或其它窗口系统下都可以以一个独立的图形窗口出现。由于OpenGL是一个与平台无关的三维图形接口,操作系统必须提供像素格式管理和渲染环境管理。下面以Windows NT操作系统为例具体介绍OpenGL运行的体系结构。OpenGL在Windows NT上的实现是基于Client/Server模式的,应用程序发出OpenGL命令,由动态链接库OpenGL32.DLL接收和打包后,发送到服务器端的WINSRV.DLL,然后由它通过DDI层发往视频显示驱动程序。如果系统安装了硬件加速器,则由硬件相关的DDI来处理。OpenGL/NT的体系结构图如图1.2所示。从程序员的角度看,在编写基于Windows的OpenGL应用程序之前必须清除两个障碍,一个是OpenGL本身是一个复杂的系统,这可以通过简化的OpenGL辅助库函数来学习和掌握;另一个是必须清楚地了解和掌握Windows与OpenGL的接口。图1.2 OpenGL/NT体系结构1.3.2 渲染上下文(RC)OpenGL的绘图方式与Windows的一般的绘图方式是不同的,其区别主要表现在以下三个方面:(1) Windows采用的是GDI绘图;(2) OpenGL采用的是渲染上下文RC(Render Context,又称渲染描述表)绘图;(3) OpenGL使用的是特殊的像素格式。在Windows中使用GDI绘图时必须指定在哪个设备上下文(Device Context,又称设备描述表)中绘制,同样地,在使用OpenGL函数时也必须指定一个所谓的渲染上下文。正如设备上下文DC要存储GDI的绘制环境信息如笔、刷和字体等,渲染上下文RC也必须存储OpenGL所需的渲染信息如像素格式等。渲染上下文主要由以下六个wgl函数来管理,下面分别对其进行介绍。l HGLRC wglCreateContext(HDC hdc)该函数用来创建一个OpenGL可用的渲染上下文RC。Hdc必须是一个合法的支持至少16色的屏幕设备描述表DC或内存设备描述表的句柄。该函数在调用之前,设备描述表必须设置好适当的像素格式。成功创建渲染上下文之后,hdc可以被释放或删除。函数返回NULL值表示失败,否则返回值为渲染上下文的句柄。2 BOOL wglDeleteContext(HGLRC hglrc)该函数删除一个RC。一般应用程序在删除RC之前,应使它成为非现行RC。不过,删除一个现行RC也是可以的。此时,OpenGL系统冲掉等待的绘图命令并使之成为非现行RC,然后删除之。注意在试图删除一个属于别的线程的RC时会导致失败。3 HGLRC wglGetCurrentContext(void)该函数返回线程的现行RC,如果线程无现行RC则返回NULL。4 HDC wglGetCurrentDC(void)该函数返回与线程现行RC关联的DC,如果线程无现行RC则返回NULL。5 BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc)该函数把hdc和hglrc关联起来,并使hglrc成为调用线程的现行RC。如果传给hglrc的值为NULL,则函数解除关联,并置线程的现行RC为非现行RC,此时忽略hdc参数。传给该函数的hdc可以不是调用wglCreateContext时使用的值,但是,它们所关联的设备必须相同并且拥有相同的像素格式。注意,如果hglrc是另一个线程的现行RC,则调用失败。6 BOOL wglUseFontBitmaps(HDC hdc, DWORD dwFirst, DWORD dwCount, DWORD dwBase)该函数使用hdc的当前字体,创建一系列指定范围字符的显示表。可以利用这些显示表在OpenGL窗口画GDI文本。如果OpenGL窗口是双缓冲的,那么这是往后缓冲区中画GDI文本的唯一途径。一般地,在使用单个RC的应用程序中,在相应WM_CREATE消息时创建RC,当WM_CLOSE或WM_DESTROY到来时再删除它。在使用OpenGL命令往窗口中绘图之前,必须先建立一个RC,并使之成为现行RC。OpenGL命令无需提供RC,它将自动使用现行RC。若无现行RC,OpenGL将简单地忽略所有的绘图命令。一个RC是指现行RC,这是针对调用线程而言的。一个线程在拥有现行RC进行绘图时,别的线程将无法同时绘图。一个线程一次只能拥有一个现行RC,但是可以拥有多个RC;一个RC也可以由多个线程共享,但是它每次只能在一个线程中是现行RC。在使用现行RC时,不应该释放或者删除与之关联的DC。如果应用程序在整个生命期内保持一个现行RC,则应用程序也一直占有一个DC资源。注意,Windows系统只有有限的DC资源。下面介绍两种管理RC与DC的方法。方法一:RC由WM_CREATE消息响应时创建,创建后立即释放DC;当WM_PAINT消息到来时,程序再获取DC句柄,并与RC关联起来,绘图完成后,立即解除RC与DC的关联,并释放DC;当WM_DESTROY消息到来时,程序只需简单地删除RC即可。如图1.3所示。图1.3 RC与DC的管理方法一方法二:RC在程序开始时创建并使之成为现行RC。它将保持为现行RC直至程序结束。相应地,GetDC在程序开始时调用,ReleaseDC在程序结束时才调用。此种方法的好处是在响应WM_PAINT消息时,无需调用十分耗时的wglMakeCurrent函数,一般它要消耗几千个时钟周期。如图1.4所示。如果应用程序需要使用动画或实时图形,建立采用第二种方法。图1.4 RC与DC的管理方法二四、OpenGL像素格式管理1、Windows下的调色板OpenGL可以使用16色、256色、64K和16M真彩色。真彩模式下不需要调色板,而在16色模式下根本不可能得到较为满意的效果,因此对OpenGL而言,调色板只有在256色模式下才有意义。我们知道,Windows把调色板分为系统调色板和逻辑调色板。每个应用程序都拥有一套自己的逻辑调色板(或使用缺省调色板),当该应用程序拥有键盘输入焦点时可以最多使用从16M种色彩中选取的256种颜色(20种系统保留颜色和236种自由选取的颜色),而失去焦点的应用程序可能会有某些颜色显示不正常。系统调色板由Windows内核来管理,它是由系统保留的20种颜色和经仲裁后各个应用程序设置的颜色组成,并与硬件的256个调色板相对应。应用程序的逻辑调色板与硬件的调色板没有直接的对应关系,而是按照最小误差的原则映射到系统调色板中,因此即使应用程序自由选取256种不同颜色构成自己的逻辑调色板,也有可能某些颜色显示到屏幕上时是一样的。当应用程序的窗口接收到键盘输入焦点时,Windows会向它发送一条WM_QUERYNEWPALETTE消息,让它设置自己的逻辑调色板,此时Windows会在系统调色板中尽量多地加入该应用程序需要的颜色,并生成相应的映射关系。接着Windows会向系统中所有的覆盖型窗口和顶级窗口(包括拥有键盘输入焦点的窗口)发送一条WM_PALETTECHANGED消息,让它们设置逻辑调色板和重绘客户区,以便能更充分地利用系统调色板,已拥有键盘输入焦点的窗口不应再处理这条消息,以避免出现死循环。2、OpenGL的颜色表示与转换OpenGL内部用浮点数来表示和处理颜色,红绿蓝和Alpha值这四种成份每种的最大值为1.0,最小值为0.0。在256色模式下,OpenGL把一个像素颜色的内部值按线性关系转换为8比特(Bit)来输出到屏幕上,其中红色占最低位的3比特,绿色占中间的3比特,蓝色占最高位的2比特,Windows将这个8比特值看作逻辑调色板的索引值。例如OpenGL的颜色值(1.0,0.14,0.6667)经过转换后二进制值为10001111(红色为111,绿色为001,蓝色为10),即第143号调色板,该调色板指定的颜色的RGB值应与(1.0,0.14,0.6667)有相同的比率,为(255,36,170),如果不是该值,那么显示出来的颜色就会有误差。3、调色板的生成算法很明显,OpenGL输出的8比特值中直接表明了颜色的组成,为了使图形显示正常,我们应以线性关系来设置逻辑调色板,使其索引值直接表明颜色的组成。因此生成调色板时,把索引值从低位到高位分成3-3-2共三个部分,将每一部分映射到0-255中去,这样3比特映射为0,36,73,109,146,182,219,255,2比特映射为0,85,170,255,最后把三部分组合起来成为一种颜色。经过上面的处理后,256种颜色均匀分布在颜色空间中,并没有完全包含系统保留的20种颜色(只包含了7种),这意味着将会有数种颜色显示成一样,从而影响效果。一个较好的解决办法是按照最小均方误差的原则把13种系统颜色纳入到逻辑调色板中。从原理上来说,并非一定要使用线性映射,还可以用其它一些映射关系,如加入Gamma校正以便更能符合人眼的视觉特性,不过这些映射关系应用得并不广泛,在此不再讨论。1.3.4 像素格式设置像素格式是OpenGL窗口的重要属性,它包括是否使用双缓冲,颜色位数和类型以及深度位数等。像素格式可由Windows系统定义的所谓像素格式描述子结构来定义(PIXELFORMATDESCRIPTOR),该结构定义在windows.h中。在该结构中包含有26个属性信息,其形式为:typedef struct tagPIXELFORMATDESCRIPTORWORD nSize;WORD nVersion;DWORD dwFlags;BYTE iPixelType;BYTE cColorBits;BYTE cRedBits;BYTE cRedShift;BYTE cGreenBits;BYTE cGreenShift;BYTE cBlueBits;BYTE cBlueShift;BYTE cAlphaBits;BYTE cAlphaShift;BYTE cAccumBits;BYTE cAccumRedBits;BYTE cAccumGreenBits;BYTE cAccumBlueBits;BYTE cAccumAlphaBits;BYTE cDepthBits;BYTE cStencilBits;BYTE cAuxBuffers;BYTE iLayerType;BYTE bReserved;DWORD dwLayerMask;DWORD dwVisibleMask;DWORD dwDamageMask; PIXELFORMATDESCRIPTOR;各变量的含义如下:nSize:该结构所占内存空间。nVersion:版本号,当前为1。dwFlags:指定像素格式属性,可选参量如表1.1所示。表1.1 像素格式属性标识符 解释PFD_DRAW_TO_BITMAP 支持内存中绘制位图PFD_DRAW_TO_WINDOW 支持屏幕绘图PFD_DOUBLEBUFFER 支持双缓冲PFD_CENERIC_FORMAT 指定选择GDI支持的像素格式PFD_NEED_PALETTE 指定需要逻辑调色板PFD_NEED_SYSTEM_PALETTE 指定需要硬件调色板PFD_STEREO NT不支持PFD_SUPPORT_OPENGL 支持OpenGLPFD_SUPPORT_GDI 支持GDI,此时不可使用PFD_DOUBLEBUFFERiPixelType:像素颜色模式,可选项为PFD_TYPE_RGBA或PFD_TYPE_INDEX,分别对应于RGBA模式和颜色索引模式。cColorBits:指定颜色的位数。cRedBits:采用RGBA模式时,红色组分占用位数。cRedShift:采用RGBA模式时,红色组分偏移量。cGreenBits:采用RGBA模式时,绿色组分占用位数。cGreenShift:采用RGBA模式时,绿色组分偏移量。cBlueBits:采用RGBA模式时,蓝色组分占用位数。cBlueShift: 采用RGBA模式时,蓝色组分偏移量。cAlphaBits:采用RGBA模式时,Alpha组分占用位数。cAlphaShift:采用RGBA模式时,Alpha组分偏移量。cAccumBits:指定累积缓冲区表示一个像素所用位数。cAccumRedBits:指定累积缓冲区表示红色组分占用位数。cAccumGreenBits:指定累积缓冲区表示绿色组分占用位数。cAccumBlueBits:指定累积缓冲区表示蓝色组分占用位数。cAccumAlphaBits:指定累积缓冲区表示Alpha组分占用位数。cDepthBits:指定深度缓冲区表示一个像素所用位数。cStencilBits:指定模板缓冲区表示一个像素所用位数。cAuxBuffers:指定辅助缓冲区,Windows9x、NT不支持。iLayerType:Windows9x、NT下只能是PFD_MAIN_PLANE。bReserved:0。dwLayerMask:指定覆盖层的屏蔽,Windows9x、NT不支持。dwVisibleMask:Windows9x、NT不支持。dwDamageMask:Windows9x、NT不支持。Windows提供了四个像素格式管理函数,分别介绍如下:(1) int ChoosePixelFormat(HDC hdc,PIXELFORMATDESCRIPTOR *ppdf)该函数比较传过来的像素格式描述和OpenGL支持的像素格式,返回一个最佳匹配的像素格式索引。该索引值可传给SetPixelFormat为DC设置像素格式。返回值为0表示失败。在比较像素格式时,匹配优先级顺序为像素格式描述子结构中的下述各域:dwFlagscColorBitscAlphaBitscAccumBitscDepthBitscStencilBitscAuxBuffersiLayerType硬件支持的像素格式优先。(2) int DescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes,LPPIXELFORMATDESCRIPTOR *ppfd)该函数用格式索引iPixelFormat说明的像素格式来填写由ppfd所指向的像素格式描述子结构,利用该函数可以枚举像素格式。(3) int GetPixelFormat(HDC hdc)该函数用于获取hdc的格式索引。(4) BOOL SetPixelFormat(HDC hdc, int iPixelFormat,LPPIXELFORMATDESCRIPTOR *ppfd)该函数用格式索引iPixelFormat来设置hdc的像素格式。在使用该函数之前应该调用ChoosePixelFormat来获取像素格式索引。另外,OpenGL窗口风格必须包含WS_CLIPCHILDREN和WS_CLIPSIB
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 瓷砖专卖店年终总结
- 消防安全普及培训报道课件
- 2025至2030中国加筋土工合成材料行业项目调研及市场前景预测评估报告
- 二手房屋买卖合同模板:含房屋交易风险评估及建议
- 文化创意产业园区空场地租赁及运营管理合同
- 因男方过错离婚的财产分割及子女监护安排协议
- 企业核心技术人员离职竞业限制保密协议书
- 高端人才离职后商业秘密保护与竞业禁止合同
- 2025至2030中国皮肤套刮器行业项目调研及市场前景预测评估报告
- 离婚协议书范本:共同财产分割与债务处理
- 潮汐能发电站课件
- 国际化跨国经营中的伦理问题概述
- 2025-2026学年度武汉市部分学校高三年级九月调研考试 语文试卷(含标准答案)
- 2025年秋期新部编人教版五年级上册道德与法治教学计划+进度表
- 2025年全国企业员工全面质量管理知识竞赛题库及答案
- 粮食机收减损培训课件
- 超星尔雅学习通《军事理论(中北大学)》2025章节测试附答案
- 排球《正面上手发球》教案
- 房地产项目委托开发管理合同的(模板)
- 夕阳箫鼓-钢琴谱(共11页)
- 各类金属常见缺陷
评论
0/150
提交评论