From 73c3f39e460fa5ca1e5909430fce540586ec48ae Mon Sep 17 00:00:00 2001 From: Alrik Date: Wed, 8 Apr 2015 12:58:25 +0200 Subject: [PATCH] - add test case --- .../post/TestBloomAlphaThreshold.java | 178 ++++++++++++++++++ .../src/main/resources/Textures/glass.dds | Bin 0 -> 349680 bytes 2 files changed, 178 insertions(+) create mode 100644 jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java create mode 100644 jme3-testdata/src/main/resources/Textures/glass.dds diff --git a/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java b/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java new file mode 100644 index 000000000..7e8608882 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/post/TestBloomAlphaThreshold.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package jme3test.post; + +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.light.DirectionalLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.post.filters.BloomFilter.GlowMode; +import com.jme3.renderer.queue.RenderQueue.ShadowMode; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.debug.WireFrustum; +import com.jme3.scene.shape.Box; +import com.jme3.util.SkyFactory; + +public class TestBloomAlphaThreshold extends SimpleApplication +{ + + float angle; + Spatial lightMdl; + Spatial teapot; + Geometry frustumMdl; + WireFrustum frustum; + boolean active = true; + FilterPostProcessor fpp; + + public static void main(String[] args) + { + TestBloomAlphaThreshold app = new TestBloomAlphaThreshold(); + app.start(); + } + + @Override + public void simpleInitApp() + { + // put the camera in a bad position + cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -10)); + cam.setRotation(new Quaternion(0.23602544f, 0.11321983f, -0.027698677f, 0.96473104f)); + // cam.setFrustumFar(1000); + + Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + + mat.setFloat("Shininess", 15f); + mat.setBoolean("UseMaterialColors", true); + mat.setColor("Ambient", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Diffuse", ColorRGBA.Yellow.mult(0.2f)); + mat.setColor("Specular", ColorRGBA.Yellow.mult(0.8f)); + mat.setColor("GlowColor", ColorRGBA.Green); + + Material matSoil = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md"); + matSoil.setFloat("Shininess", 15f); + matSoil.setBoolean("UseMaterialColors", true); + matSoil.setColor("Ambient", ColorRGBA.Gray); + matSoil.setColor("Diffuse", ColorRGBA.Black); + matSoil.setColor("Specular", ColorRGBA.Gray); + + teapot = assetManager.loadModel("Models/Teapot/Teapot.obj"); + teapot.setLocalTranslation(0, 0, 10); + + teapot.setMaterial(mat); + teapot.setShadowMode(ShadowMode.CastAndReceive); + teapot.setLocalScale(10.0f); + rootNode.attachChild(teapot); + + Geometry soil = new Geometry("soil", new Box(new Vector3f(0, -13, 550), 800, 10, 700)); + soil.setMaterial(matSoil); + soil.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(soil); + + Material matBox = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + matBox.setTexture("ColorMap", assetManager.loadTexture("Textures/glass.dds")); + matBox.setFloat("AlphaDiscardThreshold", 0.5f); + + Geometry box = new Geometry("box", new Box(new Vector3f(-3.5f, 10, -2), 2, 2, 2)); + box.setMaterial(matBox); + // box.setShadowMode(ShadowMode.CastAndReceive); + rootNode.attachChild(box); + + DirectionalLight light = new DirectionalLight(); + light.setDirection(new Vector3f(-1, -1, -1).normalizeLocal()); + light.setColor(ColorRGBA.White.mult(1.5f)); + rootNode.addLight(light); + + // load sky + Spatial sky = SkyFactory.createSky(assetManager, "Textures/Sky/Bright/FullskiesBlueClear03.dds", false); + sky.setCullHint(Spatial.CullHint.Never); + rootNode.attachChild(sky); + + fpp = new FilterPostProcessor(assetManager); + int numSamples = getContext().getSettings().getSamples(); + if (numSamples > 0) + { + fpp.setNumSamples(numSamples); + } + + BloomFilter bloom = new BloomFilter(GlowMode.Objects); + bloom.setDownSamplingFactor(2); + bloom.setBlurScale(1.37f); + bloom.setExposurePower(3.30f); + bloom.setExposureCutOff(0.2f); + bloom.setBloomIntensity(2.45f); + BloomUI ui = new BloomUI(inputManager, bloom); + + viewPort.addProcessor(fpp); + fpp.addFilter(bloom); + initInputs(); + + } + + private void initInputs() + { + inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE)); + + ActionListener acl = new ActionListener() + { + + @Override + public void onAction(String name, boolean keyPressed, float tpf) + { + if (name.equals("toggle") && keyPressed) + { + if (active) + { + active = false; + viewPort.removeProcessor(fpp); + } + else + { + active = true; + viewPort.addProcessor(fpp); + } + } + } + }; + + inputManager.addListener(acl, "toggle"); + + } + +} diff --git a/jme3-testdata/src/main/resources/Textures/glass.dds b/jme3-testdata/src/main/resources/Textures/glass.dds new file mode 100644 index 0000000000000000000000000000000000000000..5344df36434ade40191ce74ea6d7c11a02f67a35 GIT binary patch literal 349680 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