diff --git a/engine/src/android/com/jme3/renderer/android/RendererUtil.java b/engine/src/android/com/jme3/renderer/android/RendererUtil.java
index a84ca1775..ce611044d 100644
--- a/engine/src/android/com/jme3/renderer/android/RendererUtil.java
+++ b/engine/src/android/com/jme3/renderer/android/RendererUtil.java
@@ -3,23 +3,27 @@ package com.jme3.renderer.android;
import android.opengl.GLES20;
import android.opengl.GLU;
import com.jme3.renderer.RendererException;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
/**
- * Utility class used by the {@link OGLESShaderRenderer renderer} and sister classes.
- *
+ * Utility class used by the {@link OGLESShaderRenderer renderer} and sister
+ * classes.
+ *
* @author Kirill Vainer
*/
public class RendererUtil {
-
+
/**
- * When set to true, every OpenGL call will check for errors and throw
- * an exception if there is one, if false, no error checking is performed.
+ * When set to true, every OpenGL call will check for errors and throw an
+ * exception if there is one, if false, no error checking is performed.
*/
public static boolean ENABLE_ERROR_CHECKING = true;
-
+
/**
- * Checks for an OpenGL error and throws a {@link RendererException}
- * if there is one. Ignores the value of {@link RendererUtil#ENABLE_ERROR_CHECKING}.
+ * Checks for an OpenGL error and throws a {@link RendererException} if
+ * there is one. Ignores the value of
+ * {@link RendererUtil#ENABLE_ERROR_CHECKING}.
*/
public static void checkGLErrorForced() {
int error = GLES20.glGetError();
@@ -32,14 +36,86 @@ public class RendererUtil {
}
}
}
-
+
+ /**
+ * Checks for an EGL error and throws a {@link RendererException} if there
+ * is one. Ignores the value of {@link RendererUtil#ENABLE_ERROR_CHECKING}.
+ */
+ public static void checkEGLError(EGL10 egl) {
+ int error = egl.eglGetError();
+ if (error != EGL10.EGL_SUCCESS) {
+ String errorMessage;
+ switch (error) {
+ case EGL10.EGL_SUCCESS:
+ return;
+ case EGL10.EGL_NOT_INITIALIZED:
+ errorMessage = "EGL is not initialized, or could not be "
+ + "initialized, for the specified EGL display connection. ";
+ break;
+ case EGL10.EGL_BAD_ACCESS:
+ errorMessage = "EGL cannot access a requested resource "
+ + "(for example a context is bound in another thread). ";
+ break;
+ case EGL10.EGL_BAD_ALLOC:
+ errorMessage = "EGL failed to allocate resources for the requested operation.";
+ break;
+ case EGL10.EGL_BAD_ATTRIBUTE:
+ errorMessage = "An unrecognized attribute or attribute "
+ + "value was passed in the attribute list. ";
+ break;
+ case EGL10.EGL_BAD_CONTEXT:
+ errorMessage = "An EGLContext argument does not name a valid EGL rendering context. ";
+ break;
+ case EGL10.EGL_BAD_CONFIG:
+ errorMessage = "An EGLConfig argument does not name a valid EGL frame buffer configuration. ";
+ break;
+ case EGL10.EGL_BAD_CURRENT_SURFACE:
+ errorMessage = "The current surface of the calling thread "
+ + "is a window, pixel buffer or pixmap that is no longer valid. ";
+ break;
+ case EGL10.EGL_BAD_DISPLAY:
+ errorMessage = "An EGLDisplay argument does not name a valid EGL display connection. ";
+ break;
+ case EGL10.EGL_BAD_SURFACE:
+ errorMessage = "An EGLSurface argument does not name a "
+ + "valid surface (window, pixel buffer or pixmap) configured for GL rendering. ";
+ break;
+ case EGL10.EGL_BAD_MATCH:
+ errorMessage = "Arguments are inconsistent (for example, a "
+ + "valid context requires buffers not supplied by a valid surface). ";
+ break;
+ case EGL10.EGL_BAD_PARAMETER:
+ errorMessage = "One or more argument values are invalid.";
+ break;
+ case EGL10.EGL_BAD_NATIVE_PIXMAP:
+ errorMessage = "A NativePixmapType argument does not refer to a valid native pixmap. ";
+ break;
+ case EGL10.EGL_BAD_NATIVE_WINDOW:
+ errorMessage = "A NativeWindowType argument does not refer to a valid native window. ";
+ break;
+ case EGL11.EGL_CONTEXT_LOST:
+ errorMessage = "A power management event has occurred. "
+ + "The application must destroy all contexts and reinitialise "
+ + "OpenGL ES state and objects to continue rendering. ";
+ break;
+ default:
+ errorMessage = "Unknown";
+ }
+
+ throw new RendererException("EGL error 0x" + Integer.toHexString(error) + ": " + errorMessage);
+ }
+ }
+
/**
- * Checks for an OpenGL error and throws a {@link RendererException}
- * if there is one. Does nothing if {@link RendererUtil#ENABLE_ERROR_CHECKING}
- * is set to false
.
+ * Checks for an OpenGL error and throws a {@link RendererException} if
+ * there is one. Does nothing if {@link RendererUtil#ENABLE_ERROR_CHECKING}
+ * is set to
+ * false
.
*/
public static void checkGLError() {
- if (!ENABLE_ERROR_CHECKING) return;
+ if (!ENABLE_ERROR_CHECKING) {
+ return;
+ }
int error = GLES20.glGetError();
if (error != 0) {
String message = GLU.gluErrorString(error);
diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
index 9eead12fa..b3036203d 100644
--- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
+++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
@@ -2,9 +2,8 @@ package com.jme3.system.android;
import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView.EGLConfigChooser;
+import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.AppSettings;
-import java.util.ArrayList;
-import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.microedition.khronos.egl.EGL10;
@@ -20,9 +19,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
public final static String SETTINGS_CONFIG_TYPE = "configType";
- protected int clientOpenGLESVersion = 0;
- protected EGLConfig bestConfig = null;
- protected EGLConfig fastestConfig = null;
protected EGLConfig choosenConfig = null;
protected AppSettings settings;
protected int pixelFormat;
@@ -91,14 +87,30 @@ public class AndroidConfigChooser implements EGLConfigChooser {
this.settings = settings;
}
+ private static int eglGetConfigAttribSafe(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute) {
+ int[] value = new int[1];
+ if (!egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ RendererUtil.checkEGLError(egl);
+ throw new AssertionError();
+ }
+ return value[0];
+ }
+
/**
* Gets called by the GLSurfaceView class to return the best config
*/
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
- logger.fine("GLSurfaceView asks for egl config, returning: ");
- logEGLConfig(choosenConfig, display, egl, Level.FINE);
- return choosenConfig;
+ logger.fine("GLSurfaceView asking for egl config");
+ boolean configFound = findConfig(egl, display);
+ if (configFound) {
+ logger.fine("GLSurfaceView asks for egl config, returning: ");
+ logEGLConfig(choosenConfig, display, egl, Level.FINE);
+ return choosenConfig;
+ } else {
+ logger.fine("GLSurfaceView asks for egl config, No config found");
+ return null;
+ }
}
/**
@@ -108,7 +120,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @return true if successfull, false if no config was found
*/
- public boolean findConfig(EGL10 egl, EGLDisplay display) {
+ private boolean findConfig(EGL10 egl, EGLDisplay display) {
ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples());
@@ -116,48 +128,46 @@ public class AndroidConfigChooser implements EGLConfigChooser {
logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name());
if (choosenConfig != null) {
+ // Remember the display for which we have the EGLConfig for
logger.info("JME3 using choosen config: ");
logEGLConfig(choosenConfig, display, egl, Level.INFO);
pixelFormat = getPixelFormat(choosenConfig, display, egl);
- clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
return true;
} else {
logger.severe("ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this.");
- clientOpenGLESVersion = 1;
pixelFormat = PixelFormat.UNKNOWN;
return false;
}
}
private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) {
- int[] value = new int[1];
-
//Android Pixel format is not very well documented.
//From what i gathered, the format is chosen automatically except for the alpha channel
//if the alpha channel has 8 bit or more, e set the pixel format to Transluscent, as it allow transparent view background
//if it's 0 bit, the format is OPAQUE otherwise it's TRANSPARENT
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
- if (value[0] >= 8) {
+ int result = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE);
+
+ if (result >= 8) {
+ logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
return PixelFormat.TRANSLUCENT;
}
- if (value[0] >= 1) {
+ if (result >= 1) {
+ logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
return PixelFormat.TRANSPARENT;
}
+ logger.log(Level.FINE, "Pixel Format: OPAQUE");
return PixelFormat.OPAQUE;
}
private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) {
- int[] value = new int[1];
- int result = 1;
-
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
+ int val = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE);
// Check if conf is OpenGL ES 2.0
- if ((value[0] & EGL_OPENGL_ES2_BIT) != 0) {
- result = 2;
+ if ((val & EGL_OPENGL_ES2_BIT) != 0) {
+ return 2;
+ } else {
+ return 1;
}
-
- return result;
}
/**
@@ -167,50 +177,37 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display
* @param egl
*/
- public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
- int[] value = new int[1];
-
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
- logger.log(level, String.format("EGL_RED_SIZE = %d", value[0]));
+ private void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl, Level level) {
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
- logger.log(level, String.format("EGL_GREEN_SIZE = %d", value[0]));
+ logger.log(level, "EGL_RED_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RED_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
- logger.log(level, String.format("EGL_BLUE_SIZE = %d", value[0]));
+ logger.log(level, "EGL_GREEN_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_GREEN_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
- logger.log(level, String.format("EGL_ALPHA_SIZE = %d", value[0]));
+ logger.log(level, "EGL_BLUE_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_BLUE_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
- logger.log(level, String.format("EGL_DEPTH_SIZE = %d", value[0]));
+ logger.log(level, "EGL_ALPHA_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
- logger.log(level, String.format("EGL_STENCIL_SIZE = %d", value[0]));
+ logger.log(level, "EGL_DEPTH_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_DEPTH_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
- logger.log(level, String.format("EGL_RENDERABLE_TYPE = %d", value[0]));
+ logger.log(level, "EGL_STENCIL_SIZE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_STENCIL_SIZE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
- logger.log(level, String.format("EGL_SURFACE_TYPE = %d", value[0]));
+ logger.log(level, "EGL_RENDERABLE_TYPE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE));
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLE_BUFFERS, value);
- logger.log(level, String.format("EGL_SAMPLE_BUFFERS = %d", value[0]));
-
- egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLES, value);
- logger.log(level, String.format("EGL_SAMPLES = %d", value[0]));
- }
+ logger.log(level, "EGL_SURFACE_TYPE = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SURFACE_TYPE));
- public int getClientOpenGLESVersion() {
- return clientOpenGLESVersion;
- }
-
- public void setClientOpenGLESVersion(int clientOpenGLESVersion) {
- this.clientOpenGLESVersion = clientOpenGLESVersion;
- }
+ logger.log(level, "EGL_SAMPLE_BUFFERS = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLE_BUFFERS));
- public int getPixelFormat() {
- return pixelFormat;
+ logger.log(level, "EGL_SAMPLES = {0}",
+ eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
}
private abstract class BaseConfigChooser implements EGLConfigChooser {
@@ -226,11 +223,17 @@ public class AndroidConfigChooser implements EGLConfigChooser {
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE};
- egl.eglChooseConfig(display, configSpec, null, 0, num_config);
+ if (!egl.eglChooseConfig(display, configSpec, null, 0, num_config)) {
+ RendererUtil.checkEGLError(egl);
+ throw new AssertionError();
+ }
int numConfigs = num_config[0];
EGLConfig[] configs = new EGLConfig[numConfigs];
- egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config);
+ if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config)) {
+ RendererUtil.checkEGLError(egl);
+ throw new AssertionError();
+ }
logger.fine("--------------Display Configurations---------------");
for (EGLConfig eGLConfig : configs) {
@@ -252,12 +255,10 @@ public class AndroidConfigChooser implements EGLConfigChooser {
*/
private class ComponentSizeChooser extends BaseConfigChooser {
- private int[] mValue;
private ConfigType configType;
protected int mSamples;
public ComponentSizeChooser(ConfigType configType, int samples) {
- mValue = new int[1];
mSamples = samples;
this.configType = configType;
}
@@ -272,22 +273,22 @@ public class AndroidConfigChooser implements EGLConfigChooser {
// first pass through config list. Try to find an exact match.
for (EGLConfig config : configs) {
- int r = findConfigAttrib(egl, display, config,
- EGL10.EGL_RED_SIZE, 0);
- int g = findConfigAttrib(egl, display, config,
- EGL10.EGL_GREEN_SIZE, 0);
- int b = findConfigAttrib(egl, display, config,
- EGL10.EGL_BLUE_SIZE, 0);
- int a = findConfigAttrib(egl, display, config,
- EGL10.EGL_ALPHA_SIZE, 0);
- int d = findConfigAttrib(egl, display, config,
- EGL10.EGL_DEPTH_SIZE, 0);
- int s = findConfigAttrib(egl, display, config,
- EGL10.EGL_STENCIL_SIZE, 0);
- int isMs = findConfigAttrib(egl, display, config,
- EGL10.EGL_SAMPLE_BUFFERS, 0);
- int nbMs = findConfigAttrib(egl, display, config,
- EGL10.EGL_SAMPLES, 0);
+ int r = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_RED_SIZE);
+ int g = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_GREEN_SIZE);
+ int b = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_BLUE_SIZE);
+ int a = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_ALPHA_SIZE);
+ int d = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_DEPTH_SIZE);
+ int s = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_STENCIL_SIZE);
+ int isMs = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_SAMPLE_BUFFERS);
+ int nbMs = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_SAMPLES);
if (inRange(r, configType.mr, configType.r)
&& inRange(g, configType.mg, configType.g)
@@ -344,13 +345,13 @@ public class AndroidConfigChooser implements EGLConfigChooser {
return keptConfig;
}
}
-
+
logger.log(Level.WARNING, "Failed to find a suitable display configuration for FASTEST, hoping for the best...");
// failsafe. pick the 1st config with a 16 bit depth buffer.
for (EGLConfig config : configs) {
- int d = findConfigAttrib(egl, display, config,
- EGL10.EGL_DEPTH_SIZE, 0);
+ int d = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_DEPTH_SIZE);
if (d >= 16) {
return config;
}
@@ -363,15 +364,6 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private boolean inRange(int val, int min, int max) {
return min <= val && val <= max;
}
-
- private int findConfigAttrib(EGL10 egl, EGLDisplay display,
- EGLConfig config, int attribute, int defaultValue) {
-
- if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
- return mValue[0];
- }
- return defaultValue;
- }
}
//DON'T REMOVE THIS, USED FOR UNIT TESTING FAILING CONFIGURATION LISTS.
// private static class Config {
diff --git a/engine/src/android/com/jme3/system/android/OGLESContext.java b/engine/src/android/com/jme3/system/android/OGLESContext.java
index c51c4eca8..d6bd64ddf 100644
--- a/engine/src/android/com/jme3/system/android/OGLESContext.java
+++ b/engine/src/android/com/jme3/system/android/OGLESContext.java
@@ -32,11 +32,15 @@
package com.jme3.system.android;
import android.app.Activity;
-import com.jme3.renderer.android.AndroidGLSurfaceView;
+import android.app.ActivityManager;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
+import android.content.pm.ConfigurationInfo;
+import android.graphics.PixelFormat;
import android.opengl.GLSurfaceView;
import android.text.InputType;
+import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.ViewGroup.LayoutParams;
@@ -48,16 +52,16 @@ import com.jme3.input.android.AndroidSensorJoyInput;
import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput;
+import com.jme3.renderer.android.AndroidGLSurfaceView;
+import com.jme3.renderer.RendererException;
import com.jme3.renderer.android.OGLESShaderRenderer;
+import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.*;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
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;
public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {
@@ -91,7 +95,7 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
public Type getType() {
return Type.Display;
}
-
+
/**
* createView
creates the GLSurfaceView that the renderer will
* draw to.
The result GLSurfaceView will receive input events and
@@ -104,27 +108,27 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
* ConfigType.BEST
* @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view
- * @deprecated AndroidGLSurfaceView createView()
+ * @deprecated AndroidGLSurfaceView createView()
* and put the configType in the appSettigs with the key AndroidConfigChoose.SETTINGS_CONFIG_TYPE
*/
@Deprecated
public AndroidGLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, configType);
- return this.createView();
+ return this.createView();
}
/**
* createView
creates the GLSurfaceView that the renderer will
* draw to.
The result GLSurfaceView will receive input events and * forward them to the Application. Any rendering will be done into the * GLSurfaceView. Only one GLSurfaceView can be created at this time. The - * given configType specifies how to determine the display configuration. + * given configType specifies how to determine the display configuration. + * * - * * @param eglConfigVerboseLogging if true show all found configs * @return GLSurfaceView The newly created view */ public AndroidGLSurfaceView createView() { - AndroidGLSurfaceView view; + AndroidGLSurfaceView view; ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE); // Start to set up the view @@ -135,60 +139,60 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex androidInput.setView(view); androidInput.loadSettings(settings); - if (configType == ConfigType.LEGACY) { - // Hardcoded egl setup - clientOpenGLESVersion = 2; - view.setEGLContextClientVersion(2); - // RGB565, Depth16 - view.setEGLConfigChooser(5, 6, 5, 0, 16, 0); - logger.fine("ConfigType.LEGACY using RGB565"); + int rawOpenGLESVersion = getOpenGLESVersion(); + logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}", + new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16}); + if (rawOpenGLESVersion < 0x20000) { + throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device"); } else { - 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.log(Level.INFO, "Display EGL Version: {0}.{1}", new Object[]{version[0], version[1]}); - } - - try { - // Create a config chooser - AndroidConfigChooser configChooser = new AndroidConfigChooser(settings); - // Init chooser - if (!configChooser.findConfig(egl, display)) { - listener.handleError("Unable to find suitable EGL config", null); - return null; - } - - clientOpenGLESVersion = configChooser.getClientOpenGLESVersion(); - if (clientOpenGLESVersion < 2) { - listener.handleError("OpenGL ES 2.0 is not supported on this device", null); - return null; - } - - // Requesting client version from GLSurfaceView which is extended by - // AndroidInput. - view.setEGLContextClientVersion(clientOpenGLESVersion); - view.setEGLConfigChooser(configChooser); - view.getHolder().setFormat(configChooser.getPixelFormat()); - } finally { - if (display != null) { - egl.eglTerminate(display); - } - } + clientOpenGLESVersion = 2; + view.setEGLContextClientVersion(clientOpenGLESVersion); } view.setFocusableInTouchMode(true); view.setFocusable(true); view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); - if (configType == ConfigType.BEST_TRANSLUCENT) { - //This is important to allow the GL surface to have a translucent background + + // setFormat must be set before AndroidConfigChooser is called by the surfaceview. + // if setFormat is called after ConfigChooser is called, then execution + // stops at the setFormat call without a crash. + // We look at the user setting for alpha bits and set the surfaceview + // PixelFormat to either Opaque, Transparent, or Translucent. + // ConfigChooser will do it's best to honor the alpha requested by the user + // For best rendering performance, use Opaque (alpha bits = 0). + int alphaBits = configType.a; + logger.log(Level.FINE, "alphaBits: {0}", alphaBits); + if (alphaBits >= 8) { + logger.log(Level.FINE, "Pixel Format: TRANSLUCENT"); + view.getHolder().setFormat(PixelFormat.TRANSLUCENT); view.setZOrderOnTop(true); + } else if (alphaBits >= 1) { + logger.log(Level.FINE, "Pixel Format: TRANSPARENT"); + view.getHolder().setFormat(PixelFormat.TRANSPARENT); + } else { + logger.log(Level.FINE, "Pixel Format: OPAQUE"); + view.getHolder().setFormat(PixelFormat.OPAQUE); } + + AndroidConfigChooser configChooser = new AndroidConfigChooser(settings); + view.setEGLConfigChooser(configChooser); + view.setRenderer(this); return view; } + /** + * Get the OpenGL ES version + * @return version returns the int value of the GLES version + */ + public int getOpenGLESVersion() { + ActivityManager am = + (ActivityManager) JmeAndroidSystem.getActivity().getApplication().getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + logger.log(Level.FINE, "OpenGL Version {0}:", info.getGlEsVersion()); + return info.reqGlEsVersion; +// return (info.reqGlEsVersion >= 0x20000); + } // renderer:initialize @Override @@ -218,10 +222,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex } }); - if (clientOpenGLESVersion < 2) { - throw new UnsupportedOperationException("OpenGL ES 2.0 is not supported on this device"); - } - timer = new AndroidTimer(); renderer = new OGLESShaderRenderer(); @@ -405,10 +405,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex } } - public int getClientOpenGLESVersion() { - return clientOpenGLESVersion; - } - public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) { logger.log(Level.FINE, "requestDialog: title: {0}, initialValue: {1}", new Object[]{title, initialValue});