OpenGL Es 簡單創建和使用

Android 第一個OpenGL ES程序

  在你的Android應用中用OpenGL ES繪製圖形,首先需要有一個容器,最直接的方法是實現GLSurfaceView 和  GLSurfaceView.Renderer

  前者是一個放置圖形的View容器,後者用來控制在這個View中如何進行繪製。

 

  GLSurfaceView只是一種選擇,比較適合於全屏繪製圖形或者近似全屏繪製,其他可以選擇的還有 TextureViewSurfaceView

  

  本文展示一個最基本的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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章