天天看點

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

本節書摘來自華章出版社《opengl es應用開發實踐指南:android卷》一 書中的第1章,第1.3節,作者:(美)kevin brothaler ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

下一步就是使用一個特殊的類glsurfaceview初始化opengl。glsurfaceview會處理opengl初始化過程中比較基本的操作,如配置顯示裝置(display)以及在背景線程中渲染;渲染是在顯示裝置中一個稱為“surface”的特定區域完成的,有時也稱為視口(viewport)。

glsurfaceview類也使得處理标準android activity生命周期變得容易了;在android裡,任何activity都可以建立(create)和銷毀(destroy),并且在使用者切換到其他activity時暫停(pause),在切換回來時繼續(resume)。根據這個生命周期,在activity被暫停的時候,我們需要釋放opengl的資源;glsurfaceview為此提供了很多輔助方法。

在edburnette所寫的《hello, android》裡,你可以學到更多關于activity生命周期的内容。

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

紋理視圖

在幕後,glsurfaceview實際上為它自己建立了一個視窗(window),并在視圖層次(view hierarchy)上穿了個“洞”,讓底層的opengl surface顯示出來。對于大多數使用情況,這就足夠了;但是,glsurfaceview與正常視圖(view)不同,它沒有動畫或者變形特效,因為glsurfaceview是視窗(window)的一部分。

從android 4.0 ice cream sandwich開始,android提供了一個紋理視圖(textureview),它可以渲染opengl而不用建立單獨的視窗或打洞了,這就意味着,這個視圖像一個正常視窗一樣,可以被操作,且有動畫和變形特效。但是,textureview類沒有内置opengl初始化操作,要想使用textureview,一種方法是執行自定義的opengl初始化,并在textureview上運作,另外一種方法是把glsurfaceview的源代碼拿出來,把它适配到textureview上。

打開前面自動生成的activity類firstopenglprojectactivity。按下“ctrl+shift+t”快捷鍵,“open type”對話框就會彈出來,然後輸入“firstopenglprojectactivity”,當那個類顯示出來時,就選擇它。

eclipse鍵盤快捷鍵

在mac或者linux平台上,快捷鍵可能與windows平台不同;比如,快捷鍵“ctrl+shift+o”,在windows平台上,它是用來組織和查找新的java 導入(import)的;在mac平台上就是。可以通過菜單“help→key assist”選擇按鍵輔助功能檢視各個平台的鍵綁定。

現在看起來沒有多少代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

我們給這個activity添加一個glsurfaceview執行個體,這樣就可以初始化opengl。讓我們在類的頂部加入如下兩個新的成員變量:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

我們需要導入glsurfaceview類,是以,按“ctrl+shift+o”快捷鍵組織導入,并把這個新類放到代碼裡;每次加入一個新的類引用,并且它需要被導入時,我們都要做這一步。我們将用rendererset記住glsurfaceview是否處于有效狀态。讓我們從代碼中移除setcontentview()的調用,并加入如下代碼初始化glsurfaceview:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

因為我們隻為2.0版本寫代碼,我們要做的下一件事就是檢查系統是否實際支援opengl es 2.0。讓我們添加如下幾行代碼到oncreate()函數中:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

首先,我們需要android activitymanager的一個引用,用它擷取裝置配置資訊,然後,取出reqglesversion變量檢查opengl es版本号。如果版本号為0×20000或後續版本,我們就可以使用 opengl es 2.0的api了。

但是這段代碼實際上不能在模拟器上工作,因為gpu模拟部分有缺陷;為了使代碼在模拟器上正常工作,我們要按如下代碼修改那個檢查條件:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

這段代碼測試目前裝置是不是模拟器,如果是,就假定它支援opengl es 2.0。要確定程式能運作,模拟器一定要配置opengl es 2.0,參見1.1.1節。

下一步就是配置渲染表面(rendering surface),添加如下幾行代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

如果裝置支援opengl es 2.0,我們就通過調用seteglcontextclientversion(2)配置這個surface視圖;然後調用setrenderer()傳進自定義renderer類的一個新執行個體,稍後,我們會看到如何建立這個renderer類,同時這段代碼通過設定rendererset為true記住渲染器(renderer)已經設定過了。當surface建立或者發生變化的時候,以及要繪制一幅新幀時,渲染器都會被glsurfaceview調用。

如果裝置不支援opengl es 2.0,怎麼辦呢?也可以添加一個支援opengl es 1.0的回退的渲染器,但是,這種情形現在已經很少見了,可能不值得付出這樣的努力。根據android開發者統計闆,僅有大約9%的裝置隻支援opengl es 1.1,這個數字還在随着時間不斷縮減。如果一個裝置不支援opengl es 2.0,公開釋出的應用應該在這個裝置的應用程式市場中被隐藏起來,在14.1.6節中,我們會學到這點。

我們需要添加另外一個調用把glsurfaceview加入到這個activity中,并把它顯示到螢幕上,在oncreate()函數結尾處,用如下代碼替換舊的調用setcontentview():

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

我們還需要處理android activity生命周期的事件,否則,如果使用者切換到另外一個應用,應用就會崩潰;加入如下方法讓這個activity類變得完整:

《OpenGL ES應用開發實踐指南:Android卷》—— 1.3 初始化OpenGL

這些方法非常重要,有了它們 ,這個surface視圖才能正确暫停并繼續背景渲染線程,同時釋放和續用opengl上下文。如果它沒有做這些,應用程式可能會崩潰,并被android終止;我們還要保證渲染器也設定了,否則調用這些方法也會引起程式崩潰。

繼續閱讀