文章目錄
- 2.2.1. 用戶端-伺服器模型
- 2.2.2. OpenGL ES 依賴於具體平台的關鍵功能庫
- 2.2.3. 命令可以非同步執行
- 2.2.4. 命令可以依序執行
- 2.2.5. 呼叫時參數會被複製
- 2.2.6. 定義在規範中具擴充功能實踐方法
第二章 iOS上的OpenGL ES
OpenGL ES提供者介面原函數以透過圖形加速硬體管線繪製。OpenGL消耗圖形命令產生影像用以顯示給使用者,或進一步處理OpenGL ES以外的檢索。
OpenGL ES規範明確聲明了每個函數的行為。參考下面步驟以理解大部份OpenGL ES命令:
· 參考25頁“Determining OpenGL ESCapabilities” 獲得各類別的詳細實踐資訊。
· 讀寫狀態變數聲明於規範中。OpenGL ES的狀態通常表示當前配置的圖形管線。例如,OpenGL ES的1.1使用狀態變數,廣泛地配置燈光,材料和固定功能管線進行計算。
· 建立,修改及推毀OpenGL ES對象。OpenGL ES對象不是Objective-C對象;它們是透過OpenGL ES程式介面操作的資源。參考17頁See “OpenGL ES Objects Encapsulate Resources on Behalf ofYour Application” 獲得更多訊息。
· 頂點需透過繪圖原函數提交至管線加工,組合,或著作為禎緩衝影格。
2.1 該選擇哪一個版本的OpenGL ES?
當你設計OpenGL ES應用程式時,必須回答一個關鍵問題:你的應用要支援OpenGL ES2.0或OpenGL ES 1.1或是兩者兼有。
· OpenGL ES 2.0比OpenGL ES1.1更強大靈活,是新應用的最佳選擇。可更清晰,簡潔的自訂頂點及著色器,以及有更好的效能。在OpenGL ES1.1執行相同的計算,往往需要多個渲染通道或更複雜的狀態配置,容易掩蓋演算法目的。如果演算法變複雜,OpenGL ES2.0的著色器更能清晰及簡潔的表達運算,以及更高的效能。建制OpenGL ES2.0應用程式需要較多工作,預設情況下,需重新為OpenGL ES1.1建立一些基礎配置。
· OpenGL ES1.1提供了一些固定功能管線,包括一些不錯的基礎3D應用功能,轉換和光照,及混合至禎緩衝。如果應用需求簡單,用OpenGL ES1.1可較少編碼。若需要支援所有iOS裝置,就只能選擇OpenGL ES1.1。
如果你為了就裝置相容性選擇實踐OpenGL ES1.1為主,可以考慮增加一個OpenGL ES 2.0的渲染選項,OpenGL ES2.0有更大的能力及優勢發揮新的iOS裝置的圖形處理器。
重要如果你的應用不支援OpenGL ES 1.1與2.0繪圖路徑,將會限制應用能選擇的裝置版本。參考 iOS App Programming Guild中的”Declaring the Required Device Capabilities”章節。 |
2.2. 瞭解OpenGLES的架構
OpenGL ES運作在幾個關鍵原則上。為了設計高效的OpenGL ES應用程式,需要瞭解底層架構。
2.2.1. 用戶端-伺服器模型
OpenGL ES使用用戶端-伺服器模型,1.1。當應用程式呼叫OpenGL ES函數時,它會與OpenGL ES用戶端交談。用戶端程式到函數調用完畢,必要時轉化為OpenGL伺服器命令。用戶端-伺服器模型允許工作處理被分為用戶端與伺服器端的函數調用。用戶端,伺服器,及之間的溝通路徑的本質,OpenGL ES各別具體實踐;在iOS終至上,工作是介於CPU與專用的圖形處理器之間。
圖1.1 OpenGL ES 用戶端-伺服器模型
2.2.2. OpenGL ES 依賴於具體平台的關鍵功能庫
OpenGL ES規範聲明了OpenGL ES如何工作,但是沒有聲明管理OpenGL ES與主作業系統之間互動的功能。相反地,規範假設每個實踐都提供配置渲染內文與系統禎緩衝的配置功能。渲染內文儲存OpenGL ES狀態機器的內部狀態。渲染內文每個OpenGLES應用程式各自維護自己的狀態資料副本,不用擔心會影響其他程式。參考20頁的“Configuring OpenGL ES Contexts”。也可以在單一應用中使用多個宣染內文。系統禎緩衝是OpenGL ES繪製命令的終點,也與主作業系統的圖形子系統有關。iOS不提供系統禎緩衝。相反地,iOS擴充了OpenGLES的禎緩衝對象,並允許與CoreAnimation共用資料。參考18頁的“Framebuffer Objects are theOnly Rendering Target on iOS”獲得更多有關禎緩衝對象的資訊,28頁的“Drawing With OpenGL ES”詳細討論了在應用中建立與使用禎緩衝。
2.2.3. 命令可以非同步執行
OpenGL ES用戶端-伺服器模型的一個好處是OpenGL ES函數可以在請求操作完成前將控制權還給應用程式。假如OpenGL ES在將控制權還給應用前,需等每個函數執行完畢,CPU與GPU將會步調一致,應用會喪失很多並行機會。在iOS中,延遲執行繪圖命令很常見。延遲幾個繪圖命令,並同時處理,圖形硬體可以刪除隱藏的表面於執行昂貴的片段計算之前。許多OpenGL ES函數或明或暗送重新整理命令給圖形裝置。其他重新整理圖形處理器的OpenGL命令會等到某些或全部命令完成。儘可能避免設計出客戶-服務端同步的應用。
2.2.4. 命令可以依序執行
若用戶端應用程式照相同順序執行函數,OpenGL ES保證函數調用的結果與宣染內文相同。當你的應用調用OpenGL ES函數,可以假設這些函數結果是有效,即時命令尚未執行完畢。
2.2.5. 呼叫時參數會被複製
為了讓命令非同步處理,應用調用函數時需要的參數資料必須在控制權返回應用前被複製。若參數是個指嚮應用程式記憶體中的頂點資料數組指標,OpenGL ES必須在返回前複製頂點資料。這有一些重要意義。首先,應用可以自由改變自己的記憶體無論是否調用OpenGL ES,因為OpenGL ES絕不會和應用同時存取記憶體。再來,複製及格式化資料,以便圖形裝置可讀取,並增加每個函數呼叫開銷。為了最好的效能,應用需聲明為了圖形裝置最佳化的資料格式,並且應該使用緩衝對象隱藏應用與OpenGL ES之間的記憶體管理及複製。
2.2.6. 定義在規範中具擴充功能實踐方法
一個OpenGL ES實現可以擴展 OpenGL ES規範的兩種方法之一。首先實現需滿足規範規定的最低要求,如應用程式可存取的紋理大小,紋理單元數量。一個OpenGL ES實現是自由支援較大變數:如一個大型紋理或更多紋理單元。其次,OpenGL ES擴充允許一個實踐提供新的OpenGL ES函數其常量。擴充允許實踐添加全新特性。Apple實踐許多擴充功能,允許應用程式利用硬體特性來改善應用程式的效能。不同的iOS裝置與版本的實際硬體限制與提供的擴充功能清單會有所不同。應用需測試回合能力,以確保行為一致。
2.3. 應用程式中常用OpenGL ES中具代表性封裝對象資源
對象是不透明的容器,在應用中用來儲存配置狀態或是渲染器所需的資料。因為只有對象的訪問是通過程式的API,在應用中設定物件時,可以選擇不同策略的OpenGL ES實踐。它可以儲存在資料格式或是監禁處理器最佳化的記憶體位置中。對象的另一個好處是重複使用,允許應用一次或多次設定物件。
OpenGL ES最重要的物件類型包括:
l 紋理(texture)是個映像,可被繪圖管線採樣。通常紋理被用來映射到原語上的彩色映像,但也可映射到其他資料,如一般映射或是預計算的照明訊息。章節“Best Practices for Workingwith Texture Data”討論在iOS上使用紋理(texture)這重要議題。
l 緩衝(buffer)對象在應用中是一個擁有OpenGL ES儲存資料的區塊記憶體。緩衝被用來精確控制應用跟OpenGL ES之間複製資料的過程。舉例來說,假設你提供頂點數組給,每次提交繪製呼叫都必需複製資料。相比之下,若你的應用將資料儲存在頂點緩衝對象(vertex buffer object),當應用提交命令修改頂點緩衝對象的內文時,資料才被複製。使用緩衝來管理頂點資料,可顯著提高應用效能。
l 頂點數組(vertex array)對象持有的是圖型管線讀取的頂點屬性配置。許多應用渲染實體需要不同的管線配置。通過儲存頂點數組配置,避免重新設定管線的成本,並可能允許執行特定的頂點配置最佳化處理。
l 著色器程式(Shader programs),或著稱作著色器(shaders),也是對象。OpenGL ES2.0應用可建立頂點與片段著色器分別進行頂點或片段的計算。
l 渲染緩衝(renderbuffer)是簡單的2D圖型影像的特殊格式。這種格式通常被定義為顏色,深度或模板資料。渲染緩衝通常是不單獨使用,而是與禎緩衝(framebuffer)一起使用。
l 禎緩衝(Framebuffer)對象是圖型管線的最終目的。禎緩衝對象只是個容器,內含紋理(texture)與渲染緩衝(renderbuffer),本身建立渲染器的完整配置。在之後的章節“Drawing With OpenGL ES”, 討論在iOS應用中建立及使用禎緩衝的策略。
雖然在OpenGL ES中的每個物件類型都有它自己的函數來操縱它,所有的對象共用一個類似的編程模型:
1. 產生對象身份
身份是個普通的整數,用來表示某個特定對象執行個體。每當你需要一個新對象,呼叫OpenGL ES建立一個新的身份。建立對象身份不代表實際建立對象,只是配置個參考。
2. 綁定對象到OpenGLES內文
大部分OpenGL ES函數隱含作用於對象,而不是要求每次呼叫時明確指定對象身份。你設定對象並綁定配置到內文。每個不同類型的對象使用不同的綁定函數。在第一次綁定一個對象身分時,OpenGL ES會配置及初始化對象。
3.修改對象狀態
你的應用程式使一或多個函數調用設定物件。舉例來說,在綁定紋理對象後,通常會配置紋理過濾及讀取映像資料。改變一個對象可能是昂貴的,因為他可能需要提交新的資料給圖型硬體。這是合理的,建立及設定物件一次,並在應用程式中不要改變它。
4. 使用對象渲染
一但建立並配置了渲染情境所需全部對象,你要替管線綁定對象並執行一或多個繪圖功能。OpenGL ES照原語將對象儲存的資料渲染出來。結果會送到綁定的禎緩衝對象。
5. 刪除對象
當對象不用時,應用應該要將其刪除。對象被刪除後,內容會被摧毀,對象身分會被回收。
2.4. 只宣染在iOS上的偵緩衝對象(Framebuffer)
禎緩衝(framebuffer)對象是渲染命令的目標。OpenGL ES2.0提供的禎緩衝對象是核心規範中的一部分;在OpenGLES1.1中由OES_framebuffer_object拓展提供。因威禎緩衝對象只在iOS上渲染,蘋果保證OES_framebuffer_object拓展會被實踐在所有
實踐OpenGL ES1.1的iOS上。1-2,禎緩衝對象提供色彩深度或模版資料存放區將映像連結至禎緩衝。最常見的映像連結對象是渲染緩衝(renderbuffer)。然而,OpenGL ES紋理可以被串連到禎緩衝的顏色附著點,而讓映像直接渲染成紋理。
之後,紋理可以作為未來的渲染命令的輸入。
圖1-2,禎緩衝與顏色及深度渲染緩衝
建立禎緩衝需依循下列步驟:
1. 產生及連結一個禎緩衝對象。
2. 產生,連結,及配置映像。
3. 連結映像到禎緩衝的附著點。
4. 若需更多映像則重複2-3。
5. 測試禎緩衝完整性。完整性的規則聲明在OpenGL ES規範中。這些規則確保了禎緩衝及其附著點。