标题：DirectX软件
DirectX软件
DirectX，它比Windows GDI要快好几倍，可用于不同的语言和多种平台，支持从绘制象素到高级3D图象，从播放简单声音到数字音乐，从键盘控制到反震手柄……它给你游戏编程所需的一切（有点夸张）。当然了，它是巨大的，需要好几本书才能含盖它的全部。
阅读本章，你需要前几章的知识和C语言的知识，由于我们还要谈到组件对象模型（COM），它是面向对象系统的基础，你最好还要有一点儿C++的知识。没有也不太要紧，我在讲到这处时会照顾你的。反正你记住，使用DirectX并不需要多少C++的知识。开始吧！ 
什么是DirectX 
DirectX是游戏制作者的API（Application programming Interface）。它是一组允许你直接控制计算机硬件设备的软件。如果你的硬件支持DirectX，并且你用硬件加速你的程序，这就意味着一个字——快。不用担心你的硬件知识，你不会真正的接触到它们。我们是通过硬件抽象层（HAL）和硬件仿真层（HEL）来保证设备无关性和让你的程序正常运行。 
DirectX由很多组件构成，每一个都有特定的用途。组件DirectDraw是最为重要的一个，因为所有的图形都要用到它，它是2D图形的引擎，3D图形也同样离不开它。DirectDraw是我们今天就要说的。其它的组件是： 
DirectSound：提供硬件和软件的声音混合与回放。 
DirectMusic：处理基于消息的音乐数据。它支持乐器数字接口（MIDI）并为创建交互式音乐提供创作工具。 
DirectPlay：使得通过调制解调器链接或通过网络来与应用程序相连成为可能。 
Direct3D：是一个三维图形包，它提供一个高级的保留模式（Retained Mode）接口，这使得你能够实现一个完整的三维图形系统。它还包含一个低级的即时模式（Immediate Mode）接口，使得应用程序获得对渲染管线的完全控制。 
DirectInput：为包括游戏杆、鼠标、键盘和游戏控制器在内的输入设备提供支持。它还为反馈游戏设备提供支持。 
DirectSetup：为DirectX提供了一个简单的安装过程。它简化了更新显示和音频驱动程序的过程，并且确保没有硬件或软件冲突的存在。 
AutoPlay：让你能够制作一张一旦插入驱动器就能自动安装的光盘。AutoPlay并非DirectX所独有，因为它是Microsoft Win32 API的一部分。 
组件对象模型（COM）是DirectX的基础，有一些技巧建立COM对象——别问我怎么做——但你知道一点点还是有好处的。我只是简单说一下，如果你有兴趣，具体的细节就自己查资料吧！可能下一节你有些困惑，但不要紧，我所说的你不用太明白，毕竟我们的目的是使用COM对象，这可比创建容易多了。 
功用
DirectX加强3D图形和声音效果，并提供设计人员一个共同的硬件驱动标准，让游戏开发者不必为每一品牌的硬件来写不同的驱动程序，也降低用户安装及设置硬件的复杂度。从字面意义上说，Direct就是直接的意思，而后边的X则代表了很多的意思，从这一点上我们就可以看出DirectX的出现就是为了为众多软件提供直接服务的。
举个例子，骨灰级玩家以前在DOS下玩游戏时，可不像我们现在，安装上就可以玩了，他们往往首先要先设置声卡的品牌和型号，然后还要设置IRQ（中断）、I/O（输入与输出）、DMA（存取模式），如果哪项设置的不对，那么游戏声音就发不出来。这部分的设置不仅让玩家伤透脑筋，而且对游戏开发者来说就更头痛了，因为为了让游戏能够在众多电脑中正确运行，开发者必须在游戏制作之初，便需要把市面上所有声卡硬件数据都收集过来，然后根据不同的 API（应用编程接口）来写不同的驱动程序，这对于游戏制作公司来说，是很难完成的，所以说在当时多媒体游戏很少。微软正是看到了这个问题，为众厂家推出了一个共同的应用程序接口——DirectX，只要这个游戏是依照Directx来开发的，不管你是什么显卡、声卡、统统都能玩，而且还能发挥更佳的效果。当然，前提是你的显卡、声卡的驱动程序也必须支持DirectX才行。
组件对象模型（COM） 
COM接口是DirectX技术的基础，没有COM就没有DirectX。（不用担心，你只需要对COM技术有一个粗浅的了解就可以使用DirectX——只要你在编写DirectX应用程序时遵循一定的步骤，甚至都可以在不了解COM的情况下使用DirectX。 
DirectX的大多数API都是基于COM结构的。COM为软件模块化和软件重用提供了最坚实的基础，它的最重要的概念就是接口（interface），接口是软件重用的最基本方法。更专业的说，接口是一系列操作的规范描述，即接口规范。 
所有的COM接口都是从Iunknown接口继承而来的，IUnknown接口是所有COM接口的根。IUnknown接口具有3个方法： 
· QueryInterface()：此方法查询新接口，并在新接口存在时返回之。 
· AddRef()：此方法在接口或其它应用程序连编到此COM对象上时将引用计数值递加1。 
· Release（）：此方法将COM对象的引用计数递减1。当引用计数递减到0时，该COM对象自动释放。 
所有COM对象都具有这三个方法。虽然DirectX应用程序一般不需要考虑引用计数的问题，但引用计数确实是存在的，它已经由DirectX自动完成了。我们所要做的，就是创建DirectX对象，然后在使用完毕后调用Release方法释放引用。 
设置 
用DirectX创建程序，你需要有三件主要的事要做。第一件事是COM对象本身，它们包含在.DLL文件里，这些.DLL文件需要在Windows里注册，这在安装DirectX软件包时已经完成了。这些对象是我们创建DirectX应用程序时用到的接口，例如IdirectDraw。但这还不够，因为在COM层上直接使用DirectX是令人沮丧的和乏味的。我们希望有更容易的办法解决它。利用静态库（.LIB文件）是个好办法，它是DirectX软件包的一部分，你可以从Microsoft免费获得。它有一个“打包”函数使你工作更轻松。使用DirectX的不同组件，你需要链接不同的静态库。例如你要使用DirectDraw组件，你就需要ddraw.lib。 
最后，你还需要DrectX头文件，它包含函数原形、宏、常量和你需要用到的各种类型。对于DirectDraw，这个头文件是ddraw.h。要确认你使用了正确的文件版本，你还得让编译器包含软件开发包的目录。具体的做法是： 
首先点击Tool菜单，选择Options，然后点击Directories，在Show Directories for 组合框下拉菜单中选择Include files，增加一个新的目录。将你的DirectX的路径填入。（例如：C:DXSDKinclude）然后将它移到列表的第一位，使编译时第一个寻找它（防止寻找老版本）。然后选择Show Directories for组合框下拉菜单中的Library files，方法同前，只是把include改成lib。现在，你已经设置完了DirectX。你仍然需要手动增加一些库文件到你的项目中，但先不急，我将在以后讲它。我们将使用DirectX 7.0。
DirectX版本号
DirectX 5.0
微软公司并没有推出DirectX 4.0，而是直接推出了DirectX 5.0。此版本对Direct3D做出了很大的改动，加入了雾化效果、Alpha混合等3D特效，使3D游戏中的空间感和真实感得以增强，还加入了S3的纹理压缩技术。同时，DirectX 5.0在其它各组件方面也有加强，在声卡、游戏控制器方面均做了改进，支持了更多的设备。因此，DirectX发展到DirectX 5.0才真正走向了成熟。此时的DirectX性能完全不逊色于其它3D API，而且大有后来居上之势。
DirectX 6.0
DirectX 6.0推出时，其最大的竞争对手之一Glide，已逐步走向了没落，而DirectX则得到了大多数厂商的认可。DirectX 6.0中加入了双线性过滤、三线性过滤等优化3D图像质量的技术，游戏中的3D技术逐渐走入成熟阶段。
DirectX 7.0
DirectX 7.0最大的特色就是支持T&L，中文名称是“坐标转换和光源”。3D游戏中的任何一个物体都有一个坐标，当此物体运动时，它的坐标发生变化，这指的就是坐标转换；3D游戏中除了场景+物体还需要灯光，没有灯光就没有3D物体的表现，无论是实时3D游戏还是3D影像渲染，加上灯光的3D渲染是最消耗资源的。虽然OpenGL中已有相关技术，但此前从未在民用级硬件中出现。在T&L问世之前，位置转换和灯光都需要CPU来计算，CPU速度越快，游戏表现越流畅。使用了T&L功能后，这两种效果的计算用显示卡的GPU来计算，这样就可以把CPU从繁忙的劳动中解脱出来。换句话说，拥有T&L显示卡，使用DirectX 7.0，即使没有高速的CPU，同样能流畅的跑3D游戏。
DirectX 8.0
DirectX 8.0的推出引发了一场显卡革命，它首次引入了“像素渲染”概念，同时具备像素渲染引擎(Pixel Shader)与顶点渲染引擎(Vertex Shader)，反映在特效上就是动态光影效果。同硬件T&L仅仅实现的固定光影转换相比，VS和PS单元的灵活性更大，它使GPU真正成为了可编程的处理器。这意味着程序员可通过它们实现3D场景构建的难度大大降低。通过VS和PS的渲染，可以很容易的宁造出真实的水面动态波纹光影效果。此时DirectX的权威地位终于建成。
DirectX 9.0
2002年底，微软发布DirectX9.0。DirectX 9中PS单元的渲染精度已达到浮点精度，传统的硬件T&L单元也被取消。全新的VertexShader(顶点着色引擎)编程将比以前复杂得多，新的VertexShader标准增加了流程控制，更多的常量，每个程序的着色指令增加到了1024条。
PS 2.0具备完全可编程的架构，能对纹理效果即时演算、动态纹理贴图，还不占用显存，理论上对材质贴图的分辨率的精度提高无限多；另外PS1.4只能支持28个硬件指令，同时操作6个材质，而PS2.0却可以支持160个硬件指令，同时操作16个材质数量，新的高精度浮点数据规格可以使用多重纹理贴图，可操作的指令数可以任意长，电影级别的显示效果轻而易举的实现。
VS 2.0通过增加Vertex程序的灵活性，显著的提高了老版本(DirectX8)的VS性能，新的控制指令，可以用通用的程序代替以前专用的单独着色程序，效率提高许多倍；增加循环操作指令，减少工作时间，提高处理效率；扩展着色指令个数，从128个提升到256个。
增加对浮点数据的处理功能，以前只能对整数进行处理，这样提高渲染精度，使最终处理的色彩格式达到电影级别。突破了以前限制PC图形图象质量在数学上的精度障碍，它的每条渲染流水线都升级为128位浮点颜色，让游戏程序设计师们更容易更轻松的创造出更漂亮的效果，让程序员编程更容易。
DirectX 10.0
DirectX 10
几何渲染单元
在DirectX 10的图形流水线体系中，最大的结构性变化就是在几何处理阶段增加了几何渲染单元（Geometry Shader）。几何渲染单元被附加在顶点渲染单元之后，但它并不像顶点渲染单元那样输出一个个顶点，而是以图元作为处理对象。图元在层次上比顶点高一级，它由一个或多个顶点构成。由单个顶点组成的图元被称为“点”，由两个顶点组成的图元被称为“线”，由三个顶点组成的图元被称为“三角形”。几何渲染单元支持点、线、三角形、带邻接点的线、带邻接点的三角形等多种图元类型，它一次最多可处理六个顶点。借助丰富的图元类型支持，几何渲染单元可以让GPU提供更精细的模型细节。
几何渲染单元赋予GPU自行创造新几何物体、为场景添加内容的神奇能力。灵活的处理能力使GPU更加通用化，以往很多必须倚靠CPU才能完成的工作，现在完全可交由GPU处理。如此一来，CPU就有更多时间处理人工智能、寻址等工作。更令人惊喜的是，几何渲染单元还让物理运算的加入变得更简单，DirectX 10可创建具备物理特性的盒子、模拟刚性物体，物理运算有望在它的带领下逐渐走向普及。可以预见，借助几何渲染单元这一武器，显卡性能将产生质的飞跃，我们也将体验到速度更流畅、画面更精美、情节更细致的游戏。
改进的API和驱动功效
我们知道，每一个游戏角色、武器和景物在3D程序中都是一个Object（对象），而每一帧游戏画面就可能出现数百个Object。在显卡工作时，每一个Object都要从应用程序传输到API接口，然后通过显卡驱动程序到达显卡。在现有的DirectX体系中，任何一个Object进行操作或者渲染，都会导致系统资源的额外消耗，游戏的Object越多，所耗费的传递时间就越长，造成的额外消耗也就越多。据统计，现有的DirectX 9图形芯片在工作时，只有60%的性能用于运算3D程序，其余40%的运算能力被白白浪费了！
为了改变这一现状，DirectX 10在渲染程序中采用了动态索引功能，Object被驱动程序自动加载，数据可以分类并连续输入，这样一来，单次传输的数据量就增加了，从而大大降低了额外耗费的时间。通过引入新的API及驱动程序，DirectX 10将图形芯片的执行效能提升至80%。在不增加显卡硬件成本的前提下，显卡性能得到了大幅提升。
并行引擎支持技术
为了提升多块显卡协作的工作效率，微软在DirectX 10中提出了“Parallel Engine Support（并行引擎支持）”的概念，它可以预先把两个GPU需要的数据分别传输到两块对应的GPU当中，帧渲染将完全由驱动控制和调配，两块显卡的工作强度可以获得很好的平衡。而在目前主从卡的运作模式中，主卡要对从卡框架、渲染数量进行判定，而引入并行引擎支持技术后，主从卡的概念将消失，两块甚至多块显卡的协作威力将充分体现。
统一渲染架构
DirectX 10最大的革新就是统一渲染架构（Unified Shader Architecture）。目前各类图形硬件和API均采用分离渲染架构，即顶点渲染和像素渲染各自独立进行，前者的任务是构建出含三维坐标信息的多边形顶点，后者则是将这些顶点从三维转换为二维，这样便可以通过视觉欺骗在屏幕上显示出“三维”的场景。与此对应，GPU中也有专门的顶点渲染单元和像素渲染单元来分别执行这两项工作（由于工作量不同，这两种渲染单元的数量不相等，顶点渲染单元通常只有像素渲染单元的1/3～1/2）。在过去几年中，这种分离式设计对计算机图形领域的发展做出了一定的贡献。
不过，微软认为这种分离渲染架构不够灵活，不同的GPU，其像素渲染单元和顶点渲染单元的比例不一样，软件开发人员在编写代码时必须考虑这个比例，这就大大限制了开发人员自由发挥的空间。另外，不同的图形游戏或软件对像素渲染和顶点渲染的需求不一样，导致GPU的运算资源得不到充分利用。为此，微软在DirectX 10中提出了统一渲染架构的思想：在相同物理类型的渲染单元上执行不同类型的渲染程序。换句话说，只用一种渲染单元，让它既能完成顶点渲染，也能完成像素渲染，甚至还能实现几何渲染。这样一来，渲染单元可以得到最大程度的利用，减少了资源闲置的情形。目前，Xbox 360的显示芯片Xenos就采用了统一渲染架构，该芯片一共有48个渲染单元，它们可全部用于顶点渲染或像素渲染，没有固定分配比例。此外，ATI也打算在新一代的R600芯片中采用统一渲染架构。
当然，统一渲染架构也并非完美无瑕。相对顶点渲染来说，像素渲染将面临大规模使用纹理所带来的材质延迟，这是统一渲染架构急待解决的问题。据悉，NVIDIA下一代的G80有可能继续坚持分离式设计。到底是统一架构好还是分离设计好？相信只有等G80和R600同台竞技后，答案才会揭晓。不过有一点可以肯定，在微软的大力推动下，统一渲染架构是大势所趋。
Vista
除统一渲染架构外，DirectX 10的另一大特色就是与Windows Vista紧密结合，Vista系统将调用GPU资源来渲染Aero Glass 3D界面，这样图形API就与操作系统核心高度整合在一起。举个例子，当我们点击应用程序时，CPU将立刻收到驱动程序的指令，而软件界面渲染指令则通过DirectX 10直接传送给GPU，这样，Vista就能与CPU和GPU同时沟通，让3D界面渲染工作变得更高效。
相比之下，在DirectX 9环境中，Vista（软件）界面的渲染工作就要“迟钝”一些了：用户点击运行某个软件，Vista将相应的指令发送给CPU，要求CPU进行后续处理；CPU接到运行指令的同时向GPU发出请求，要求GPU在屏幕上渲染出界面。GPU（支持DirectX 9）识别Vista界面渲染指令后完成相应的工作（注意：DirectX 8显卡无法完成渲染工作，必须让CPU通过软件模拟来实现，此时系统速度非常缓慢）。换句话说，在“DirectX 9显卡+Vista”的平台中，CPU还是核心，GPU必须在CPU的控制下工作，而Vista系统也必须通过CPU来调用GPU的资源。
DirectX9还有一个不足之处，那就是它只能进行单任务渲染，即无法同时完成两个场景的渲染工作（如无法在运行游戏的同时为软件渲染3D界面），应用范围受到极大的限制。而DirectX 10则允许GPU同时渲染多个不相关的3D场景，工作效率大为提高。因此，尽管DirectX 9显卡大都能驱动Vista华丽的Aero Glass视觉模式，但很多方面受到了限制，只有DirectX 10显卡才是Vista的理想“伴侣”。
SM 4.0
从DirectX 8开始，Shader Model（渲染单元模式）在DirectX体系中的地位就日趋重要，其版本和渲染单元的规格也成为了决定显卡性能高低的关键因素（编注：关于Shader Model的具体介绍，请大家参阅本报今年第7期D15版）。随着DirectX 10时代的到来，Shader Model也升级到了4.0版本。与眼下如日中天的Shader Model 3.0（以下简称SM 3.0）相比，Shader Model 4.0（以下简称SM 4.0）有哪些可喜的变化？
首先，SM4.0中的指令长度被提升到大于64K（即64×1024）的水平，这是SM 3.0规格（渲染指令长度允许大于512）的128倍。显然，SM 4.0在为渲染出电影级别的游戏画面做准备。由于渲染指令长度大幅提升，SM 4.0中相应的寄存器规格也有所增强，如Constant寄存器采用16×4096阵列、tmp寄存器则有4096个、input寄存器采用16/32规格等，上述指标都比以前的DirectX有明显的改进。其次，SM 4.0在纹理数量方面也有提高。DirectX 10允许程序员在渲染物体时使用128个纹理，而DirectX 9只提供4/16规格，更多的纹理意味着物体表面精度更接近真实，游戏开发者拥有更广泛的选择。
从上述情况不难看出，DirectX 10在性能方面的提升是巨大的，它将进一步解放CPU的资源。当然，我们也必须看到，DirectX 10对硬件（尤其是显卡）的要求也更为苛刻，GPU在设计上也将更加复杂。