This is my first post here, even though I’ve been using JME3 for almost 2 years now. I’m currently working on writing an Android game with JME3 and I have been running into strange depth buffer problems on android involving the depth buffer. I’m developing on a Nexus 5, but the problem also exists on a Nexus 7 (2012). Basically, I’ve narrowed it down to whenever something turns the DepthMask to false in a shader, the framebuffer gets corrupted.
Here is a picture of the corruption that happens when I try to use a Particle Emitter:
I’ve noticed the problem in everything from filters, to when using nifty gui, and most recently when using particle emitters. From my research, this appears to affect only certain Android devices. I finally decided to do something about it (I gotta have my particles!!!). I checked the forums here and I noticed a few people mentioning depth buffer weirdness in Android, but no solutions. So, I’m posting here to hopefully help someone in the future, or to maybe let one of the developers know about a potential fix.
This link explains whats going on. Basically whenever the DepthMask is set to false, and left at false when the page flip occurs, on some Android devices, the framebuffer will get corrupted. The fix is simple: to call glDepthMask(true) after finishing rendering. Well, after a bit of digging I figured a way to hook into the postRender using an AppState:
[java]import java.io.IOException;
import android.opengl.GLES20;
import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.effect.ParticleEmitter;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
public class DepthBufferFix implements com.jme3.app.state.AppState {
@Override
public void cleanup() { }
@Override
public void initialize(AppStateManager arg0, Application arg1) {}
@Override
public boolean isEnabled() { return true; }
@Override
public boolean isInitialized() { return true; }
@Override
public void postRender() {
GLES20.glDepthMask(true);
}
@Override
public void render(RenderManager arg0) {}
@Override
public void setEnabled(boolean arg0) {}
@Override
public void stateAttached(AppStateManager arg0) {}
@Override
public void stateDetached(AppStateManager arg0) {}
@Override
public void update(float arg0) { }
}[/java]
and then in the simpleInitApp method of your SimpleApplication class:
[java] DepthBufferFix dbfix =new DepthBufferFix();
dbfix.setEnabled(true);
this.getStateManager().attach(dbfix);[/java]
Applying this fix, my Particle Emitters now work, and I’m fairly certain several other depth mask related problems will be solved. Below is a screenshot of the particles working as expected:
My solution of course, is a bandaid. I think the engine should probably set the glDepthMask back to true post render. But I wanted to put this out there for any fellow Android JME3 developers. Also, many thanks to all the developers of JME3, you guys are great!