OpenGL超級寶典7th簡體中文-第一章:簡介

NOTE

簡書傳送門

第一章

簡介

我們從這章能學到什麼

  • 什麼是圖形管線(Graphics Pipeline)以及OpenGL如何與它關聯
  • OpenGL的起源以及它如何演變成現在的模樣
  • 我們在全書中都會使用到的一些基本概念

OpenGL是一種接口,在我們的應用程序中可以用它來訪問或者控制它所運行的設備的圖形子系統。它所運行的設備可以從一個高端圖形工作站到商用臺式機、視頻遊戲主機甚至是一臺智能手機。將這些設備的接口標準化到一個子系統可以增強移植性並且可以讓軟件開發者集中精力創作高品質的產品、製作更有有趣的內容以及關心他們的應用的整體效能,而不是陷於他們想要應用運行的平臺的細節中。這些標準接口被稱爲Apllication Programming Interfaces(or APIs),OpenGL是其中之一。這一章簡要介紹OpenGL,描述它如何與底層的圖形子系統關聯,並且提供一些OpenGL的起源和演化歷史。

OpenGL和圖形管線

生成一個高效能並且高容量的產品通常需要兩個東西:可伸縮性(scalability)和並行性(parallelism)。在工廠中,這兩個東西通過使用產品線(production lines)來達成。說來就是一個工人安裝汽車的引擎,另一個安裝車門,再另一個安裝車輪。通過將產品的生產階段進行重疊,每一個階段都由一個專業的專家來專門完成這個任務,這樣每一個階段就變得更高效,然後整體生產效率就會提升。同樣,通過在同一時間製作很多汽車,一個工廠可以讓多個工人專門安裝引擎,或者多個工人專門安裝車輪,這樣多輛汽車可以同時運作在產品線上,每輛車都處在完工的不同階段。

計算機圖形是同樣的道理。我們的程序發送命令給OpenGL,然後OpenGL以一種儘可能高效的方式將命令發送給底層的圖形硬件來產生預期的結果。在圖形硬件上可能有很多命令排隊等待執行(專業術語稱爲in flight),其中一些命令可能是完成了一部分的。一個處於後續階段的命令可以和一個處於前期階段的命令被併發執行,這樣它們的執行就重疊了。此外,計算機圖形通常由很多非常相似的重複性任務組成(例如計算一個像素該爲什麼顏色)並且這些任務都彼此獨立–意即,一個像素的顏色與另外一個像素的顏色沒有任何關係。就好像一個車間可以同時製造多個汽車,所以OpenGL可以把你給他的工作拆解開然後用它的基礎元素並行完成。通過組合管線(pipelining)和並行(parallelism),現代圖形處理器超乎想象的性能就被實現了。

OpenGL的目的是在我們的應用程序和底層的圖形子系統中間提供一個抽象層(abstraction layer),圖形子系統通常是一個硬件加速器(由一個或多個自定義的高性能處理器和專用內存、顯示輸出等等構成)。這個抽象層可以使我們的應用程序不必知曉誰是製造的圖形處理器(或者叫GPU - 圖形處理單元)、它如何工作、它工作得好不好。當然我們的應用程序仍然可以獲知這些信息,重要的是我們的應用程序不必如此。

作爲一個設計原則,OpenGL必須在抽象層次的過高與過低之間取得平衡。一方面,它必須隱藏不同製造商的產品的區別(或者同一廠商的不同產品)和平臺相關的特性,比如:顯示屏分辨率、處理器架構、安裝的操作系統等等。另一方面,它的抽象層次要低到可以讓程序員獲得底層硬件的訪問權限並且充分利用它。如果OpenGL展現過高的抽象層次,這樣它就可以很容易地用來創造符合它的樣式的程序,但卻很難使用到它未包含的圖形硬件的高級特性。這種高層次抽象的樣式有一些軟件用到,如:遊戲引擎–爲了讓基於它構建的遊戲訪問到新的圖形硬件特性通常需要對引擎做出很大量的改變。如果抽象層次過低,應用程序需要關心它們所運行的平臺的架構特性。低層次抽象在比如視頻遊戲主機中比較普遍,但這種抽象層次的圖形庫不能跨平臺支持從移動手機到遊戲的個人電腦甚至高性能專業的圖形工作站。

隨着技術的發展,計算機圖形進行了越來越多的研究,最佳實踐被開發出來,瓶頸和需求在變化,所以OpenGL也必須不斷變化趕上時代。

大多數OpenGL實現都基於當前最先進的圖形處理單元,可進行多個每秒萬億次浮點運算的運算能力、擁有好多G每秒吞吐量好幾百G的內存、並且可以驅動多個幾百萬像素高頻刷新的顯示器。GPU也超級靈活,以至於可以處理跟圖形完全不沾邊的任務,比如:物理模擬、人工智能、甚至音頻處理。

如今的GPU由大量的小型可編程處理器(被稱爲shader cores)組成,這些shader cores運行一種叫做着色器(shaders)的迷你程序。每個core有相對較低的吞吐量、在一個或多個時鐘週期內處理shader的一條指令,並且一般缺少高級的特性,比如: 無序執行、分支預測、超標量技術等等。但每個GPU都可能包含從幾十個到幾千個這樣的core,當它們聚集在一起時可以完成一個巨量的工作。圖形系統被分解爲多個階段(stages),每個階段被用一個shader或者固定功能函數(fixed-function)、可能可配置的處理區塊表示。圖示1.1展示了一個精簡的圖形管線的概要。

fiture1.1

在圖示1.1中,圓角矩形框(如Vertex fetch)表示固定功能函數階段,而方角矩形表示可編程的階段,意即它們會執行你提供的着色器。實際上有些固定功能函數階段或者全部的也會真正使用着色器代碼來實現–只不過不是我們提供的代碼,而是通常由GPU廠商當做驅動程序的一部分、固件或者其他系統性軟件提供。

OpenGL的起源和演化

OpenGL起源於Silicon Graphics公司和它的IRIS GL。當時GL表示(現在仍表示)圖形庫(Graphics Library)的意思並且在很多現代的OpenGL文檔中你會看到術語”the GL”,它表示特定圖形庫(“the graphics library”),這也是源於當時。Silicon Graphics曾經是一家高端圖形工作站生廠商。曾有非常昂貴並且私有專利性的圖形API。很多其他生廠商製造更便宜的解決方案運行於兼容其他生廠商的API之上。90年代早期,SGI意識到可移植性的重要性,於是他們決意清理IRIS GL,移除API中與特定系統關聯的部分並把它當做一種開放標準進行發行,這個開放標準可被任何人無須專利地進行實做。初見成型的OpenGL第一個版本在1992年6月發行並被標記爲OpenGL 1.0。

同年,SGI幫助成立了OpenGL架構評審委員會(OpenGL Architectural Review Board - ARB),原始的成員包含有Compaq,DEC,IBM,Intel以及Microsoft。很快,其他公司,諸如: Hewlett Packard, Sun Microsystem, Evans&Sutherland以及Intergraph也加入到委員會中。OpenGL ARB是設計、控制並且創作OpenGL標準的主體,現在它是Khronos Group的一部分,Khronos Group是一個更大的多家公司的聯合機構用以監督很多開放標準的開發。這些原始成員的一些有的不存在了(可能退出商業市場或者被其他公司收購或合併),有的退出了ARB。

本書創作的當時,OpenGL已發行有19個版本。它們的版本號和發行日期如下(本書講述版本4.5):

Version                         Publication Date
OpenGL 1.0                      1992.1
OpenGL 1.1                      1997.1
OpenGL 1.2                      1998.3
OpenGL 1.2.1                    1998.10
OpenGL 1.3                      2001.8
OpenGL 1.4                      2002.7
OpenGL 1.5                      2003.7
OpenGL 2.0                      2004.9
OpenGL 2.1                      2006.7
OpenGL 3.0                      2008.8
OpenGL 3.1                      2009.3
OpenGL 3.2                      2009.8
OpenGL 3.3                      2010.3
OpenGL 4.0                      2010.3
OpenGL 4.1                      2010.7
OpenGL 4.2                      2011.8
OpenGL 4.3                      2012.8
OpenGL 4.4                      2013.7
OpenGL 4.5                      2014.8

OpenGL核心檔案(Core Profile)

在刀刃技術(電子芯片切割)的開發中,20年是一個很長的時間。在1992年,頂尖的Intel CPU是80486,數學協處理器還是可選的,並且奔騰(Pentium)也還未發明(至少沒發行)。蘋果電腦還在使用摩托羅拉68K衍生處理器,後來切換到的PowerPC處理器是1992年下半年纔可用。在商用家用計算機上高性能圖形加速基本什麼也不是。如果你沒有一臺高性能圖形工作站,你可能不會想用OpenGL來幹什麼事。軟件渲染主宰世界,Future Crew的Unreal示例贏得Assembly的1992示例聚會。對於一臺家用計算機,你能期望的最好的渲染能力就是一些填充的多邊形或者精靈。1992的家用計算3D圖形藝術的狀態如圖示1.2:

figure 1.2

隨着時間的推移,圖形硬件的價格走低,性能上升以及可用於家用計算機的廉價加速板卡和視頻遊戲主機性能提升的一些因素,新的功能和能力在不太昂貴的圖形處理器上展現出來並加入到OpenGL。這些功能的極大一部分由OpenGL ARB成員在擴展(extensions)中進行提案。有一些擴展與其他的擴展和OpenGL現有的功能可以很好的交互,有一些不能。同時,新的、更好的榨乾圖形系統性能的手段被髮明,它們都被加入到OpenGL,於是做同一件事有了多種方案。

長久以來,ARB向後兼容上花了很大力氣,現在仍然如此。但是,這種向後兼容帶來一個可觀的消耗。在1990年代中期可以很好工作或者其實不是瓶頸的圖形硬件並不能很好適應如今的圖形處理器。指定新的功能如何與舊的傳統的功能交互並不容易,而且很多時候使得乾淨地引入一個新功能到OpenGL幾近不可能。對於實做OpenGL來說,這種兼容性也變成了一項艱鉅的任務,它導致驅動程式更容易出錯,而且圖形廠商也需要花費可觀的精力來維護所有的傳統功能,而這些功能對圖形技術的發展和變革沒有任何用處。

基於這些原因,在2008年,ARB決意將OpenGL標準變更爲兩份檔案(profile)。第一個爲核心檔案(core profile),它移除了許多傳統功能,只保留了如今的圖形硬件真正會加速的功能。這份標準比舊的標準少了好幾百頁,舊的標準稱爲兼容檔案(compatibility profile)。兼容檔案維護了從1.0到現今的所有版本的兼容性。意即1992年編寫的軟體應能編譯並且以幾千倍的效率提升運行於現今的圖形卡上。

不過兼容檔案的存在可以讓軟體開發者爲傳統的應用添加新功能而不必爲了遷移到新的API白費好些年的努力。然而核心檔案是大多數OpenGL專家推薦新的應用使用的檔案。特別是在某些平臺上,新的功能只能在核心檔案下使用,從其他方面來講,使用核心檔案的應用通常會快於兼容檔案,即使應用不經過任何修改,僅僅是請求兼容檔案,甚至於只使用核心檔案的功能。總而言之,如果一個功能在兼容檔案中但從核心檔案中被移除,我們最好就不要使用這個功能。

本書只會涉及到核心檔案。

圖元(Primitives)、管線(pipelines)、像素(pixels)

正如我們討論過的,OpenGL的模型就好比一條生產線或者管線。數據流在這個模型中通常是單一路經的,數據通過我們的程式調用的命令進入管線的開端,然後流過一個一個階段直到管線的末端。在這個路經當中,管線中的着色器或者固定功能函數可以從緩衝區(buffers)或者材質(textures)提取更多的數據,緩衝區和材質是用來在渲染中存取信息的結構。管線中有一些階段甚至可能會向緩衝區或者材質存入數據,從而讓應用讀寫數據甚至反饋發生了什麼。

OpenGL中基本的渲染單元稱爲圖元(primitive)。OpenGL支持許多圖元類型,但三種基本的可渲染圖元爲:點(points)、線(lines)、三角形(triangles)。我們在熒屏上看到的渲染的任何東西都是點、線和三角形的集合。在應用中一般會把複雜的表面(surfaces)拆解成許多三角形然後發送給OpenGL通過一個叫做光柵器(rasterizer)的硬件加速器進行渲染。三角形相對來說是非常容易繪製的。對於多邊形、三角形通常是凸面的,所以填充規則很容易設計和遵循。凹多邊形總是能拆解成兩個或多個三角形,所以硬件天然地支持直接渲染三角形並且依賴其他子系統將複雜幾何形體拆解爲三角形。光柵器是專門用來將三維形式的三角形轉換爲在熒屏上進行渲染的像素的硬件。

點、線以及三角形分別是由一個、兩個或者三個頂點(vertices)集合組成的。一個頂點(vertex)就是一個座標空間的點。在我們的場景中,我們主要考慮一個三維座標空間。圖形管線被拆解爲主要的兩部分。第一部分是前端(front end),處理頂點和圖元,最後把它們組成爲點、線和三角形傳遞給光柵器。這個過程被稱爲圖元組裝(primitive assembly)。光柵器處理之後,幾何圖形已經被轉變成大量的獨立的像素。這些都是交給後端的(back end)的,它包括深度(depth)測試和模板(sencil)測試,片段着色(fragment shading),混合(blending)以及更新輸出圖像。

隨着我們閱讀本書,我們會看到如何讓OpenGL開始爲我們所用。我們會看到如何創建緩衝區和材質並和我們的程式關聯。我們會看到如何編寫着色器來處理我們的數據以及如何配置OpenGL的固定功能函數塊來做我們想做的。OpenGL其實就是一大串非常簡單的概念,它們互相依存。擁有堅實的基礎以及對這個系統的概覽是很非常重要的,在接下來的幾個章節,我們將提供這些。

總結

在這一章我們簡單介紹了OpenGL並瞭解了它的一點起源、歷史、狀態和方向。我們已經看到了OpenGL管線以及本書如何構成。我們提及了一些將會貫穿本書的專業術語。在接下來的幾個章節,我們會創建第一個OpenGL程式,稍微深入到OpenGL管線的各個階段,並打下一些在計算機圖形世界非常有用的數學基礎。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章