Antialiasing (Android)

The general goal of this change is to add openGL multisampling to AndroidConfigChooser for android devices that have that capability. We just need to request a hardware openGL context that has multisampling enabled.

In our game, we saw a pretty large improvement in visual quality of the models after enabling multisampling. There are many Android devices that don’t have this capability, but for those that do, it’s pretty nice.

Here’s some example code from Android GDC 2011 that does basically this.

In our current jME branch, we added MULTISAMPLE as a new enum configuration value, to keep the change fairly conservative. Alternately, support for multisampling could be added to the “BEST” configuration for the enum. Thoughts?

For jME, The AndroidConfigChooser.ConfigType enum with antialiasing could look like this:

[java]public enum ConfigType {

    /**
     * RGB565, 0 alpha, 16 depth, 0 stencil
     */
    FASTEST,
    /**
     * RGB???, 0 alpha, >=16 depth, 0 stencil
     */
    BEST,
    /**
     * Turn off config chooser and use hardcoded
     * setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16,
     * 0);
     */
    LEGACY,
	/**
     * RGB???, 8 alpha, >=16 depth, 0 stencil
     */
	BEST_TRANSLUCENT,
    /*
     * RGB???, 0 alpha, >=16 depth, 0 stencil, up to 4 samples for antialiasing
     */
    MULTISAMPLE
}[/java] 

Here’s the new ComponentSizeChooser with the EGL calls to check for multisampling.

You can see that i’ve added EGL_RENDERABLE_TYPE, EGL_SAMPLE_BUFFERS, and EGL_SAMPLES to the configuration request.
[java]
//this chooser has multisampling included
public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
int alphaSize, int depthSize, int stencilSize, int renderableType, int sampleBuffers, int samples) {
super(new int[]{
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];
mRedSize = redSize;
mGreenSize = greenSize;
mBlueSize = blueSize;
mAlphaSize = alphaSize;
mDepthSize = depthSize;
mStencilSize = stencilSize;
mRenderableType = renderableType;
mSampleBuffers = sampleBuffers;
mSamples = samples;
}[/java]

Here is an example configuration request that checks for 4 samples of multisampling:

[java]new ComponentSizeChooser(8, 8, 8, 8, 16, 0, 4, 1, 4);[/java]

2 samples:
[java]new ComponentSizeChooser(8, 8, 8, 8, 16, 0, 4, 1, 2);[/java]

If no configuration is found, the code falls back to the previous “BEST” configuration types.

In a configuration that did not request multisampling, renderableType, sampleBuffers, and samples would be 0.

Also, I added multisampling to the logging so that we can see what is going on.
[java] public void logEGLConfig(EGLConfig conf, EGLDisplay display, EGL10 egl) {
int[] value = new int[1];

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RED_SIZE, value);
    logger.info(String.format("EGL_RED_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_GREEN_SIZE, value);
    logger.info(String.format("EGL_GREEN_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_BLUE_SIZE, value);
    logger.info(String.format("EGL_BLUE_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_ALPHA_SIZE, value);
    logger.info(String.format("EGL_ALPHA_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_DEPTH_SIZE, value);
    logger.info(String.format("EGL_DEPTH_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_STENCIL_SIZE, value);
    logger.info(String.format("EGL_STENCIL_SIZE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_RENDERABLE_TYPE, value);
    logger.info(String.format("EGL_RENDERABLE_TYPE  = %d", value[0]));

    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SURFACE_TYPE, value);
    logger.info(String.format("EGL_SURFACE_TYPE  = %d", value[0]));
    
    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLE_BUFFERS, value);
    logger.info(String.format("EGL_SAMPLE_BUFFERS  = %d", value[0]));
    
    egl.eglGetConfigAttrib(display, conf, EGL10.EGL_SAMPLES, value);
    logger.info(String.format("EGL_SAMPLES  = %d", value[0]));
}[/java] 

I can work on a full AndroidConfigChooser patch once I get my dev environment set up to test jme nightly, otherwise this should be enough for someone to integrate multisampling into the current jme, if they were motivated :slight_smile:

6 Likes

Thanks a lot!

Is there a fallback if the device doesn’t support multisampling? It might be a good idea to have is enable and determine if the device can support it. If not then go do a default configType like FASTEST.

I seems pretty cool and I will try to add multisampling to my project.

Thanks

There is already a fall back as mentioned in the first post

If no configuration is found, the code falls back to the previous “BEST” configuration types

I’ve just committed a change for anti aliasing support on android.
I didn’t go the exact same way, and kept anti aliasing separated from config types.

You are now able to set antialiasing number of samples in the MainActivity by setting the antiAliasingSamples variable to the requested value (2 or 4…don’t expect much more until the next phone generation)
so foe example you can try the Fastest config with 4x anti aliasing, the system will try to find a suitable configuration. It’ll fall back to AA 2x if it can’t find 4x and fall back to no AA if 2x is not found.

Also, doing this I noticed that our configChooser was kind of flawed and it was not really choosing the Best configuration when Best was requested.
So i changed the algorithm a bit, and now you should really have the best one if you request it.

I think I’ll change this system anyway in the future, so one can choose a bit more precisely what kind of display support he needs.

So in short we now have anti Aliasing support on android, thanks to @ericnon

2 Likes

Sweet, that sounds like a more flexible approach. I’ll be sure to try it out :slight_smile:

1 Like