版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.10.01 |
前言
OpenGL ES是一個強大的圖形庫,是跨平臺的圖形API,屬于OpenGL的一個簡化版本。iOS系統可以利用OpenGL ES將圖像數據直接送入到GPU進行渲染,這樣避免了從CPU進行計算再送到顯卡渲染帶來的性能的高消耗,能帶來來更好的視頻效果和用戶體驗。接下來幾篇就介紹下iOS 系統的 OpenGL ES框架。感興趣的可以看上面幾篇。
1. OpenGL ES 框架詳細解析(一) —— 基本概覽
2. OpenGL ES 框架詳細解析(二) —— 關于OpenGL ES
3. OpenGL ES 框架詳細解析(三) —— 構建用于iOS的OpenGL ES應用程序的清單
4. OpenGL ES 框架詳細解析(四) —— 配置OpenGL ES的上下文
5. OpenGL ES 框架詳細解析(五) —— 使用OpenGL ES和GLKit進行繪制
6. OpenGL ES 框架詳細解析(六) —— 繪制到其他渲染目的地
Multitasking, High Resolution, and Other iOS Features - 多任務,高分辨率和其他iOS功能
使用OpenGL ES的許多方面是平臺中立的,但是在iOS上使用OpenGL ES的一些細節需要特別考慮。 特別是,使用OpenGL ES的iOS應用程序必須正確處理多任務,或者在移動到后臺時可能會被終止。 在為iOS設備開發OpenGL ES內容時,還應考慮顯示分辨率和其他設備功能。
Implementing a Multitasking-Aware OpenGL ES App - 實現多任務感知OpenGL ES應用程序
當用戶切換到其他應用程序時,您的應用程序可以繼續運行。 有關iOS上多任務的全面討論,請參閱App States and Multitasking。
當OpenGL ES應用程序移動到后臺時,它必須執行其他工作。 如果應用程序處理這些任務不正確,則可能會由iOS終止。 此外,一個應用程序可能想要釋放OpenGL ES資源,以便這些資源可用于前臺應用程序。
1. Background Apps May Not Execute Commands on the Graphics Hardware - 后臺應用程序可能無法在圖形硬件上執行命令
如果OpenGL ES應用程序嘗試在圖形硬件上執行OpenGL ES命令,則會終止該應用程序。 iOS防止后臺應用程序訪問圖形處理器,以便最前沿的應用程序始終能夠向用戶呈現出極好的體驗。 您的應用程序不僅可以在后臺進行OpenGL ES調用時被終止,還可以在后臺將先前提交的命令刷新到GPU。 您的應用程序必須確保所有以前提交的命令在移動到后臺之前已完成執行。
如果您使用GLKit
視圖并查看控制器,并且僅在繪圖方法中提交OpenGL ES命令,則當應用程序移動到后臺時,您的應用程序會自動正常運行。 默認情況下,GLKViewController
類在您的應用程序處于非活動狀態時暫停其動畫定時器,確保您的繪圖方法不被調用。
如果您不使用GLKit視圖或視圖控制器,或者如果您在GLKView繪圖方法之外提交OpenGL ES命令,則必須執行以下步驟以確保您的應用程序未在后臺終止:
- 在應用程序委托的applicationWillResignActive:方法中,您的應用程序應該停止其動畫定時器(如果有的話),將其置于已知的良好狀態,然后調用glFinish函數。
- 在您的應用程序委托的applicationDidEnterBackground:方法中,您的應用程序可能需要刪除其一些OpenGL ES對象,以使內存和資源可用于前臺應用程序。 調用
glFinish
函數以確保資源立即被刪除。 - 在您的應用程序退出其applicationDidEnterBackground:方法之后,它不能進行任何新的OpenGL ES調用。 如果是OpenGL ES調用,則由iOS終止。
- 在您的應用程序的應用程序applicationWillEnterForeground:方法中,重新創建任何對象并重新啟動動畫定時器。
總而言之,您的應用程序需要調用glFinish
函數,以確保所有以前提交的命令都從命令緩沖區中排出并由OpenGL ES執行。 移動到后臺后,您必須避免使用OpenGL ES,直到它移回到前臺。
2. Delete Easily Re-Created Resources Before Moving to the Background - 在移動到后臺之前刪除容易重新創建的資源
您的應用程序從來不需要在OpenGL ES對象移動到后臺時釋放。 通常,您的應用程序應避免處理其內容。 考慮兩種情況:
- 用戶正在玩游戲,并短暫退出以檢查他們的日歷。 當玩家返回游戲時,游戲資源仍然在內存中,游戲可以立即恢復。
- 當用戶啟動另一個OpenGL ES應用程序時,您的OpenGL ES應用程序處于后臺。 如果該應用程序需要比設備上可用的內存更多的內存,系統將自動終止您的應用程序,而不需要執行任何其他工作。
您的目標應該是將您的應用程序設計為一個好的產品:這意味著保持移動到前臺的時間盡可能短,同時在后臺減少其內存占用。
以下是處理這兩種情況的方法:
- 您的應用程序應將紋理,模型和其他資產保留在內存中; 在您的應用程序移動到后臺時,不應該處理需要很長時間重新創建的資源。
- 您的應用程序應該處理可以快速,輕松地重新創建的對象。 尋找消耗大量內存的對象。
簡單的目標是您的應用程序分配用于保存呈現結果的幀緩沖區。 當你的應用程序在后臺時,用戶看不到它,可能不會使用OpenGL ES
渲染任何新的內容。 這意味著應用程序的幀緩沖區消耗的內存是分配的,但沒有用。 此外,幀緩沖區的內容是暫時的; 大多數應用程序在每次呈現新幀時重新創建幀緩沖區的內容。 這使得renderbuffers成為可以輕松重新創建的內存密集型資源,成為當移動到后臺時可以處理的對象的良好候選。
如果您使用GLKit
視圖和視圖控制器,則當應用程序移動到后臺時,GLKViewController
類會自動處理其關聯視圖的幀緩沖區。 如果您手動創建用于其他用途的幀緩沖區,則在應用程序移動到后臺時應該處理它們。 在這兩種情況下,您還應該考慮當時應用程序可以處理的其他暫時資源。
Supporting High-Resolution Displays - 支持高分辨率顯示
默認情況下,GLKit視圖的 contentScaleFactor屬性的值與包含它的屏幕的比例匹配,因此其關聯的幀緩沖區配置為以顯示的全分辨率進行渲染。 有關UIKit中支持高分辨率顯示的詳細信息,請參閱 Supporting High-Resolution Screens In Views。
如果您使用Core Animation
層提供OpenGL ES內容,則其縮放因子默認設置為1.0。 為了繪制Retina顯示屏的完整分辨率,您應該更改CAEAGLLayer
對象的比例因子以匹配屏幕的比例因子。
當支持具有高分辨率顯示器的設備時,您應該相應地調整應用程序的模型和紋理資產。 在高分辨率設備上運行時,您可能需要選擇更詳細的模型和紋理來渲染更好的圖像。 相反,在標準分辨率設備上,您可以使用較小的模型和紋理。
重要:許多OpenGL ES API調用以屏幕像素表示維度。 如果使用大于1.0的比例因子,則應在使用glScissor,glBlitFramebuffer,glLineWidth
或glPointSize
函數或gl_PointSize
著色器變量時相應調整維度。
確定如何支持高分辨率顯示器的一個重要因素是性能。 Retina顯示屏上的比例因子倍增了像素數量的四倍,導致GPU處理的片斷數量是四倍。 如果您的應用程序執行許多每個片段的計算,像素的增加可能會降低幀速率。 如果您發現您的應用程序在較高比例因子下運行速度顯著較慢,請考慮以下選項之一:
- 使用本文檔中的性能調整指南優化片段著色器的性能。
- 在片段著色器中實現更簡單的算法。 通過這樣做,您可以降低單個像素的質量,以更高的分辨率渲染整體圖像。
- 使用1.0之間的分數比例因子和屏幕的比例因子。 比例因子1.5提供比1.0的比例因子更好的質量,但是需要填充比縮放到2.0的圖像更少的像素。
- 對您的GLKView對象的drawableColorFormat和drawableDepthFormat屬性使用較低精度的格式。 通過這樣做,可以減少對底層渲染緩沖區進行操作所需的內存帶寬。
- 使用較小的比例因子并啟用多重采樣。 另外一個優點是,多采樣在不支持高分辨率顯示器的設備上也提供了更高的質量。
要為GLKView
對象啟用多重采樣,請更改其drawableMultisample
屬性的值。 如果沒有渲染到GLKit視圖,則必須手動設置多采樣緩沖區并在呈現最終圖像之前對其進行解析(請參閱使用多重采樣來提高圖像質量)。
多次采樣不是免費的; 需要額外的內存來存儲附加樣本,并將樣本解析為解析幀緩沖區需要時間。 如果您向應用程序添加多重采樣,請始終測試應用程序的性能,以確保其仍然可以接受。
Supporting Multiple Interface Orientations - 支持多種界面方向
像任何應用程序一樣,OpenGL ES應用程序應該支持適合其內容的用戶界面方向。 您可以在其信息屬性列表中聲明支持的應用程序接口方向,或者使用supportedInterfaceOrientations方法來托管OpenGL ES內容的視圖控制器。 (有關詳細信息,請參閱View Controller Programming Guide for iOS)。
默認情況下,GLKViewController
和GLKView
類自動處理方向更改:當用戶將設備旋轉到受支持的方向時,系統會動態定向更改并更改視圖控制器視圖的大小。 當其大小更改時,GLKView對象會相應地調整其幀緩沖區和視口的大小。 如果您需要響應此更改,請在GLKViewController子類中實現viewWillLayoutSubviews
或viewDidLayoutSubviews
方法,如果使用自定義GLKView子類,則實現layoutSubviews
方法。
如果您使用Core Animation層繪制OpenGL ES內容,則應用程序仍應包含一個視圖控制器來管理用戶界面方向。
Presenting OpenGL ES Content on External Displays - 在外部顯示器上呈現OpenGL ES內容
iOS設備可以連接到外部顯示器。 外部顯示器的分辨率及其內容比例因子可能與主屏幕的分辨率和比例因子不同, 您渲染幀的代碼應該進行調整和匹配。
在外部顯示器上繪制的程序與在主屏幕上運行的程序幾乎相同。
按照Multiple Display Programming Guide for iOS中的步驟,在外部顯示器上創建一個窗口。
-
將適當的視圖或視圖控制器添加到窗口對象的渲染策略。
- 如果使用GLKit渲染,請設置GLKViewController和GLKView(或您的自定義子類)的實例,并使用其
rootViewController
屬性將其添加到窗口。 - 如果渲染到Core Animation圖層,請將包含圖層的視圖添加為window的子視圖。 要使用動畫循環進行渲染,請通過檢索窗口的屏幕屬性并調用其displayLinkWithTarget:selector:方法來創建為外部顯示優化的顯示鏈接對象。
- 如果使用GLKit渲染,請設置GLKViewController和GLKView(或您的自定義子類)的實例,并使用其
后記
未完,待續~~~