OSDN Git Service

Android: Added proper OpenGL ES version detection and a best EGL Config Chooser
authorkimxilxyong <kimxilxyong@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sun, 12 Jun 2011 09:26:22 +0000 (09:26 +0000)
committerkimxilxyong <kimxilxyong@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Sun, 12 Jun 2011 09:26:22 +0000 (09:26 +0000)
git-svn-id: http://jmonkeyengine.googlecode.com/svn/trunk@7594 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

engine/src/android/com/jme3/R.java [deleted file]
engine/src/android/com/jme3/app/AndroidHarness.java
engine/src/android/com/jme3/app/android/AndroidApplication.java
engine/src/android/com/jme3/system/android/OGLESContext.java
engine/src/android/jme3test/android/AndroidActivity.java

diff --git a/engine/src/android/com/jme3/R.java b/engine/src/android/com/jme3/R.java
deleted file mode 100644 (file)
index af96874..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* AUTO-GENERATED FILE.  DO NOT MODIFY.\r
- *\r
- * This class was automatically generated by the\r
- * aapt tool from the resource data it found.  It\r
- * should not be modified by hand.\r
- */\r
-\r
-package com.jme3;\r
-\r
-public final class R {\r
-    public static final class attr {\r
-    }\r
-    public static final class layout {\r
-        public static final int main=0x7f020000;\r
-    }\r
-    public static final class string {\r
-        public static final int app_name=0x7f030000;\r
-        public static final int jme3_appclass=0x7f030001;\r
-    }\r
-}\r
index 9b88c15..5fb82f3 100644 (file)
@@ -136,7 +136,7 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
         \r
         final String sTrace = s;\r
         \r
-        logger.severe(t != null ? t.toString() : "Failed");\r
+        logger.severe(t != null ? t.toString() : "OpenGL Exception");\r
         logger.severe((errorMsg != null ? errorMsg + ": " : "") + sTrace);\r
         \r
         this.runOnUiThread(new Runnable() {\r
@@ -145,7 +145,7 @@ public class AndroidHarness extends Activity implements DialogInterface.OnClickL
             {                                \r
                 AlertDialog dialog = new AlertDialog.Builder(AndroidHarness.this)\r
                // .setIcon(R.drawable.alert_dialog_icon)\r
-                .setTitle(t != null ? t.toString() : "Failed")\r
+                .setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "OpenGL Exception")\r
                 .setPositiveButton("Kill", AndroidHarness.this)\r
                 .setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)\r
                 .create();    \r
index c2e99e1..5d6ed2c 100644 (file)
@@ -266,10 +266,10 @@ public abstract class AndroidApplication extends Application implements DialogIn
         activity.runOnUiThread(new Runnable() {
             @Override
             public void run() 
-            {                                
+            {                                                
                 AlertDialog dialog = new AlertDialog.Builder(activity)
                // .setIcon(R.drawable.alert_dialog_icon)
-                .setTitle(t != null ? t.toString() : "Failed")
+                .setTitle(t != null ? (t.getMessage() != null ? (t.getMessage() + ": " + t.getClass().getName()) : t.getClass().getName()) : "Exception")
                 .setPositiveButton("Kill", AndroidApplication.this)
                 .setMessage((errorMsg != null ? errorMsg + ": " : "") + sTrace)
                 .create();    
index e3b3200..88a0e3f 100644 (file)
@@ -34,6 +34,7 @@ package com.jme3.system.android;
 
 import android.app.Activity;
 import android.content.Context;
+import android.opengl.GLES20;
 import android.opengl.GLSurfaceView;
 import android.view.SurfaceHolder;
 
@@ -52,7 +53,11 @@ import com.jme3.system.SystemListener;
 import com.jme3.system.Timer;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.logging.Logger;
+
+import javax.microedition.khronos.egl.EGL10;
 import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
 import javax.microedition.khronos.opengles.GL10;
 
 
@@ -84,7 +89,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
     protected int frameRate = 33;
     //protected int minFrameDuration = 1000 / frameRate;  // Set a max FPS of 33
     protected int minFrameDuration = 0;                   // No FPS cap
-
+    
+    /**
+     * EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 | EGL_OPENGL_ES2_BIT = OpenGL ES 2.0 
+     */
+    protected int clientOpenGLESVersion = 1;
+    
     public OGLESContext() { }
 
     @Override
@@ -104,7 +114,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
     }
     /**
      * <code>createView</code> 
-     * @param AndroidInput The Android input which must be bound to an activity  
+     * @param view The Android input which will be used as the GLSurfaceView for this context
      * @return GLSurfaceView The newly created view
      */
     public GLSurfaceView createView(AndroidInput view)
@@ -114,30 +124,190 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
     
     /**
      * <code>createView</code> 
-     * @param AndroidInput The Android input which must be bound to an activity  
+     * @param view The Android input which will be used as the GLSurfaceView for this context
      * @param debugflags 0, GLSurfaceView.DEBUG_CHECK_GL_ERROR | GLSurfaceView.DEBUG_LOG_GL_CALLS
      * @return GLSurfaceView The newly created view
      */    
     public GLSurfaceView createView(AndroidInput view, int debugflags)
-    {
+    {                    
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+                       
+        int[] version = new int[2];
+        if (egl.eglInitialize(display, version) == true)
+        {
+            logger.info("Display EGL Version: " + version[0] + "." + version[1]);
+        }
+        
+        //Querying number of configurations
+        int[] num_conf = new int[1];
+        egl.eglGetConfigs(display, null, 0, num_conf);  //if configuration array is null it still returns the number of configurations
+        int configurations = num_conf[0];
+
+        //Querying actual configurations
+        EGLConfig[] conf = new EGLConfig[configurations];
+        egl.eglGetConfigs(display, conf, configurations, num_conf);
+
+        EGLConfig bestConfig = null;
+        int[] value = new int[1];
+        int EGL_OPENGL_ES2_BIT = 4;
+
+        // Loop over all configs to get the best
+        for(int i = 0; i < configurations; i++)
+        {
+            //logger.info("Supported EGL Configuration #" + i );
+        
+            if (conf[i] != null)
+            {
+                //logger.info(String.format("conf[%d] = %s", i, conf[i].toString() ) );
+                //logEGLConfig(conf[i], display, egl);     
+                egl.eglGetConfigAttrib(display, conf[i], EGL10.EGL_RENDERABLE_TYPE, value);
+                if ((value[0] & EGL_OPENGL_ES2_BIT) != 0)
+                {
+                    clientOpenGLESVersion = 2;  // OpenGL ES 2.0 detected
+                }
+                
+                bestConfig = better(bestConfig, conf[i], egl, display);
+            }
+            else
+            {
+                break;
+            }
+        }
+        
+        if (clientOpenGLESVersion < 2)
+        {
+            logger.severe("OpenGL ES 2.0 is not supported on this device");
+        }
+        
+        logger.info("JME3 using best EGL configuration available here: ");        
+        logEGLConfig(bestConfig, display, egl);
+        
+        // Finished querying the configs
+        
+        
+        // Start to set up the view
         this.view = view;    
 
-       /*
-        * Requesting client version from GLSurfaceView which is extended by
-        * AndroidInput.
-        * This is required to get OpenGL ES 2.0
-        */     
-       view.setEGLContextClientVersion(2);
-       
+        /*
+         * Requesting client version from GLSurfaceView which is extended by
+         * AndroidInput.        
+         */     
+        view.setEGLContextClientVersion(clientOpenGLESVersion);
+                
         //RGB565, Depth16
-        view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
+        //view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
+        
+        // Choose best config        
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_RED_SIZE, value);
+        int redSize = value[0];
+        
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_GREEN_SIZE, value);
+        int greenSize = value[0];
+        
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_BLUE_SIZE, value);
+        int blueSize = value[0];
+
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_ALPHA_SIZE, value);
+        int alphaSize = value[0];
+        
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_DEPTH_SIZE, value);
+        int depthSize = value[0];
+                
+        egl.eglGetConfigAttrib(display, bestConfig, EGL10.EGL_STENCIL_SIZE, value);
+        int stencilSize = value[0];
+        
+        view.setEGLConfigChooser(redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize);
+        
         view.setFocusableInTouchMode(true);
         view.setFocusable(true);
         view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU);
-        view.setDebugFlags(debugflags);
-               view.setRenderer(this);
+//        view.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR);
+//                         | GLSurfaceView.DEBUG_LOG_GL_CALLS);
+        view.setRenderer(this);
         return view;
+
     }
+        
+    /**
+     * Returns the best of the two EGLConfig passed according to depth and colours
+     * @param a The first candidate
+     * @param b The second candidate
+     * @return The chosen candidate
+     */
+    private EGLConfig better(EGLConfig a, EGLConfig b, EGL10 egl, EGLDisplay display)
+    {
+        if(a == null) return b;
+    
+        EGLConfig result = null;
+    
+        int[] value = new int[1];
+    
+        egl.eglGetConfigAttrib(display, a, EGL10.EGL_DEPTH_SIZE, value);
+        int depthA = value[0];
+    
+        egl.eglGetConfigAttrib(display, b, EGL10.EGL_DEPTH_SIZE, value);
+        int depthB = value[0];
+    
+        if(depthA > depthB)
+            result = a;
+        else if(depthA < depthB)
+            result = b;
+        else //if depthA == depthB
+        {
+            egl.eglGetConfigAttrib(display, a, EGL10.EGL_RED_SIZE, value);
+            int redA = value[0];
+    
+            egl.eglGetConfigAttrib(display, b, EGL10.EGL_RED_SIZE, value);
+            int redB = value[0];
+    
+            if(redA > redB)
+                result = a;
+            else if(redA < redB)
+                result = b;
+            else //if redA == redB
+            {
+                // Don't care
+                result = a;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * log output with egl config details
+     * @param conf
+     * @param display
+     * @param egl
+     */
+    private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl)
+    {
+        int[] value = new int[1];
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
+        logger.info(String.format("EGL_RED_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
+        logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0] ) );
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
+        logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
+        logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0] ) );
+        
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
+        logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0] ) );
+                
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
+        logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0] ) );
+
+        egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
+        logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0] ) );
+
+        
+    }
+    
     
 
     protected void initInThread()
@@ -152,7 +322,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
         {
             Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                 public void uncaughtException(Thread thread, Throwable thrown) {
-                    ((AndroidHarness)ctx).handleError("Uncaught exception thrown in "+thread.toString(), thrown);
+                    ((AndroidHarness)ctx).handleError("Exception thrown in " + thread.toString(), thrown);
                 }
             });
         }
@@ -160,11 +330,16 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
         {
             Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                 public void uncaughtException(Thread thread, Throwable thrown) {
-                    listener.handleError("Uncaught exception thrown in "+thread.toString(), thrown);
+                    listener.handleError("Exception thrown in " + thread.toString(), thrown);
                 }
             });
         }
         
+        if (clientOpenGLESVersion < 2)
+        {
+            throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device");
+        }
+        
         timer = new AndroidTimer();
 
         renderer = new OGLESShaderRenderer();
@@ -278,6 +453,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
     @Override
     public void onSurfaceCreated(GL10 gl, EGLConfig cfg) 
     {
+        
         if (created.get() && renderer != null)
         {
             renderer.resetGLObjects();
@@ -394,5 +570,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer
         }
     }
 
+    public int getClientOpenGLESVersion() 
+    {
+        return clientOpenGLESVersion;
+    }
 
 }
index 350d3c2..6f116f4 100644 (file)
@@ -15,7 +15,7 @@ import android.opengl.GLSurfaceView;
 import android.os.Bundle;
 import android.view.Window;
 import android.view.WindowManager;
-import com.jme3.R;
+
 import com.jme3.system.AppSettings;
 import com.jme3.system.JmeSystem;
 import com.jme3.system.android.OGLESContext;