官方網站:https://edu.battlefire.cn
簡介
從2005年開始,圖形顯卡總會同時實現OpenGL和DirectX中的某個版本的API。比如說:2004年的DirectX 9和OpenGL 2,2008年的DirectX 10和OpenGL 3,2011年的DirectX 11和OpenGL 4。一般來說,支持更加新一代版本API的GPU能夠兼容老版本的API的調用,意思就是說:支持最新的DirectX 11的GPU可以運行DirectX 9的遊戲。
DirectX
1996年,第一個版本的Direct3D發布了之後受到了各種指責,因為即使是一些簡單的操作,比如狀態機的改變,都需要創建和提交那些叫做execute buffer的東西。與之相反的是,OpenGL的狀態機的改變只需要一個函數調用即可。那時候Direct3D的編程模型讓很多碼農失望透頂。遊戲編程領域非常出名的卡馬克大碼農就是其中的一個,他還勸說微軟放棄Direct3D而轉投OpenGL陣營。1997年,Chris Hecker在Game Developer雜誌上發表了類似的一則對微軟的公開信。
當DirectX的第二個版本也就是DirectX 5發布的時候,它使用新的DrawPrimitive替代掉了execute buffers那些操作,但是這個API仍然被認為是非常複雜的。按照Chris Hecker對微軟的公開信上的說法,DrawPrimitive這個API就是直接從OpenGL那邊抄過來的,不成熟的並且設計很糟糕,並且在架構上缺乏了一些讓OpenGL運行更快的東西。
頂著各方的吐槽,微軟仍然堅持搗鼓自己的這些東西,關於DirectX各個版本的變化以及進化史,可以參考微軟官方的Direct3D的相關頁面。
後來,曾經那些鄙視Direct3D的娃兒們開始慢慢的變得認可Direct3D的API了。在2007年2月的時候,卡馬克說道:DirectX9真的一套非常棒的API。雖然大家都認為我一直在跟DirectX抬槓,但是微軟確實一步一步的把DX改造成了一套非常乾淨的API,我非常喜歡使用DX來工作。
有一部分DX的功能從初代版本開始就沒有再改變過,其中最熟悉就是微軟的COM玩法(Component Object Model)。COM玩法的一個好處就在於你可以使用任何兼容COM的語言來使用COM組件,比如:Object Pascal、Microsoft Visual C++、C#以及Visual Basic .NET。
OpenGL
OpenGL是通過C語言實現的一套API,你可以通過C語言把它導出到其他的程式語言裡面去。OpenGL是基於狀態機的,它不依賴任何一個程式語言的特性,並且你可以通過合適的方法把它綁定到任何程式語言。
Comparison
通常來說,Direct3D是被設計用來做3D可視化硬體接口的。Direct3D讓遊戲編程人員從硬體編程中得到了解放。而OpenGL則是被設計為用來通過硬體來加速3D渲染系統的,它是軟體可選的一個功能。這兩套API一開始是按照兩種不同的思路來設計的。所以,從功能上就影響了兩套API的工作方式。其中一個非常重要的不一樣的地方就是關於硬體資源的管理。DX是期望應用程式的編碼人員來自己管理硬體資源的,而OpenGL則是幫助了硬體編碼人員來管理硬體資源。這種差異就導致了OpenGL減小了學習OpenGL開發的人的難度,但是增加了驅動實現的複雜度。對於DX來說,應用開發人員的入門門檻就相對高了一點,他們需要自己去管理硬體資源,但是這些管理也並不是特別的難。
直到2005年,這兩套API的另一個非常重要的不同的地方就是它們管理渲染目標的方式,在Direct3D中,它是通過SetRenderTarget來做的,而在早期的OpenGL版本裡,它需要對Pixel Buffer進行操作。這麼幹是比較糟糕的玩法並且有很大風險:如果與驅動實現預期的方式不一樣的話,那麼就可能會fallback到沒有硬體加速的版本,這樣性能就會下降。然而隨著大家都開始支持FrameBuffer Object擴展,使得OpenGL能夠提供跟DX類似的切換渲染目標的方式。總體來看,除了一小部分特性,OpenGL與DX提供了幾乎一模一樣的功能。
一般來說,硬體和軟體製造商會非常頻繁地對DX的變化做出相應的反應,比如從DX9裡的PS,到DX10裡的Stream Processor,再到DX11裡的Tessellation Processor。而與之相反,OpenGL這邊的新的特性一般是由硬體廠商先實現,然後才會被標準化掉。