随着OOXML与ODF的竞争为世人所知,微软又一次与开放扯上了关系。9月初OOXML在ISO的投票失败之后,就免不了有一批微软的粉丝们忿忿不平,他们很无辜地质问道,不是要一个开放文档标准吗?OOXML不是开放文档标准吗?为什么要反对呢?难道微软提出的开放标准就不是开放标准吗?当然对面阵营的人士也不含糊,他们凭直觉抗拒把微软与开放并列,并且质疑OOXML厚达数千页的说明规范是一种阴谋,或者至少会反对在ODF之外另立一个开放文档标准。不过不能否认,仅从法理上看,OOXML的开放性并不存在什么问题。其唯一的问题就是OOXML背后的名字——微软。在越来越开放的软件产业里,微软几乎是传统封闭势力的最后一块保留地。尽管做出了一些小的、无足轻重的姿态,但是在整体上讲,它仍然强硬地抗拒开放的趋势,禁止在自己的几乎任何产品和项目中使用和参与开放软件,并且在各种场合散布反对开源的观点,试图使人们的思想重新回到十数年前的状态。这些都不假,但是具体到OOXML这件事情上,微软的“开放性”似乎又确实无可指责。这就给我们讨论这一话题带来了困难:总不能仅凭臆测就妄断是非曲直吧。
在这种时候,讲一点实证主义是有好处的,认真地了解一点历史故事,看看历史上微软在开放标准领域的所作所为,有助于我们更好地理解现在正在发生的事情。很遗憾的,在微软不长的历史中,每次与开放扯上关系,几乎都是充当反面教员的角色。人们记忆犹新的,如微软分化和吞噬Java的企图,在Web标准方面与W3C唱对台戏的故事。然而有一段几乎被人遗忘的精彩故事,其实却能更全面、更深入地揭示微软对于开
放标准的策略和手段。现在就让我们来回顾一下这个充满了权谋、利诱、屈膝投降和最终悲剧收场的真实往事。
1. 和平年代
这段往事发生在实时3D计算机图形API领域。
计算机图形学就是用数学计算和软硬件手段在计算机输出设备上绘制图形的学问,1970年代以来,随着相应设备和研究的进展,计算机图形学获得了快速的发展。人是视觉动物,因此图形毫无疑问是计算机最重要的应用领域之一。一开始,计算机图形的主要应用是在科学和工程方面,比如统计图表、CAD等。1970年代末期,视频游戏出现了,计算机图形学很快从壁垒森严的国家实验室和军方研究机构走出来。不过那个时候很少有人想到,计算机图形最终能够实施绘制以假乱真的三维真实感图形,营造一个虚拟现实。
1992年斯皮尔伯格的《侏罗纪公园》引起全球轰动,计算机绘制真实感图形的能力已经无人质疑,而这一领域的进展将给游戏、CAD、教育、科学、管理和军事等几乎所有IT应用领域带来完全革命性的变化。毫无疑问,这个领域是兵家必争之地。但是怎么个争法呢?做图形硬件?当然好,但是很快就会有竞争对手。做应用软件或者游戏,不错,不过也是局限于一时之争。在IT领域里,真正高层次的竞争是工业标准的竞争,那么在计算机图形领域里,最重要的工业标准是什么呢?毫无疑问,就是图形API。所有的开发者都希望用统一的方式编写图形程序,这就给在这个领域里形成工业标准创造了条件。一旦这样的API标准出现并且被接受,那么所有的硬件设备制造商都得老老实实地实现这个API标准,并尽量对它实施优化件,所有的平台制造商都得支持这个API标准,所有软件开发商都得在这个API之上开发图形软件。谁要是掌握这个标准,就可谓挟天子以令诸侯,一呼天下应。意识到这一点,就不难明白,3D图形API是影响整个计算机图形工业的重大标准,兹事体大,不可等闲视之。也正是因此,绝不应该让这么重大的技术标准落入一家把持之下。
在当时,因为《侏罗纪公园》绘制逼真的恐龙场景而闻名于世的SGI当然是这个领域的领先者,事实上,当时SGI手上有三大法宝——其一是SGI图形工作站,其二是专门针对图形应用而优化的UNIX变体IRIS,其三是被称为IRIS GL的3D真实感图形API。这个IRIS GL这是经过在SGI工作的顶尖计算机图形学专家和工程师们数年心血的结晶,干净、清晰而且非常先进,在当时可谓无人可望其项背。
SGI本来坐居高端图形产业的顶峰,似乎可以高枕无忧。不过当时SGI也发现独孤求败的滋味并不好受,至少业绩的进一步成长受到了明显的限制。于是SGI决定将IRIS GL开放出来,让它尽快成为工业标准。SGI完全就是无私奉献吗?它是不是想凭借OpenGL控制图形工业?我们不得而知,不过无论是当时还是事后来看,这一举动有巨大的进步意义。相关厂商一拍即合,1992年初,OpenGL体系结构审核委员会(OpenGL Architecture Review Board,简称OpenGL ARB)正式成立,当年7月,经过认真审核和提高的OpenGL 1.
0规范正式出炉,标志着3D图形API正式步入开放时代。
实事求是地说,虽然已经冠以 “Open”的名号,不过OpenGL当时很大程度上还是受SGI影响的。你要在自己的平台上实现OpenGL,就得给SGI缴纳授权金。当然,也不是SGI一家独大,否则谈何开放?所谓开放,实际上是指OpenGL标准在制订过程中, ARB成员都可以充分讨论,自由发表意见,就标准的大小问题投票。应该说,这一过程还是能够保证标准的公平、公正和公开,在当时是相当不错的了。实际上Java刚出道的时候,也差不多是这个模式,在开源还没有大行其道的时候,这就算是开放了。当然,按照今天的
标准,这个开放的程度还很不够,抚今追昔,今天的计算机用户和程序员,着实应该好好感谢1990年代末期的开源运动。
在OpenGL ARB的创始成员中,微软的名字赫然在列。那时候的微软,尽管还没有后来那样不可一世的霸气,但是也已经非常强大,它会甘心全心全意支持OpenGL的发展吗?我们现在当然无法了解当时微软对于OpenGL的真实态度,但是最初微软的表现还是不错的。当时Windows NT正在研发当中,其主要的目标之一就是与基于UNIX的图形工作站竞争,因此微软内部的一个小组积极支持了Windows平台的OpenGL发展。随着PC上图形硬件的飞速发展,大约在1990年代中期,PC终于可以与高端图形工作站相比,在这个过程中
,Windows与OpenGL之间的关系,即使不能用蜜月来形容,至少也是相当和谐的。
另一个很重要的原因,就是微软此时在图形领域还羽翼未丰,甚至可以说,还相当幼稚,根本不具备跟SGI相抗衡的实力。著名的WinG事件就暴露了当时微软在图形领域的薄弱实力。那个时候,Windows 3.0/3.1已经开始大肆流行,可是PC上所有像样子的图形和游戏程序无一例外是在DOS下直接访问视频缓冲区,Windows的GDI本身就是为静态图形设计的,在当时的硬件上慢得要死,因此还冒出来一种叫做“Windows图形加速卡”之类的硬件来帮助Windows GDI图形加速,根本就自身难保,别提还在上面开发高性能动画图形程序了。不过微软已经明确Windows就是它的未来,因此努力试图证明Windows可以成为合格的游戏开发平台。大约在1994或1995年,微软推出了一个叫做WinG的图形开发包。这个开发包的主要功能,就是帮助图形开发者在Windows 3.0/3.1中快速绘制2D图形,从而实现动画功能。WinG实际上是一组DLL,安装之后,它将替换Win16中CreateDIBSection()、SetDIBColorTable()、BitBlt()和StretchBlt()等API,并通过提供一种被称为WinGDC的设备上下文,提供对图形数据双向读写的能力,从而实现快速的像素矩阵Blit。那
个时候的游戏和动画主要是2D的,衡量性能的核心指标就是Blit的速度。所以WinG也算是门当户对。笔者还记得当年运行WinG中的一些例子,屏幕上的窗口里眼花缭乱地快速绘制彩色方块和线条,看上去确实不慢。但是很显然,微软那时根本就不理解图形和游戏程序员的需求,WinG这个东西既没有提供直接访问视频缓冲区的能力,有没有提供高层的图形API,如同鸡肋,从来就没有流行开,从而也迅速被微软抛弃。事后,微软甚至根本就不承认WinG的存在,此事被传为“佳话”,为天下笑。在这样的局面下,微软对OpenGL采取合作态度,也是时势使然。
不管怎么样,这是一段风平浪静的和平年代。
一切看上去都很好,当PC图形硬件进一步发展,传统上用于科学与工程领域的OpenGL在游戏领域中也开始显现出巨大的潜力,它成熟、强大、干净而且特别适合于教学,似乎没有什么能阻挡OpenGL成为PC游戏的首选图形API。然而就在同时,随着Windows 95的巨大成功,微软成为业界霸主,实力空前壮大,心态也就悄悄发生了变化。1996年9月15日,微软在刚刚发布的DirectX套件中附带了一个被称为Direct3D的新组件,并且开始在各种场合宣称散步对OpenGL不利的言论,企图让程序员相信Direct3D才是专门针对游戏的3D图形API。美好的和平时代终结了。
2. Direct3D vs. OpenGL
在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应该也是当然之选。一切似乎已成定局,如果不是三名微软程序员的冒险行动,历史将会是另一番模样。
图1. DirectX 1.0 Logo
大约在1994年的下半年,微软的三名工程师Craig Eisler、Alex St. John和Eric Engstrom不甘心让Windows 95沦为二流的游戏平台,决心一起努力来解决这个问题。他们冒险发起了一个项目,目标是让Windows 95平台上的游戏程序员也能够全速访问硬件设备,Eisler任dev lead,St. John是主开发,Engstrom任程序经理。这个项目开始的时候,距离Windows 95预定的正式发布时间只有几个月,因此,这个项目的地位非常微妙:一方面,微软内部许可和支持它,给这三剑客照付工资,另一方面,这并不是一个“一定要成功”的项目,也没有得到更强力的支持,无论它的结局如何,Windows 95会照常发布。就在这样的局面下,技术史上又一个无心插柳柳成荫的故事诞生了。三人找到了解决问题的办法,并且逐渐完善,形成了后来被称为DirectX的解决方案。很显然,这一成果令包括比尔盖茨本人在内的微软高层大喜过望,立刻倾注大量资源予以全力支持。
图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发布不久,微软发布了一个更新版,内部版本号从4.04.00.0068增加到了“4.04.00.0069”。从版本号上看,这次更新小得不能再小了。然而具有讽刺意义的是,这实际上是一次对整个产业具有决定性影响的重大事件,因为在这个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编写程序。我需要真正能帮助我的东西,而不是给我带来麻烦的东西。”