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;