I’ve got a game, and at the start I add some FilterPostProcessors (blooms and fog). However, when I remove them at the end (when the player goes back to the “main menu”) the displays seems to stop clearing itself, and basically redraws every frame over the top of the previous frame. Are there any special rules I need to know about when removing FilterPostProcessors, or do you know what could cause this? Thanks.
Good idea. Here’s the code, it’s a straight copy of HelloJME3 but with my filters added. When you press ‘C’, it removes the filters and the graphics freeze.
import com.jme3.app.SimpleApplication;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.post.FilterPostProcessor;
import com.jme3.post.filters.BloomFilter;
import com.jme3.post.filters.FogFilter;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.scs.aresdogfighter.Statics;
public class BloomCrashTest extends SimpleApplication implements ActionListener {
private FilterPostProcessor fpp_laser_bloom, fpp_std_bloom, fogPPS;
public static void main(String[] args){
BloomCrashTest app = new BloomCrashTest();
app.showSettings = false;
app.start();
}
@Override
public void simpleInitApp() {
// Create filters
fpp_laser_bloom = new FilterPostProcessor(assetManager);
BloomFilter bloom2 = new BloomFilter(BloomFilter.GlowMode.Objects);
bloom2.setBlurScale(5f);
fpp_laser_bloom.addFilter(bloom2);
fpp_std_bloom = new FilterPostProcessor(assetManager);
BloomFilter bloom = new BloomFilter();
bloom.setBlurScale(2f);//5f);
bloom.setBloomIntensity(1.5f);//2f);
fpp_std_bloom.addFilter(bloom);
fogPPS = new FilterPostProcessor(assetManager);
FogFilter fog = new FogFilter(ColorRGBA.White, .2f, Statics.CAM_VIEW_DIST);
fogPPS.addFilter(fog);
// Add them to the viewport
viewPort.addProcessor(fpp_laser_bloom);
viewPort.addProcessor(fpp_std_bloom);
viewPort.addProcessor(fogPPS);
Box b = new Box(1, 1, 1); // create cube shape
Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
inputManager.addMapping("Crash", new KeyTrigger(KeyInput.KEY_C));
inputManager.addListener(this, "Crash");
}
@Override
public void onAction(String name, boolean isPressed, float tpf) {
if (name.equals("Crash") && isPressed) {
System.out.println("Removing filters...");
viewPort.removeProcessor(fpp_laser_bloom);
viewPort.removeProcessor(fogPPS);
viewPort.removeProcessor(fpp_std_bloom);
System.out.println("Finished removing filters");
}
}
}
Issue is reproduced on current master (3.2). It happens, when multiple FilterPostProcessor are added to the viewport, and then any of those FilterPostProcessor is removed. Maybe FilterPostProcessor is not designed to be used in multiple instances. Need to check the JME code.
It is easy to handle the issue in your case though. Just use a single FilterPostProcessor and keep track the filters instead of post processors. You can remove filter with FilterPostProcessor.removeFilter. Your code works fine with such approach.
UPD: tests show, that bug happens, when FilterPostProcessor instances are being removed in the wrong order. Your initial code will work, if you remove post processors in the FIFO order:
Just struggled with this until I found this post. If the intended purpose of the FilterPostProcessor is to have only one per viewport, shouldn’t the viewport have a getFpp() method? (So if in different parts of the code you want to manage a different filter that fpp is easily fetched?. Currently the only way is iterating over the given list with getProcessors(). Or even, a: <T extends SceneProcessor> T getProcessor(Class<T> processorType)).
Well, to avoid that should work the second alternative: <T extends SceneProcessor> T getProcessor(Class<T> processorType)). However, it is right that this would not be that useful for scene processors that can allow more instances to be added (but the spatial’s getControl(T) has the same issue and it is quite helpful)