Android: Rewrite of EGL config chooser. ConfigType is also now deprecated so that egl* protected parameters in AndroidHarness can be used. These new parameters are copied into AppSettings and then used in AndroidConfigChooser to define the minimum requirements for selecting an appropriate egl config. If a different config is choosen, the AppSettings are updated so users can detect the currently used values.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10810 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
iwg..ic 11 years ago
parent c1c9fc871a
commit 592303181e
  1. 84
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 459
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
  3. 58
      engine/src/android/com/jme3/system/android/OGLESContext.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.</br>
* Leave 0 (default) to disable multisampling.</br>
* 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);

@ -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 {
//

@ -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();
}
/**
* <code>createView</code> creates the GLSurfaceView that the renderer will
* draw to. <p> 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;

Loading…
Cancel
Save