1 /* 2 * To change this template, choose Tools | Templates 3 * and open the template in the editor. 4 */ 5 package com.jme3.post.filters; 6 7 import com.jme3.asset.AssetManager; 8 import com.jme3.effect.ParticleEmitter; 9 import com.jme3.material.Material; 10 import com.jme3.math.ColorRGBA; 11 import com.jme3.post.Filter; 12 import com.jme3.renderer.RenderManager; 13 import com.jme3.renderer.Renderer; 14 import com.jme3.renderer.ViewPort; 15 import com.jme3.renderer.queue.RenderQueue; 16 import com.jme3.scene.Node; 17 18 import com.jme3.scene.Spatial; 19 import com.jme3.texture.FrameBuffer; 20 import com.jme3.texture.Texture; 21 import com.jme3.texture.Texture2D; 22 import java.util.logging.Level; 23 import java.util.logging.Logger; 24 25 /** 26 * A filter to handle translucent objects when rendering a scene with filters that uses depth like WaterFilter and SSAOFilter 27 * just create a TranslucentBucketFilter and add it to the Filter list of a FilterPostPorcessor 28 * @author Nehon 29 */ 30 public final class TranslucentBucketFilter extends Filter { 31 32 private final static Logger logger = Logger.getLogger(TranslucentBucketFilter.class.getName()); 33 private RenderManager renderManager; 34 private boolean enabledSoftParticles = false; 35 private Texture depthTexture; 36 private ViewPort viewPort; 37 38 public TranslucentBucketFilter() { 39 super("TranslucentBucketFilter"); 40 } 41 42 public TranslucentBucketFilter(boolean enabledSoftParticles) { 43 this(); 44 this.enabledSoftParticles = enabledSoftParticles; 45 } 46 47 @Override 48 protected void initFilter(AssetManager manager, RenderManager rm, ViewPort vp, int w, int h) { 49 this.renderManager = rm; 50 this.viewPort = vp; 51 material = new Material(manager, "Common/MatDefs/Post/Overlay.j3md"); 52 material.setColor("Color", ColorRGBA.White); 53 Texture2D tex = processor.getFilterTexture(); 54 material.setTexture("Texture", tex); 55 if (tex.getImage().getMultiSamples() > 1) { 56 material.setInt("NumSamples", tex.getImage().getMultiSamples()); 57 } else { 58 material.clearParam("NumSamples"); 59 } 60 renderManager.setHandleTranslucentBucket(false); 61 if (enabledSoftParticles && depthTexture != null) { 62 initSoftParticles(vp, true); 63 } 64 } 65 66 private void initSoftParticles(ViewPort vp, boolean enabledSP) { 67 if (depthTexture != null) { 68 for (Spatial scene : vp.getScenes()) { 69 makeSoftParticleEmitter(scene, enabledSP && enabled); 70 } 71 } 72 73 } 74 75 @Override 76 protected void setDepthTexture(Texture depthTexture) { 77 this.depthTexture = depthTexture; 78 if (enabledSoftParticles && depthTexture != null) { 79 initSoftParticles(viewPort, true); 80 } 81 } 82 83 /** 84 * Override this method and return false if your Filter does not need the scene texture 85 * @return 86 */ 87 @Override 88 protected boolean isRequiresSceneTexture() { 89 return false; 90 } 91 92 @Override 93 protected boolean isRequiresDepthTexture() { 94 return enabledSoftParticles; 95 } 96 97 @Override 98 protected void postFrame(RenderManager renderManager, ViewPort viewPort, FrameBuffer prevFilterBuffer, FrameBuffer sceneBuffer) { 99 renderManager.setCamera(viewPort.getCamera(), false); 100 if (prevFilterBuffer != sceneBuffer) { 101 renderManager.getRenderer().copyFrameBuffer(prevFilterBuffer, sceneBuffer, false); 102 } 103 renderManager.getRenderer().setFrameBuffer(sceneBuffer); 104 viewPort.getQueue().renderQueue(RenderQueue.Bucket.Translucent, renderManager, viewPort.getCamera()); 105 } 106 107 @Override 108 protected void cleanUpFilter(Renderer r) { 109 if (renderManager != null) { 110 renderManager.setHandleTranslucentBucket(true); 111 } 112 113 initSoftParticles(viewPort, false); 114 } 115 116 @Override 117 protected Material getMaterial() { 118 return material; 119 } 120 121 @Override 122 public void setEnabled(boolean enabled) { 123 super.setEnabled(enabled); 124 if (renderManager != null) { 125 renderManager.setHandleTranslucentBucket(!enabled); 126 } 127 initSoftParticles(viewPort, enabledSoftParticles); 128 } 129 130 private void makeSoftParticleEmitter(Spatial scene, boolean enabled) { 131 if (scene instanceof Node) { 132 Node n = (Node) scene; 133 for (Spatial child : n.getChildren()) { 134 makeSoftParticleEmitter(child, enabled); 135 } 136 } 137 if (scene instanceof ParticleEmitter) { 138 ParticleEmitter emitter = (ParticleEmitter) scene; 139 if (enabled) { 140 enabledSoftParticles = enabled; 141 142 emitter.getMaterial().selectTechnique("SoftParticles", renderManager); 143 emitter.getMaterial().setTexture("DepthTexture", processor.getDepthTexture()); 144 emitter.setQueueBucket(RenderQueue.Bucket.Translucent); 145 146 logger.log(Level.INFO, "Made particle Emitter {0} soft.", emitter.getName()); 147 } else { 148 emitter.getMaterial().clearParam("DepthTexture"); 149 emitter.getMaterial().selectTechnique("Default", renderManager); 150 // emitter.setQueueBucket(RenderQueue.Bucket.Transparent); 151 logger.log(Level.INFO, "Particle Emitter {0} is not soft anymore.", emitter.getName()); 152 } 153 } 154 } 155 } 156