在Andre LaMothe游戏编程的经典著作《Windows游戏编程大师技巧》中介绍DirectX的时候,作者以其特有的LaMothian式幽默感叹道:
“我开始感觉自己变成微软的传教士了,总在试图把我所有的朋友们都推向这个黑势力。但是有什么办法呢?微软这帮坏家伙总是能研究出更好的技术。”
这一说法集中体现了游戏程序员的矛盾心态。当然在今天,特别是在Google的光辉下,很多人会直截了当地反对“微软技术更好”的说法,但是在1990年代的中后期,微软的确在软件技术的所有领域都高歌猛进,在3D图形API领域也不例外。
1994年,微软的全部精力都集中在即将发布的Windows 95上。从各个领域传来的声音都表明,Windows 95将是一款划时代的极为成功的操作系统。但是在一片叫好声中,也存在一些不和谐音符,这就是来自PC游戏开发领域的质疑声。大部分视频游戏的开发者坚定地认为,DOS是比Windows 95更好的游戏开发平台。在DOS下,程序员可以独占机器的全部资源,不用担心同时运行的另外的进程的干扰。更重要的是,DOS允许程序员直接访问硬件设备,尽管这带来的沉重的负担(需要针对市面上流行的每一款显卡和声卡写驱动程序),但是却能保证最大的速度。相反,Windows 95采用了保护模式,在硬件之上建立了层层的抽象,限制了对设备的访问,对于性能敏感的游戏程序员来说,这是难以接受的。再加上当时Watcom C/C++和DOS4GW等技术已经非常成熟,DOS在PC游戏产业中的地位看上去是牢不可破的。事实上,这种情况持续到Windows 95发布后的最初几年里,那时候大部分游戏玩家为了玩高质量的视频游戏,不得不在硬盘上保留一个DOS操作系统。有人甚至据此断言说,DOS永远都会存在下去。
微软的高层对这种情况并不高兴,但是似乎并没有什么办法,WinG的失败使人不得不对Windows游戏领域谨慎从事。况且这个时候微软已经将OpenGL置入Windows中,就算是在Windows上开发游戏,OpenGL应该也是当然之选。一切似乎已成定局,如果不是三名微软程序员的冒险行动,历史将会是另一番模样。
大约在1994年的下半年,微软的三名工程师Craig Eisler、Alex St. John和Eric Engstrom不甘心让Windows 95沦为二流的游戏平台,决心一起努力来解决这个问题。他们冒险发起了一个项目,目标是让Windows 95平台上的游戏程序员也能够全速访问硬件设备,Eisler任dev lead,St. John是主开发,Engstrom任程序经理。这个项目开始的时候,距离Windows 95预定的正式发布时间只有几个月,因此,这个项目的地位非常微妙:一方面,微软内部许可和支持它,给这三剑客照付工资,另一方面,这并不是一个“一定要成功”的项目,也没有得到更强力的支持,无论它的结局如何,Windows 95会照常发布。就在这样的局面下,技术史上又一个无心插柳柳成荫的故事诞生了。三人找到了解决问题的办法,并且逐渐完善,形成了后来被称为DirectX的解决方案。很显然,这一成果令包括比尔盖茨本人在内的微软高层大喜过望,立刻倾注大量资源予以全力支持。
<!--[if gte vml 1]><v:shape id="_x0000_i1026" type="#_x0000_t75" style='width:268.5pt;height:276pt'> <v:imagedata src="file:///C:\Users\myan\AppData\Local\Temp\msohtml1\01\clip_image002.png" o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图2. 1996年发布的Command & Conquer Red Alert CD封面
1995年9月,Windows 95正式发布后仅仅一个月,DirectX的第一个版本以“Windows Games SDK”的名义发布了。此后一年,微软像旋风般地连发三个DirectX版本。1996年9月发布的Direct 3.0被认为是DirectX的第一个成熟版本。1996年底当时如日中天的Westwood工作室发布即时战略游戏《红色警戒》,这款游戏分为DOS和Windows 95两版,其中Windows 95版就是基于DirectX开发的。这款2D游戏采用640x480甚至更高的800x600分辨率,在Windows 95下表现相当出色。当时的大学校园里,奔腾电脑刚刚进入寝室,若干玩家自建网络,多人联机对战“红警”,一片喊杀声震天,开寝室游戏联机对战风气之先河。《红色警戒》全球正版销量1200万张,创造了即时战略类游戏的吉尼斯世界纪录。正是这款游戏的巨大成功,使得整个PC游戏开发产业确信,DOS将成为过去,Windows和DirectX是游戏开发的未来。
图3. 红色警戒续篇The Aftermath截图
最初的DirectX与OpenGL并不构成明显的竞争关系,两者分工明确。DirectX对硬件要求低,对应普通家用PC配置,长于开发2D游戏。而OpenGL对显卡要求高,目标是高端图形工作站平台,主攻CAD市场,倒也算是泾渭分明。从技术上讲,当时微软内部正处于COM技术的高峰时代,几乎所有东西都要COM化,DirectX也不例外。DirectX以COM组件的方式暴露API,编程比较繁琐复杂,但也促进了C++在视频游戏中的应用——用C语言去访问COM实在是一种吃饱了撑的自找麻烦的行为。而OpenGL自始至终保持平坦化的C风格的API,毕竟其本质不过是图形硬件的一个接口,每个API调用最终会变成通过PCI总线对图形硬件发出的命令。因此,OpenGL编程简洁明了一些,但这并不是说OpenGL简单,3D图形编程从来也不是一件简单的事情。从图形功能上讲,DirectX中主要的视频模块称为DirectDraw,其主要出发点是向程序员提供对于视频缓冲区(frame buffer)的直接访问能力,从而能够以写内存的方式在屏幕上绘制图形元素,特别是能够飞快地bitblt图像到视频缓冲区中,以及快速在屏幕上滚动场景的能力,而这正是高性能2D游戏的关键。OpenGL虽然也提供了读写视频缓冲区的能力,但是其重点在于3D图形,用户只需要在OpenGL的逻辑空间中把所需要的图形“画出来”就行,至于3D图形怎样投影并栅格化到2D的屏幕上来,OpenGL会替你代劳。因此,OpenGL是比DirectDraw更高层的图形API,两者之间没有明确的竞争关系。然而这并不是说DirectDraw对OpenGL没有冲击。事实上,正是因为DirectDraw的出现,延缓了Windows游戏开发人员接受OpenGL的速度。倘若没有DirectDraw,Windows游戏开发人员最迟在1997年就一定会采用OpenGL作为游戏图形API,那样的话,OpenGL一统天下的局面就会迅速出现。DirectDraw打了一个时间差,而这个时间差后来被证明至关重要,因为Direct3D很快就开始与OpenGL正面对垒。
DirectX 3.0发布不久,微软发布了一个更新版,内部版本号从<chsdate w:st="on" year="1899" month="12" day="30" islunardate="False" isrocdate="False"><span lang="EN-US">4.04.00</span></chsdate>.0068增加到了“4.04.<chmetcnv w:st="on" unitname="”" sourcevalue=".0069" hasspace="False" negative="False" numbertype="1" tcsc="0">00.0069<span lang="EN-US" style="font-family: 宋体;"><span lang="EN-US">”</span></span></chmetcnv>。从版本号上看,这次更新小得不能再小了。然而具有讽刺意义的是,这实际上是一次对整个产业具有决定性影响的重大事件,因为在这个DirectX 3.0更新版中,附加了一个被称为Direct3D的组件。正是这个组件,在不到五年的时间里成为主宰整个PC游戏图形工业的标准,也彻底打碎了OpenGL试图在这个产业建立起来的开放而平等的局面。
Direct3D是怎么冒出来的呢?虽然发明DirectX的三剑客是非常杰出的工程师,但是他们的强项在于计算机系统,而要开发出可与OpenGL匹敌的3D API,就得有一个精通3D数学和图形算法,对图形硬件极为熟悉,拥有丰富游戏开发经验,且具备大局观的大师级人物坐镇背后。即使是在今天,这样的人才也绝对是凤毛麟角,更不用说在1990年代初期了。在当时,全世界屈指可数的几个高手几乎全在SGI、NASA这类的大机构力高官厚禄,微软想要发展自己的3D API,就得往小公司身上打主意。这时候,一家成立于1992年的英国公司RenderMorphics被纳入微软的法眼。这家小公司成立了一个Reality Lab实验室,专事3D图形技术及API技术研究。在当时,这家公司在当时并不大的3D图形中间件市场三分天下有其一,已经是很不简单。而其背后的灵魂人物Servan Keondjian几乎是身处SGI之外最牛的3D开发大师。受到DirectX项目进展的鼓励,微软开始信心膨胀,大约到2004年底,微软就决定要连人带公司把Servan和他的RenderMorphics一口吃下。谈判进展飞快,1995年2月,微软收购RenderMorphics,Servan也成功被微软招入麾下,主持Direct3D项目的开发。这就是Direct3D的源流。
Direct3D最初发布的时候有两个模式,一个称为Retain模式,另一个称为Immediate模式。Retain模式的大意是用事先建好一个3D模型,让摄像机在里面运动,得到屏幕上的运动的3D图像。这种方式适合于某些应用和游戏的开发,但严格来说与OpenGL并不是一回事,仍然不构成直接竞争关系。而Immediate模式则是直截了当地与OpenGL分庭抗礼,其面向的问题与OpenGL完全相同。除了一些技术细节上的区别(比如OpenGL采用右手系,Direct3D采用左手系)之外,两者最大的差别就是,一个是跨平台的,开放的,一个是专供Windows平台的,专有的。
说实话,Direct3D的最初版本远未达到工业级别,成熟度与OpenGL相去甚远。它不但完全以COM组建方式暴露接口,而且设计的非常繁琐。任何一个简单的操作,哪怕只是一次状态改变,都需要创建和提交一种称为“execute buffer”的对象。这不仅意味着编程的复杂性大大提高,代码的可读性大大降低。但是,这毕竟是一个3D图形API,而且站在它背后的是微软巨人,没人会小看它。相反,正是因为人们十分清楚微软的力量,因此对于Direct3D的出现将导致的3D图形API大分裂的局面感到非常忧心。一时间,要Direct3D还是要OpenGL的争论尘嚣日上。
这个时候,发生了一件在游戏开发历史上非常著名的事件。DOOM的主程序、3D游戏程序员的精神领袖John Carmack发表了公开发表了一篇文章。他在尝试将Quake游戏移植到两种API上,并且从功能、性能、驱动程序支持和使用的易用性四方面对Direct3D和OpenGL进行了对比,得出的结论是,两者功能相当,性能接近,驱动程序方面,Direct3D略有优势,所以前三项基本旗鼓相当。但是从易用性来看,OpenGL的优势是压倒性的。由于Direct3D中executive buffer的存在,Direct3D程序非常繁琐晦涩,用它简直是自找麻烦。在这封公开信的结尾,Carmack坚定地站在了OpenGL的一边,甚至呼吁微软放弃Direct3D,拥抱OpenGL。他最后说:“在接下来的很多年里,我每天都会基于3D API编写程序。我需要真正能帮助我的东西,而不是给我带来麻烦的东西。”
<!--[if gte vml 1]><v:shape id="_x0000_i1028" type="#_x0000_t75" style='width:414.75pt;height:312.75pt'> <v:imagedata src="file:///C:\Users\myan\AppData\Local\Temp\msohtml1\01\clip_image006.png" o:title="" /> </v:shape><![endif]--><!--[if !vml]--><!--[endif]-->
图4. John Carmack,程序员的偶像
这一权威的、理性的声音很大程度上冲销了微软的宣传功效,但显然不可能使微软放弃自己亲生的Direct3D。相反,John Carmack实际上充当了一个咨询专家,让微软认识到了Direct3D的缺陷所在。到了1997年6月DirectX 5.0发布的时候,微软在Direct3D中加入了DrawPrimitive API,消除了创建executive buffer的必要。但实际上,DrawPrimitive仍然是一个不怎么样的设计,另一个3D大牛Chris Hecker给微软写了一封公开信,在信里他说,DrawPrimitive“是OpenGL设计的一个不成熟的、糟糕的抄袭,但却偏偏漏掉了使OpenGL如此高效的关键的架构决策”。
但是,此一时也彼一时也,这封公开信影响有限。微软强大的宣传机器已经开始全力运作起来,在整个市场上到处嚷嚷“今年过节不游戏呀不游戏,游戏就用D3D呀D3D”。更厉害的是,仗着微软在操作系统领域的霸主地位,微软开始与众多硬件厂商谈判,要求它们优先支持DirectX。不但如此,很多人猜测,微软故意降低了OpenGL在Windows平台上的性能,采取不正当手段败坏OpenGL的名誉。这种咄咄逼人的攻势之下,OpenGL ARB这个松散的组织软弱无力的一面就体现出来了,基本上束手无策。
胜利的天平似乎开始向微软倾斜了。怎么办?
这个时候,SGI——OpenGL的娘家人——挺身而出。