OpenGL ES for iOS - 2

配置OpenGL ES上下文

OpenGL ES的每個實現(xiàn)都提供了一種創(chuàng)建渲染上下文以管理OpenGL ES規(guī)范所需狀態(tài)的方法孙咪。通過在上下文中放置此狀態(tài),多個應用程序可以輕松共享圖形硬件巡语,而不會干擾對方的狀態(tài)翎蹈。

本章詳細介紹了如何在iOS上創(chuàng)建和配置上下文。

EAGL是iOS實現(xiàn)的OpenGL ES渲染上下文

在您的應用程序可以調(diào)用任何OpenGL ES函數(shù)之前男公,必須初始化一個EAGLContext對象荤堪。 EAGLContext類還提供了將OpenGL ES內(nèi)容與Core Animation集成的方法合陵。

當前上下文是OpenGL ES函數(shù)調(diào)用的目標

iOS應用程序中的每個線程都具有當前上下文;當您調(diào)用OpenGL ES函數(shù)時,這是通過調(diào)用更改其狀態(tài)的上下文。

要設(shè)置線程的當前上下文嗡载,請在該線程上執(zhí)行時調(diào)用EAGLContext類方法setCurrentContext梅猿。

[EAGLContext setCurrentContext: myContext];

調(diào)用EAGLContext類方法currentContext以檢索線程的當前上下文。
注意:如果您的應用程序主動在同一線程上的兩個或多個上下文之間切換低剔,請在設(shè)置新的上下文作為當前上下文之前調(diào)用glFlush函數(shù)。這樣可以確保先前提交的命令及時傳遞給圖形硬件肮塞。

OpenGL ES持有對當前上下文對應的EAGLContext對象的強引用襟齿。 (如果使用手動引用計數(shù),OpenGL ES會保留此對象枕赵。)當調(diào)用setCurrentContext:方法來更改當前上下文時猜欺,OpenGL ES不再引用上一個上下文。 (如果您使用手動引用計數(shù)拷窜,OpenGL ES將釋放EAGLContext對象开皿。)為防止當不在當前上下文時EAGLContext對象被釋放,您的應用程序必須保持強制引用(或保留)這些對象装黑。

每個上下文都針對特定版本的OpenGL ES

EAGLContext對象只支持一個版本的OpenGL ES副瀑。例如,為OpenGL ES 1.1編寫的代碼與OpenGL ES 2.0或3.0上下文不兼容恋谭。使用核心OpenGL ES 2.0功能的代碼與OpenGL ES 3.0上下文兼容糠睡,為OpenGL ES 2.0擴展設(shè)計的代碼通常可以在OpenGL ES 3.0上下文中進行微小更改疚颊。許多新的OpenGL ES 3.0功能和增加的硬件功能需要OpenGL ES 3.0上下文狈孔。

當您創(chuàng)建并初始化EAGLContext對象時,您的應用程序?qū)Q定要支持的OpenGL ES版本材义。如果設(shè)備不支持所需版本的OpenGL ES均抽,initWithAPI:方法返回nil。您的應用程序必須進行測試其掂,以確保上下文在使用之前已初始化成功油挥。

為了支持OpenGL ES的多個版本作為應用程序中的渲染選項,您應該首先嘗試初始化要定位的最新版本的渲染上下文款熬。如果返回的對象為nil深寥,則初始化舊版本的上下文。清單2-1演示了如何做到這一點贤牛。

EAGLContext* CreateBestEAGLContext()
{
   EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
   if (context == nil) {
      context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
   }
   return context;
}

上下文的API屬性指出上下文支持的OpenGL ES版本惋鹅。您的應用程序應測試上下文的API屬性并使用它來選擇正確的渲染路徑。實現(xiàn)此行為的常見模式是為每個渲染路徑創(chuàng)建一個類殉簸。您的應用程序在初始化時測試上下文并創(chuàng)建一次渲染器闰集。

EAGL共享組管理上下文的OpenGL ES對象

盡管上下文保持OpenGL ES狀態(tài)沽讹,但它并不直接管理OpenGL ES對象。相反武鲁,OpenGL ES對象由EAGLSharegroup對象創(chuàng)建和維護爽雄。每個上下文都包含一個EAGLSharegroup對象,它將對象創(chuàng)建委托給沐鼠。

當兩個或多個上下文引用相同的共享組時盲链,共享組的優(yōu)點變得明顯,如圖2-1所示迟杂。當多個上下文連接到公共共享組時,由任何上下文創(chuàng)建的OpenGL ES對象可用于所有上下文;如果綁定到與創(chuàng)建它相同的上下文上的相同對象標識符本慕,則引用同一個OpenGL ES對象排拷。移動設(shè)備上的資源通常很少;在多個上下文中創(chuàng)建相同內(nèi)容的多個副本是浪費的。共享共享資源可以更好地利用設(shè)備上可用的圖形資源锅尘。

一個共享組是一個不透明的對象;它沒有您的應用可以調(diào)用的方法或?qū)傩约嗲狻J褂胹haregroup對象的上下文保持強有力的參考。

2-1.png

在兩種具體情況下藤违,共享組最有用

  • 當上下文之間共享的大部分資源是不變的浪腐。
  • 當您希望您的應用程序能夠在除渲染器的主線程之外的線程上創(chuàng)建新的OpenGL ES對象。在這種情況下顿乒,第二個上下文在單獨的線程上運行议街,專門用于獲取數(shù)據(jù)和創(chuàng)建資源。在資源被加載之后璧榄,第一個上下文可以綁定到對象并立即使用它特漩。 GLKTextureLoader類使用此模式提供異步紋理加載。

要創(chuàng)建引用同一個共享組的多個上下文骨杂,首先通過調(diào)用initWithAPI:將為上下文自動創(chuàng)建一個共享組涂身。第二個和更晚的上下文通過調(diào)用initWithAPI:sharegroup:方法來初始化為使用第一個上下文的共享組。清單2-2顯示了如何工作搓蚪。第一個上下文使用清單2-1中定義的方便函數(shù)創(chuàng)建蛤售。第二個上下文通過從第一個上下文提取API版本和共享組來創(chuàng)建。
重要提示:與同一共享組相關(guān)聯(lián)的所有上下文都必須使用與初始上下文相同版本的OpenGL ES API

EAGLContext* firstContext = CreateBestEAGLContext();
EAGLContext* secondContext = [[EAGLContext alloc] initWithAPI:[firstContext API] sharegroup: [firstContext sharegroup]];

當共享組由多個上下文共享時妒潭,應用程序有責任管理OpenGL ES對象的狀態(tài)更改悴能。規(guī)則如下:

  • 如果對象未被修改,您的應用程序可以同時訪問跨多個上下文的對象杜耙。
  • 當對象被發(fā)送到上下文的命令修改時搜骡,對象不得在任何其他上下文中被讀取或修改。
  • 修改對象后佑女,所有上下文都必須重新綁定對象以查看更改记靡。如果上下文在綁定它之前引用它谈竿,則對象的內(nèi)容是未定義的。

以下是您的應用程序應該更新OpenGL ES對象的步驟:

  • 在可能使用對象的每個上下文上調(diào)用glFlush摸吠。
  • 在要修改對象的上下文中空凸,調(diào)用一個或多個OpenGL ES函數(shù)來更改對象。
  • 在接收到狀態(tài)修改命令的上下文中調(diào)用glFlush寸痢。
  • 在其他上下文中呀洲,重新綁定對象標識符。

注意:共享對象的另一種方法是使用單個渲染上下文啼止,但使用多個目標幀緩沖區(qū)道逗。在渲染時,您的應用程序會綁定相應的幀緩沖區(qū)献烦,并根據(jù)需要呈現(xiàn)其幀滓窍。因為所有OpenGL ES對象都是從單個上下文中引用的,所以它們會看到相同的OpenGL ES數(shù)據(jù)巩那。此模式使用較少的資源吏夯,但僅適用于可以仔細控制上下文狀態(tài)的單線程應用程序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市即横,隨后出現(xiàn)的幾起案子噪生,更是在濱河造成了極大的恐慌,老刑警劉巖东囚,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跺嗽,死亡現(xiàn)場離奇詭異,居然都是意外死亡页藻,警方通過查閱死者的電腦和手機抛蚁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來惕橙,“玉大人瞧甩,你說我怎么就攤上這事∶逐校” “怎么了肚逸?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長彬坏。 經(jīng)常有香客問我朦促,道長,這世上最難降的妖魔是什么栓始? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任务冕,我火速辦了婚禮,結(jié)果婚禮上幻赚,老公的妹妹穿的比我還像新娘禀忆。我一直安慰自己臊旭,他們只是感情好,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布箩退。 她就那樣靜靜地躺著离熏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戴涝。 梳的紋絲不亂的頭發(fā)上滋戳,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機與錄音啥刻,去河邊找鬼奸鸯。 笑死,一個胖子當著我的面吹牛可帽,可吹牛的內(nèi)容都是我干的府喳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼蘑拯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了兜粘?” 一聲冷哼從身側(cè)響起申窘,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孔轴,沒想到半個月后剃法,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡路鹰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年贷洲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晋柱。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡优构,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雁竞,到底是詐尸還是另有隱情钦椭,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布碑诉,位于F島的核電站彪腔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏进栽。R本人自食惡果不足惜德挣,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望快毛。 院中可真熱鬧格嗅,春花似錦番挺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至懂扼,卻和暖如春禁荸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阀湿。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工赶熟, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人陷嘴。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓映砖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灾挨。 傳聞我的和親對象是個殘疾皇子邑退,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

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