简介
, j6 \4 j* `: Y6 x" Y" J. S0 v4 ^. W) T
DirectX(简称DX)是Microsoft在Windows平台上提供的一组开发多媒体程序的API。其中包括了2D/3D图像,声音,输入设备,网络设备等几个部分。本文主要讨论的其图像方面内容的演化。$ E/ j; J! T( C1 B; I
& [+ c7 g$ `' j; g3 YDX的2D部分称为DirectDraw,简称DDraw。DDraw所提供的主要功能是画平面图形,这个功能适合于制作2D游戏。DX的3D部分称为Direct3D,简称D3D,主要用于3D游戏的开发。早期的D3D是很依赖于DDraw的,D3D负责将3D的模型通过坐标变换投影到2D的平面,然后内部调用DDraw的功能把他画出来。但后来3D游戏成为了主流,几乎所有的显卡都提供了一定的3D加速功能。所以D3D得到了更多的重视,也逐渐和DDraw划清了界限。而DDraw则逐渐衰败,到了DX8以后,DDraw甚至被取消了。这也是很合理的,你既然能画3D东西,自然能画2D的东西。加之DDraw的复杂性根本不能与现在的D3D相提并论,所以被取消是必然的。) U m& Z) U: {( _( n
' c. Y7 Q) p# I3 z8 ]
DX从出现至今已将近十年,经过了9个版本的改进,现在已成为PC上游戏开发的最重要的工业标准。但这并不是与生俱来的,而是经历了无数的挫折,改进。让我们来回顾一下这段历史吧。' h* x1 a8 H" w. j; q# T
; R( \ {! y6 {: T Q; s
! \- N, C! Y$ H4 k3 v2 z! |
. g+ O7 d7 g0 w$ y0 E8 t1 _, ZDX1.0" ~/ S% L8 h0 t, |) \- U: h( |
* ~: ?' z) T# W" ^6 t1 B2 Y( a5 V
我第一次听说有DirectX这个名词的时候DX已经发展到了3.0。那时DX1.0早已是传说中的东西了,时至今日,传说更是变成了神话。即使在互联网上也极难找到关于1.0的资料。我唯一找得到的传闻是,1.0开发于1994年底到1995年9月。主要开发人员为:Craig Eisler , Alex St.John, Eric Engstrom. 运行在Windows95 之上。
( m" q) i$ @% a0 _1 ^. I' i# H& t/ k: T$ y
让我们回想一下当时的情况:Window95还在开发和最后测试中。绝大多数PC运行的操作系统是DOS6.22和Windows3.1。CPU基本上是386/486,显卡多是EISA/VESA。显卡厂商出于战国时代,品牌奇多,而且互不兼容。当时重要的品牌有Trident8900/9000, Cirrus Logic 54xx系列。8 o1 {3 `' Q) f' u3 ^' l9 J
9 j: o) D& R9 R- X
当时游戏分两种,DOS的和Windows(WIN31)的。
" J! x2 E! E7 q' w. _9 x1 r
+ n! O0 @1 D( u& V$ ?' vDOS游戏占了绝大部分。当时显卡芯片制造商在软件支持方面没有一个强而且统一的标准。唯一统一的标准是BIOS INT10,那个标准只支持640x480x16或320*240*256以下的显示模式。而当时的显卡芯片则在不同程度上提供超越这个标准的能力。另一个标准是VESA的标准,这个标准的问题是它只规定像素级别的操作,对块操作则没有什么支持。画东西得一点一点的画,每画一个点都是一个中断调用,所以很慢。快的方法直接访问位于物理地址0xA0000的显存。而访问显存则是没有什么标准的。 u, Y( y$ q# k* _7 S4 D
/ K# c! i* l' J% R& c
这种局面对软件开发商,硬件开发商,以及用户都造成了不利的影响。软件开发商得根据不同的显卡来编写不同的代码,硬件开发商则要为那些大牌应用程序(比如wordperfect/autocad)开发驱动程序,这些驱动程序的要求又各不相同。最终用户则不知所措,没有什么可以保证你的显卡和应用程序能够一起工作。
2 i2 ]$ J6 Y7 J$ L2 }) A
7 T- |7 v1 O% d' y1 E6 }: [在声卡方面也是类似的情况,好在Createive SoundBlaster 处于声卡市场的统治地位,所以所有的软件商至少保证它的程序对于SoundBlatser是能工作的。而小硬件商者尽量把自己的产品做成SB兼容(记得当时的DOS游戏大多会带一个setup.exe。让用户来选择显卡芯片和声卡芯片)。
9 i2 V; m! I' w: ~7 ]! P% B; S' @
4 o' g; j$ ~; J0 o8 m% v再来看一看Windows下怎么样。象扫雷,纸牌这类游戏对于图形系统无论是功能上还是速度上要求都不高,GDI就可以搞定。而复杂一些的游戏则需要额外的支持。提供这个支持的库叫做WinG。WinG和DDraw有着相同的使命,即提供一个与硬件无关的高性能的图形编程界面。但WinG显然没有完成这个使命,它提供的性能还是不够高(相对于DOS下直接写屏)。它也没能成为DDraw的前身,因为它是一个完全基于Win16的构架。( l% U4 u# W& C3 z- D
8 [. P5 ]2 a* o, P! R, ]这就是DirectX出现的背景。/ G3 A z @! y
0 H/ X" G# d% Z& g
$ h4 {1 b# e# y Z0 z2 O1 |" i1 j
, d9 y2 f2 [6 _" z) u" l: `. d, SDirectX到底意味着什么?我觉得它实际上包含了三个部分,首先是Microsoft与硬件商的协议,硬件商的职责除了制造芯片板卡以外还要提供一个驱动程序,这类驱动程序提供了一个一致的接口来调用或查询硬件所提供的功能。这个接口称为DDK。软件开发商对DDK应该是一无所知的(至少理想情况下是这样)。第二部分是Microsoft与软件开发商的协议。Microsoft向软件商承诺:只要你遵守这套协议,我保证无论Windows是运行在何种显卡上,你的程序都能正常运行。这个协议叫做SDK。第三部分这是DirectX本身,这部分东西负责把DDK得到的功能加上增值服务转化成SDK所需要提供的东西。这样软件和硬件间的耦合就在相当大的程度上分离开来了。硬件商从此只需要为Windows写一个驱动程序,而不用为各个应用程序写一个驱动程序。软件开发者也不必过于关心程序到底运行在什么芯片板卡上。用户购买设备的时候也只需要认清Windows compatible这两个字。每个人都是获益者。+ Z0 k- D+ z( `$ N K
8 r4 I/ D# T7 i8 ?2 m" ^
0 Z U& q$ V1 e$ ~' R+ o
: r7 d0 U- S' a: G: l[闲话:关于标准]. A5 I: `) C$ a2 I# a! t2 C- _
( ^: g# z2 ^" g6 d* h" ]6 v“每个人都是获益者”这种好事可不是每天都会发生的。如果真是这样,为什么不早发生呢?
% f M' r' M+ v" `
" |! a0 y. c8 r4 \ Q0 g! \* s8 w标准不是谁都可以制定的,定标准的人得有一定的实力,别人才会拥护你制定的标准。而在PC世界里,直到那时,Microsoft绝对的统治地位开始显露(虽然IBM还在夜郎自大的叫嚣OS2Warp是如何的稳定,如何的高性能)。所以Microsoft有实力来制定这样的标准,为了支持新一代的Windows, Microsoft 也有需要来制定这样一个标准。0 c8 s. L# m8 P" x+ }
& C3 |3 Z) D) B4 L1 M
Microsoft得到的好处是什么?使在Windows平台上开发更为方便,自然有更多开发者被吸引过来,开发者越多应用也就越丰富,自然用户也就越多。这自不在话下。另一个更大到好处是,从此再无操作系统能在PC上与Windows抗衡。因为如果有一个新的操作系统要想和Windows争一下短长,它至少要支持Windows所支持的设备。而这些设备的标准捏在Microsoft的手里,如果你用这个标准,你就总是跟在Microsoft背后面转。Microsoft想改一点什么你也得跟着改。如果你不用这个标准,有多少硬件商会花力气来为你这个市场份额很小的操作系统开发驱动程序?即使你愿意为每个硬件来写驱动,只怕你也没有能力在第一时间来提供对最新硬件的支持。Linux基本上就是中了这个套。
: m( ~7 y: {' |& _! B7 o% E t+ Z; _
6 N/ }: s0 A7 @4 t1 y" a8 ]# t9 j9 F, Q O& |" d$ c
3 O' X' C( |8 b' A4 t
F0 U2 O" f- j' P# w
1 c- w/ a$ Q6 j! ^4 @DX2.0
* A* N" ~8 Q( a
+ T2 Y6 a6 U6 e; s5 hDX2.0发布于1996年春。这套SDK包括了六个部分。DirectDraw, DirectSound, DirectPlay, Direct3D, DirectInput, AutoPlay。这基本划定了DX所要处理的问题的范围,这些基本的模块的划分虽然只以后版本中有所增减,但大致上保持了如此风貌至今。DX2采用了COM构架。这一决定也从未曾改变。1 q K4 R' w' s* f& {
( z% ^' x: a9 r$ W5 \: }4 G
当时主要的游戏游戏几乎全是2D的。若干幅卷轴作为背景,加上一些Sprite在上面移动,作为角色。DDraw基本上是为这类游戏设计的。
: b1 K' n% f- Y; o
& ~* d9 C+ A& V/ D% SDDraw提供了4个Interface,IDirectDraw, IDirectDrawSurface, IDirectDrawClipper, IDirectDrawPalette。DDraw的基本工作过程是这样的,你首先要创建一个IDirectDraw的interface,一般这由DirectDrawCreate来完成,但你也可以用CoCreateInstance。然后你通过IDirectDraw::CreateSurface来创建一些OffScreenSurface,用以保存背景或Sprite。然后就是把背景和Sprite用IDirectDrawSurface::BltFast画在不同的位置上。最后调用Flip方法将BackBuffer瞬间置成FrontBuffer。DDraw只能用来画长方形。而象角色这类非规则图形,则通过SetColorKey将周边无用的像素设成透明。. J7 s! S% ]* a& l4 e6 q6 V1 i. N
2 M* a; C+ D# C: u3 W
/ d6 T3 p0 R$ ~! e+ k% J$ }1 k9 I u% g; r1 H: ^5 J, V, i/ V& U
从2.0开始,D3D就提供了两种模式,retained-mode和immediate-mode。Immediate-mode提供primitive层面上的功能,相对来说比较底层。Retained-Mode则提供model层面上的功能,以及其他一些“高级”特性,如动画支持。当时Microsoft宣称除了从其他API上移植旧代码,大家都应该使用retained-mode。* c9 |+ I' n. q4 K
; E! y$ {5 r1 B5 m- n X4 t/ v但那些所谓的高级功能并不是软件开发者所需要的,相反,由于retained-mode层次太高,如果你正好做它支持的事情,用起来很方便,但如果你要做一些它不直接支持的事情,则非常的牵手绊脚(这是所有高层API所共有的特点)。
: H0 a9 L& z* [7 D" w
R% M( ^- i4 W! T7 k6 u% J并不如Microsoft所希望的那样,retained-mode从头到尾就没有受到过开发者的欢迎,所以从DX6开始,retained-mode逐渐淡出,DX8彻底取消了retained-mode。相反,并不是主打的Immediate-mode倒是每个版本都有所改进,并且越来越兴旺。7 h6 n# i! k' E5 h9 ~# f
* [# u' t: O6 ?让我们看一看2.0里的immediate-mode都有些什么。IDirect3D, IDirect3DDevice, IDirec3DExecuteBuffer, IDirect3DLight, IDirect3DMaterial, IDirect3DTexture, IDirect3DViewport, 一共是7个interface。IDirect3D负责创建除IDirect3DExecuteBuffer以外的各类interface。IDirect3DDevice用来设置矩阵,设置当前Texture,建立并执行ExecuteBuffer,IDirect3DExecuteBuffer则用数据的形式描述了DrawPrimitive的操作。在这个早期版本里几乎没有没有RenderState / TextureStageState这类概念。是一个非常简单的API。
& M# P, d4 ~" I% {$ B# `- S8 l1 O2 `2 X) }1 T5 D* C: ~; k5 T3 s
虽然当时已经是1996年了,但游戏几乎清一色的是2D游戏,所以,即使DX提供了D3D,但并没有什么人真正使用它。唯一两个伪3D的游戏Doom2 / Duke3D 又运行在DOS下。
) [2 j5 B( x6 ]# O3 U; [
- z0 c) ~' z8 S0 r4 t* F& J7 ?4 W8 \4 e% a. u) B; y0 z7 o& |6 C
( I' g* G, S, M, j( f: _3 U" \伴着Win95的普及EISA/VESA 显卡已逐渐被PCI显卡所取代,代表显卡有S3765/S3868。: Y F4 p0 l6 ?& w+ C% M4 ?) f
- ?( S: ], M2 b; \3 s# T- V6 k% T. Y' ~- L' @) |
& U7 B7 N; u- Q( w' D& q4 k& o[闲话:关于COM]
9 j/ p7 b/ O5 j/ _+ I0 {/ Y9 z/ n9 ^
在我看来COM并不是一件必需品。它更像是一种编程规范或指导原则,而且应该是Microsoft公司内部的规范和原则,但Microsoft却把它拿出来,强加给所有的开发者,这实在是一件不太可思议的事情,但Microsoft确实这么做了。GUID, QueryInterface 这些张牙舞爪的东西着实吓退了一帮初学者,但COM所提供的好处DX却没享用到什么,比如说分布式对象系统,我从来没有看到过有人试图把DX作为一个Server,放在一个单独的进程里,或是放在不同的机器上。好在DX也没有非常频繁地使用COM相关的特性。看久了也就习惯了。$ F. l* Y# `! c0 r( t" g; L$ L% {+ T
" {6 \+ g9 [+ Y' O* k+ @; I6 e7 ?
9 N! F' u2 `/ q/ |/ A: Y; j1 q g. [: W" r
3.0
' g% D" c0 v2 L/ s) i s
* R+ Q2 R9 s" U紧跟着2.0 ,Microsoft于1996年夏季推出了3.0。从SDK的方面来看几乎没有什么变化,DDraw和D3D纹丝不动。DSound和DPlay增强了一点。为什么要推出这个与2.0如此相似的版本呢?原因是NT4.0希望整合DirectX。所以Microsoft开发了两个Runtime,一个工作在Win95上,另一个工作在NT上,这两个Runtime共享相同的API。4 M) K- W3 ?2 F" c
9 Y# I5 n8 l S B3 J7 }
0 s# m5 F* Q8 r6 p% H
# a+ b; i0 i$ W% u7 S0 P
4.0% i! g2 G9 \- K
4 ^1 U3 p. r; p0 L# [5 i4 h
4.0没有正式发布过,Microsoft也没有官方记载。我只能从一个名叫Reymond Chen的人的WebBlog上找到一些线索,转译如下:- L6 R& S. N r1 i8 T2 [5 M
$ N2 Q' q4 W1 B7 n# @
2 a8 M0 H" b# ], N ]- q7 u. r$ q7 {0 i4 ~
' \: F' @ P9 W" k( ^* j7 c% [) YDirectX 4怎么了? 如果你看一眼DirectX 的历史, 你会发现没有DirectX 4 。直接从DirectX 3跳到 DirectX 5 。为什么会这样? 在DirectX 3 发布了之后, 有二个后继者产品同时被开发:希望在短期内发行的称作DirectX4,希望有较大改变并有更多时间开发的叫DirectX5 。但从游戏开发者那里得到的反馈是, 他们并不在意DirectX 4的那些小改动; 相比之下令他们更感兴趣是DirectX 5所能提供的功能 。因此决定取消DirectX 4 ,并把所有的功能都加入DirectX 5 。 那么为什么不把DirectX 5 改名为DirectX 4呢? 那是因为在当时所有的文档中已有成百上千个地方分别称呼这二个项目为DirectX 4 和DirectX 5。在项目开发到一半的时候更换名字只会造成更大的混乱…..* j, {5 a9 W+ t
. K3 |' P( _8 @9 U. r& D; d5 t5.0+ J' ]7 S; p* n( x. T' @" U
# e: q# Y2 w, V: P
1997年夏季DirectX5发布了,这个版本比之前三个版本有着较大的变化。DDraw的主要改动如下:增加了Viewport的概念;利用MMX技术提高硬件模拟层的性能;支持创建比BackBuffer更大的OffScreenSurface;支持AGP显卡,可以把OffScreenSurface建立在系统内存上,从而摆脱显存大小的限制。DDraw发展到这个阶段,已完全站稳了脚跟,2D游戏基本上都已到了Windows平台上。只有少数一些喜欢怀旧的人还在玩DOS下的游戏。 Q: W% v3 a$ J* v) a& u
5 x9 N, U6 Y. J7 [
在D3D方面,虽然在文档中,Microsoft仍然推荐Retained-Mode,但他们显然认识到了Immediate-Mode更受欢迎,所以在Immediate-Mode上作了很大的修改,并且完善了文档。
; {$ Y; K' X% }& `! {' u5 F) d
6 M& Z0 _& I" b$ |) Y u! M在这个版本中,你可以看到两个D3DDevice interface,一个是IDirect3DDevice,这个interface基本上兼容于2.0/3.0里的device,通过ExecuterBuffer来画东西。另一个是IDirect3DDevice2,它提供了DrawPrimitive / DrawIndexedPrimitive / SetRenderState 等方法,你无需使用ExecuterBuffer这个类似于opengl里DisplayList的概念。这个Device和我们现在所看到的DX8/DX9里的Device已经有点像了。但注意,由于当时没有VertexBuffer / IndexBuffer 的概念,所以,DrawPrimitve / DrawIndexedPrimitive 实际相当于现在的DrawPrimitiveUp / DrawIndexedPrimitiveUp。而且Vertex种类也只有三种,Vertex / Lit Vertex / Lit & Transformed Vertex。4 e) |6 L. t. ^
8 C% V2 Z/ L- y! m( V
当时3D游戏却并不繁荣,但有几个重要的3D游戏出现在那个时期前后:古墓丽影1和Quake 1。这两个游戏都运行在在DOS下,靠的是软件渲染。另一个是Need For Speed 2, NFS运行在Win95之上,需要DX3支持。有趣的是这三个游戏都额外支持一个称为Glide的API。
2 l3 a( W3 f# R* d5 t- u4 @; e# T* d" \. E
提起Glide,你可能觉得陌生,但如果说到3dfx / voodoo马上就觉得如雷灌耳了吧。Glide就是voodoo卡的API。当时绝大部分显卡制造商还只是把目光集中在Mpeg解码上。3dfx却已经开发出了真正具有3D加速的硬件voodoo1芯片。Voodoo1具有z-buffer, alpha blending, bi-linear filting等重要的功能,并且均以硬件方式实现,这给3D游戏的画面质量的速度以质的改变。在软件支持方面,3dfx并不追随D3D或是OpenGL,而是自己开发了一套和voodoo硬件紧密结合的API --Glide。由于有了硬件支持,glide的游戏远胜于D3D的游戏,这个状态持续了很久。
/ b; `5 f" H0 r& |3 I1 E S3 p1 {# a( {( d- n
D3D5没有受到热烈的欢迎,相反遭到了强烈的抨击,抨击来自IDSoft的Carmark,主要意见集中在易用性上:/ X5 I: G ?. b
$ G F, q3 E" u F7 i5 C6 e(1996年底)% @: M/ a+ `4 K" ?6 y1 T" R
" v2 w& m" l' y) p7 `
我用了六个月的OpenGL,这个API给我很深刻的印象,尤其是在易用性方面,一个月以前,我把Quake移植到了OpenGL上,这是一段令人愉快的经历,没用多长时间,代码也很干净。2 c8 Y8 O8 C/ w0 w+ G2 [
7 \" B1 z1 u- e+ V( E f+ t
然后我试图把QuakeGL移植到D3D-IM上,以便学习这个API,并拿它和OpenGL作一下比较。好吧,我已经学够了。我不会完成这个移植,我的时间可以用来做更有意义的事情。* r/ ^, e+ G! G7 S, u0 x0 e
2 }7 H# A4 w( T* K. J; M6 \
…..) r X7 [% ?, {& {
- X- L# B2 H1 @7 q3 K6 J
D3D-IM是一个遭透了的API,它给使用它的程序员带来无尽的痛苦,却没有丝毫好处。我不认为它适合于做任何事情,而OpenGL则什么都干的很好,从Quake到SoftImage。从技术上讲,D3D毫无存在的理由。
$ N% N a$ L" P. u; A7 t$ P+ t# u" W5 k. N* U3 {# w. X
我相信D3D未来的版本会烂的少一些,但开发社团何必和这个先天不足的API一同经历混乱的进化过程。
A4 c: {- J) Q }
9 d: e2 v( E1 A…...' h/ r( E/ X8 Q
, r4 C' h8 V; V" E8 D, C6 Z
http://www.bluesnews.com/archives/carmack122396.html( X$ y! G# {% P
# m' Z: T2 @/ ?5 O) {9 V
. g6 S1 H) ]. v# e
1 l( ]8 a1 @8 F" a F0 r/ P [2 S(1997年中)6 E+ ?5 A( V4 O: I% s4 y* N3 {
3 L4 }) q$ B# x/ Y2 o2 n
我们没有必要盲从Microsoft所犯的每一个错误。; m6 V+ l8 O, K
1 Y- s4 B+ Z4 @0 @
http://doom-ed.com/blog/1997/07/03/d3d-vs-opengl
/ ?, E0 b6 V2 Y$ q! u
( \2 g' q2 c1 {( c; G& @- W) T+ }" y' {1 m' I) o Z' I
2 s7 K" F) y2 \; f5 V- r6 l9 y2 R+ p0 w4 H
* j" h6 Z$ _- A) b4 [
0 V6 ~4 b. d# t' T: k
! q i% h l$ l/ S( E5 R H1 {D3D的负责人Alex St.John对此给以了回应: F2 I5 E: q; v) ~; \% \4 B
5 Y" b+ a3 `9 R$ A0 R* ?8 r
http://rmitz.org/stjohn.html2 W5 s9 U1 |, J0 p% @& K
3 n$ w% W/ i0 U9 F( W0 F
http://www.winnetmag.com/Article/Ar...7172/17172.html
* J; M2 G3 E9 e- S( b" B1 k$ z8 _5 R4 r' ^, w2 P9 A
但DX5项目一结束,Alex就被Microsoft解雇了。. c( ?+ @4 @" ?, X9 l9 l0 ]
: d r$ _& _% c! O* D/ r+ ?% Y" D7 L# ]9 S
' U% V$ r3 D+ Z8 H4 H8 p
7 z) R' L- [5 {+ u9 ]9 n
- v, l. n) V5 r' Y" G, c; p5 e5 _6.0
* z7 T0 m% T6 j
1 d! N5 |3 K3 w5 C6.0推出是在1998年夏。DDraw在DX5的时候已经颇为完善,所以6.0的DDraw主要做的是易用性的改善和性能的提高,以及对多显示器的支持。
# C2 k' p) o( d$ g, V# ~! u: S5 i+ z+ F9 _. P3 x% _. O$ m9 l2 }
相比之下D3D的改动则很大。
$ R, b! G$ j7 X+ J3 A. }! E1 Q7 p* Z; P( P& q8 F7 l
首先,Retained-Mode被扔到了一个称为DirectX Media的组里,意味着它已经不是核心的部分了。Intermediate-Mode终于成为了首发阵容。D3D6为它增加了很多新的特性,比如,VertexBuffer, FVF,MultiTexture,StencilBuffer。都在这个版本中引入。D3D6仍然保留了ExecuterBuffer,但这也是ExecuterBuffer最后一次登场。; m3 ^! k( z' R, C0 H* m
# l% c$ a2 {) c. n; H) X
无可置疑DX6在3D方面作了巨大的努力,也取得了很大的进步,但这并没有扭转颓势,还是受到了不少的批评。批评主要来自Glide阵营。在3dfx的新闻组里,你可以清晰地感觉到这样一种认识:D3D作了太多的事情,比如说Vertex Transform 和 Lightening的事情完全应该由游戏的开发者来做,这样才能有细微的控制和最佳的优化。D3D硬是要接管了这个过程,但又管不好。! }: [( M% V7 e7 a9 h9 A1 V) p o
5 }4 d% f4 c: N0 H3 @" `这是因为Glide基本上是一个2D的API,Glide程序员已经习惯了程序员控制坐标转换和光照,API只管光栅化的这种工作方式,所以他们自然的感觉D3D把手伸得太长。- T! {5 P2 x* ^+ U& W
7 b1 a, l# }% _, J* v4 ~8 s& p! B2 V- R- Q4 X2 T9 o! w6 h
. P# ] y7 R) m不久后,Microsoft推出了6.1,在DDraw / D3D API 上没有变化。 X1 U- L, k c2 m& [# d% S+ y7 Q: s
6 D) O& [( j3 u/ F& Y. l& s& }2 X
6 I8 K. {3 V% ~. l9 L/ O+ h0 @% D6 U; K$ S/ P: [5 f% k
在DX6推出前后,3D加速卡开始多元,Voodoo1 / Voodoo2 / Riva 128 /TNT1 / Ati Rage Pro / S3 Savage / G400,1999年以后推出的TNT2和VOODOO3 代表了当时的最高水平。
+ m# k" K) P( w
0 m7 M& H$ k& G* H/ n+ @. O* ?# x, a
- M& x( U! D& e3 G. p$ r8 V
[闲话:关于API]
- B6 P+ D# G4 J9 x' h! B9 Z" J+ b! M( w
有三个API并存,一个的提供者是向来无往不利的Microsoft,一个的推崇者是游戏程序员里的大哥大,另一个当时最好3D硬件唯一支持的API(后来voodoo也开始支持opengl/d3d)。到底选那一个呢?小公司基本上是随便压一个宝,大公司的态度则是跨API,就是试图在三个API上建立一个抽象层,尽量把更多的逻辑移到这层以上来。( { @# l( j L* \
2 z; h, @9 r$ U% V) PMicrosoft也放出风声要和OpenGL社团紧密合作创建一个工作在OpenGL和D3D之上的API。但这个API从没有真的出现过,可能是因为后来D3D逐渐占到了统治地位。5 ]7 d: i9 v" {/ D! \9 d
1 I$ b; {3 o+ o8 a& M* w" j3 k# ~5 t
7.0
! N+ J: }" b8 Z1 v- m, y2 o$ z! a
夏季看来是DX更新版本的季节,1999年夏,DX7如期而至。在功能上,D3D率先支持Hardware TnL,以及其他不少高级的渲染技术,如Matrix Blending动画,Blinn-Bump mapping. Cubic Environment mapping。 Hardware TnL是一个极为重要的功能,就是让显卡来进行3维坐标变换和光照计算。这项繁重的工作以前都是由CPU来进行,有了Hardware TnL后,CPU的计算能力就能被节省下来进行AI或物理模型的计算。
4 d% u) y: `. S5 d7 Q# d# `4 |( U- l l! e0 f* k& R8 q1 o" o# e
在API布局上,Microsoft作了大刀阔斧的修改,挪走了几乎所有从2.0起就有的Interface,诸如,IDirect3DViewport, IDirect3DMaterial, IDirect3DTexture, IDirect3DExecuteBuffer, IDirect3DLight, IDirect3DViewPort。 只剩下三个Interface, IDirect3D, IDirect3DDevice, IDirect3DVertexBuffer。那些被取消的Interface变成了简单的数据结构。IDirect3DTexture 则用IDirectDrawSurface来代替。
. H* i+ ?7 H6 Q( l
2 r! h$ v$ h3 }) Z# x& OD3DX首次出现,这是一个辅助性的Library。其中包含了许多经常要被用到但逻辑上又不属于D3D例程。; g0 P& O* i" C6 A0 @ C
$ H0 u7 |( |" y1 N0 B. x. J更出乎意料的是这个版本的DX除了支持C++以外还支持Visual Basic。也就是说,从逻辑上讲,你可以用VB编一个完整的游戏。但实际上似乎没有人去干这件事情。所以这个特性的实际意义并不在于此,而在于DX可以有除C++以外的Client。而具备这个能力可以表明DX内部逻辑的清晰与完整性达到了一个新的高度。1 ?) w0 z% W+ z# Q( T
# w0 `) d: o; i2 y5 a$ ~9 ]& N
DX7是D3D真正走向胜利的第一步。根本的原因是在于Microsoft和硬件商开始了对未来3D技术的合作.Microsoft知道硬件商正在发展什么技术,并在新版本的DX中给以支持,同时也保持对新技术发展方向有一定的影响力。从而使DX在对新技术的支持上始终保持领先地位,这是OpenGL所无法做到的。
) j7 d3 h) M/ H; q- t9 d# L1 Y9 `: p" D: [) k& O
在DX7发布时,唯一一块能支持Hardware TnL的显卡是nVidia的Geforce256。$ F8 Q5 T" j6 i$ P/ m# W Y8 c" r
' X# o" C/ @3 m, O! t( P
2 [2 J: j2 {- t" i1 ?( @$ p1 m# {0 k; j, Q, E
[闲话:关于3dfx]! e- E+ w$ X" E" J
, k6 \% \6 c: V0 [/ B3dfx从voodoo1起家,到voodoo2如日中天,再到voodoo3被nVidia逐渐赶上,voodoo4/5时代开始走向没落,终于没有熬过2000年IT界寒冷的冬天,于那年年底宣布破产。
n; ^$ H. p) n, ?5 c: M9 X
/ G( F7 T& \/ u7 D: E! ]4 F虽然与劲敌的nVidia 的激烈竞争是一个原因,但更大程度上是自己搞砸了。连续的决策失误把自己逼上了绝路。
* `7 [/ p8 q% n V
. {' b7 F- c" w首先,在D3D还没有成长起来的时候,没有将其彻底打垮。试想一下,如果Microsoft放弃了D3D,Glide将有很大机会成为PC上3D唯一的API。持有这样一个API,会给其他硬件商的崛起造成很大的障碍。而3dfx却错失良机,Glide发展缓慢,从2.x到3.x竟然花了两年多的时间,而且没有本质的进步,临死基本上还是一个2D的API。如果说作为一个硬件商,不想更多介入软件事务,那么就应该积极的支持D3D或者是OpenGL。但3dfx也没有这样做,他们很晚才开始编写D3D和OpenGL的驱动程序。+ T+ F2 G2 ~7 k3 [* V* u" o
1 z+ J1 T9 r: b% p) |其次,1998年底,3dfx收购了板卡制造商STB,并且从此高端芯片只提供给STB,低端的芯片才给以前的合作伙伴如华硕,创新,ELSA。这种自绝于人民的行为无疑是要把这些板卡制造商推进nVidia的怀抱。
/ b7 |' U+ ^ v$ O6 s- d% F/ a S* n0 L i* s& I. c( ~
再者,当3dfx还沉湎于multitexture时nVidia早已进入了下一个时代,技术上也确实落后了。5 v) E2 ^0 h/ n) N
) Z/ F- ?8 k/ D. T0 F3dfx破产之后,nVidia替他收了尸。招募了一些他的员工,购买了一些无形资产,如voodoo/3dfx的商标。但很久也没有看到nVidia用这些购买来的东西做点什么。后来终于明白了nVidia根本就不想用这些东西做些什么。他只是怕有人用voodoo/3dfx玩一手借尸还魂,平添一个潜在的威胁。
7 y' A' |+ I* Z6 X0 o6 z; N* P V* @/ L) e7 J5 {- U- p8 H
$ a1 \% f! e% M6 l ?3 d' Y/ ?
" ~3 Z+ k9 \( B" L- N1 N9 B% ]- r- }3 E
! z! P# j& u7 d! c: e8.00 O$ d3 O3 S1 J. {
H2 h" q3 v( K7 V" y8 O( v9 s
2000年夏,DX8乘胜追击- p. ^ @) o# O7 D8 Z( O* R9 t' ~6 z X; [
" z9 S) G# n5 n4 `
这一次在功能上的进步毫不逊于DX7之于DX6,最大的突破在于引入了VertexShader和PixelShader。VertexShader是作用于每一个顶点的一种小程序,这种程序负责三维坐标变换以及顶点光照,贴图坐标和雾化参数的计算。而PixelShader是另一种小程序,这种程序负责对每一个像素,根据它所对应的贴图,材质,以及所采用的特效,计算其最终颜色。这两种程序都是靠显卡硬件执行,所以不占CPU的运算能力,这一点和D3D7所提出的Hardware TnL是一致的。和Hardware TnL相比,VertexShader的突破则是:Hardware TnL怎样来T(ransform)和L(it)的算法是固定的,程序员所能控制的只是这些算法的参数,比如变换矩阵和光源信息。PixelShader所要取代的是从DX6开始出现的MulitStages Texture pipeline。而VertexShader和PixelShader是可编程的,所以,它提供的灵活性非以前任何一个D3D版本可同日而语。# F( Y1 O7 z; [" k7 L1 z
# U4 V8 ~2 N3 E# M; i除了Shader以外,D3D8还提供了其他若干高级特性,如VolumeTexture,Higher-Order Primitive。这两项特性并不实用,至少从目前看来是这样。但Shader的引入足以使D3D8熠熠生辉了。
6 ?/ E& b, L' N: O9 \1 z' u3 l4 B* t: T. _
API的布局也向着更合理的方向迈进。DDraw终于退出了历史舞台。DDraw的功能实际上是D3D的一个真子集,到了DX8时,D3D能够轻易的做所有DDraw能做的事情,而且做的更好,所以DDraw没有存在的价值了。
# [7 ?+ {' s* ^# J2 {8 u' Z& p1 G0 b6 U- I& r4 \7 E
这带来的一个额外的好处是,D3D的初始化过程变得格外的简捷明了。以前的混乱很大程度上来自D3D和DDraw相互掺杂,你首先要建立一个DDraw的interface,然后SetCooperateLevel,然后用DDraw创建一个Surface作为PrimaryBuffer, 然后用QueryInterface从DDraw interface里Query出一个D3D interface,最后调用DDraw的CreateDevice创建一个D3DDevice interface。这是多么繁琐和令人困惑的过程! 这种繁琐的过程从DX2开始就只是这样。DX8终于把这个过程变成了简单而清晰的两句话:# \2 x6 G# N# h+ R1 g9 |( `
3 T+ A0 u5 y D$ U
pD3D = Direct3DCreate8(SDK_VERSION);
: |, M7 v4 c9 _0 D x" E i, \/ {. F R- X1 i6 q* V0 T' D
pD3D->CreateDevice(….&pDevice);/ p h" [. p% W6 V: V; d
1 V6 \$ }- o) @
真是谢天谢地!
2 M& E; C: r# @- ]5 s; P
. ^; d; u& I3 n7 D8 a' q其他主要的变化是,IDirect3D8 仅负责创建IDirect3DDevice8,而其他interface都由IDirect3DDevice8来创建。首次加入了IDirect3DIndexBuffer8,并加回了texture和surface等一些interface。(Texture interface在DX7例被DDrawSurface所替代)。) E8 B, c; K" N" s; Q
0 r8 O' M. C- q3 V6 N% s/ F
DX8这样一个API就很令人赏心悦目了,相信如果Carmack拿这个版本和OpenGL比较,绝对会客气很多。
% r7 } A& W! o/ s. T* l& m& W, ~- V5 Y- s6 o. v& k& f- R, v
2001年夏,Microsoft推出了DX8.1,较之于8.0主要的改进是增加了PixelShader 1.2/1.3/1.4。! }' ^/ m: V6 z |' b+ I) N
' y2 S. u! U/ }6 I( b0 p6 v! B! e/ C: N4 o7 [; ^
& L7 I% j* \$ l# k- k" m) @/ V
以前总是每年出一个全新的版本,到DX8以后,这个速度开始减缓,通常是出一个新版本以后的一两年中只出改进版。DX9亦是如此。主要的原因是自DX7以后,每一个DX版本(major release)实际对应于一代新的硬件设备,硬件的更新周期要长于软件,所以DX要放慢脚步,另外,游戏开发的复杂程度也越来越高,开发周期也越来越长,而开发商不是很喜欢在开发过程中更新API。& p# Y7 P5 J- P2 f- @
0 M) O3 j/ N, i% F# f
4 S+ T8 ]5 [( m$ G/ N# R9 V. i( U/ y6 G
DX8发布至今,无数3D游戏涌现,其中绝大多数是基于D3D的,基于OpenGL的屈指可数,DOOM3 / Never Winter Night / Medal of Honor。。。API之争胜负已判,Microsoft又一次笑到了最后。; ?- C6 I# T8 ~- d
; v7 x, j8 a! Z/ k+ l- x! V0 J; y5 ~' e& k j
5 N8 E; [1 X2 Z4 w# E! @
, \# j! C: {& G6 n* `* S( z
% i: Z4 m* w+ p
9.0
& E4 {+ E+ ~5 A+ s7 p1 w" D4 C5 y" L2 j* `- f- D
2002夏季,DX9发布。D3D9的主要进步是提出了Shader Model2/Model3, 相对于D3D8里的Shader1,2和3有更丰富的指令集和寄存器,逻辑结构也更趋于合理。其他增加的功能有IDirect3DQuery9用来采集性能测试的数据,Pixel级别的ScissorTest。
+ Y6 A |4 a# C' G* L ^' q$ A8 p ?" m8 h X3 G6 U- {/ c2 m
2003年,DX90b,和2004年DX90c在DX90的基础上完善了一些功能。并提供了更好的支持工具,如ShaderDebugger, d3dspy, PIX。
+ l. W) \, L8 F5 ], s
( f9 ~; ~ l& Y" @5 q7 d0 i) O9.0并不是历史,而是活生生的现在,所以我也不多说什么了。如果你对3D Programming感兴趣的话,你可以到Mircosoft的站点上去免费下载DXSDK9.0C,SDK里包含了完整的文档和入门教程。看看你能做些什么。8 m4 Y& v* q: g1 n
% s! }4 O- u" p: D- S下载地址如下:
" w. @" j+ E& A6 _4 c
- @! E( F. ~* o1 _, w$ `http://www.microsoft.com/downloads/...&DisplayLang=en; i2 a# a. N v0 m1 _3 O
$ ^/ U: T; V! C) u( O最后感谢maozy99和sguy对完成此文所提供的帮助。$ t* L* T4 \% C. [7 [8 r9 S& p
& r5 G; I7 O3 {: l0 {3 t( V% m
(完) |