OpenGL ES for iOS - 5

多任務(wù),高分辨率和其他iOS功能

Implementing a Multitasking-Aware OpenGL ES App使用OpenGL ES的許多方面是平臺中立的,但是在iOS上使用OpenGL ES的一些細(xì)節(jié)特別考慮徒溪。特別是琅关,使用OpenGL ES的iOS應(yīng)用程序必須正確處理多任務(wù),或者在移動到后臺時可能會被終止旦委。在為iOS設(shè)備開發(fā)OpenGL ES內(nèi)容時苇瓣,您還應(yīng)該考慮顯示分辨率和其他設(shè)備功能尉间。

實(shí)現(xiàn)多任務(wù)感知OpenGL ES應(yīng)用程序

當(dāng)用戶切換到其他應(yīng)用程序時,您的應(yīng)用程序可以繼續(xù)運(yùn)行击罪。有關(guān)iOS上多任務(wù)的全面討論哲嘲,請參閱應(yīng)用程序狀態(tài)和多任務(wù)。

當(dāng)OpenGL ES應(yīng)用程序移動到后臺時媳禁,必須執(zhí)行其他工作眠副。如果應(yīng)用程序不正確地處理這些任務(wù),則可能會被iOS終止竣稽。此外囱怕,一個應(yīng)用程序可能想要釋放OpenGL ES資源,以便這些資源可用于前臺應(yīng)用程序毫别。

后臺應(yīng)用程序可能無法在圖形硬件上執(zhí)行命令

如果OpenGL ES應(yīng)用程序嘗試在圖形硬件上執(zhí)行OpenGL ES命令,則會終止該應(yīng)用程序岛宦。 iOS防止后臺應(yīng)用程序訪問圖形處理器,以便最前沿的應(yīng)用程序始終能夠向用戶呈現(xiàn)出極好的體驗(yàn)恋博。您的應(yīng)用程序不僅可以在后臺進(jìn)行OpenGL ES調(diào)用時終止齐佳,還可以在以后提交的命令在后臺刷新GPU私恬。您的應(yīng)用程序必須確保所有以前提交的命令在移動到后臺之前已完成執(zhí)行债沮。

如果您使用GLKit視圖并查看控制器,并且僅在繪圖方法中提交OpenGL ES命令本鸣,則當(dāng)應(yīng)用程序移動到背景時疫衩,您的應(yīng)用程序?qū)⒆詣诱_\(yùn)行。默認(rèn)情況下荣德,GLKViewController類在您的應(yīng)用程序變?yōu)榉腔顒訝顟B(tài)時暫停其動畫定時器闷煤,確保您的繪圖方法不被調(diào)用。

如果您不使用GLKit視圖或查看控制器涮瞻,或者如果您在GLKView繪圖方法之外提交OpenGL ES命令鲤拿,則必須執(zhí)行以下步驟以確保您的應(yīng)用程序未在后臺終止:

  1. 在應(yīng)用程序委托的ApplicationWillResignActive:方法中,應(yīng)用程序應(yīng)該停止其動畫定時器(如果有的話)署咽,將其置于已知的良好狀態(tài)近顷,然后調(diào)用glFinish函數(shù)生音。
  2. 在應(yīng)用程序委托的applicationDidEnterBackground:方法中,您的應(yīng)用程序可能需要刪除一些OpenGL ES對象窒升,以使內(nèi)存和資源可用于前臺應(yīng)用程序缀遍。調(diào)用glFinish函數(shù)以確保資源立即被刪除。
  3. 在您的應(yīng)用程序退出其applicationDidEnterBackground:方法之后饱须,它不能進(jìn)行任何新的OpenGL ES調(diào)用域醇。如果是OpenGL ES呼叫,則由iOS終止蓉媳。
  4. 在您的應(yīng)用程序的應(yīng)用程序WillEnterForeground:方法中譬挚,重新創(chuàng)建任何對象并重新啟動動畫計(jì)時器。

總而言之酪呻,您的應(yīng)用程序需要調(diào)用glFinish函數(shù)殴瘦,以確保所有以前提交的命令都從命令緩沖區(qū)中排除,并由OpenGL ES執(zhí)行号杠。移動到后臺后蚪腋,您必須避免使用OpenGL ES,直到它回到前臺姨蟋。

在移動到背景之前刪除輕松重新創(chuàng)建的資源

您的應(yīng)用程序不需要在OpenGL ES對象移動到后臺時釋放屉凯。通常,您的應(yīng)用程序應(yīng)避免處理其內(nèi)容眼溶∮蒲猓考慮兩種情況:

  • 用戶正在玩游戲,并短暫退出以檢查他們的日歷堂飞。當(dāng)玩家返回游戲時灌旧,游戲的資源仍然在內(nèi)存中,游戲可以立即恢復(fù)
  • 當(dāng)用戶啟動另一個OpenGL ES應(yīng)用程序時绰筛,您的OpenGL ES應(yīng)用程序處于后臺。如果該應(yīng)用程序需要比設(shè)備上更多的內(nèi)存铝噩,系統(tǒng)將自動終止您的應(yīng)用程序,而不需要執(zhí)行任何其他工作毛甲。

您的目標(biāo)應(yīng)該是將您的應(yīng)用程序設(shè)計(jì)為一個好的公民:這意味著保持盡可能短的時間移動到前臺具被,同時在后臺減少其內(nèi)存占用。

這是您應(yīng)該如何處理這兩種情況:

  1. 您的應(yīng)用程序應(yīng)保留內(nèi)存中的紋理七咧,模型和其他資源;在您的應(yīng)用程序移動到后臺時,不應(yīng)該處理需要很長時間重新創(chuàng)建的資源
  2. 您的應(yīng)用程序應(yīng)該處理可以快速輕松重新創(chuàng)建的對象坑雅。尋找消耗大量內(nèi)存的對象。

容易的目標(biāo)是您的應(yīng)用程序分配來支持呈現(xiàn)結(jié)果的幀緩沖區(qū)终蒂。當(dāng)你的應(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)存密集型資源粤咪,成為當(dāng)移動到后臺時可以處理的對象的良好候選谚中。

如果您使用GLKit視圖和視圖控制器寥枝,則當(dāng)您的應(yīng)用程序移動到后臺時,GLKViewController類會自動處理其關(guān)聯(lián)視圖的幀緩沖區(qū)某筐。如果您手動創(chuàng)建用于其他用途的幀緩沖區(qū)艾疟,那么當(dāng)應(yīng)用程序移動到后臺時蔽莱,您應(yīng)該處理它們戚长。在這兩種情況下,您還應(yīng)該考慮當(dāng)時應(yīng)用程序可以處理哪些其他臨時資源仪糖。

支持高分辨率顯示

默認(rèn)情況下,GLKit視圖的contentScaleFactor屬性的值與包含它的屏幕的比例匹配攒驰,因此其關(guān)聯(lián)的幀緩沖區(qū)配置為以顯示的完整分辨率呈現(xiàn)故爵。有關(guān)UIKit支持高分辨率顯示的更多信息,請參閱在視圖中支持高分辨率屏幕劲室。

如果您使用Core Animation層提供OpenGL ES內(nèi)容结窘,則默認(rèn)情況下其比例因子設(shè)置為1.0。為了繪制Retina顯示屏的完整分辨率喉磁,您應(yīng)該更改CAEAGLLayer對象的比例因子以符合屏幕的比例因子官脓。

當(dāng)支持具有高分辨率顯示器的設(shè)備時,應(yīng)該相應(yīng)地調(diào)整應(yīng)用的模型和紋理資產(chǎn)斤讥。在高分辨率設(shè)備上運(yùn)行時湾趾,您可能需要選擇更詳細(xì)的模型和紋理來渲染更好的圖像。相反铛楣,在標(biāo)準(zhǔn)分辨率設(shè)備上艺普,您可以使用較小的模型和紋理歧譬。

重要提示:許多OpenGL ES API調(diào)用以屏幕像素表示維度。如果使用大于1.0的比例因子瑰步,則應(yīng)在使用glScissor缩焦,glBlitFramebuffer责静,glLineWidth或glPointSize函數(shù)或gl_PointSize著色器變量時相應(yīng)調(diào)整維度灾螃。

確定如何支持高分辨率顯示器的一個重要因素是性能揩徊。視網(wǎng)膜顯示屏上的比例因子倍增了像素?cái)?shù)量的四倍,導(dǎo)致GPU處理了四倍的片段垃喊。如果您的應(yīng)用程序執(zhí)行許多每個片段的計(jì)算本谜,像素的增加可能會降低幀速率偎窘。如果您發(fā)現(xiàn)您的應(yīng)用程序在較高比例因子下運(yùn)行速度顯著較慢,請考慮以下選項(xiàng)之一

  • 使用本文檔中的性能調(diào)整指南優(yōu)化片段著色器的性能他托。
  • 在片段著色器中實(shí)現(xiàn)更簡單的算法仆葡。通過這樣做沿盅,您正在降低單個像素的質(zhì)量,以更高的分辨率渲染整體圖像腰涧。
  • 使用1.0之間的分?jǐn)?shù)比例因子和屏幕的比例因子窖铡。比例因子1.5提供比1.0的比例因子更好的質(zhì)量,但是需要填充比圖像縮放到2.0的像素少的像素滑臊。
  • 對于GLKView對象的drawableColorFormat和drawableDepthFormat屬性使用較低精度的格式简珠。通過這樣做,可以減少在底層渲染緩沖區(qū)上操作所需的內(nèi)存帶寬聋庵。
  • 使用較小比例因子并啟用多重采樣祭玉。另外一個優(yōu)點(diǎn)是春畔,多采樣也可以在不支持高分辨率顯示器的設(shè)備上提供更高的質(zhì)量。

要為GLKView對象啟用多重采樣振峻,請更改其drawableMultisample屬性的值择份。如果沒有渲染到GLKit視圖,則必須手動設(shè)置多采樣緩沖區(qū)并在呈現(xiàn)最終圖像之前對其進(jìn)行解析(請參閱使用多重采樣來提高圖像質(zhì)量)凤价。

多次采樣不是免費(fèi)的;需要額外的內(nèi)存來存儲附加樣本拔创,并將樣本解析為解析幀緩沖區(qū)需要時間。如果您向應(yīng)用程序添加多重采樣慢逾,請始終測試應(yīng)用程序的性能灭红,以確保其仍然可以接受。

支持多接口定向

像任何應(yīng)用程序一樣胜卤,OpenGL ES應(yīng)用程序應(yīng)支持與其內(nèi)容相適應(yīng)的用戶界面方向葛躏。您可以在其信息屬性列表中為您的應(yīng)用程序聲明支持的接口方向悠菜,或者使用supportedInterfaceOrientations方法來托管OpenGL ES內(nèi)容的視圖控制器悔醋。 (有關(guān)詳細(xì)信息,請參閱iOS的View Controller編程指南猾愿。)

默認(rèn)情況下,GLKViewController和GLKView類自動處理方向更改:當(dāng)用戶將設(shè)備旋轉(zhuǎn)到受支持的方向時泽本,系統(tǒng)會動態(tài)定向更改并更改視圖控制器視圖的大小规丽。當(dāng)其大小更改時撇贺,GLKView對象會相應(yīng)調(diào)整其幀緩沖區(qū)和視口的大小。如果需要響應(yīng)此更改艘狭,請?jiān)贕LKViewController子類中實(shí)現(xiàn)viewWillLayoutSubviews或viewDidLayoutSubviews方法缓升,如果使用自定義GLKView子類港谊,則實(shí)現(xiàn)layoutSubviews方法橙弱。

如果您使用Core Animation圖層繪制OpenGL ES內(nèi)容,則應(yīng)用程序仍應(yīng)包含一個視圖控制器來管理用戶界面方向斜筐。

在外部顯示器上呈現(xiàn)OpenGL ES內(nèi)容

iOS設(shè)備可以連接到外部顯示器蛀缝。外部顯示器的分辨率及其內(nèi)容比例因子可能與主屏幕的分辨率和比例因子不同;您渲染框架的代碼應(yīng)該調(diào)整為匹配屈梁。

在外部顯示器上繪制的步驟與在主屏幕上運(yùn)行的程序幾乎相同在讶。

  1. 按照“多顯示器編程指南”中的步驟煞抬,在外部顯示器上創(chuàng)建一個窗口革答。
  2. 將窗口添加到適當(dāng)?shù)囊晥D或查看控制器對象以用于渲染策略
  • 如果使用GLKit渲染残拐,請?jiān)O(shè)置GLKViewController和GLKView(或您的自定義子類)的實(shí)例途茫,并使用其rootViewController屬性將其添加到窗口。
  • 如果渲染到Core Animation圖層蹦骑,請將包含圖層的視圖添加為窗口的子視圖慈省。要使用動畫循環(huán)進(jìn)行渲染臀防,請通過檢索窗口的屏幕屬性并調(diào)用其DisplayLinkWithTarget:selector:method來創(chuàng)建為外部顯示優(yōu)化的顯示鏈接對象眠菇。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市袱衷,隨后出現(xiàn)的幾起案子捎废,更是在濱河造成了極大的恐慌,老刑警劉巖致燥,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件登疗,死亡現(xiàn)場離奇詭異,居然都是意外死亡嫌蚤,警方通過查閱死者的電腦和手機(jī)葫盼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門箱蝠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牙瓢,“玉大人矾克,你說我怎么就攤上這事。” “怎么了饼暑?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長陈惰。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么睡榆? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任包雀,我火速辦了婚禮劳曹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜕劝。我一直安慰自己,他們只是感情好婴削,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雹姊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歧杏。 梳的紋絲不亂的頭發(fā)上陨献,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼晨雳。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的末盔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼优烧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎颓鲜,沒想到半個月后甜滨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年磕诊,在試婚紗的時候發(fā)現(xiàn)自己被綠了纹腌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片莱褒。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡涎劈,死狀恐怖广凸,靈堂內(nèi)的尸體忽然破棺而出阅茶,到底是詐尸還是另有隱情,我是刑警寧澤枫吧,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布尼酿,位于F島的核電站裳擎,受9級特大地震影響鹿响,放射性物質(zhì)發(fā)生泄漏惶我。R本人自食惡果不足惜毅哗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一声搁、第九天 我趴在偏房一處隱蔽的房頂上張望骤铃。 院中可真熱鬧丛版,春花似錦巩掺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至豫缨,卻和暖如春独令,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背好芭。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工燃箭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舍败。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓招狸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邻薯。 傳聞我的和親對象是個殘疾皇子裙戏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容