主题:  三维图形应用编程接口

文羽

职务:普通成员
等级:1
金币:0.0
发贴:33
注册:2000/9/19 10:07:20
#12000/10/12 14:28:53
三维图形应用编程接口



  本文对沟通3D图形应用程序和3D图形加速卡的三维图形编程接口(3D API)做了透彻的说明。

一、3D API

  3D API是架设在3D图形应用程序和3D图形加速卡之间用于沟通的桥梁。
  对于三维图形应用开发者来说,可供选择的三维(3D)图形编程接口(API)太丰富了,多达50多种。如此丰富的选择同时也为开发者出了一道难题,即如何选择适合自己应用的API?对于具有丰富软件开发经验的编程者来说,以往选择API的经验可以帮助他们迅速作出正确的选择。你开发的应用要面向什么平台?是否支持跨平台的工作 ?是否支持客户机/服务器模式 ?是否支持面向对象的开发等等,这些都是选择API的一般准则。总的说来,著名的大公司和在图形应用方面获得广泛认可的公司所提供的三维API引擎是大多数应用开发首先考虑的。如SGI公司的OpenGL ,Apple公司的 Quick-Draw 3D (QD3D), 以及Microsoft 公司的Direct3D等。对开发者来说,重要的是在开发工作开始之前必须详细了解这些API的功能和优缺点,以便作出恰当的抉择。
  对于跨平台的应用开发,可考虑OpenGL,它可运行在Unix, Windows NT ,Windows 95 以及Mac平台之上,它的客户机/服务器体系结构可使桌面系统将图形处理提交给服务器去做。QD3D也具有同样的长处,它既可以运行在Power Macs上,也可以运行在Windows NT和Windows 95上。然而,OpenGL不能完成某些高级功能,例如某些文件操作功能。QD3D和Direct3D则解决了这一令人头痛的问题,它们二者还具有硬件抽象,从而可以使芯片和板卡厂家能以一种设备无关的方式提供硬件的功能。如果开发是面向Macs 和Windows的,可选择QD3D 。如果要充分利用PC硬件的优势,比如说开发基于PC的游戏,Direct3D 和Apple的RAVE ( Rendering Acceleration Virtual Engine ,它是QD3D使用的设备无关接口)则可提供很好的支持。

二、OpenGL

  OpenGL能将基于顶点和象素的数据高效地转换为图象,其应用范围比传统的三维图形库要更大一些。它的纹理映射提供了一个桥梁,从而能将基于顶点的数据表示和基于象素的数据表示的光栅化处理更有效地结合起来。由于OpenGL非常适于操作顶点和象素数据,支持纹理映射,并体现了一种体系结构,因而有人称其为可视化体系结构。从概念上说OpenGL 可被看成一个状态机,其命令包括设置/恢复状态变量,恢复帧缓存内容,编译或调用显示表,将顶点或象素数据读入状态机等。读入到状态机的顶点和象素数据依据当前OpenGL的状态进行处理,并根据当前状态将处理结果送往帧缓存、纹理存储器、显示表或选择/反馈缓冲。图1是OpenGL体系结构中的高级数据流。
  OpenGL的状态变量是相互无关的。一般地,恢复使用或重配置OpenGL的某些特征不会对其它特征产生影响。例如,光照计算相对于当前的深度缓冲模式可以独立地启用或关闭。这意味着程序员能将可预见的结果与特征结合起来。OpenGL的大部分易于扩展性可以通过特征无关来预见。没有特征无关性,对OpenGL进行多种体系结构的扩展将导致互相依赖关系的混乱,甚至产生特征之间的矛盾。从概念上而不是从网络互连的角度来看,OpenGL体系结构是客户机/服务器模式。这意味着一个OpenGL应用和一个OpenGL实现之间的接口是严格定义的,所有在应用和实现之间传递的数据是明确定义的。客户机/服务器式的划分定义了OpenGL实现与应用之间的分界,这一清晰的分界使得网络可扩展的OpenGL实现成为可能,并使OpenGL可直接用作硬件接口。OpenGL体系结构支持丰富的数据格式。由于避免了数据格式的转换,应用性能得到了改善。OpenGL的体系结构是可重组的,但不是可编程的。OpenGL的状态机可看成是具有固定拓扑结构的流水线,但各处理阶段可被选择或关闭。这种思想模仿了高性能图形子系统的设计,这些子系统将绘制步骤分解并用特殊化的硬件模块实现。
  OpenGL是目前跨平台最广泛的三维图形引擎,除PC和Mac平台外,它还支持多种风格的Unix。在Unix 系统上必须首先启动X Window系统,由大约十多个调用组成的一个称作GLX的扩展库来初始化这个窗口环境。该扩展库建立绘制环境以及与窗口系统帧缓存的连接。OpenGL在其它平台上的实现也使用相似的接口库来处理这种与系统相关的细节。
  与QD3D和Direct3D相比,OpenGL不是一个高级的应用程序接口。它的目标是绘制对象,而象对象编辑和文件I/O等高级任务则由应用程序来做,如SGI的Open Inventor。OpenGL为低级绘制引擎提供了一个平台无关的接口。该接口包含了大约250条绘制命令,编程者可以使用这些命令来描述对象并执行一组操作以产生最后的图象。编程者还可以在高级编程语言如C/C++, Fortran , Ada 和Java中调用OpenGL 。OpenGL 采用客户机/服务器机制来完成图形处理,即一个图形客户或一个三维应用利用OpenGL接口以及宿主机的操作系统将顶点坐标、颜色、纹理坐标等图形构件传送给运行OpenGL光栅处理器的图形服务器进程去完成图形的绘制。光栅处理器依据当前的OpenGL 图形状态执行一个或多个图形操作并产生象素。这些象素值再经过纹理映射、雾效果、反走样、深度比较、混合等处理,将结果送到客户机的应用程序窗口显示。通常情况下,客户机和服务器运行在同一个系统之上,也可将二者分开。如一个低档的桌面系统可以通过网络将OpenGL的命令传送到一个运行服务器进程的高性能系统,该系统将最后得到的图象返回给桌面系统。
  OpenGL支持立即模式和驻留模式的图形操作。在立即模式下,应用将图形命令传给OpenGL,OpenGL立即执行。这一方式为图形的任何改变提供了快速响应,这是交互式图形应用的关键特征。在驻留模式下,图形命令序列被存储在一个显示表中。显示表的运用有两个好处,首先,如果你必须经常显示某个复杂对象,你只需引用其显示表;其次,对象信息可以这种方式在网络上快速传送。其缺点是对对象的频繁修改需要产生新的对象描述。OpenGL的核心API提供了一组原语来处理点、线、多边形面、有理多边形曲面及位映射图象等。这些原语可以描述位置坐标、颜色、表面法线及纹理坐标等,光栅处理器利用这些原语和OpenGL的当前图形状态对最终输出象素执行图形操作,如雾效果、纹理映射、反走样、混合处理、屏蔽处理和深度检测等。为保持可移植性,OpenGL不支持某些几何对象,但是,结合多个原语可以组装这样的对象。OpenGL的共用库(GLU)提供了建造通用对象如球、圆柱、圆锥等的能力。
  三维绘制过程通常由一系列可并行执行的子任务来完成。为了改善性能,三维应用编程接口大多由可重入代码组成,这使得它们非常适合于工作在多线程操作系统环境中。但在处理线程的方式上各个API则存在着差别。OpenGL可以处理多个线程,每个线程管理一个独立的窗口。相应地,在一个窗口之内多个线程可以共同协作完成一个图象处理工作。值得注意的是重入代码本身并不能保证并发的图形处理。OpenGL的那些控制图形状态的命令使得并发操作成为可能,这些命令在进行线程之间的环境切换时为每个窗口保存或恢复图形环境。
  许多供应商都提供三维应用以及使用OpenGL的工具包。Open Inventor就是一个三维工具包,它提供了颜色、纹理编辑器等内建的图形工具,可以运行在工作站和Windows环境下,并以一种Inventor的文件格式保存三维图形,这一文件格式是虚拟现实建模语言(VRML)的一个超集。VRML则是Web上描述三维对象的文件格式,是一个工业标准。OpenGL不支持面向对象的设计,但它对从低端到高端的图形环境提供广泛的支持。在低端,它可以为PC提供纯软件的绘制,它也可以与装有可视化硬件每秒绘制上千万个多边形的工作站直接通信。SGI新推出的OpenGL++已可支持多边形网格化简、多分辨率建模及可见性预处理等,这些是处理复杂场景的重要手段。OpenGL已成为一个标准,该标准由一个专门机构管理,成员包括DEC,Microsoft和Evens&Sutherland。

三、Direct3D

  Direct3D是Microsoft于1996年6月发布的三维API,是该公司交互式媒体技术家族DirectX中的一员。Direct3D为程序员提供了一个显示三维图形的与硬件无关的应用编程接口,它同时也提供了一种机制,一个应用可以通过这种机制进入系统中的任何图形加速硬件。由于它提供了对三维图形的OS级支持同时又将硬件从接口分离,产生三维图形的应用程序便可运行于更广泛的桌面计算机上。Microsoft希望Direct3D能支持跨平台操作,能对Windows 95 , Windows NT , Power Mac等提供支持。Direct3D为Windows 95下的三维开发者提供了一个优秀的开发环境,特别是对游戏开发者来说是如此。
Direct3D是如何做到既隐藏显示卡硬件的细节,又可利用明显依赖硬件的加速特征? 在接口级,低级Direct3D API 以一种一致的方式对硬件特征进行抽象,这种方式提供了这种方便,从而可以隐藏不同供应商的三维加速硬件的某些差别。Direct3D由两种类型的驱动器组成。第一种类型的驱动器实现了一个硬件抽象层(HAL: Hardware Abstract Layer),芯片和板卡厂家通过使用这个HAL以一种设备无关的方式提供硬件的功能,通过一种询问机制,程序员可以从HAL接口获得有关加速硬件的特征信息,包括硬件的设备专有信息和性能信息,从而利用这些信息。对于没有加速硬件的系统,Direct3D在软件一级实现了另一种类型的驱动器,它使用一个硬件仿真层HEL(Hardware Emulation Layer)来用软件仿真这些特征。HEL利用台式系统的处理器产生所有的图形操作,生成的象素送往一个DirectDraw帧Buffer,DirectDraw 是一个处理二维图形的DirectX API。HEL 保证一个应用程序在任何系统上都能利用Direct3D的所有服务,但性能可能会有所降低。硬件驱动器必须实现询问操作展示的所有特征,它可以通过软件或软、硬结合的方式来实现这些特征。
  Direct3D由许多C/C++头文件和基于组件对象模型(Component Object Model :COM)的接口组成。头文件包含许多枚举类型和数据结构,它们被用于向OS传送设备信息,这些信息使得应用可以控制3D对象的外观,如纹理等。其中的几个数据结构用于处理从设备无关API调用到设备依赖绘制调用的转换过程。表1总结了这些Direct3D数据结构及其在驱动器中的应用。实质上,这些数据结构向OS描述了驱动器下面的3D绘制芯片的能力。一个结构提供了操作芯片绘制引擎的HAL函数的进入点。定义这些结构通常很容易,只须简单地比较Direct3D头描述的特征能力位和芯片支持的特征,然后将相应的位置位。由于显示管理软件、3D绘制驱动器软件以及其下的硬件能力之间的相互作用,实现这些芯片支持的特征是相当困难的(见表1)。
  通过将三角形或线的坐标传给3D芯片便可开始一个绘画操作,然后建立属性位,如纹理映射、Z-Buffer比较方式、雾效果、Gouraud明暗处理等,并将芯片命令寄存器中的相应位置位或复位。如果芯片是一个真正的立即模式3D绘制芯片,当完成对命令寄存器的编程处理时,它便开始画线或三角形。Direct3D驱动器与一个DirectDraw驱动器一起启动。DirectDraw驱动器提供Direct3D驱动器所需要的对卡上帧缓存以及任何脱屏缓存(off-screen buffer )的访问。而且,DirectDraw驱动器内的一个HAL数据结构,DDHALINFO,包含定义Direct3D驱动器的设备能力位。当一个Direct3D驱动器初始化时,它便将DDHALINFO中的特定位置位。一个Direct3D驱动器的生成顺序以对一个DirectDraw驱动器的初始化开始。作为初始化过程的一部分,DirectDraw驱动器调用一个生成驱动器函数,该函数位于板卡制造商的32位驱动器之内,由它建立Direct3D驱动器。该函数首先将DirectDraw 驱动器内的能力位置位,然后建立上表中所列出的Direct3D数据结构。该函数从板卡的固件中获取数据并将其插入这些数据结构中。绘制函数的调用地址则被放在一个称作D3DHAL_CALLBACKS的表中。这些地址被返回给DirectX软件层并作为驱动器CALL_BACK函数的进入点。一个3D图形操作通过唤起这个表中的一个callback函数,由被唤醒的HAL函数完成描述的3D操作。驱动器至少必须支持6个callback函数,其中几个处理图形环境的上下关系,两个函数控制环境的状态及其绘制特征。
  从应用的角度来看,3D应用程序产生DirectDraw对象。为建立显示的象素深度并获得frame buffer的位置,应用程序必须产生一个DirectDraw 对象。应用程序然后询问OS关于一个Direct3D系统对象,获取支持3D绘制的所有驱动器的信息及它们的能力。应用程序通过遍历驱动器表以确定那个最适合其图形或性能需求的驱动器的位置。例如如果主机系统缺少某个加速特征,则应用可以降低显示的象素深度或分辨率,或通过删掉某个绘制属性如纹理映射来作为回应。由于对驱动器的访问是通过一个良好定义的接口及一组callback函数,应用程序员便永远不会直接与硬件打交道,这样便可以写出在几乎任何硬件组合上执行的应用。这样,一个应用也可以通过适当的调整运行在旧一些或能力弱一些的系统上。
  Direct3D支持立即模式和驻留模式的操作。Direct3D的驻留模式与QD3D的驻留模式相似,为应用提供了一个高级的面向对象的接口以操作三维对象。当使用一个API调用装入一个对象之后,可以使用其它API对其进行旋转和缩放。驻留模式提供了对存储三维数据的文件格式的读写调用,这些数据由预先定义的三维对象、网格、纹理和动画集组成。应用程序可以利用这一文件格式交换三维数据信息,并实时回放动画序列。Direct3D的立即模式是一个瘦的处理多边形和顶点的API层。立即模式的API将由顶点数据和图形命令组成的显示表传送给绘制引擎去处理,Microsoft称这个显示表为运行缓冲。程序员可以利用该系统提供的高性能的与设备无关机制访问系统的图形硬件或利用硬件加速器。该模式不提供任何对象或场景管理功能,这些由应用程序负责。对于那些具有自己的绘制引擎而又希望利用系统的硬件加速特征的应用来说,立即模式是最适合的选择。编程者可以在C和C++以及Visual Basic中访问Direct3D的调用。
  Direct3D提供了许多图形对象。在立即模式中,这些对象包括运行缓冲(execute buffer)、变换矩阵、光照、纹理、对象表面特性、视区、管理屏幕的设备以及接口等。驻留模式在立即模式的基础上又增加了多边形面、网格、管理一个场景中所有对象的位置及其方向的帧、阴影以及动画变换。Direct3D更象OpenGL那样提供了绘制构件,而没有象QD3D那样提供象球、圆柱等基本对象。
  Direct3D的核心体系结构是一个三维绘制引擎,它是一个三级图形流水线。每一级是一个独立的动态加载软件模块。在绘制操作开始时,首先用一个Direct3D API调用为每个模块建立图形状态,然后将一个运行缓冲载入引擎。第一级模块是变换模块,处理一个对象需要完成的所有几何变换。第二个模块是光照模块,为每个对象做光照计算,它可以处理多种类型的光源。最后一级是绘制模块,她利用前两级的输出结果生成最终的场景图象。可以通过软件控制方便地切换这些模块。这使得利用不同或具有增强功能的模块代替流水线中的相应模块成为可能。一些模块可以与硬件加速器进行通信,流水线中的任何一级都可以通过硬件来加速。Direct3D支持多线程环境,在该环境中不同的应用可以同时对各自不同的窗口进行操作。由于Windows 95对单处理器是优化的,因而Direct3D对多处理来说并不最优。驻留模式对象包含了图形状态信息,当管理不同场景的线程之间进行环境切换时,绘制流水线的模块的图形状态便可以被自动更新。对于使用立即模式的应用来说,当进行状态切换时必须自己负责流水线的图形状态的保存和恢复。图2是Direct3D的体系结构和图形绘制流水线示意图。

四、QuickDraw 3D(Heidi)

  QD3D是一个完整的三维图形环境。开发者可以使用其最高层的API产生和操作三维对象,对文件进行三维数据的读写操作。该API向一个可扩展的处理绘制操作的流水线传送消息,流水线又依次向一个瘦的硬件抽象层(HAL)传送消息,该HAL为游戏设计者提供了一个与设备无关的API。QD3D支持立即模式和驻留模式,其立即模式与OpenGL相同,都需要应用向绘制处理器提供画图命令。在驻留模式中,面向对象的编程结构为显示和操作维护场景几何数据。立即模式为应用提供细致的控制,而驻留模式则可以将场景几何数据存储到一个对象数据库中,它使得对对象的读写更容易,并可以通过对数据结构的缓冲来实现快速显示或硬件加速。QD3D与OpenGL最大的不同点在于它是面向对象的图形系统。一个对象的新实例能从其类中继承特征,这些特征包括几何、尺寸、方向、颜色、纹理以及光照,从而可以快速建造一个场景的对象,它同时也简化了用于操作和显示的每个对象的信息的维护。高级API命令可以生成、旋转、编辑一个对象,也可以给一个对象施加光照和变换。附件机制提供的可视“操柄(handles)”可以交互地编辑和缩放一个对象。由于QD3D的面向对象特征,无需三维对象内部结构的知识就可以执行这些操作。目前仅能从C/C++语言中实现对QD3D的调用。QD3D允许用户以一种公用的三维元文件格式(3DMF)读写三维图象。这一格式不仅存储每个对象的几何数据,也存储其光照和纹理。3DMF还使三维图形在应用之间的拷贝、粘贴和拖放成为可能。QD3D 的API提供了大量的基本对象如线、球、圆锥等,可以利用这些基本对象快速建造一个场景的原型。它也提供了一个接口以实现对对象的可视编辑。QD3D的体系结构是可扩展的,这样就可以利用第三方的绘制器或者获得对硬件加速器的访问能力。1996年三月Netscape、SGI、 Apple联合宣布将开发Web上的基于3DMF格式的动态三维环境跨平台规范,QD3D的文件格式正在变成一个事实上的标准。
  同OpenGL一样,QD3D是一个与平台无关的图形API ,它在Mac OS上以共享库的方式实现,在Windows平台上则以动态连接库的方式实现。与OpenGL的平台专用GLX库相似,QD3D有大约10个依赖于系统的调用,它们被用来初始化图形环境,生成窗口,获取指向窗口帧缓存的指针。QD3D大约有1050个调用,这个API不仅管理绘制和显示,而且包含了对应用程序的支持和文件的I/O。QD3D使用多处理器或多线程应用来支持交互式绘制。由于QD3D的视类对象(View class object)保留了图形的上下关系,因而对于不同处理器或不同线程的不同图形状态之间的切换就可以自动进行。与OpenGL不同,QD3D不支持网络上的分布式处理,但其体系结构允许第三方插件(plug-in)开发这一功能。