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