Android 第一個OpenGL ES程序
在你的Android應用中用OpenGL ES繪制圖形,首先需要有一個容器,最直接的方法是實現GLSurfaceView
和 GLSurfaceView.Renderer
。
前者是一個放置圖形的View容器,后者用來控制在這個View中如何進行繪制。
GLSurfaceView只是一種選擇,比較適合於全屏繪制圖形或者近似全屏繪制,其他可以選擇的還有 TextureView
和SurfaceView
。
本文展示一個最基本的Android OpenGL ES繪制Demo。
1.在Manifest中添加聲明
為了使用OpenGL ES 2.0 API,需要添加如下聲明:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
OpenGL ES 2.0 requires Android 2.2 (API Level 8) or higher,所以需要確認系統版本。
2.創建Activity
在Activity的布局中,需要加入GLSurfaceView來放置繪制的圖形。
一個最簡單的版本如下:
public class OpenGLES20 extends Activity { private GLSurfaceView mGLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. mGLView = new MyGLSurfaceView(this); setContentView(mGLView); } }
3.創建GLSurfaceView
GLSurfaceView是一個特殊的組件,你可以在其中繪制OpenGL ES圖形。
你需要擴展這個類,在它的構造方法中設置渲染器:
class MyGLSurfaceView extends GLSurfaceView { public MyGLSurfaceView(Context context){ super(context); // Set the Renderer for drawing on the GLSurfaceView setRenderer(new MyRenderer()); } }
如果使用OpenGL ES 2.0,還需要加一句聲明:
// Create an OpenGL ES 2.0 context setEGLContextClientVersion(2);
還有一個可選的設置是,把渲染模式改為 GLSurfaceView.RENDERMODE_WHEN_DIRTY
,這樣僅在你的數據有變化時重新進行渲染。
// Render the view only when there is a change in the drawing data setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
除非你調用requestRender(),這個設置會阻止幀被重畫,有些情況下這樣效率更高。
4.建立一個Renderer類
Renderer類(渲染器類),即 GLSurfaceView.Renderer
的實現類,它控制了與它相關聯的 GLSurfaceView
上繪制什么。
其中有三個主要的回調方法:
onSurfaceCreated()
- Called once to set up the view's OpenGL ES environment.onDrawFrame()
- Called for each redraw of the view.onSurfaceChanged()
- Called if the geometry of the view changes, for example when the device's screen orientation changes.
一個簡單的實現例子:
public class MyGL20Renderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); } public void onDrawFrame(GL10 unused) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); } }
程序例子
一個簡單的程序例子,並沒有繪制什么,只是設置了背景色,為了展示方便,GLSurfaceView類和渲染器類都作為Acitivity的內部類寫出。
首先在Manifest中加上聲明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.helloopengles" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="15" /> <!-- Tell the system this app requires OpenGL ES 2.0. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".HelloOpenGLESActivity" android:label="@string/title_activity_hello_open_gles" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

package com.example.helloopengles; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.Context; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.util.Log; public class HelloOpenGLESActivity extends Activity { private GLSurfaceView mGLView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Create a GLSurfaceView instance and set it // as the ContentView for this Activity. mGLView = new MyGLSurfaceView(this); setContentView(mGLView); } class MyGLSurfaceView extends GLSurfaceView { public MyGLSurfaceView(Context context) { super(context); try { // Create an OpenGL ES 2.0 context setEGLContextClientVersion(2); // Set the Renderer for drawing on the GLSurfaceView setRenderer(new MyRenderer()); // Render the view only when there is a change in the drawing // data setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // 注意上面語句的順序,反了可能會出錯 } catch (Exception e) { e.printStackTrace(); } } } public class MyRenderer implements GLSurfaceView.Renderer { public void onSurfaceCreated(GL10 unused, EGLConfig config) { // Set the background frame color GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); } public void onDrawFrame(GL10 unused) { // Redraw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); } public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); } } }
參考資料
Training: Building an OpenGL ES Environment
http://developer.android.com/training/graphics/opengl/environment.html
OpenGL ES Developer Guide:
http://developer.android.com/guide/topics/graphics/opengl.html