標籤:

從零開始手敲次世代遊戲引擎(六)

現在我們已經有了一個跨平台的基本應用框架。接下來我們可以開始圖形方面的編碼了。

參照我們編寫應用模塊的方式,我們可以很快地添加圖形模塊的骨架。

讓我們在Framework/Common下面添加兩個文件:

GraphicsManager.hpp:

#pragma once n#include "IRuntimeModule.hpp" nnamespace My { n class GraphicsManager : implements IRuntimeModulen { n public:n virtual ~GraphicsManager() {} n }; n}n

GraphicsManager.cpp:

#include "GraphicsManager.hpp"n

注意我們並沒有重載那些純虛函數。在我們真正開始實例化這個類之前,這是沒有關係的。

因為我們添加了文件,需要編輯Framework/Common下面的CMakeLists.txt,將新文件加入編譯:

add_library(Common nBaseApplication.cpp nGraphicsManager.cpp nmain.cppn)n

好了,我們可以重新編譯我們的代碼了。

到目前為止,我們已經寫了好幾個文件,好幾個類了。但是,從實現得功能上來講,和(一)當中的hello engine,基本上沒有啥差別。那個甚至還有個輸出,現在我們這個程序連輸出都沒有。

所以,架構是有overhead,就是有額外的開銷的。架構往往在給程序帶來一種內部的結構,使概念上比較獨立的部分解耦成單獨的模塊,從而更為方便可以進行部分的擴張和替換的同時,也帶來了很多條條框框和額外的開銷。某些本來從事物的流程上來說是線性的處理,因為模塊的劃分,需要分割到不同模塊進行處理,從而使得代碼不那麼一目了然。

在我們碼農的日常當中,處於初級階段的時候主要的精力可能放在一些語言特性和系統介面的認知方面;而到了中級階段的時候可能最多的時間是花在了選擇實現方法上面;到了高級階段則就是常常面臨著平衡問題。之前通過各種渠道所學的,自己所堅信的,都隨著人生閱歷的豐富變得不那麼絕對,任何事情也都不再是黑白分明,有的只是灰多少的問題。

但是平衡這種東西就是屬於只可意會不可言傳的範疇。這東西似乎是逝去的時間和自我反省的混合物,除了極個別的所謂天才,大多數人還是無法頓悟的。特別是對於我們所不熟悉的領域,在深入了解它之前就想進行架構設計,那只有一種方法:拍腦袋。這樣的架構最後基本上是肯定還不如沒有架構的。

很多計算機領域的書籍都是按照架構設計-詳細設計-實現這樣完美地組織的。這是因為他們早就把《血緣》玩成了「無雙」,然後才來做的梳理。這並沒有什麼不好,但絕不是拓荒的真實故事。

因此,在我們進入圖形模塊的詳細設計和編碼之前,很有必要暫時接個支線任務。先忘記架構,拋開我們剛剛寫的架子,用最為直觀的方式,先探一下圖形編程的路。

-- (圖形支線任務開始)--

在寫作本文的時間點,圖形API用得比較多的是微軟的Direct X系列,OpenGL系列,和蘋果的Metal系列。手機上用的OpenGL ES是OpenGL的一個子集。而Vulkan是最近剛剛興起的一個圖形API,被稱為OpenGL的後繼。Vulkan被稱為OpenGL的後繼是因為,Vulkan是由OpenGL的標準組織策定的。這個API本身和OpenGL並不是兼容的。

Direct X系列是微軟專利產品。其實早期微軟推出Direct X是迫於無奈的。早期的遊戲,如《仙劍一》,都是基於DOS的。這種情況在Windows推出很多年之後,仍然是這樣。大家堅守微軟已經不更新的DOS,而不轉移陣地到微軟大力推薦的Windows的主要原因是當時的Windows只有一個圖形API,叫GDI,那個是非常非常慢的一個圖形API。如果用來做遊戲,幀率簡直慘不忍睹。

所以,為了讓大家都上Windows這條賊船,用劣幣驅逐良幣的玩法徹底搞死比Windows推出得更早的IBM OS/2 Warp,以及蘋果的Mac OS,微軟急急忙忙地推出了Direct X。早期的Direct X其實就是在微軟倖幸苦苦封裝的GDI上面打個洞,讓應用程序能夠直接使用比較底層的API,從而提高效率。(說穿了就是架構Overhead了,然後搭了個梯子完全繞開架構)

但這種亂暴的方式其實依然沒有能夠收買多少遊戲開發商的心。因為這種亂暴的手段帶來性能提升的同時,也帶來了藍屏。

-- (題外話開始) --

知乎上最近很多人在討論鵝廠的問題。其實,這是資本積累階段常見的現象,早在2,30年前微軟就玩過的東西。但是這並不妨礙微軟今天成為大家心目中的偶像。所以鵝廠將來一片光明,做大了撒點錢洗洗就好,一年洗不幹凈就洗十年,總能洗乾淨的。

-- (題外話結束)--

這種局面的根本性改變,是在Win95之後,也就是在Windows一舉佔據家用電腦大半江山之後。憑藉著捨我其誰的市場佔有率,Direct X反過來變成一種對於顯卡廠商的強制標準。當然顯卡廠商也並不是有多麼憋屈,聽話就不愁賣,大家Happy。

-- (題外話開始) --

所以不要聽近年的企業吹噓什麼互聯網思想,共享經濟。說穿了就是不擇手段壟斷市場,然後怎麼都能賺錢,就是這麼一會兒事情。只不過對於傳統的製造業服務業來說,法規成熟,不允許傾銷;但到了互聯網這裡,人家服務業,免費提供服務,不算傾銷。綁架用戶也不叫綁架,叫掃碼登陸,免費用券。

-- (題外話結束)--

Direct X發展到今天,由於商業利益鏈條的形成,倒確確實實是推動圖形硬體發展的先鋒力量了。微軟在這方面做了大量的工作,普及了先端科技,培養了大量的人才。

近代GPU方面一個較大的變化就是GPGPU的出現。在DX9時代,圖形渲染管道是固定的。也就是說,除了通過調整一些參數有限地改變GPU的行為之外,是沒有辦法對GPU的行為進行自定義編程的。

然而從DX9時代之後,出現了GPGPU。GPU變得和CPU一樣,可以跑我們碼農寫的程序了。甚至,一些GPU開始不務正業了,並不是用來繪圖,而是用來計算,算天氣,跑阿爾法狗。

而OpenGL是來自於工業界,AutoCAD什麼的。其最大的特點除了支持多平台之外,就是封裝得比較徹底,或者說API比較傻瓜。傻瓜到網頁也可以用它來畫圖,這個叫WebGL。如果你還沒有體驗過的話,可以到下面這個地方去逛一逛。

get.webgl.org/

然而這還是一個平衡問題。高度的封裝固然對於CAD軟體的開發來說是個好事,但是對於遊戲這種軟實時系統來說,就顯得過於臃腫。OpenGL當中有非常複雜的狀態管理和預測機制,它時時刻刻都在試圖推測應用程序的意圖,來彌補過於簡單抽象的API造成的信息不足的問題。就好比我寫這個專欄,很多人覺得寫得太細太羅嗦,並不需要交代那麼多基礎的事情。這是因為這些人他們自己有一套完整的知識體系,你只需要給他們一個方向,然後他們自行可以腦補很多。

這對於我來說當然是很省力的好事。然而,在軟體開發當中,這也意味著更少的控制力。我們無法知道OpenGL到底是怎麼去做這件事情,什麼時候開始做,大概需要多久。我們甚至不能確保結果是完全符合我們期待的。

同樣的情況,也存在在DX12之前(不含)的DX API當中。

而主機平台,就如我之前的文章所介紹的,從歷史上就是廠商把集成塊焊接好,然後寫個最基本的系統,把硬體介面暴露出來,剩下的就是遊戲開發商自己好自為之了。所以主機歷來是一個十分高效的平台,因為它沒有那麼多封裝,架構,額外的開銷。

隨著PC遊戲的飛速發展,DX/OpenGL面臨了再一次的挑戰。之前為了減少開發者負擔所做的種種努力,在今天看來相當一部分反而成為了束縛性能的「並不需要的東西」。DX 12/Vulkan/Metal就是在這樣的環境下誕生出來的新一代圖形API。這些API更接近主機所提供的圖形API。

所以,在接下來的文章當中,我們將逐個體驗這些圖形API,用這些API開發一些最基本的圖形程序,然後抽象出他們的共性。基於這些共性,我們就可以進行我們渲染模塊的詳細設計了。

-- (EOF)--

本作品採用知識共享署名 4.0 國際許可協議進行許可。


推薦閱讀:

【大咖分享】熱血傳奇研發經驗分享by 鄭建鑫
從零開始手敲次世代遊戲引擎(五)
卡通渲染-向罪惡裝備xrd前進!
全球首家爆款手游公司,縮水9倍上市卻是「最好」結果

TAG:游戏开发 |