Android : MultiSampling is now supported on android

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10460 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent fc96e52a4c
commit 1d7a631430
  1. 4
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 298
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java

@ -68,7 +68,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
/** /**
* set to 2, 4 to enable multisampling. * set to 2, 4 to enable multisampling.
*/ */
// protected int antiAliasingSamples = 0; protected int antiAliasingSamples = 0;
/** /**
* If true Android Sensors are used as simulated Joysticks Users can use the * If true Android Sensors are used as simulated Joysticks Users can use the
* Android sensor feedback through the RawInputListener or by registering * Android sensor feedback through the RawInputListener or by registering
@ -193,7 +193,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
settings.setEmulateMouse(mouseEventsEnabled); settings.setEmulateMouse(mouseEventsEnabled);
settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY); settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY);
settings.setUseJoysticks(joystickEventsEnabled); settings.setUseJoysticks(joystickEventsEnabled);
// settings.setSamples(antiAliasingSamples); settings.setSamples(antiAliasingSamples);
settings.setResolution(disp.getWidth(), disp.getHeight()); settings.setResolution(disp.getWidth(), disp.getHeight());
settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, eglConfigType); settings.put(AndroidConfigChooser.SETTINGS_CONFIG_TYPE, eglConfigType);

@ -34,9 +34,10 @@ public class AndroidConfigChooser implements EGLConfigChooser {
*/ */
FASTEST(5, 6, 5, 0, 16, 0, 5, 6, 5, 0, 16, 0), FASTEST(5, 6, 5, 0, 16, 0, 5, 6, 5, 0, 16, 0),
/** /**
* RGB???, 0 alpha, >=16 depth, 0 stencil * min RGB888, 0 alpha, 16 depth, 0 stencil max RGB888, 0 alpha, 32
* depth, 8 stencil
*/ */
BEST(8, 8, 8, 0, 32, 0, 8, 8, 8, 0, 16, 0), BEST(8, 8, 8, 0, 32, 8, 8, 8, 8, 0, 16, 0),
/** /**
* Turn off config chooser and use hardcoded * Turn off config chooser and use hardcoded
* setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16, * setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16,
@ -44,17 +45,18 @@ public class AndroidConfigChooser implements EGLConfigChooser {
*/ */
LEGACY(5, 6, 5, 0, 16, 0, 5, 6, 5, 0, 16, 0), LEGACY(5, 6, 5, 0, 16, 0, 5, 6, 5, 0, 16, 0),
/** /**
* RGB???, 8 alpha, >=16 depth, 0 stencil * min RGB888, 8 alpha, 16 depth, 0 stencil max RGB888, 8 alpha, 32
* depth, 8 stencil
*/ */
BEST_TRANSLUCENT(8, 8, 8, 8, 32, 0, 8, 8, 8, 8, 16, 0); BEST_TRANSLUCENT(8, 8, 8, 8, 32, 8, 8, 8, 8, 8, 16, 0);
/** /**
* red, green, blue, alpha, depth, stencil * red, green, blue, alpha, depth, stencil (max values)
*/ */
int r, g, b, a, d, s; int r, g, b, a, d, s;
/** /**
* fallback * minimal values
*/ */
int fbr, fbg, fbb, fba, fbd, fbs; int mr, mg, mb, ma, md, ms;
private ConfigType(int r, int g, int b, int a, int d, int s, int fbr, int fbg, int fbb, int fba, int fbd, int fbs) { private ConfigType(int r, int g, int b, int a, int d, int s, int fbr, int fbg, int fbb, int fba, int fbd, int fbs) {
this.r = r; this.r = r;
@ -63,12 +65,12 @@ public class AndroidConfigChooser implements EGLConfigChooser {
this.a = a; this.a = a;
this.d = d; this.d = d;
this.s = s; this.s = s;
this.fbr = fbr; this.mr = fbr;
this.fbg = fbg; this.mg = fbg;
this.fbb = fbb; this.mb = fbb;
this.fba = fba; this.ma = fba;
this.fbd = fbd; this.md = fbd;
this.fbs = fbs; this.ms = fbs;
} }
} }
@ -104,45 +106,15 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @param display * @param display
* @return true if successfull, false if no config was found * @return true if successfull, false if no config was found
*/ */
public boolean findConfig(EGL10 egl, EGLDisplay display) { public boolean findConfig(EGL10 egl, EGLDisplay display) {
ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE); ConfigType type = (ConfigType) settings.get(SETTINGS_CONFIG_TYPE);
ComponentSizeChooser compChooser = new ComponentSizeChooser(type.r, type.g, type.b, type.a, type.d, type.s, 4,1,2); ComponentSizeChooser compChooser = new ComponentSizeChooser(type, settings.getSamples());
choosenConfig = compChooser.chooseConfig(egl, display); choosenConfig = compChooser.chooseConfig(egl, display);
if (choosenConfig == null) {
compChooser = new ComponentSizeChooser(type.fbr, type.fbg, type.fbb, type.fba, type.fbd, type.fbs);
choosenConfig = compChooser.chooseConfig(egl, display);
}
logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name()); logger.log(Level.FINE, "JME3 using {0} EGL configuration available here: ", type.name());
// switch (type) {
// case BEST:
// compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0);
// choosenConfig = compChooser.chooseConfig(egl, display);
// if (choosenConfig == null) {
// compChooser = new ComponentSizeChooser(8, 8, 8, 0, 16, 0);
// choosenConfig = compChooser.chooseConfig(egl, display);
// }
// logger.fine("JME3 using best EGL configuration available here: ");
// break;
// case BEST_TRANSLUCENT:
// compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);
// choosenConfig = compChooser.chooseConfig(egl, display);
// if (choosenConfig == null) {
// compChooser = new ComponentSizeChooser(8, 8, 8, 8, 16, 0);
// choosenConfig = compChooser.chooseConfig(egl, display);
// }
// logger.fine("JME3 using best EGL configuration available here with translucent pixels: ");
// break;
// case FASTEST:
// compChooser = new ComponentSizeChooser(5, 6, 5, 0, 16, 0);
// choosenConfig = compChooser.chooseConfig(egl, display);
// logger.fine("JME3 using fastest EGL configuration available here: ");
// break;
//
// }
if (choosenConfig != null) { if (choosenConfig != null) {
logger.fine("JME3 using choosen config: "); logger.info("JME3 using choosen config: ");
logEGLConfig(choosenConfig, display, egl); logEGLConfig(choosenConfig, display, egl);
pixelFormat = getPixelFormat(choosenConfig, display, egl); pixelFormat = getPixelFormat(choosenConfig, display, egl);
clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl); clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
@ -197,34 +169,34 @@ public class AndroidConfigChooser implements EGLConfigChooser {
int[] value = new int[1]; int[] value = new int[1];
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
logger.fine(String.format("EGL_RED_SIZE = %d", value[0])); logger.info(String.format("EGL_RED_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
logger.fine(String.format("EGL_GREEN_SIZE = %d", value[0])); logger.info(String.format("EGL_GREEN_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
logger.fine(String.format("EGL_BLUE_SIZE = %d", value[0])); logger.info(String.format("EGL_BLUE_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
logger.fine(String.format("EGL_ALPHA_SIZE = %d", value[0])); logger.info(String.format("EGL_ALPHA_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
logger.fine(String.format("EGL_DEPTH_SIZE = %d", value[0])); logger.info(String.format("EGL_DEPTH_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
logger.fine(String.format("EGL_STENCIL_SIZE = %d", value[0])); logger.info(String.format("EGL_STENCIL_SIZE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
logger.fine(String.format("EGL_RENDERABLE_TYPE = %d", value[0])); logger.info(String.format("EGL_RENDERABLE_TYPE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
logger.fine(String.format("EGL_SURFACE_TYPE = %d", value[0])); logger.info(String.format("EGL_SURFACE_TYPE = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLE_BUFFERS, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLE_BUFFERS, value);
logger.fine(String.format("EGL_SAMPLE_BUFFERS = %d", value[0])); logger.info(String.format("EGL_SAMPLE_BUFFERS = %d", value[0]));
egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLES, value); egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLES, value);
logger.fine(String.format("EGL_SAMPLES = %d", value[0])); logger.info(String.format("EGL_SAMPLES = %d", value[0]));
} }
public int getClientOpenGLESVersion() { public int getClientOpenGLESVersion() {
@ -241,78 +213,34 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private abstract class BaseConfigChooser implements EGLConfigChooser { private abstract class BaseConfigChooser implements EGLConfigChooser {
private boolean bClientOpenGLESVersionSet; public BaseConfigChooser() {
public BaseConfigChooser(int[] configSpec) {
bClientOpenGLESVersionSet = false;
mConfigSpec = filterConfigSpec(configSpec);
} }
@Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
int[] num_config = new int[1];
if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
num_config)) {
throw new IllegalArgumentException("eglChooseConfig failed");
}
int numConfigs = num_config[0]; int[] num_config = new int[1];
int[] configSpec = new int[]{
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE};
if (numConfigs <= 0) { egl.eglChooseConfig(display, configSpec, null, 0, num_config);
//throw new IllegalArgumentException("No configs match configSpec");
return null;
}
int numConfigs = num_config[0];
EGLConfig[] configs = new EGLConfig[numConfigs]; EGLConfig[] configs = new EGLConfig[numConfigs];
if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, egl.eglChooseConfig(display, configSpec, configs, numConfigs, num_config);
num_config)) {
throw new IllegalArgumentException("eglChooseConfig#2 failed"); // System.err.println("-----------------------------");
} // for (EGLConfig eGLConfig : configs) {
// logger.log(Level.FINE, "num_config: {0}", num_config[0]); // logEGLConfig(eGLConfig, display, egl);
//
// logger.log(Level.FINE, "There are {0} configurations that match the configAttrs", num_config[0]);
// logger.log(Level.FINE, "All Matching Configs:");
// for (int i=0; i<configs.length; i++) {
// if (configs[i] != null) {
// logger.log(Level.FINE, "configs{0} is not null", i);
// logEGLConfig(configs[i], display, egl);
// } else {
// logger.log(Level.FINE, "configs{0} is null", i);
// }
// } // }
EGLConfig config = chooseConfig(egl, display, configs); EGLConfig config = chooseConfig(egl, display, configs);
//if (config == null) {
// throw new IllegalArgumentException("No config chosen");
//}
return config; return config;
} }
abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
EGLConfig[] configs); EGLConfig[] configs);
protected int[] mConfigSpec;
private int[] filterConfigSpec(int[] configSpec) {
if (bClientOpenGLESVersionSet == true) {
return configSpec;
}
/*
* We know none of the subclasses define EGL_RENDERABLE_TYPE. And we
* know the configSpec is well formed.
*/
int len = configSpec.length;
int[] newConfigSpec = new int[len + 2];
System.arraycopy(configSpec, 0, newConfigSpec, 0, len - 1);
newConfigSpec[len - 1] = EGL10.EGL_RENDERABLE_TYPE;
newConfigSpec[len] = 4; /*
* EGL_OPENGL_ES2_BIT
*/
newConfigSpec[len + 1] = EGL10.EGL_NONE;
bClientOpenGLESVersionSet = true;
return newConfigSpec;
}
} }
/** /**
@ -322,66 +250,47 @@ public class AndroidConfigChooser implements EGLConfigChooser {
private class ComponentSizeChooser extends BaseConfigChooser { private class ComponentSizeChooser extends BaseConfigChooser {
private int[] mValue; private int[] mValue;
// Subclasses can adjust these values: private ConfigType configType;
protected int mRedSize;
protected int mGreenSize;
protected int mBlueSize;
protected int mAlphaSize;
protected int mDepthSize;
protected int mStencilSize;
protected int mRenderableType;
protected int mSampleBuffers;
protected int mSamples; protected int mSamples;
public ComponentSizeChooser(int redSize, int greenSize, int blueSize, // public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
int alphaSize, int depthSize, int stencilSize) { // int alphaSize, int depthSize, int stencilSize, int samples) {
super(new int[]{ // super(new int[]{
EGL10.EGL_RED_SIZE, redSize, // EGL10.EGL_RED_SIZE, redSize,
EGL10.EGL_GREEN_SIZE, greenSize, // EGL10.EGL_GREEN_SIZE, greenSize,
EGL10.EGL_BLUE_SIZE, blueSize, // EGL10.EGL_BLUE_SIZE, blueSize,
EGL10.EGL_ALPHA_SIZE, alphaSize, // EGL10.EGL_ALPHA_SIZE, alphaSize,
EGL10.EGL_DEPTH_SIZE, depthSize, // EGL10.EGL_DEPTH_SIZE, depthSize,
EGL10.EGL_STENCIL_SIZE, stencilSize, // EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE}); // EGL10.EGL_SAMPLE_BUFFERS, TRUE,
mValue = new int[1]; // EGL10.EGL_SAMPLES, samples,
mRedSize = redSize; // EGL10.EGL_NONE});
mGreenSize = greenSize; // mValue = new int[1];
mBlueSize = blueSize; // mRedSize = redSize;
mAlphaSize = alphaSize; // mGreenSize = greenSize;
mDepthSize = depthSize; // mBlueSize = blueSize;
mStencilSize = stencilSize; // mAlphaSize = alphaSize;
} // mDepthSize = depthSize;
// mStencilSize = stencilSize;
public ComponentSizeChooser(int redSize, int greenSize, int blueSize, // mSamples = samples;
int alphaSize, int depthSize, int stencilSize, int renderableType, int sampleBuffers, int samples) { // }
super(new int[]{ public ComponentSizeChooser(ConfigType configType, int samples) {
EGL10.EGL_RED_SIZE, redSize,
EGL10.EGL_GREEN_SIZE, greenSize,
EGL10.EGL_BLUE_SIZE, blueSize,
EGL10.EGL_ALPHA_SIZE, alphaSize,
EGL10.EGL_DEPTH_SIZE, depthSize,
EGL10.EGL_STENCIL_SIZE, stencilSize,
EGL10.EGL_RENDERABLE_TYPE, renderableType,
EGL10.EGL_SAMPLE_BUFFERS, sampleBuffers,
EGL10.EGL_SAMPLES, samples,
EGL10.EGL_NONE});
mValue = new int[1]; mValue = new int[1];
mRedSize = redSize;
mGreenSize = greenSize;
mBlueSize = blueSize;
mAlphaSize = alphaSize;
mDepthSize = depthSize;
mStencilSize = stencilSize;
mRenderableType = renderableType;
mSampleBuffers = sampleBuffers;
mSamples = samples; mSamples = samples;
this.configType = configType;
} }
@Override @Override
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) { 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. // first pass through config list. Try to find an exact match.
for (EGLConfig config : configs) { for (EGLConfig config : configs) {
// logEGLConfig(config, display, egl);
int r = findConfigAttrib(egl, display, config, int r = findConfigAttrib(egl, display, config,
EGL10.EGL_RED_SIZE, 0); EGL10.EGL_RED_SIZE, 0);
int g = findConfigAttrib(egl, display, config, int g = findConfigAttrib(egl, display, config,
@ -394,36 +303,49 @@ public class AndroidConfigChooser implements EGLConfigChooser {
EGL10.EGL_DEPTH_SIZE, 0); EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config, int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0); 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);
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 = false;
//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 ((r == mRedSize) && (g == mGreenSize) if (mSamples != 0) {
&& (b == mBlueSize) && (a == mAlphaSize) if (nbMs >= knbMs && nbMs <= mSamples) {
&& (d == mDepthSize) && (s == mStencilSize)) { knbMs = nbMs;
return config; keep = true;
} else {
keep = false;
}
}
if (keep) {
keptConfig = config;
}
} }
} }
// second pass through config list. Try to find an RGBA match. if (keptConfig != null) {
for (EGLConfig config : configs) { return keptConfig;
int d = findConfigAttrib(egl, display, config,
EGL10.EGL_DEPTH_SIZE, 0);
int s = findConfigAttrib(egl, display, config,
EGL10.EGL_STENCIL_SIZE, 0);
if ((d >= mDepthSize) && (s >= mStencilSize)) {
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);
if ((r == mRedSize) && (g == mGreenSize)
&& (b == mBlueSize) && (a == mAlphaSize)) {
return config;
}
}
} }
// failsafe. pick the 1st config. // failsafe. pick the 1st config.
if (configs.length > 0) { if (configs.length > 0) {
return configs[0]; return configs[0];
@ -433,6 +355,10 @@ 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, private int findConfigAttrib(EGL10 egl, EGLDisplay display,
EGLConfig config, int attribute, int defaultValue) { EGLConfig config, int attribute, int defaultValue) {

Loading…
Cancel
Save