建立OpenGL ES的環境

編寫:jdneo - 原文:http://developer.android.com/training/graphics/opengl/environment.html

要在應用中使用OpenGL ES繪製圖像,我們必須為它們創建一個View容器。一種比較直接的方法是實現GLSurfaceView類和GLSurfaceView.Renderer類。其中,GLSurfaceView是一個View容器,它用來存放使用OpenGL繪製的圖形,而GLSurfaceView.Renderer則用來控制在該View中繪製的內容。關於這兩個類的更多信息,你可以閱讀:OpenGL ES開發手冊。

使用GLSurfaceView是一種將OpenGL ES集成到應用中的方法之一。對於一個全屏的或者接近全屏的圖形View,使用它是一個理想的選擇。開發者如果希望把OpenGL ES的圖形集成在佈局的一小部分裡面,那麼可以考慮使用TextureView。對於喜歡自己動手實現的開發者來說,還可以通過使用SurfaceView搭建一個OpenGL ES View,但這將需要編寫更多的代碼。

在這節課中,我們將展示如何在一個的Activity中完成GLSurfaceViewGLSurfaceView.Renderer的最簡單的實現。

在Manifest配置文件中聲明使用OpenGL ES

為了讓應用能夠使用OpenGL ES 2.0接口,我們必須將下列聲明添加到Manifest配置文件當中:

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

如果我們的應用使用紋理壓縮(Texture Compression),那麼我們必須對支持的壓縮格式也進行聲明,確保應用僅安裝在可以兼容的設備上:

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

更多關於紋理壓縮的內容,可以閱讀:OpenGL開發手冊。

為OpenGL ES圖形創建一個activity

使用OpenGL ES的安卓應用就像其它類型的應用一樣有自己的用戶接口,即也擁有多個Activity。主要的區別體現在Acitivity佈局內容上的差異。在許多應用中你可能會使用TextViewButtonListView等,而在使用OpenGL ES的應用中,我們還可以添加一個GLSurfaceView

下面的代碼展示了一個使用GLSurfaceView作為其主View的Activity:

public class OpenGLES20Activity 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);
    }
}

**Note:**OpenGL ES 2.0需要Android 2.2(API Level 8)或更高版本的系統,所以確保你的Android項目的API版本滿足該要求。

構建一個GLSurfaceView對象

GLSurfaceView是一種比較特殊的View,我們可以在該View中繪製OpenGL ES圖形,不過它自己並不做太多和繪製圖形相關的任務。繪製對象的任務是由你在該View中配置的GLSurfaceView.Renderer所控制的。事實上,這個對象的代碼非常簡短,你可能會希望不要繼承它,直接創建一個未經修改的GLSurfaceView實例,不過請不要這麼做,因為我們需要繼承該類來捕捉觸控事件,這方面知識會在響應觸摸事件(該系列課程的最後一節課)中做進一步的介紹。

GLSurfaceView的核心代碼非常簡短,所以對於一個快速的實現而言,我們通常可以在Acitvity中創建一個內部類並使用它:

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer mRenderer;

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        mRenderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);
    }
}

另一個對於GLSurfaceView實現的可選選項,是將渲染模式設置為:GLSurfaceView.RENDERMODE_WHEN_DIRTY,其含義是:僅在你的繪製數據發生變化時才在視圖中進行繪製操作:

// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

如果選用這一配置選項,那麼除非調用了requestRender(),否則GLSurfaceView不會被重新繪製,這樣做可以讓應用的性能及效率得到提高。

構建一個渲染類

在一個使用OpenGL ES的應用中,一個GLSurfaceView.Renderer類的實現(或者我們將其稱之為渲染器),正是事情變得有趣的地方。該類會控制和其相關聯的GLSurfaceView,具體而言,它會控制在GLSurfaceView上繪製的內容。在渲染器中,一共有三個方法會被Android系統調用,以此來明確要在GLSurfaceView上繪製的內容以及如何繪製:

  • onSurfaceCreated():調用一次,用來配置View的OpenGL ES環境。
  • onDrawFrame():每次重新繪製View時被調用。
  • onSurfaceChanged():如果View的幾何形態發生變化時會被調用,例如當設備的屏幕方向發生改變時。

下面是一個非常基本的OpenGL ES渲染器的實現,它僅僅在GLSurfaceView中畫一個黑色的背景:

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 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);
    }
}

就是這樣!上面的代碼創建了一個簡單地應用程序,它使用OpenGL讓屏幕呈現為黑色。雖然它的代碼看上去並沒有做什麼非常有意思的事情,但是通過創建這些類,我們已經對使用OpenGL繪製圖形有了基本的認識和鋪墊。

**Note:**你可能想知道,自己明明使用的是OpenGL ES 2.0接口,為什麼這些方法會有一個GL10的參數。這是因為這些方法的簽名(Method Signature)在2.0接口中被簡單地重用了,以此來保持Android框架的代碼儘量簡單。

如果你對OpenGL ES接口很熟悉,那麼你現在就可以在你的應用中構建一個OpenGL ES的環境並繪製圖形了。當然, 如果你希望獲取更多的幫助來學會使用OpenGL,那麼請繼續學習下一節課程獲取更多的知識。


书籍推荐