FadeFilter causes crash on Android (Samsung Galaxy S4)

Hey there!

I’m building an Android app using the v3.1-alpha1 linux-x64 build of the jME SDK, and I noticed that I get the following stack trace as soon as I add a FadeFilter to the FilterPostProcessor (e.g. fpp.addFilter(new FadeFilter(1.5f)); ):

W/dalvikvm(25598): threadid=11: thread exiting with uncaught exception (group=0x4162cce0)
E/com.jme3.app.AndroidHarnessFragment(25598): SEVERE Exception thrown in Thread[GLThread 9702,5,main]
E/com.jme3.app.AndroidHarnessFragment(25598): java.lang.IllegalStateException: Framebuffer object format is unsupported by the video hardware.
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.renderer.opengl.GLRenderer.checkFrameBufferError(GLRenderer.java:1340)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.renderer.opengl.GLRenderer.updateFrameBuffer(GLRenderer.java:1488)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.renderer.opengl.GLRenderer.setFrameBuffer(GLRenderer.java:1577)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1005)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.renderer.RenderManager.render(RenderManager.java:1078)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.app.SimpleApplication.update(SimpleApplication.java:260)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:577)
E/com.jme3.app.AndroidHarnessFragment(25598):     at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:336)
E/com.jme3.app.AndroidHarnessFragment(25598):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1525)
E/com.jme3.app.AndroidHarnessFragment(25598):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1242)
E/com.jme3.app.AndroidHarnessFragment(25598):

This happens on my Samsung Galaxy S4 running a JFLTE CyanogenMod nightly (20150524).

I found some older posts talking about similar stack traces (I had to segment the links due to the link limit of 2 per post for new users):

http:// Framebuffer object format is unsupported by the video hardware
http:// Framebuffer object format is unsupported by the video hardware
http:// Framebuffer object format not supported

As well as a related thread about 3089 on indieDB: http://www.indiedb.com/games/3089/forum/thread/crash-on-start-v0123b

Given that those threads lead to the suspicion of graphics drivers not supporting non-power-of-two textures, I’m guessing that there’s probably not too much I can do about this, and that the best option may be refraining from their use altogether since I can’t guarantee users’ phones will support it.

Thoughts?

Thanks,
Brandon

…use small texture (Picture) of size (128x128), solid color of choice, and simply have it scaled to fill full screen and change transparency, will do fade in/out job …

1 Like

the FilterPostPorcessor was not done with android in mind tbh, and usually any filter need so much fill rate that it’s usually a no go on android devices.
Now about that issue… If the device doesn’t support non power of 2 textures, there is no way the FPP will work.
What you can do is to detect the support of non power of two and enable disable the FPP accordingly.

@Ecco’s solution sounds pretty good too… you could even have just a quad that takes all the screen in the gui viewport and in the transparent bucket and just play with the alpha value of it’s color… that’s pretty much what the filter does except here there would be no texture involved.

2 Likes

Thanks for the replies! Those solutions are similar to what I quickly implemented as a replacement, but it’s good to have confirmation.

@nehon Cool, I’ll probably do a little more experimenting down the line and abstract out the use of Filters or replacements when the texture_non_power_of_two extension isn’t available.

Probably related to this change:

When using gamma correction, banding could occur due to low precision in the format. However there’s no way of overriding this choice when not using gamma correction.

Essentially adding support for gamma correction caused all filters to become incompatible with Android.

mhh…
I guess we can check if the format is supported and if not fall back to classic rgba8

For future forum-goers who may find this useful, this was the solution I went with.

First initialize the Geometry and Material (make sure to set it’s blend mode to alpha):

    private void initFade() {
        Camera guiCam = app.getGuiViewPort().getCamera();

        Quad fadeQuad = new Quad(guiCam.getWidth(), guiCam.getHeight());
        Geometry fadeLayer = new Geometry("TransitionFade", fadeQuad);

        Material fadeMat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
        fadeMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
        fadeLayer.setMaterial(fadeMat);
        
        fadeColor = new ColorRGBA(0, 0, 0, 1);
        fadeMat.setColor("Color", fadeColor);

        app.getGuiNode().attachChild(fadeLayer);
    }

And then simply set the alpha of the material color when animating the transition in the update loop:

fadeColor.a = Math.max(0, fadeColor.a - 1*tpf);
1 Like