openGL 着色語言 C#-tao框架

2.1.1 頂點:3D圖形的基礎

OpenGL中的基本單元是頂點。簡單來說,頂點就是空間中的一個點。在這些點上可以附加其他信息,如它如何映射到紋理,是否具有一定的重量或顏色等,但是最重要的信息是它的位置。

遊戲會把大量的時間用於發送OpenGL頂點,或者告訴OpenGL以特定的方式移動頂點等。遊戲可能首先告訴OpenGL它將要發送的全部頂點會構成三角形。此時,OpenGL將使用線把它收到的每三個頂點連接起來以創建一個多邊形,然後可能還會使用紋理或顏色填充多邊形的表面。

現代圖形硬件非常擅長處理大量的頂點,把它們構成多邊形,然後渲染到屏幕上。這個從頂點到屏幕的過程叫做流水線(pipeline)。流水線負責定位頂點和提供光照,以及進行投影變換。這個過程將把收到的3D數據變換爲2D數據,以便將其顯示到屏幕上。投影變換聽起來有點複雜,但是幾個世紀以來,畫家和藝術家們一直在利用這種變換,在平展的畫布上繪製出他們周圍的世界。


2.1.2 流水線

流水線的流程如圖2-3所示。這個流水線叫做固定功能流水線(fixed function pipeline)。當程序員爲這種流水線提供輸入後,所有的功能已被固定,無法修改。例如,在像素處理階段很容易向屏幕上添加藍色調,但是在固定功能流水線中,程序員無法直接控制這個階段。

圖2-3 基本的固定功能流水線

固定功能流水線包含6個主要的階段。這些階段幾乎都可以並行應用。如果硬件支持的話,每個頂點可以同時經過同一個階段。由於這個原因,圖形卡的處理速度比CPU的處理速度要快得多。


輸入階段。輸入以頂點的形式給出,頂點的屬性包括位置、顏色和紋理數據。


變換和光照。根據當前視圖變換頂點。這包括將頂點的位置由3D空間(也叫做世界空間)改爲2D空間(也叫做屏幕空間)。如果有些頂點對最終的顯示沒有影響,可以在這個階段移除它們。在這個階段也可以對每個頂點執行光照計算。


創建圖元。這是使用頂點信息創建多邊形的過程,需要根據OpenGL的狀態把頂點連接到一起。遊戲經常使用三角形或者三角帶作爲圖元。


光柵化。這是將多邊形轉換爲像素(也叫做片段)的過程。

像素處理。像素處理也叫做片段處理。這個階段將測試像素,以確定是否把它們繪製到幀緩衝區中。


幀緩衝區。幀緩衝區是一塊內存,代表特定的幀將顯示在屏幕上的部分。混合設置將決定像素如何與已經繪製的部分進行混合。


使用程序控制流水線了。將程序上傳到圖形卡以後,它們將替換固定功能流水線的默認階段。重寫流水線的特定部分的小程序叫做着色器(shader)。


圖2-4顯示了可編程流水線的階段。這裏刪除了變換和光照階段,添加了頂點和幾何着色器。像素處理階段也可以像像素着色器那樣進行編程。通過流水線的每個像素都會被應用像素着色器。像素着色器不能添加頂點,但是可以修改位置、顏色和紋理位置等屬性。

圖2-4

與像素着色器和頂點着色器相比,幾何着色器加入的時間較晚。幾何着色器以一個完整的圖元(如線、點或三角形組成的帶)作爲輸入,而頂點着色器針對每個圖元都會運行。幾何着色器可以創建新的頂點信息、點、線,甚至圖元。幾何着色器還可用於創建點精靈和動態鑲嵌,以及實現其他一些效果。點精靈可以快速渲染大量精靈,這種技術經常用於粒子系統,可創建類似於火焰或者煙霧效果。動態鑲嵌可以在幾何形狀中添加更多的多邊形。這種技術可以用來增加包含多邊形數較少的遊戲模型的平滑度,並在攝像機放大模型時展現更多的細節。

像素着色器會應用到被髮送到幀緩衝區的每個像素。像素着色器用於創建凹凸貼圖效果、鏡面高光和逐像素光照。凹凸貼圖效果可以給表面增加額外的高度信息。凹凸貼圖通常包含一個圖片,其中每個像素代表一個標準的法向量,該法向量描述瞭如何扭曲表面。像素着色器可以使用凹凸貼圖來爲模型提供一個更有趣的紋理,使其看上去有一定的深度感。逐像素光照用於替換OpenGL的默認的光照公式。OpenGL的光照公式可計算出每個頂點的光照,然後爲該頂點提供一種合適的顏色。逐像素光照使用更精確的光照模型,爲每個像素單獨應用光照。鏡面高光是模型中非常亮、反射大量光的區域。


2.2 變化中的OpenGL

現在是學習OpenGL的大好時機。OpenGL的當前版本非常適合學習。這個版本中包含了大量易於使用的函數,可以完成各種各樣與圖形處理有關的工作。可以把OpenGL的當前版本想象成一個帶有輔助輪的自行車,剛開始時藉助它們學習怎麼騎車,熟練之後就把它們取下來。OpenGL的下一個版本更像是一個性能強大的摩托車,沒有必要的東西都被移除了,剩下的就是不受限制的原始力量。對於有經驗的OpenGL程序員,其好處自不必言,但是初學者卻容易對其望而生畏。

可以使用的OpenGL版本要取決於系統中安裝的圖形卡驅動程序。幾乎每臺計算機都支持OpenGL 2.1,而近期生產的圖形卡會支持OpenGL 3.x。

2.2.1 OpenGL ES

OpenGL ES是用於嵌入式系統的OpenGL的新版本。它與OpenGL的近期版本相似,但是功能集更加受限。它用於高端手機,例如Android、BlackBerry和iPhone。OpenGL ES也用於軍用硬件,例如戰機上的平視顯示器。

OpenGL ES支持可編程流水線,也支持着色器。


2.2.2 WebGL

WebGL目前仍處於開發中,這個版本的OpenGL是專爲在Web上使用而設計的。使用WebGL的瀏覽器必須支持HTML 5 canvas標籤。就現在而言,還無法知道它會取得多大的成功。以前人們曾有過在Web上使用3D的嘗試,但是都失敗了。例如,VRML(Virtual Reality Modeling Language,虛擬現實建模語言)與HTML類似,但是允許用戶創建3D世界,它在學術界受到了不少關注,卻從沒有吸引過普通的用戶。

WebGL有一些強有力的支持者,許多大公司都加入了WebGL工作組,如Google、Apple和Mozilla,而且WebGL還有一些讓人印象非常深刻的演示。就目前來看,WebGL的性能還是不錯的,在成熟以後很可能可以與Flash一較高低。


2.3 OpenGL和圖形卡

OpenGL是一個允許程序員發送指令到圖形卡的庫。圖形卡是一種專用於顯示3D數據的硬件,由很多標準組件構成,包括幀緩衝區、紋理內存和GPU。GPU是圖形處理單元(Graphics Processing Unit)的縮寫,它控制着如何處理頂點並把它們顯示到屏幕上。CPU向GPU發送指令和數據,描述每一幀應該怎樣顯示到屏幕上。紋理內存通常是一塊較大的內存,用於存儲遊戲所需的大量紋理。幀緩衝區是內存中的一塊區域,存儲下一幀中將顯示到屏幕上的圖像。現代的圖形卡通常有多個GPU,每個GPU上都有許多着色器處理單元來執行大規模的並行着色器操作。分佈式應用程序(如模擬蛋白質摺疊的Folding@home)和世界各地的數十萬臺計算機都利用了這一特點。

第一個獲得流行的3D圖形卡是3dfx Voodoo 1。這是早期的一個圖形卡,有2MB的紋理內存和2MB的幀緩衝區,並且使用PCI總線,時鐘速度爲135MHz。早期的一些遊戲使用它來加速執行,例如《古墓麗影(Tomb Raider)》、Descent II、《雷神之錘(Quake)》以及《雷神之錘2(Quake 2)》的演示,從而運行得更加流暢,並且可顯示更多的細節。Voodoo 1使用一個標準的PCI總線,允許CPU以最高533MB/s的速度向圖形卡發送數據。現代的圖形卡已經從PCI轉向使用AGP(Accelerated Graphics Port,加速圖形端口),其最高數據發送速度爲2GB/s,後來又轉向使用PCI Express。當前的這一代PCI Express卡的最高數據發送速度爲8GB/s。

好像每個月都會有新的圖形卡問世,每個新圖形卡都比之前的圖形卡更快。在編寫本書時,最快的圖形卡可能是ATI Radeon HD 5970。它有兩個GPU,每個GPU都有1600個着色器處理器。它的時鐘速度爲725MHz,每秒可以處理4.64萬億次浮點運算。

大多數現代圖形卡都有專門執行新操作的特殊硬件。這種硬件通過使用擴展提供給OpenGL。當收到一個標識新擴展的字符串時,OpenGL能夠展示驅動程序和圖形卡中的功能。例如,ATI Radeon HD 5970有兩個GPU,這種情況很少見。爲了能夠充分利用兩個GPU,需要使用一些新的擴展方法,如AMD_gpu_association。這個擴展允許用戶在兩個GPU之間分配任務。如果多家供應商實現了相同的擴展,那麼擴展字符串的某個位置會有字母EXT。有時候,控制OpenGL規範的架構評審委員會可能會把某個擴展的狀態提升爲官方擴展,此時,擴展字符串中將包含字母ARB,所有的供應商都必須支持該擴展。

着色器--圖形卡上的程序

着色器(shader)這個詞帶有一定的誤導性。最初的着色器程序主要用於處理組成每個多邊形表面的像素,以便爲模型着色。但是隨着時間推移,着色器程序的功能已經被擴展,現在還可以修改頂點屬性、創建新頂點,甚至完成一般的操作。

着色器與運行在CPU上的普通程序具有不同的工作方式。着色器程序在大量的元件上同時執行,這意味着着色器程序是大規模並行程序,而運行在CPU上的程序一般則是串行運行的,一次只有一個實例運行。着色器程序非常適合對構成3D世界的像素和頂點的集合執行操作。

目前共有3類着色器,分別是頂點着色器、幾何着色器和像素着色器,每種着色器都只能執行特定的操作。頂點着色器處理頂點,像素着色器處理像素,幾何着色器處理圖元。爲了降低複雜性,並使硬件製造商可以更高效地進行優化,所有這些着色器都被一種叫統一着色器(unified shader)的着色器替代了。

着色器通過運行在圖形卡上的特殊語言進行編程。目前,這些語言比C++低級得多(更別提C#了)。OpenGL有一門叫做GLSL(OpenGL Shading Language,OpenGL着色語言)的着色語言,它與C語言有些類似,但是有大量用於處理向量和矩陣的特殊操作。DirectX也有自己的着色語言,叫做HLSL(High Level Shading Language,高級着色語言)。兩種語言十分類似。讓人更加困惑的是,除了這兩種語言以外,還有一種叫做Cg的語言,它由Microsoft和Nvidia開發,與HLSL有些類似。

遊戲中的着色器非常適合創建需要進行大量計算的特殊效果,如視差貼圖的光照。當前的技術使得着色器程序幾乎不能用於其他用途。本書主要介紹遊戲編程,由於可編程流水線是一個很大的主題,所以不會討論該技術。如果對此主題感興趣,可以參閱附錄A部分,那裏介紹了幾本非常好的書籍。

着色器的一種趨勢是用於一般性的並行編程任務,而不只是處理圖形。例如,Nvidia PhysX庫允許在GPU而非CPU上完成物理計算,從而得到更佳的性能。PhysX是用另外一種叫做CUDA的着色器語言編寫的,但是CUDA與其他着色器語言有一些不同,這種語言不怎麼關注像素和頂點,而是更關注一般目的的並行編程。假設在遊戲中要模擬一個城市,並且有一個非常新奇的並行算法可以更新城市中的全部居民,那麼這種計算在GPU上可以更快地執行,而CPU就可以被解放出來,執行其他任務。CUDA通常用於科學研究項目,因爲這是利用強大的計算能力的一種廉價的方式。使用CUDA的應用程序包括量子化學計算、心肌模擬和黑洞建模。



2.4 Tao框架

Tao框架是C#使用OpenGL庫的一種方式。Tao包裝了許多C庫(見表2-1),並使得在C#中使用這些函數變得很簡單。Tao中還綁定了Mono,所以也可以用在Linux和Mac中。

通過Tao,C#不只可以使用OpenGL,還可以使用其他一些有用的庫。

表2-1 Tao框架中包含的庫

用途

Tao.OpenAl

OpenAL是一個強大的音頻庫

Tao.OpenGl

OpenGL是我們將要使用的圖形庫

Tao.Sdl

SDL(Simple DirectMedia Layer),一個

構建在OpenGL之上的2D庫

Tao.Platform.Windows

支持通過Windows.Forms使用OpenGL

Tao.PhysFs

一個I/O的包裝器,支持遊戲資源的存檔文件,如.zip文件

Tao.FreeGlut

OpenGL實用程序工具包(OpenGL Utility

Toolkit)是一組包裝器,用於設置OpenGL

程序和一些繪圖例程

Tao.Ode

Open Dynamics Engine是在遊戲中使用的

一個實時物理引擎

Tao.Glfw

OpenGL Framework是一個可以在多個平臺

上使用的輕量級的包裝器類

(續表)

用途

Tao.DevIL

DevIL是將各種圖片類型(bmp、tif、gif、

png等)加載到OpenGL的出色的工具

Tao.Cg

Cg是一種高級着色語言

Tao.Lua

Lua是遊戲業最常用的腳本語言之一

Tao.FreeType

字體包

Tao.FFmpeg

主要用於播放視頻

OpenAL代表開放音頻庫(Open Audio Library),是一個強大的開源庫。《生化奇兵(BioShock)》、《雷神之錘4(Quake 4)》、《毀滅戰士3(Doom III)》和《虛幻(Unreal)》等遊戲都使用了這個音頻庫。它採用OpenGL作爲模型,具有相同的狀態機風格的設計和擴展方法。

SDL(Simple DirectMedia Layer)是一個跨平臺的庫,支持輸入、聲音和圖形。SDL在遊戲開發商中非常流行,在獨立或者開源遊戲中使用得尤其多。使用SDL開發的最著名的開源遊戲之一是FreeCiv,它是《文明(Civilization)》的一個聯機版本。多數Linux遊戲端口中也使用了SDL。

PhysFs初看起來可能是一個物理庫,但是實際上卻是一個小型的IO庫。它可以將全部遊戲資源打包爲一個較大的二進制文件,或者幾個小的二進制文件。許多商業遊戲都有類似的系統,例如《毀滅戰士(Doom)》的wad系統或《雷神之錘(Quake)》的pak系統。它可以使遊戲在發佈後的修改和更新變得更加簡單。

FreeGLUT是OpenGL實用程序工具包的免費版本。這個庫中的函數可以讓用戶馬上就能夠使用OpenGL。它還有從鍵盤和鼠標接受輸入的方法,以及繪製各種基本形狀的方法,例如球形、立方形,甚至茶壺形(這個茶壺在計算機圖形學中非常有名,它是由Martin Newell在猶他大學求學期間進行建模的。茶壺是一個非常複雜的表面,所以在測試新的圖形技術時非常有用。動畫電影《玩具總動員》中就有一個典型的茶壺模型,DirectX甚至有自己的茶壺創建方法D3DXCreateTeapot( )。在講授OpenGL時經常用到FreeGLUT,但是它的功能很有限,很少用於真正的項目。

ODE(Open Dynamics Engine)是一個可以用在多個平臺上的物理引擎,可以完成碰撞檢測和剛體模擬。PC上的第一人稱射擊遊戲《潛行者(S.T.A.L.K.E.R)》中就使用了ODE。Glfw是可以通過Tao使用的第三個可移植的OpenGL包裝器。Glfw代表OpenGL框架(OpenGL framework),它的目的是擴展GLUT提供的功能。如果不想使用SDL,但又確實想使用框架來訪問OpenGL,就可以考慮使用Glfw。

DevIL(Developer's Image Library)是一個從磁盤加載紋理到OpenGL中的庫。DevIL與OpenGL有些類似,因爲它也是一個狀態機,並且有類似的方法名稱。DevIL是跨平臺的,支持多種(43種)不同的圖片格式。Cg是本章前面提到的一種着色器語言。通過使用Tao.Cg,可以從文本文件或字符串中加載着色器程序,進行處理,然後在OpenGL中使用。

Lua可能是遊戲開發中最流行的腳本語言。它是一種小型的、易於嵌入的語言,表達力非常強。使用Tao.Lua可以在腳本和C#程序之間傳遞函數和數據。Tao.FreeType是一個基本的字體包,可以將FreeType類型的字體轉換成一幅位圖。它的接口簡單易用。

Tao提供的最後一個庫是FFmpeg,這個名稱由MPEG(一個視頻標準)和FF(Fast Forward,快進)組成。它提供了一種播放視頻的方式。如果想要在遊戲中使用過場動畫,FFmpeg是一個不錯的選擇。

Tao提供的所有庫都是完全開源的。其中的多數庫都可以免費用在商業項目中,但還是有必要閱讀許可證中列出的具體說明。Tao是一個出色的程序包,剛開始涉足遊戲的開發商可以把它作爲一個起點。對每個庫的介紹不在本書的討論範圍之內,我們將只關注其中最重要的那些庫。從第5章開始,我們將使用OpenGL和Tao.Platform.Windows庫。第6章將討論DevIL。第9章將討論使用OpenAL播放聲音,以及使用SDL處理手柄輸入。每個庫都很有用,所以很有必要花些時間研究每個感興趣的庫。


發佈了8 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章