鍍金池/ 教程/ Android/ GLSurfaceView
                                          繪制線段 Line Segment
                                          投影變換 Projection
                                          繪制迷你太陽系
                                          繪制一個球體
                                          繪制三角形 Triangle
                                          OpenGL 光照模型
                                          三維坐標系及坐標變換初步
                                          定義 3D 模型的前面和后面
                                          繪制一個 20 面體
                                          顏色 Color
                                          Depth Buffer
                                          材質及光照示例
                                          基本幾何圖形定義
                                          關于EGL
                                          導言
                                          Viewing 和 Modeling(MODELVIEW) 變換
                                          FrameBuffer
                                          設置光照效果 Set Lighting
                                          Viewport 變換
                                          階段小結
                                          繪制點 Point
                                          OpenGL ES API 命名習慣
                                          通用的矩陣變換指令
                                          關于 OpenGL ES
                                          創建實例應用 OpenGLDemos 程序框架
                                          OpenGL ES 管道(Pipeline)
                                          GLSurfaceView

                                          GLSurfaceView

                                          Android OpenGL ES 相關的包主要定義在

                                          • javax.microedition.khronos.opengles GL 繪圖指令
                                          • javax.microedition.khronos.egl EGL 管理Display, surface等
                                          • android.opengl Android GL輔助類,連接OpenGL 與Android View,Activity
                                          • javax.nio Buffer類

                                          其中 GLSurfaceView 為 android.opengl 包中核心類:

                                          • 起到連接 OpenGL ES 與 Android 的 View 層次結構之間的橋梁作用。
                                          • 使得 Open GL ES 庫適應于 Anndroid 系統的 Activity 生命周期。
                                          • 使得選擇合適的 Frame buffer 像素格式變得容易。
                                          • 創建和管理單獨繪圖線程以達到平滑動畫效果。
                                          • 提供了方便使用的調試工具來跟蹤 OpenGL ES 函數調用以幫助檢查錯誤。

                                          使用過 Java ME ,JSR 239 開發過 OpenGL ES 可以看到 Android 包javax.microedition.khronos.egl ,javax.microedition.khronos.opengles 和 JSR239 基本一致,因此理論上不使用 android.opengl 包中的類也可以開發 Android 上 OpenGL ES 應用,但此時就需要自己使用 EGL 來管理 Display,Context,Surfaces 的創建,釋放,捆綁,可以參見 Android OpenGL ES 開發教程(5):關于EGL 。

                                          使用 EGL 實現 GLSurfaceView 一個可能的實現如下:

                                          class GLSurfaceView extends SurfaceView
                                           implements SurfaceHolder.Callback, Runnable {
                                           public GLSurfaceView(Context context) {
                                           super(context);
                                           mHolder = getHolder();
                                           mHolder.addCallback(this);
                                           mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
                                           }
                                           public void setRenderer(Renderer renderer) {
                                           mRenderer = renderer;
                                           }
                                           public void surfaceCreated(SurfaceHolder holder) {
                                           }
                                           public void surfaceDestroyed(SurfaceHolder holder) {
                                           running = false;
                                           try {
                                           thread.join();
                                           } catch (InterruptedException e) {
                                           }
                                           thread = null;
                                           }
                                           public void surfaceChanged(SurfaceHolder holder,
                                           int format, int w, int h) {
                                           synchronized(this){
                                           mWidth = w;
                                           mHeight = h;
                                           thread = new Thread(this);
                                           thread.start();
                                           }
                                           }
                                           public interface Renderer {
                                           void EGLCreate(SurfaceHolder holder);
                                           void EGLDestroy();
                                           int Initialize(int width, int height);
                                           void DrawScene(int width, int height);
                                           }
                                           public void run() {
                                           synchronized(this) {
                                           mRenderer.EGLCreate(mHolder);
                                           mRenderer.Initialize(mWidth, mHeight);
                                           running=true;
                                           while (running) {
                                           mRenderer.DrawScene(mWidth, mHeight);
                                           }
                                           mRenderer.EGLDestroy();
                                           }
                                           }
                                           private SurfaceHolder mHolder;
                                           private Thread thread;
                                           private boolean running;
                                           private Renderer mRenderer;
                                           private int mWidth;
                                           private int mHeight;
                                          }
                                          class GLRenderer implements GLSurfaceView.Renderer {
                                           public GLRenderer() 
                                           }
                                           public int Initialize(int width, int height){
                                           gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
                                           return 1;
                                           }
                                           public void DrawScene(int width, int height){
                                           gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
                                           egl.eglSwapBuffers(eglDisplay, eglSurface);
                                           }
                                           public void EGLCreate(SurfaceHolder holder){
                                           int[] num_config = new int[1];
                                           EGLConfig[] configs = new EGLConfig[1];
                                           int[] configSpec = {
                                           EGL10.EGL_RED_SIZE,            8,
                                           EGL10.EGL_GREEN_SIZE,        8,
                                           EGL10.EGL_BLUE_SIZE,        8,
                                           EGL10.EGL_SURFACE_TYPE,     EGL10.EGL_WINDOW_BIT,
                                           EGL10.EGL_NONE
                                           };
                                           this.egl = (EGL10) EGLContext.getEGL();
                                           eglDisplay = this.egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
                                           this.egl.eglInitialize(eglDisplay, null);
                                           this.egl.eglChooseConfig(eglDisplay, configSpec,
                                           configs, 1, num_config);
                                           eglConfig = configs[0];
                                           eglContext = this.egl.eglCreateContext(eglDisplay, eglConfig,
                                           EGL10.EGL_NO_CONTEXT, null);
                                           eglSurface = this.egl.eglCreateWindowSurface(eglDisplay,
                                           eglConfig, holder, null);
                                           this.egl.eglMakeCurrent(eglDisplay, eglSurface,
                                           eglSurface, eglContext);
                                           gl = (GL10)eglContext.getGL();
                                           }
                                           public void EGLDestroy(){
                                           if (eglSurface != null) {
                                           egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE,
                                           EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
                                           egl.eglDestroySurface(eglDisplay, eglSurface);
                                           eglSurface = null;
                                           }
                                           if (eglContext != null) {
                                           egl.eglDestroyContext(eglDisplay, eglContext);
                                           eglContext = null;
                                           }
                                           if (eglDisplay != null) {
                                           egl.eglTerminate(eglDisplay);
                                           eglDisplay = null;
                                           }
                                           }
                                           private EGL10 egl;
                                           private GL10 gl;
                                           private EGLDisplay eglDisplay;
                                           private EGLConfig  eglConfig;
                                           private EGLContext eglContext;
                                           private EGLSurface eglSurface;
                                          }  

                                          可以看到需要派生 SurfaceView ,并手工創建,銷毀 Display,Context,工作繁瑣。

                                          使用 GLSurfaceView 內部提供了上面類似的實現,對于大部分應用只需調用一個方法來設置 OpenGLView 用到的 GLSurfaceView.Renderer。

                                          public void  setRenderer(GLSurfaceView.Renderer renderer)   

                                          GLSurfaceView.Renderer 定義了一個統一圖形繪制的接口,它定義了如下三個接口函數:

                                          // Called when the surface is created or recreated.
                                          public void onSurfaceCreated(GL10 gl, EGLConfig config)
                                          // Called to draw the current frame.
                                          public void onDrawFrame(GL10 gl)
                                          // Called when the surface changed size.
                                          public void onSurfaceChanged(GL10 gl, int width, int height)  
                                          • onSurfaceCreated:在這個方法中主要用來設置一些繪制時不常變化的參數,比如:背景色,是否打開 z-buffer等。
                                          • onDrawFrame:定義實際的繪圖操作。
                                          • onSurfaceChanged:如果設備支持屏幕橫向和縱向切換,這個方法將發生在橫向<->縱向互換時。此時可以重新設置繪制的縱橫比率。

                                          如果有需要,也可以通過函數來修改 GLSurfaceView 一些缺省設置:

                                          • setDebugFlags(int) 設置 Debug 標志。
                                          • setEGLConfigChooser (boolean) 選擇一個 Config 接近 16bitRGB 顏色模式,可以打開或關閉深度(Depth)Buffer ,缺省為RGB_565 并打開至少有 16bit 的 depth Buffer。
                                          • setEGLConfigChooser(EGLConfigChooser) 選擇自定義 EGLConfigChooser。
                                          • setEGLConfigChooser(int, int, int, int, int, int) 指定 red ,green, blue, alpha, depth ,stencil 支持的位數,缺省為 RGB_565 ,16 bit depth buffer。

                                          GLSurfaceView 缺省創建為 RGB_565 顏色格式的 Surface,如果需要支持透明度,可以調用 getHolder().setFormat(PixelFormat.TRANSLUCENT)。

                                          GLSurfaceView 的渲染模式有兩種,一種是連續不斷的更新屏幕,另一種為 on-demand ,只有在調用 requestRender() 在更新屏幕。 缺省為 RENDERMODE_CONTINUOUSLY 持續刷新屏幕。

                                          上一篇:導言下一篇:材質及光照示例
                                          人妻精品动漫h无码中字