Welcome 微信登录

首页 / 操作系统 / Linux / Android利用OpenGLES开发动态壁纸用到的GLWallpaperService类

Android利用OpenGLES开发动态壁纸用到的GLWallpaperService类:
 
  1. /* 
  2.  * Copyright (C) 2008 The Android Open Source Project 
  3.  * 
  4.  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5.  * you may not use this file except in compliance with the License. 
  6.  * You may obtain a copy of the License at 
  7.  * 
  8.  *      http://www.apache.org/licenses/LICENSE-2.0 
  9.  * 
  10.  * Unless required by applicable law or agreed to in writing, software 
  11.  * distributed under the License is distributed on an "AS IS" BASIS, 
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13.  * See the License for the specific language governing permissions and 
  14.  * limitations under the License. 
  15.  */  
  16. import java.io.Writer;  
  17. import java.util.ArrayList;  
  18.   
  19. import javax.microedition.khronos.egl.EGL10;  
  20. import javax.microedition.khronos.egl.EGL11;  
  21. import javax.microedition.khronos.egl.EGLConfig;  
  22. import javax.microedition.khronos.egl.EGLContext;  
  23. import javax.microedition.khronos.egl.EGLDisplay;  
  24. import javax.microedition.khronos.egl.EGLSurface;  
  25. import javax.microedition.khronos.opengles.GL;  
  26. import javax.microedition.khronos.opengles.GL10;  
  27.   
  28. import android.service.wallpaper.WallpaperService;  
  29. import android.util.Log;  
  30. import android.view.SurfaceHolder;  
  31.   
  32. import com.mediawoz.firewallpaper.BaseConfigChooser.ComponentSizeChooser;  
  33. import com.mediawoz.firewallpaper.BaseConfigChooser.SimpleEGLConfigChooser;  
  34.   
  35.   
  36. // Original code provided by Robert Green   
  37. // http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers   
  38. public class GLWallpaperService extends WallpaperService {  
  39.     private static final String TAG = "GLWallpaperService";  
  40.   
  41.     @Override  
  42.     public Engine onCreateEngine() {  
  43.         return new GLEngine();  
  44.     }  
  45.   
  46.     public class GLEngine extends Engine {  
  47.         public final static int RENDERMODE_WHEN_DIRTY = 0;  
  48.         public final static int RENDERMODE_CONTINUOUSLY = 1;  
  49.   
  50.         private GLThread mGLThread;  
  51.         private EGLConfigChooser mEGLConfigChooser;  
  52.         private EGLContextFactory mEGLContextFactory;  
  53.         private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;  
  54.         private GLWrapper mGLWrapper;  
  55.         private int mDebugFlags;  
  56.   
  57.         public GLEngine() {  
  58.             super();  
  59.         }  
  60.   
  61.         @Override  
  62.         public void onVisibilityChanged(boolean visible) {  
  63.             if (visible) {  
  64.                 onResume();  
  65.             } else {  
  66.                 onPause();  
  67.             }  
  68.             super.onVisibilityChanged(visible);  
  69.         }  
  70.   
  71.         @Override  
  72.         public void onCreate(SurfaceHolder surfaceHolder) {  
  73.             super.onCreate(surfaceHolder);  
  74.             // Log.d(TAG, "GLEngine.onCreate()");   
  75.         }  
  76.   
  77.         @Override  
  78.         public void onDestroy() {  
  79.             super.onDestroy();  
  80.             // Log.d(TAG, "GLEngine.onDestroy()");   
  81.             mGLThread.requestExitAndWait();  
  82.         }  
  83.   
  84.         @Override  
  85.         public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {  
  86.             // Log.d(TAG, "onSurfaceChanged()");   
  87.             mGLThread.onWindowResize(width, height);  
  88.             super.onSurfaceChanged(holder, format, width, height);  
  89.         }  
  90.   
  91.         @Override  
  92.         public void onSurfaceCreated(SurfaceHolder holder) {  
  93.             Log.d(TAG, "onSurfaceCreated()");  
  94.             mGLThread.surfaceCreated(holder);  
  95.             super.onSurfaceCreated(holder);  
  96.         }  
  97.   
  98.         @Override  
  99.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
  100.             Log.d(TAG, "onSurfaceDestroyed()");  
  101.             mGLThread.surfaceDestroyed();  
  102.             super.onSurfaceDestroyed(holder);  
  103.         }  
  104.   
  105.         /** 
  106.          * An EGL helper class. 
  107.          */  
  108.         public void setGLWrapper(GLWrapper glWrapper) {  
  109.             mGLWrapper = glWrapper;  
  110.         }  
  111.   
  112.         public void setDebugFlags(int debugFlags) {  
  113.             mDebugFlags = debugFlags;  
  114.         }  
  115.   
  116.         public int getDebugFlags() {  
  117.             return mDebugFlags;  
  118.         }  
  119.   
  120.         public void setRenderer(Renderer renderer) {  
  121.             checkRenderThreadState();  
  122.             if (mEGLConfigChooser == null) {  
  123.                 mEGLConfigChooser = new SimpleEGLConfigChooser(true);  
  124.             }  
  125.             if (mEGLContextFactory == null) {  
  126.                 mEGLContextFactory = new DefaultContextFactory();  
  127.             }  
  128.             if (mEGLWindowSurfaceFactory == null) {  
  129.                 mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();  
  130.             }  
  131.             mGLThread = new GLThread(renderer, mEGLConfigChooser, mEGLContextFactory, mEGLWindowSurfaceFactory, mGLWrapper);  
  132.             mGLThread.start();  
  133.         }  
  134.   
  135.         public void setEGLContextFactory(EGLContextFactory factory) {  
  136.             checkRenderThreadState();  
  137.             mEGLContextFactory = factory;  
  138.         }  
  139.   
  140.         public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {  
  141.             checkRenderThreadState();  
  142.             mEGLWindowSurfaceFactory = factory;  
  143.         }  
  144.   
  145.         public void setEGLConfigChooser(EGLConfigChooser configChooser) {  
  146.             checkRenderThreadState();  
  147.             mEGLConfigChooser = configChooser;  
  148.         }  
  149.   
  150.         public void setEGLConfigChooser(boolean needDepth) {  
  151.             setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));  
  152.         }  
  153.   
  154.         public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize,  
  155.                 int stencilSize) {  
  156.             setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize, depthSize,  
  157.                     stencilSize));  
  158.         }  
  159.   
  160.         public void setRenderMode(int renderMode) {  
  161.             mGLThread.setRenderMode(renderMode);  
  162.         }  
  163.   
  164.         public int getRenderMode() {  
  165.             return mGLThread.getRenderMode();  
  166.         }  
  167.   
  168.         public void requestRender() {  
  169.             mGLThread.requestRender();  
  170.         }  
  171.   
  172.         public void onPause() {  
  173.             mGLThread.onPause();  
  174.         }  
  175.   
  176.         public void onResume() {  
  177.             mGLThread.onResume();  
  178.         }  
  179.   
  180.         public void queueEvent(Runnable r) {  
  181.             mGLThread.queueEvent(r);  
  182.         }  
  183.   
  184.         private void checkRenderThreadState() {  
  185.             if (mGLThread != null) {  
  186.                 throw new IllegalStateException("setRenderer has already been called for this instance.");  
  187.             }  
  188.         }  
  189.     }  
  190.   
  191.     public interface Renderer {  
  192.   
  193.         public void onSurfaceCreated(GL10 gl, EGLConfig config);  
  194.   
  195.         public void onSurfaceChanged(GL10 gl, int width, int height);  
  196.   
  197.         public void onDrawFrame(GL10 gl);  
  198.     }  
  199. }  
  200.   
  201. class LogWriter extends Writer {  
  202.     private StringBuilder mBuilder = new StringBuilder();  
  203.   
  204.     @Override  
  205.     public void close() {  
  206.         flushBuilder();  
  207.     }  
  208.   
  209.     @Override  
  210.     public void flush() {  
  211.         flushBuilder();  
  212.     }  
  213.   
  214.     @Override  
  215.     public void write(char[] buf, int offset, int count) {  
  216.         for (int i = 0; i < count; i++) {  
  217.             char c = buf[offset + i];  
  218.             if (c == " ") {  
  219.                 flushBuilder();  
  220.             } else {  
  221.                 mBuilder.append(c);  
  222.             }  
  223.         }  
  224.     }  
  225.   
  226.     private void flushBuilder() {  
  227.         if (mBuilder.length() > 0) {  
  228.             Log.v("GLSurfaceView", mBuilder.toString());  
  229.             mBuilder.delete(0, mBuilder.length());  
  230.         }  
  231.     }  
  232. }  
  233.   
  234. // ----------------------------------------------------------------------   
  235.   
  236. /** 
  237.  * An interface for customizing the eglCreateContext and eglDestroyContext calls. 
  238.  * 
  239.  
  240.  * This interface must be implemented by clients wishing to call 
  241.  * {@link GLWallpaperService#setEGLContextFactory(EGLContextFactory)} 
  242.  */  
  243. interface EGLContextFactory {  
  244.     EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig);  
  245.   
  246.     void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);  
  247. }  
  248.   
  249. class DefaultContextFactory implements EGLContextFactory {  
  250.   
  251.     public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {  
  252.         return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);  
  253.     }  
  254.   
  255.     public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {  
  256.         egl.eglDestroyContext(display, context);  
  257.     }  
  258. }  
  259.   
  260. /** 
  261.  * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls. 
  262.  * 
  263.  
  264.  * This interface must be implemented by clients wishing to call 
  265.  * {@link GLWallpaperService#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)} 
  266.  */  
  267. interface EGLWindowSurfaceFactory {  
  268.     EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config, Object nativeWindow);  
  269.   
  270.     void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);  
  271. }  
  272.   
  273. class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory {  
  274.   
  275.     public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay  
  276.             display, EGLConfig config, Object nativeWindow) {  
  277.         // this is a bit of a hack to work around Droid init problems - if you don"t have this, it"ll get hung up on orientation changes   
  278.         EGLSurface eglSurface = null;  
  279.         while (eglSurface == null) {  
  280.             try {  
  281.                 eglSurface = egl.eglCreateWindowSurface(display,  
  282.                         config, nativeWindow, null);  
  283.             } catch (Throwable t) {  
  284.             } finally {  
  285.                 if (eglSurface == null) {  
  286.                     try {  
  287.                         Thread.sleep(10);  
  288.                     } catch (InterruptedException t) {  
  289.                     }  
  290.                 }  
  291.             }  
  292.         }  
  293.         return eglSurface;  
  294.     }  
  295.   
  296.     public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {  
  297.         egl.eglDestroySurface(display, surface);  
  298.     }  
  299. }  
  300.   
  301. interface GLWrapper {  
  302.     /** 
  303.      * Wraps a gl interface in another gl interface. 
  304.      * 
  305.      * @param gl 
  306.      * a GL interface that is to be wrapped. 
  307.      * @return either the input argument or another GL object that wraps the input argument. 
  308.      */  
  309.     GL wrap(GL gl);  
  310. }  
  311.   
  312. class EglHelper {  
  313.   
  314.     private EGL10 mEgl;  
  315.     private EGLDisplay mEglDisplay;  
  316.     private EGLSurface mEglSurface;  
  317.     private EGLContext mEglContext;  
  318.     EGLConfig mEglConfig;  
  319.   
  320.     private EGLConfigChooser mEGLConfigChooser;  
  321.     private EGLContextFactory mEGLContextFactory;  
  322.     private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;  
  323.     private GLWrapper mGLWrapper;  
  324.   
  325.     public EglHelper(EGLConfigChooser chooser, EGLContextFactory contextFactory,  
  326.             EGLWindowSurfaceFactory surfaceFactory, GLWrapper wrapper) {  
  327.         this.mEGLConfigChooser = chooser;  
  328.         this.mEGLContextFactory = contextFactory;  
  329.         this.mEGLWindowSurfaceFactory = surfaceFactory;  
  330.         this.mGLWrapper = wrapper;  
  331.     }  
  332.   
  333.     /** 
  334.      * Initialize EGL for a given configuration spec. 
  335.      * 
  336.      * @param configSpec 
  337.      */  
  338.     public void start() {  
  339.         // Log.d("EglHelper" + instanceId, "start()");   
  340.         if (mEgl == null) {  
  341.             // Log.d("EglHelper" + instanceId, "getting new EGL");   
  342.             /* 
  343.              * Get an EGL instance 
  344.              */  
  345.             mEgl = (EGL10) EGLContext.getEGL();  
  346.         } else {  
  347.             // Log.d("EglHelper" + instanceId, "reusing EGL");   
  348.         }  
  349.   
  350.         if (mEglDisplay == null) {  
  351.             // Log.d("EglHelper" + instanceId, "getting new display");   
  352.             /* 
  353.              * Get to the default display. 
  354.              */  
  355.             mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);  
  356.         } else {  
  357.             // Log.d("EglHelper" + instanceId, "reusing display");   
  358.         }  
  359.   
  360.         if (mEglConfig == null) {  
  361.             // Log.d("EglHelper" + instanceId, "getting new config");   
  362.             /* 
  363.              * We can now initialize EGL for that display 
  364.              */  
  365.             int[] version = new int[2];  
  366.