Android OpenGL ES 2.0繪圖:搭建OpenGL ES環(huán)境
為了能夠在Android應(yīng)用程序中使用OpenGL ES繪制圖形,你必須創(chuàng)建一個(gè)視圖作為容器。
而更直接的做法是從GLSurfaceView和 GLSurfaceView.Renderer各派生一個(gè)實(shí)現(xiàn)類。GLSurfaceView作為使用OpenGL繪制的容器,GLSurfaceView.Renderer將用于控制繪圖的動(dòng)作。
對(duì)這些類的更多信息,請(qǐng)參閱OpenGL ES開(kāi)發(fā)人員指南。
使用GLSurfaceView幾乎是整合OpenGL ES到你的應(yīng)用中的唯一方式。對(duì)于一個(gè)需要全屏或近乎屏幕圖形視圖,它是一個(gè)合理的選擇。如果開(kāi)發(fā)人員只是期望借助OpenGL ES在某個(gè)布局中一小部分繪圖,則應(yīng)該考慮使用TextureView。如果覺(jué)得自己是“大牛”,完全可以使用SurfaceView建立一個(gè) OpenGL ES視圖,但這樣做需要編寫(xiě)相當(dāng)多的額外的代碼。
這一節(jié)將介紹如何在一個(gè)簡(jiǎn)單應(yīng)用的activity中完成一個(gè)最小的GLSurfaceView和GLSurfaceView.Renderer的實(shí)現(xiàn)。
一、在Manifest文件中聲明使用OpenGL ES
為了能夠使用OpenGL ES 2.0 API,你必須在manifest文件中添加以下聲明:
- [html] view plaincopyprint?
如果你的應(yīng)用需要使用紋理壓縮功能,還要聲明設(shè)備需要支持什么樣的壓縮格式:
- [html] view plaincopyprint?
更多關(guān)于紋理壓縮格式的信息,請(qǐng)參閱OpenGL開(kāi)發(fā)人員指南。
二、為OpenGL ES圖形創(chuàng)建一個(gè)Activity
這個(gè)Activity跟任何其他的應(yīng)用程序中的Activity一樣,也有一個(gè)用戶界面。唯一的區(qū)別是在它的布局文件中存放的視圖不是TextView、Button和ListView,而是一個(gè)GLSurfaceView。
下面的代碼演示了使用GLSurfaceView作為主視圖的Acitivity的核心代碼:
- [java] view plaincopyprint?
- public class OpenGLES20 extends Activity {
- private GLSurfaceView mGLView;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 創(chuàng)建一個(gè)GLSurfaceView對(duì)象,并將其設(shè)置為當(dāng)前Activity的ContentView
- mGLView = new MyGLSurfaceView(this);
- setContentView(mGLView);
- }
- }
- public class OpenGLES20 extends Activity {
- private GLSurfaceView mGLView;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 創(chuàng)建一個(gè)GLSurfaceView對(duì)象,并將其設(shè)置為當(dāng)前Activity的ContentView
- mGLView = new MyGLSurfaceView(this);
- setContentView(mGLView);
- }
- }
注:OpenGL ES 2.0需要Android2.2 (API Level 8) 及以上版本,所以請(qǐng)確保你的Android項(xiàng)目的運(yùn)行目標(biāo)的API等級(jí)不低于8或更高。
三、構(gòu)造一個(gè)GLSurfaceView對(duì)象
事實(shí)上GLSurfaceView并沒(méi)有提供很多功能,實(shí)際上繪制對(duì)象的任務(wù)都在GLSurfaceView.Renderer中進(jìn)行。所以 GLSurfaceView中代碼也非常少,甚至可以直接使用GLSurfaceView。但***別這樣做,因?yàn)槟阈枰獢U(kuò)展這個(gè)類來(lái)響應(yīng)觸摸事件。
通常在當(dāng)前Activity中以內(nèi)部類的方式創(chuàng)建GLSurfaceView,這樣實(shí)現(xiàn)起來(lái)非??欤诵拇a如下
- [java] view plaincopyprint?
- class MyGLSurfaceView extends GLSurfaceView {
- public MyGLSurfaceView(Context context){
- super(context);
- // 設(shè)置渲染對(duì)象,用于控制在GLSurfaceView中的繪制工作
- setRenderer(new MyRenderer());
- }
- }
- class MyGLSurfaceView extends GLSurfaceView {
- public MyGLSurfaceView(Context context){
- super(context);
- // 設(shè)置渲染對(duì)象,用于控制在GLSurfaceView中的繪制工作
- setRenderer(new MyRenderer());
- }
- }
當(dāng)使用OpenGL ES 2.0時(shí),你必須在GLSurfaceView構(gòu)造器中調(diào)用另外一個(gè)方法,它指定了你將要使用2.0版的API:
- [java] view plaincopyprint?
- // 創(chuàng)建一個(gè)OpenGL ES 2.0 context
- setEGLContextClientVersion(2);
- // 創(chuàng)建一個(gè)OpenGL ES 2.0 context
- setEGLContextClientVersion(2);
- 注:如果你使用的是OpenGL ES 2.0的API,那么請(qǐng)確保在Manifest文件中作出相關(guān)API版本聲明。有關(guān)更多信息,請(qǐng)參見(jiàn)在Manifest文件中聲明使用OpenGL ES。
- 另一個(gè)可以添加到你的GLSurfaceView中可選操作是設(shè)置渲染模式為僅當(dāng)繪制數(shù)據(jù)發(fā)生改變時(shí)才繪制view。該渲染模式常量是GLSurfaceView.RENDERMODE_WHEN_DIRTY。
- [java] view plaincopyprint?
- // 只有在繪制數(shù)據(jù)改變時(shí)才繪制view
- setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
- // 只有在繪制數(shù)據(jù)改變時(shí)才繪制view
- setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
該設(shè)置可以防止GLSurfaceView幀重繪,直到調(diào)用requestRender()方法。這樣的繪制機(jī)制更高效。
四、構(gòu)造一個(gè)Renderer類
Renderer類負(fù)責(zé)控制在GLSurfaceView中繪制任務(wù),并提供三個(gè)回調(diào)方法供Android系統(tǒng)調(diào)用,用來(lái)計(jì)算在GLSurfaceView中繪制什么以及如何繪制。
1.onSurfaceCreated():僅調(diào)用一次,用于設(shè)置view的OpenGL ES環(huán)境。
2.onDrawFrame():每次重繪view時(shí)調(diào)用。
3.onSurfaceChanged():當(dāng)view的幾何形狀發(fā)生變化時(shí)調(diào)用,比如設(shè)備從豎屏變?yōu)闄M屏。
下面是一個(gè)OpenGL ES renderer的最基本的實(shí)現(xiàn),僅在GLSurfaceView上畫(huà)了一個(gè)灰色的背景:
以上就是所有要做的東西!上面的代碼示例創(chuàng)建了一個(gè)簡(jiǎn)單的Android應(yīng)用,它使用OpenGL顯示了一個(gè)灰色的屏幕。雖然這段代碼并沒(méi)有做什么有趣的事情,但是通過(guò)創(chuàng)建這些類,已經(jīng)為你使用OpenGL繪制圖形奠定了基礎(chǔ)。
注:當(dāng)你使用OpengGLES 2.0 API時(shí),可以不用去明白這些方法們?yōu)槭裁炊加幸粋€(gè)GL10參數(shù)。其實(shí)這樣做的目的是讓Android框架能夠簡(jiǎn)單的兼容OpenGL ES的各版本。
如果你對(duì)OpenGL ES API很熟悉,你現(xiàn)在應(yīng)該能夠在應(yīng)用程序中建立一個(gè)OpenGL ES環(huán)境并開(kāi)始繪制圖形了。然而,如果你想要學(xué)習(xí)更多的相關(guān)知識(shí),那么就請(qǐng)繼續(xù)關(guān)注下一節(jié)吧。