OpenGL ES之GLSurfaceView學習一:介紹


原文地址::http://120.132.134.205/cmdn/supesite/?uid-5358-action-viewspace-itemid-6527

 GLSurfaceView是一個視圖,繼承至SurfaceView,它內嵌的surface專門負責OpenGL渲染。

        GLSurfaceView提供了下列特性:
                1> 管理一個surface,這個surface就是一塊特殊的內存,能直接排版到android的視圖view上。
                2> 管理一個EGL display,它能讓opengl把內容渲染到上述的surface上。
                3> 用戶自定義渲染器(render)。
                4> 讓渲染器在獨立的線程里運作,和UI線程分離。
                5> 支持按需渲染(on-demand)和連續渲染(continuous)。
                6> 一些可選工具,如調試。
        
使用GLSurfaceView
        通常會繼承GLSurfaceView,並重載一些和用戶輸入事件有關的方法。如果你不需要重載事件方法,GLSurfaceView也可以直接使用, 你可以使用set方法來為該類提供自定義的行為。例如,GLSurfaceView的渲染被委托給渲染器在獨立的渲染線程里進行,這一點和普通視圖不一 樣,setRenderer(Renderer)設置渲染器。
        
初始化GLSurfaceView
        初始化過程其實僅需要你使用setRenderer(Renderer)設置一個渲染器(render)。當然,你也可以修改GLSurfaceView一些默認配置。
            * setDebugFlags(int)
            * setEGLConfigChooser(boolean)
            * setEGLConfigChooser(EGLConfigChooser)
            * setEGLConfigChooser(int, int, int, int, int, int)
            * setGLWrapper(GLWrapper) 
 
定制android.view.Surface
        GLSurfaceView默認會創建像素格式為PixelFormat.RGB_565的surface。如果需要透明效果,調用 getHolder().setFormat(PixelFormat.TRANSLUCENT)。透明(TRANSLUCENT)的surface的像 素格式都是32位,每個色彩單元都是8位深度,像素格式是設備相關的,這意味着它可能是ARGB、RGBA或其它。
        
選擇EGL配置
        Android設備往往支持多種EGL配置,可以使用不同數目的通道(channel),也可以指定每個通道具有不同數目的位(bits)深度。因此, 在渲染器工作之前就應該指定EGL的配置。GLSurfaceView默認EGL配置的像素格式為RGB_656,16位的深度緩存(depth buffer),默認不開啟遮罩緩存(stencil buffer)。
        如果你要選擇不同的EGL配置,請使用setEGLConfigChooser方法中的一種。
        
調試行為
        你可以調用調試方法setDebugFlags(int)或setGLWrapper(GLSurfaceView.GLWrapper)來自定義 GLSurfaceView一些行為。在setRenderer方法之前或之后都可以調用調試方法,不過最好是在之前調用,這樣它們能立即生效。
        
設置渲染器
        總之,你必須調用setRenderer(GLSurfaceView.Renderer)來注冊一個GLSurfaceView.Renderer渲染器。渲染器負責真正的GL渲染工作。
        
渲染模式
        渲染器設定之后,你可以使用setRenderMode(int)指定渲染模式是按需(on demand)還是連續(continuous)。默認是連續渲染。
        
Activity生命周期
        Activity窗口暫停(pause)或恢復(resume)時,GLSurfaceView都會收到通知,此時它的onPause方法和 onResume方法應該被調用。這樣做是為了讓GLSurfaceView暫停或恢復它的渲染線程,以便它及時釋放或重建OpenGL的資源。
        
事件處理
        為了處理事件,一般都是繼承GLSurfaceView類並重載它的事件方法。但是由於GLSurfaceView是多線程操作,所以需要一些特殊的處 理。由於渲染器在獨立的渲染線程里,你應該使用Java的跨線程機制跟渲染器通訊。queueEvent(Runnable)方法就是一種相對簡單的操 作,例如下面的例子。
         class MyGLSurfaceView extends GLSurfaceView {
 
             private MyRenderer mMyRenderer;
 
             public void start() {
                 mMyRenderer = ...;
                 setRenderer(mMyRenderer);
             }
 
             public boolean onKeyDown(int keyCode, KeyEvent event) {
                 if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                     queueEvent(new Runnable() {
                         // 這個方法會在渲染線程里被調用
                         public void run() {
                             mMyRenderer.handleDpadCenter();
                         }});
                     return true;
                 }
                 return super.onKeyDown(keyCode, event);
             }
         }
 
        (注:如果在UI線程里調用渲染器的方法,很容易收到“call to OpenGL ES API with no current context”的警告,典型的誤區就是在鍵盤或鼠標事件方法里直接調用opengl es的API,因為UI事件和渲染繪制在不同的線程里。更甚者,這種情況下調用glDeleteBuffers這種釋放資源的方法,可能引起程序的崩潰, 因為UI線程想釋放它,渲染線程卻要使用它。)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM