diff --git a/engine/src/android/com/jme3/app/AndroidHarness.java b/engine/src/android/com/jme3/app/AndroidHarness.java
index 965811f8d..708602c76 100644
--- a/engine/src/android/com/jme3/app/AndroidHarness.java
+++ b/engine/src/android/com/jme3/app/AndroidHarness.java
@@ -24,7 +24,6 @@ import com.jme3.input.event.TouchEvent;
import com.jme3.renderer.android.AndroidGLSurfaceView;
import com.jme3.system.AppSettings;
import com.jme3.system.SystemListener;
-import com.jme3.system.android.AndroidConfigChooser;
import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import com.jme3.system.android.JmeAndroidSystem;
import com.jme3.system.android.OGLESContext;
@@ -58,8 +57,51 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
/**
* ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is
* RGBA8888 or better if supported by the hardware
+ * @deprecated ConfigType has been deprecated. AppSettings are now used
+ * to determine the desired configuration to match how LWJGL is implemented.
+ * Use eglBitsPerPixel, eglAlphaBits, eglDepthBits, eglStencilBits in MainActivity to
+ * override the default values
+ * (default values: RGB888, 0 alpha bits, 16 bit depth, 0 stencil bits)
*/
- protected ConfigType eglConfigType = ConfigType.FASTEST;
+ @Deprecated
+ protected ConfigType eglConfigType = null;
+
+ /**
+ * Sets the desired RGB size for the surfaceview. 16 = RGB565, 24 = RGB888.
+ * (default = 24)
+ */
+ protected int eglBitsPerPixel = 24;
+
+ /**
+ * Sets the desired number of Alpha bits for the surfaceview. This affects
+ * how the surfaceview is able to display Android views that are located
+ * under the surfaceview jME uses to render the scenegraph.
+ * 0 = Opaque surfaceview background (fastest)
+ * 1->7 = Transparent surfaceview background
+ * 8 or higher = Translucent surfaceview background
+ * (default = 0)
+ */
+ protected int eglAlphaBits = 0;
+
+ /**
+ * The number of depth bits specifies the precision of the depth buffer.
+ * (default = 16)
+ */
+ protected int eglDepthBits = 16;
+
+ /**
+ * Sets the number of samples to use for multisampling.
+ * Leave 0 (default) to disable multisampling.
+ * Set to 2 or 4 to enable multisampling.
+ */
+ protected int eglSamples = 0;
+
+ /**
+ * Set the number of stencil bits.
+ * (default = 0)
+ */
+ protected int eglStencilBits = 0;
+
/**
* If true all valid and not valid egl configs are logged
* @deprecated this has no use
@@ -69,7 +111,9 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
/**
* set to 2, 4 to enable multisampling.
+ * @deprecated Use eglSamples
*/
+ @Deprecated
protected int antiAliasingSamples = 0;
/**
@@ -210,9 +254,41 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
settings.setEmulateMouse(mouseEventsEnabled);
settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY);
settings.setUseJoysticks(joystickEventsEnabled);
- settings.setSamples(antiAliasingSamples);
+ if (eglConfigType == null) {
+ logger.log(Level.FINE, "using new appsettings for eglConfig");
+ settings.setBitsPerPixel(eglBitsPerPixel);
+ settings.setAlphaBits(eglAlphaBits);
+ settings.setDepthBits(eglDepthBits);
+ settings.setSamples(eglSamples);
+ settings.setStencilBits(eglStencilBits);
+ } else {
+ logger.log(Level.FINE, "using old eglConfigType {0} for eglConfig", eglConfigType);
+ switch (eglConfigType) {
+ case BEST:
+ settings.setBitsPerPixel(24);
+ settings.setAlphaBits(0);
+ settings.setDepthBits(16);
+ settings.setStencilBits(0);
+ break;
+ case FASTEST:
+ case LEGACY:
+ settings.setBitsPerPixel(16);
+ settings.setAlphaBits(0);
+ settings.setDepthBits(16);
+ settings.setStencilBits(0);
+ break;
+ case BEST_TRANSLUCENT:
+ settings.setBitsPerPixel(24);
+ settings.setAlphaBits(8);
+ settings.setDepthBits(16);
+ settings.setStencilBits(0);
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid eglConfigType");
+ }
+ settings.setSamples(antiAliasingSamples);
+ }
settings.setResolution(disp.getWidth(), disp.getHeight());
- settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, eglConfigType);
settings.setAudioRenderer(audioRendererType);
diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
index 4c9de7a8c..0b143f479 100644
--- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
+++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
@@ -1,7 +1,5 @@
package com.jme3.system.android;
-import android.graphics.PixelFormat;
-import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.EGLConfigChooser;
import com.jme3.renderer.android.RendererUtil;
import com.jme3.system.AppSettings;
@@ -14,20 +12,16 @@ import javax.microedition.khronos.egl.EGLDisplay;
/**
* AndroidConfigChooser is used to determine the best suited EGL Config
*
- * @author larynx
+ * @author iwgeric
*/
public class AndroidConfigChooser implements EGLConfigChooser {
private static final Logger logger = Logger.getLogger(AndroidConfigChooser.class.getName());
- public final static String SETTINGS_CONFIG_TYPE = "configType";
- protected EGLConfig choosenConfig = null;
- protected EGLDisplay configForDisplay = null;
protected AppSettings settings;
- protected GLSurfaceView view;
- protected int pixelFormat;
- protected boolean verbose = false;
private final static int EGL_OPENGL_ES2_BIT = 4;
+
+ @Deprecated
public enum ConfigType {
/**
@@ -75,112 +69,249 @@ public class AndroidConfigChooser implements EGLConfigChooser {
}
}
- /**
- *
- * @param type
- * @deprecated use AndroidConfigChooser(AppSettings settings)
- */
- @Deprecated
- public AndroidConfigChooser(ConfigType type) {
- this.settings = new AppSettings(true);
- settings.put(SETTINGS_CONFIG_TYPE, type);
- }
-
public AndroidConfigChooser(AppSettings settings) {
this.settings = settings;
}
- public AndroidConfigChooser(AppSettings settings, GLSurfaceView view) {
- this(settings);
- this.view = view;
- }
-
- 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 asking for egl config");
- boolean configFound = findConfig(egl, display);
- if (configFound) {
+ Config requestedConfig = getRequestedConfig();
+ EGLConfig[] configs = getConfigs(egl, display);
+
+ // First try to find an exact match, but allowing a higher stencil
+ EGLConfig choosenConfig = chooseConfig(egl, display, configs, requestedConfig, false, false, false, true);
+ if (choosenConfig == null && requestedConfig.d > 16) {
+ logger.log(Level.INFO, "EGL configuration not found, reducing depth");
+ requestedConfig.d = 16;
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, false, false, false, true);
+ }
+
+ if (choosenConfig == null) {
+ logger.log(Level.INFO, "EGL configuration not found, allowing higher RGB");
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
+ }
+
+ if (choosenConfig == null && requestedConfig.a > 0) {
+ logger.log(Level.INFO, "EGL configuration not found, allowing higher alpha");
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
+ }
+
+ if (choosenConfig == null && requestedConfig.s > 0) {
+ logger.log(Level.INFO, "EGL configuration not found, allowing higher samples");
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, true, true);
+ }
+
+ if (choosenConfig == null && requestedConfig.a > 0) {
+ logger.log(Level.INFO, "EGL configuration not found, reducing alpha");
+ requestedConfig.a = 1;
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
+ }
+
+ if (choosenConfig == null && requestedConfig.s > 0) {
+ logger.log(Level.INFO, "EGL configuration not found, reducing samples");
+ requestedConfig.s = 1;
+ if (requestedConfig.a > 0) {
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, true, true);
+ } else {
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, true, true);
+ }
+ }
+
+ if (choosenConfig == null && requestedConfig.getBitsPerPixel() > 16) {
+ logger.log(Level.INFO, "EGL configuration not found, setting to RGB565");
+ requestedConfig.r = 5;
+ requestedConfig.g = 6;
+ requestedConfig.b = 5;
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
+
+ if (choosenConfig == null) {
+ logger.log(Level.INFO, "EGL configuration not found, allowing higher alpha");
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, true, false, true);
+ }
+ }
+
+ if (choosenConfig == null) {
+ logger.log(Level.INFO, "EGL configuration not found, looking for best config with >= 16 bit Depth");
+ //failsafe, should pick best config with at least 16 depth
+ requestedConfig = new Config(0, 0, 0, 0, 16, 0, 0);
+ choosenConfig = chooseConfig(egl, display, configs, requestedConfig, true, false, false, true);
+ }
+
+ if (choosenConfig != null) {
logger.fine("GLSurfaceView asks for egl config, returning: ");
logEGLConfig(choosenConfig, display, egl, Level.FINE);
- view.getHolder().setFormat(pixelFormat);
+
+ storeSelectedConfig(egl, display, choosenConfig);
return choosenConfig;
} else {
- logger.fine("GLSurfaceView asks for egl config, No config found");
+ logger.severe("No EGL Config found");
return null;
}
}
+ private Config getRequestedConfig() {
+ int r, g, b;
+ if (settings.getBitsPerPixel() == 24) {
+ r = g = b = 8;
+ } else {
+ if (settings.getBitsPerPixel() != 16) {
+ logger.log(Level.SEVERE, "Invalid bitsPerPixel setting: {0}, setting to RGB565 (16)", settings.getBitsPerPixel());
+ settings.setBitsPerPixel(16);
+ }
+ r = 5;
+ g = 6;
+ b = 5;
+ }
+ logger.log(Level.FINE, "Requested Display Config:");
+ logger.log(Level.FINE, "RGB: {0}, alpha: {1}, depth: {2}, samples: {3}, stencil: {4}",
+ new Object[]{settings.getBitsPerPixel(),
+ settings.getAlphaBits(), settings.getDepthBits(),
+ settings.getSamples(), settings.getStencilBits()});
+ return new Config(
+ r, g, b,
+ settings.getAlphaBits(),
+ settings.getDepthBits(),
+ settings.getSamples(),
+ settings.getStencilBits());
+ }
+
/**
- * findConfig is used to locate the best config and init the chooser with
- *
+ * Query egl for the available configs
* @param egl
* @param display
- * @return true if successfull, false if no config was found
+ * @return
*/
- private boolean findConfig(EGL10 egl, EGLDisplay display) {
- ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
+ private EGLConfig[] getConfigs(EGL10 egl, EGLDisplay display) {
- ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples());
- choosenConfig = compChooser.chooseConfig(egl, display);
- logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name());
+ int[] num_config = new int[1];
+ int[] configSpec = new int[]{
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE};
- if (choosenConfig != null) {
- // Remember the display for which we have the EGLConfig for
- configForDisplay = display;
- logger.info("JME3 using choosen config: ");
- logEGLConfig(choosenConfig, display, egl, Level.INFO);
- pixelFormat = getPixelFormat(choosenConfig, display, egl);
- if (pixelFormat == PixelFormat.TRANSLUCENT) {
- view.setZOrderOnTop(true);
- }
- 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.");
- pixelFormat = PixelFormat.UNKNOWN;
- return false;
+ 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];
+ if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config)) {
+ RendererUtil.checkEGLError(egl);
+ throw new AssertionError();
}
+
+ logger.fine("--------------Display Configurations---------------");
+ for (EGLConfig eGLConfig : configs) {
+ logEGLConfig(eGLConfig, display, egl, Level.FINE);
+ logger.fine("----------------------------------------");
+ }
+
+ return configs;
}
- private int getPixelFormat(EGLConfig conf, EGLDisplay display, EGL10 egl) {
- //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
- int result = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_ALPHA_SIZE);
+ private EGLConfig chooseConfig(
+ EGL10 egl, EGLDisplay display, EGLConfig[] configs, Config requestedConfig,
+ boolean higherRGB, boolean higherAlpha,
+ boolean higherSamples, boolean higherStencil) {
+
+ EGLConfig keptConfig = null;
+ int kr = 0;
+ int kg = 0;
+ int kb = 0;
+ int ka = 0;
+ int kd = 0;
+ int ks = 0;
+ int kst = 0;
+
+
+ // first pass through config list. Try to find an exact match.
+ for (EGLConfig config : configs) {
+ 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_SAMPLES);
+ int st = eglGetConfigAttribSafe(egl, display, config,
+ EGL10.EGL_STENCIL_SIZE);
+
+ logger.log(Level.FINE, "Checking Config r: {0}, g: {1}, b: {2}, alpha: {3}, depth: {4}, samples: {5}, stencil: {6}",
+ new Object[]{r, g, b, a, d, s, st});
+
+ if (higherRGB && r < requestedConfig.r) { continue; }
+ if (!higherRGB && r != requestedConfig.r) { continue; }
+
+ if (higherRGB && g < requestedConfig.g) { continue; }
+ if (!higherRGB && g != requestedConfig.g) { continue; }
+
+ if (higherRGB && b < requestedConfig.b) { continue; }
+ if (!higherRGB && b != requestedConfig.b) { continue; }
+
+ if (higherAlpha && a < requestedConfig.a) { continue; }
+ if (!higherAlpha && a != requestedConfig.a) { continue; }
+
+ if (d < requestedConfig.d) { continue; } // always allow higher depth
+
+ if (higherSamples && s < requestedConfig.s) { continue; }
+ if (!higherSamples && s != requestedConfig.s) { continue; }
+
+ if (higherStencil && st < requestedConfig.st) { continue; }
+ if (!higherStencil && !inRange(st, 0, requestedConfig.st)) { continue; }
+
+ //we keep the config if it is better
+ if ( r >= kr || g >= kg || b >= kb || a >= ka ||
+ d >= kd || s >= ks || st >= kst ) {
+ kr = r; kg = g; kb = b; ka = a;
+ kd = d; ks = s; kst = st;
+ keptConfig = config;
+ logger.log(Level.FINE, "Keeping Config r: {0}, g: {1}, b: {2}, alpha: {3}, depth: {4}, samples: {5}, stencil: {6}",
+ new Object[]{r, g, b, a, d, s, st});
+ }
- if (result >= 8) {
- logger.log(Level.FINE, "Pixel Format: TRANSLUCENT");
- return PixelFormat.TRANSLUCENT;
}
- if (result >= 1) {
- logger.log(Level.FINE, "Pixel Format: TRANSPARENT");
- return PixelFormat.TRANSPARENT;
+
+ if (keptConfig != null) {
+ return keptConfig;
}
- logger.log(Level.FINE, "Pixel Format: OPAQUE");
- return PixelFormat.OPAQUE;
+ //no match found
+ logger.log(Level.SEVERE, "No egl config match found");
+ return null;
}
- private int getOpenGLVersion(EGLConfig conf, EGLDisplay display, EGL10 egl) {
- int val = eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_RENDERABLE_TYPE);
- // Check if conf is OpenGL ES 2.0
- if ((val & EGL_OPENGL_ES2_BIT) != 0) {
- return 2;
- } else {
- return 1;
+ 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];
+ }
+
+ private void storeSelectedConfig(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
+ int r = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_RED_SIZE);
+ int g = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_GREEN_SIZE);
+ int b = eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_BLUE_SIZE);
+ settings.setBitsPerPixel(r+g+b);
+
+ settings.setAlphaBits(
+ eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_ALPHA_SIZE));
+ settings.setDepthBits(
+ eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_DEPTH_SIZE));
+ settings.setSamples(
+ eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_SAMPLES));
+ settings.setStencilBits(
+ eglGetConfigAttribSafe(egl, display, eglConfig, EGL10.EGL_STENCIL_SIZE));
}
/**
@@ -223,161 +354,31 @@ public class AndroidConfigChooser implements EGLConfigChooser {
eglGetConfigAttribSafe(egl, display, conf, EGL10.EGL_SAMPLES));
}
- private abstract class BaseConfigChooser implements EGLConfigChooser {
-
- public BaseConfigChooser() {
- }
-
- @Override
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
-
- int[] num_config = new int[1];
- int[] configSpec = new int[]{
- EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL10.EGL_NONE};
-
- 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];
- if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config)) {
- RendererUtil.checkEGLError(egl);
- throw new AssertionError();
- }
-
- logger.fine("--------------Display Configurations---------------");
- for (EGLConfig eGLConfig : configs) {
- logEGLConfig(eGLConfig, display, egl, Level.FINE);
- logger.fine("----------------------------------------");
- }
-
- EGLConfig config = chooseConfig(egl, display, configs);
- return config;
- }
-
- abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
- EGLConfig[] configs);
+ private boolean inRange(int val, int min, int max) {
+ return min <= val && val <= max;
}
- /**
- * Choose a configuration with exactly the specified r,g,b,a sizes, and at
- * least the specified depth and stencil sizes.
- */
- private class ComponentSizeChooser extends BaseConfigChooser {
-
- private ConfigType configType;
- protected int mSamples;
-
- public ComponentSizeChooser(ConfigType configType, int samples) {
- mSamples = samples;
- this.configType = configType;
- }
-
- @Override
- public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
-
- EGLConfig keptConfig = null;
- int kd = 0;
- int knbMs = 0;
-
-
- // first pass through config list. Try to find an exact match.
- for (EGLConfig config : configs) {
- 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)
- && inRange(b, configType.mb, configType.b)
- && inRange(a, configType.ma, configType.a)
- && inRange(d, configType.md, configType.d)
- && inRange(s, configType.ms, configType.s)) {
- if (mSamples == 0 && isMs != 0) {
- continue;
- }
- boolean keep;
- //we keep the config if the depth is better or if the AA setting is better
- if (d >= kd) {
- kd = d;
- keep = true;
- } else {
- keep = false;
- }
-
- if (mSamples != 0) {
- if (nbMs >= knbMs && nbMs <= mSamples) {
- knbMs = nbMs;
- keep = true;
- } else {
- keep = false;
- }
- }
-
- if (keep) {
- keptConfig = config;
- }
- }
- }
-
- if (keptConfig != null) {
- return keptConfig;
- }
-
- if (configType == ConfigType.BEST) {
- logger.log(Level.WARNING, "Failed to find a suitable display configuration for BEST, attempting BEST_TRANSLUCENT");
- configType = ConfigType.BEST_TRANSLUCENT;
- keptConfig = chooseConfig(egl, display, configs);
- if (keptConfig != null) {
- return keptConfig;
- }
- }
-
- if (configType == ConfigType.BEST_TRANSLUCENT) {
- logger.log(Level.WARNING, "Failed to find a suitable display configuration for BEST_TRANSLUCENT, attempting FASTEST");
- configType = ConfigType.FASTEST;
- keptConfig = chooseConfig(egl, display, configs);
-
- if (keptConfig != null) {
- 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 = eglGetConfigAttribSafe(egl, display, config,
- EGL10.EGL_DEPTH_SIZE);
- if (d >= 16) {
- return config;
- }
- }
+ private class Config {
+ /**
+ * red, green, blue, alpha, depth, samples, stencil
+ */
+ int r, g, b, a, d, s, st;
- //nothing much we can do...
- return null;
+ private Config(int r, int g, int b, int a, int d, int s, int st) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.a = a;
+ this.d = d;
+ this.s = s;
+ this.st = st;
}
- private boolean inRange(int val, int min, int max) {
- return min <= val && val <= max;
+ private int getBitsPerPixel() {
+ return r+g+b;
}
}
+
//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 aab8561fe..cbd5e8d04 100644
--- a/engine/src/android/com/jme3/system/android/OGLESContext.java
+++ b/engine/src/android/com/jme3/system/android/OGLESContext.java
@@ -37,9 +37,9 @@ 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;
@@ -52,11 +52,8 @@ 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;
@@ -102,33 +99,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
* GLSurfaceView. Only one GLSurfaceView can be created at this time. The
* given configType specifies how to determine the display configuration.
*
- *
- * @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
- * ConfigType.BEST
- * @param eglConfigVerboseLogging if true show all found configs
- * @return GLSurfaceView The newly created view
- * @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();
- }
- /**
- * 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. - * - * - * @param eglConfigVerboseLogging if true show all found configs * @return GLSurfaceView The newly created view */ public AndroidGLSurfaceView createView() { AndroidGLSurfaceView view; - ConfigType configType = (ConfigType)settings.get(AndroidConfigChooser.SETTINGS_CONFIG_TYPE); // Start to set up the view view = new AndroidGLSurfaceView(JmeAndroidSystem.getActivity().getApplication()); @@ -138,9 +112,11 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex androidInput.setView(view); androidInput.loadSettings(settings); + // setEGLContextClientVersion must be set before calling setRenderer + // this means it cannot be set in AndroidConfigChooser (too late) int rawOpenGLESVersion = getOpenGLESVersion(); - logger.log(Level.FINE, "clientOpenGLESVersion {0}.{1}", - new Object[]{clientOpenGLESVersion>>16, clientOpenGLESVersion<<16}); +// 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 { @@ -152,9 +128,29 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex view.setFocusable(true); view.getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); - AndroidConfigChooser configChooser = new AndroidConfigChooser(settings, view); - view.setEGLConfigChooser(configChooser); + // 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 curAlphaBits = settings.getAlphaBits(); + logger.log(Level.FINE, "curAlphaBits: {0}", curAlphaBits); + if (curAlphaBits >= 8) { + logger.log(Level.FINE, "Pixel Format: TRANSLUCENT"); + view.getHolder().setFormat(PixelFormat.TRANSLUCENT); + view.setZOrderOnTop(true); + } else if (curAlphaBits >= 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;