aboutsummaryrefslogtreecommitdiff
path: root/engine/src/test/jme3test/post
diff options
context:
space:
mode:
Diffstat (limited to 'engine/src/test/jme3test/post')
-rw-r--r--engine/src/test/jme3test/post/BloomUI.java109
-rw-r--r--engine/src/test/jme3test/post/LightScatteringUI.java136
-rw-r--r--engine/src/test/jme3test/post/SSAOUI.java140
-rw-r--r--engine/src/test/jme3test/post/TestBloom.java161
-rw-r--r--engine/src/test/jme3test/post/TestCartoonEdge.java129
-rw-r--r--engine/src/test/jme3test/post/TestCrossHatch.java155
-rw-r--r--engine/src/test/jme3test/post/TestDepthOfField.java200
-rw-r--r--engine/src/test/jme3test/post/TestFBOPassthrough.java117
-rw-r--r--engine/src/test/jme3test/post/TestFog.java162
-rw-r--r--engine/src/test/jme3test/post/TestHDR.java101
-rw-r--r--engine/src/test/jme3test/post/TestLightScattering.java121
-rw-r--r--engine/src/test/jme3test/post/TestMultiRenderTarget.java219
-rw-r--r--engine/src/test/jme3test/post/TestMultiViewsFilters.java194
-rw-r--r--engine/src/test/jme3test/post/TestMultiplesFilters.java153
-rw-r--r--engine/src/test/jme3test/post/TestPostFilters.java179
-rw-r--r--engine/src/test/jme3test/post/TestPosterization.java155
-rw-r--r--engine/src/test/jme3test/post/TestRenderToMemory.java259
-rw-r--r--engine/src/test/jme3test/post/TestRenderToTexture.java148
-rw-r--r--engine/src/test/jme3test/post/TestSSAO.java96
-rw-r--r--engine/src/test/jme3test/post/TestTransparentCartoonEdge.java97
-rw-r--r--engine/src/test/jme3test/post/TestTransparentSSAO.java74
21 files changed, 3105 insertions, 0 deletions
diff --git a/engine/src/test/jme3test/post/BloomUI.java b/engine/src/test/jme3test/post/BloomUI.java
new file mode 100644
index 0000000..5029732
--- /dev/null
+++ b/engine/src/test/jme3test/post/BloomUI.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009-2010 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.input.InputManager;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.AnalogListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.post.filters.BloomFilter;
+
+/**
+ *
+ * @author nehon
+ */
+public class BloomUI {
+
+ public BloomUI(InputManager inputManager, final BloomFilter filter) {
+
+ System.out.println("----------------- Bloom UI Debugger --------------------");
+ System.out.println("-- blur Scale : press Y to increase, H to decrease");
+ System.out.println("-- exposure Power : press U to increase, J to decrease");
+ System.out.println("-- exposure CutOff : press I to increase, K to decrease");
+ System.out.println("-- bloom Intensity : press O to increase, P to decrease");
+ System.out.println("-------------------------------------------------------");
+
+ inputManager.addMapping("blurScaleUp", new KeyTrigger(KeyInput.KEY_Y));
+ inputManager.addMapping("blurScaleDown", new KeyTrigger(KeyInput.KEY_H));
+ inputManager.addMapping("exposurePowerUp", new KeyTrigger(KeyInput.KEY_U));
+ inputManager.addMapping("exposurePowerDown", new KeyTrigger(KeyInput.KEY_J));
+ inputManager.addMapping("exposureCutOffUp", new KeyTrigger(KeyInput.KEY_I));
+ inputManager.addMapping("exposureCutOffDown", new KeyTrigger(KeyInput.KEY_K));
+ inputManager.addMapping("bloomIntensityUp", new KeyTrigger(KeyInput.KEY_O));
+ inputManager.addMapping("bloomIntensityDown", new KeyTrigger(KeyInput.KEY_L));
+
+
+ AnalogListener anl = new AnalogListener() {
+
+ public void onAnalog(String name, float value, float tpf) {
+ if (name.equals("blurScaleUp")) {
+ filter.setBlurScale(filter.getBlurScale() + 0.01f);
+ System.out.println("blurScale : " + filter.getBlurScale());
+ }
+ if (name.equals("blurScaleDown")) {
+ filter.setBlurScale(filter.getBlurScale() - 0.01f);
+ System.out.println("blurScale : " + filter.getBlurScale());
+ }
+ if (name.equals("exposurePowerUp")) {
+ filter.setExposurePower(filter.getExposurePower() + 0.01f);
+ System.out.println("exposurePower : " + filter.getExposurePower());
+ }
+ if (name.equals("exposurePowerDown")) {
+ filter.setExposurePower(filter.getExposurePower() - 0.01f);
+ System.out.println("exposurePower : " + filter.getExposurePower());
+ }
+ if (name.equals("exposureCutOffUp")) {
+ filter.setExposureCutOff(Math.min(1.0f, Math.max(0.0f, filter.getExposureCutOff() + 0.001f)));
+ System.out.println("exposure CutOff : " + filter.getExposureCutOff());
+ }
+ if (name.equals("exposureCutOffDown")) {
+ filter.setExposureCutOff(Math.min(1.0f, Math.max(0.0f, filter.getExposureCutOff() - 0.001f)));
+ System.out.println("exposure CutOff : " + filter.getExposureCutOff());
+ }
+ if (name.equals("bloomIntensityUp")) {
+ filter.setBloomIntensity(filter.getBloomIntensity() + 0.01f);
+ System.out.println("bloom Intensity : " + filter.getBloomIntensity());
+ }
+ if (name.equals("bloomIntensityDown")) {
+ filter.setBloomIntensity(filter.getBloomIntensity() - 0.01f);
+ System.out.println("bloom Intensity : " + filter.getBloomIntensity());
+ }
+
+
+ }
+ };
+
+ inputManager.addListener(anl, "blurScaleUp", "blurScaleDown", "exposurePowerUp", "exposurePowerDown",
+ "exposureCutOffUp", "exposureCutOffDown", "bloomIntensityUp", "bloomIntensityDown");
+
+ }
+}
diff --git a/engine/src/test/jme3test/post/LightScatteringUI.java b/engine/src/test/jme3test/post/LightScatteringUI.java
new file mode 100644
index 0000000..22cc8c7
--- /dev/null
+++ b/engine/src/test/jme3test/post/LightScatteringUI.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2009-2010 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.input.InputManager;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.AnalogListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.post.filters.LightScatteringFilter;
+
+/**
+ *
+ * @author nehon
+ */
+public class LightScatteringUI {
+ private LightScatteringFilter filter;
+ public LightScatteringUI(InputManager inputManager, LightScatteringFilter proc) {
+ filter=proc;
+
+
+ System.out.println("----------------- LightScattering UI Debugger --------------------");
+ System.out.println("-- Sample number : press Y to increase, H to decrease");
+ System.out.println("-- blur start : press U to increase, J to decrease");
+ System.out.println("-- blur width : press I to increase, K to decrease");
+ System.out.println("-- Light density : press O to increase, P to decrease");
+// System.out.println("-- Toggle AO on/off : press space bar");
+// System.out.println("-- Use only AO : press Num pad 0");
+// System.out.println("-- Output config declaration : press P");
+ System.out.println("-------------------------------------------------------");
+
+ inputManager.addMapping("sampleUp", new KeyTrigger(KeyInput.KEY_Y));
+ inputManager.addMapping("sampleDown", new KeyTrigger(KeyInput.KEY_H));
+ inputManager.addMapping("blurStartUp", new KeyTrigger(KeyInput.KEY_U));
+ inputManager.addMapping("blurStartDown", new KeyTrigger(KeyInput.KEY_J));
+ inputManager.addMapping("blurWidthUp", new KeyTrigger(KeyInput.KEY_I));
+ inputManager.addMapping("blurWidthDown", new KeyTrigger(KeyInput.KEY_K));
+ inputManager.addMapping("lightDensityUp", new KeyTrigger(KeyInput.KEY_O));
+ inputManager.addMapping("lightDensityDown", new KeyTrigger(KeyInput.KEY_L));
+ inputManager.addMapping("outputConfig", new KeyTrigger(KeyInput.KEY_P));
+// inputManager.addMapping("toggleUseAO", new KeyTrigger(KeyInput.KEY_SPACE));
+// inputManager.addMapping("toggleUseOnlyAo", new KeyTrigger(KeyInput.KEY_NUMPAD0));
+
+ ActionListener acl = new ActionListener() {
+
+ public void onAction(String name, boolean keyPressed, float tpf) {
+
+ if (name.equals("sampleUp")) {
+ filter.setNbSamples(filter.getNbSamples()+1);
+ System.out.println("Nb Samples : "+filter.getNbSamples());
+ }
+ if (name.equals("sampleDown")) {
+ filter.setNbSamples(filter.getNbSamples()-1);
+ System.out.println("Nb Samples : "+filter.getNbSamples());
+ }
+ if (name.equals("outputConfig") && keyPressed) {
+ System.out.println("lightScatteringFilter.setNbSamples("+filter.getNbSamples()+");");
+ System.out.println("lightScatteringFilter.setBlurStart("+filter.getBlurStart()+"f);");
+ System.out.println("lightScatteringFilter.setBlurWidth("+filter.getBlurWidth()+"f);");
+ System.out.println("lightScatteringFilter.setLightDensity("+filter.getLightDensity()+"f);");
+ }
+
+
+ }
+ };
+
+ AnalogListener anl = new AnalogListener() {
+
+ public void onAnalog(String name, float value, float tpf) {
+
+ if (name.equals("blurStartUp")) {
+ filter.setBlurStart(filter.getBlurStart()+0.001f);
+ System.out.println("Blur start : "+filter.getBlurStart());
+ }
+ if (name.equals("blurStartDown")) {
+ filter.setBlurStart(filter.getBlurStart()-0.001f);
+ System.out.println("Blur start : "+filter.getBlurStart());
+ }
+ if (name.equals("blurWidthUp")) {
+ filter.setBlurWidth(filter.getBlurWidth()+0.001f);
+ System.out.println("Blur Width : "+filter.getBlurWidth());
+ }
+ if (name.equals("blurWidthDown")) {
+ filter.setBlurWidth(filter.getBlurWidth()-0.001f);
+ System.out.println("Blur Width : "+filter.getBlurWidth());
+ }
+ if (name.equals("lightDensityUp")) {
+ filter.setLightDensity(filter.getLightDensity()+0.001f);
+ System.out.println("light Density : "+filter.getLightDensity());
+ }
+ if (name.equals("lightDensityDown")) {
+ filter.setLightDensity(filter.getLightDensity()-0.001f);
+ System.out.println("light Density : "+filter.getLightDensity());
+ }
+
+ }
+ };
+ inputManager.addListener(acl,"sampleUp","sampleDown","outputConfig");
+
+ inputManager.addListener(anl, "blurStartUp","blurStartDown","blurWidthUp", "blurWidthDown","lightDensityUp", "lightDensityDown");
+
+ }
+
+
+
+}
diff --git a/engine/src/test/jme3test/post/SSAOUI.java b/engine/src/test/jme3test/post/SSAOUI.java
new file mode 100644
index 0000000..21509f5
--- /dev/null
+++ b/engine/src/test/jme3test/post/SSAOUI.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009-2010 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.input.InputManager;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.AnalogListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.post.ssao.SSAOFilter;
+
+/**
+ *
+ * @author nehon
+ */
+public class SSAOUI {
+
+ SSAOFilter filter;
+
+ public SSAOUI(InputManager inputManager, SSAOFilter filter) {
+ this.filter = filter;
+ init(inputManager);
+ }
+
+ private void init(InputManager inputManager) {
+ System.out.println("----------------- Water UI Debugger --------------------");
+ System.out.println("-- Sample Radius : press Y to increase, H to decrease");
+ System.out.println("-- AO Intensity : press U to increase, J to decrease");
+ System.out.println("-- AO scale : press I to increase, K to decrease");
+ System.out.println("-- AO bias : press O to increase, P to decrease");
+ System.out.println("-- Toggle AO on/off : press space bar");
+ System.out.println("-- Use only AO : press Num pad 0");
+ System.out.println("-- Output config declaration : press P");
+ System.out.println("-------------------------------------------------------");
+
+ inputManager.addMapping("sampleRadiusUp", new KeyTrigger(KeyInput.KEY_Y));
+ inputManager.addMapping("sampleRadiusDown", new KeyTrigger(KeyInput.KEY_H));
+ inputManager.addMapping("intensityUp", new KeyTrigger(KeyInput.KEY_U));
+ inputManager.addMapping("intensityDown", new KeyTrigger(KeyInput.KEY_J));
+ inputManager.addMapping("scaleUp", new KeyTrigger(KeyInput.KEY_I));
+ inputManager.addMapping("scaleDown", new KeyTrigger(KeyInput.KEY_K));
+ inputManager.addMapping("biasUp", new KeyTrigger(KeyInput.KEY_O));
+ inputManager.addMapping("biasDown", new KeyTrigger(KeyInput.KEY_L));
+ inputManager.addMapping("outputConfig", new KeyTrigger(KeyInput.KEY_P));
+ inputManager.addMapping("toggleUseAO", new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addMapping("toggleUseOnlyAo", new KeyTrigger(KeyInput.KEY_NUMPAD0));
+
+ ActionListener acl = new ActionListener() {
+
+ public void onAction(String name, boolean keyPressed, float tpf) {
+
+ if (name.equals("toggleUseAO") && keyPressed) {
+ filter.setEnabled(!filter.isEnabled());
+ // filter.setUseAo(!filter.isUseAo());
+ System.out.println("use AO : " + filter.isEnabled());
+ }
+ if (name.equals("toggleUseOnlyAo") && keyPressed) {
+ filter.setUseOnlyAo(!filter.isUseOnlyAo());
+ System.out.println("use Only AO : " + filter.isUseOnlyAo());
+
+ }
+ if (name.equals("outputConfig") && keyPressed) {
+ System.out.println("new SSAOFilter(" + filter.getSampleRadius() + "f," + filter.getIntensity() + "f," + filter.getScale() + "f," + filter.getBias() + "f);");
+ }
+ }
+ };
+
+ AnalogListener anl = new AnalogListener() {
+
+ public void onAnalog(String name, float value, float tpf) {
+ if (name.equals("sampleRadiusUp")) {
+ filter.setSampleRadius(filter.getSampleRadius() + 0.01f);
+ System.out.println("Sample Radius : " + filter.getSampleRadius());
+ }
+ if (name.equals("sampleRadiusDown")) {
+ filter.setSampleRadius(filter.getSampleRadius() - 0.01f);
+ System.out.println("Sample Radius : " + filter.getSampleRadius());
+ }
+ if (name.equals("intensityUp")) {
+ filter.setIntensity(filter.getIntensity() + 0.01f);
+ System.out.println("Intensity : " + filter.getIntensity());
+ }
+ if (name.equals("intensityDown")) {
+ filter.setIntensity(filter.getIntensity() - 0.01f);
+ System.out.println("Intensity : " + filter.getIntensity());
+ }
+ if (name.equals("scaleUp")) {
+ filter.setScale(filter.getScale() + 0.01f);
+ System.out.println("scale : " + filter.getScale());
+ }
+ if (name.equals("scaleDown")) {
+ filter.setScale(filter.getScale() - 0.01f);
+ System.out.println("scale : " + filter.getScale());
+ }
+ if (name.equals("biasUp")) {
+ filter.setBias(filter.getBias() + 0.001f);
+ System.out.println("bias : " + filter.getBias());
+ }
+ if (name.equals("biasDown")) {
+ filter.setBias(filter.getBias() - 0.001f);
+ System.out.println("bias : " + filter.getBias());
+ }
+
+ }
+ };
+ inputManager.addListener(acl, "toggleUseAO", "toggleUseOnlyAo", "outputConfig");
+ inputManager.addListener(anl, "sampleRadiusUp", "sampleRadiusDown", "intensityUp", "intensityDown", "scaleUp", "scaleDown",
+ "biasUp", "biasDown");
+
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestBloom.java b/engine/src/test/jme3test/post/TestBloom.java
new file mode 100644
index 0000000..1c371b4
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestBloom.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2009-2010 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.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 TestBloom extends SimpleApplication {
+
+ float angle;
+ Spatial lightMdl;
+ Spatial teapot;
+ Geometry frustumMdl;
+ WireFrustum frustum;
+ boolean active=true;
+ FilterPostProcessor fpp;
+
+ public static void main(String[] args){
+ TestBloom app = new TestBloom();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ // put the camera in a bad position
+ cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f));
+ 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));
+
+
+
+
+ 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);
+
+ 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);
+ // fpp.setNumSamples(4);
+ BloomFilter bloom=new BloomFilter();
+ 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() {
+
+ 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/engine/src/test/jme3test/post/TestCartoonEdge.java b/engine/src/test/jme3test/post/TestCartoonEdge.java
new file mode 100644
index 0000000..a57656d
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestCartoonEdge.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2009-2010 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.light.DirectionalLight;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.CartoonEdgeFilter;
+import com.jme3.renderer.Caps;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.Spatial.CullHint;
+import com.jme3.texture.Texture;
+
+public class TestCartoonEdge extends SimpleApplication {
+
+ private FilterPostProcessor fpp;
+
+ public static void main(String[] args){
+ TestCartoonEdge app = new TestCartoonEdge();
+ app.start();
+ }
+
+ public void setupFilters(){
+ if (renderer.getCaps().contains(Caps.GLSL100)){
+ fpp=new FilterPostProcessor(assetManager);
+ //fpp.setNumSamples(4);
+ CartoonEdgeFilter toon=new CartoonEdgeFilter();
+ toon.setEdgeColor(ColorRGBA.Yellow);
+ fpp.addFilter(toon);
+ viewPort.addProcessor(fpp);
+ }
+ }
+
+ public void makeToonish(Spatial spatial){
+ if (spatial instanceof Node){
+ Node n = (Node) spatial;
+ for (Spatial child : n.getChildren())
+ makeToonish(child);
+ }else if (spatial instanceof Geometry){
+ Geometry g = (Geometry) spatial;
+ Material m = g.getMaterial();
+ if (m.getMaterialDef().getName().equals("Phong Lighting")){
+ Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png");
+// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
+// t.setMagFilter(Texture.MagFilter.Nearest);
+ m.setTexture("ColorRamp", t);
+ m.setBoolean("UseMaterialColors", true);
+ m.setColor("Specular", ColorRGBA.Black);
+ m.setColor("Diffuse", ColorRGBA.White);
+ m.setBoolean("VertexLighting", true);
+ }
+ }
+ }
+
+ public void setupLighting(){
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(new Vector3f(-1, -1, 1).normalizeLocal());
+ dl.setColor(new ColorRGBA(2,2,2,1));
+
+ rootNode.addLight(dl);
+ }
+
+ public void setupModel(){
+ Spatial model = assetManager.loadModel("Models/MonkeyHead/MonkeyHead.mesh.xml");
+ makeToonish(model);
+ model.rotate(0, FastMath.PI, 0);
+// signpost.setLocalTranslation(12, 3.5f, 30);
+// model.scale(0.10f);
+// signpost.setShadowMode(ShadowMode.CastAndReceive);
+ rootNode.attachChild(model);
+ }
+
+ @Override
+ public void simpleInitApp() {
+ viewPort.setBackgroundColor(ColorRGBA.Gray);
+
+ cam.setLocation(new Vector3f(-5.6310086f, 5.0892987f, -13.000479f));
+ cam.setRotation(new Quaternion(0.1779095f, 0.20036356f, -0.03702727f, 0.96272093f));
+ cam.update();
+
+ cam.setFrustumFar(300);
+ flyCam.setMoveSpeed(30);
+
+ rootNode.setCullHint(CullHint.Never);
+
+ setupLighting();
+ setupModel();
+ setupFilters();
+ }
+
+}
diff --git a/engine/src/test/jme3test/post/TestCrossHatch.java b/engine/src/test/jme3test/post/TestCrossHatch.java
new file mode 100644
index 0000000..d5230fa
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestCrossHatch.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009-2010 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.CrossHatchFilter;
+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 TestCrossHatch extends SimpleApplication {
+
+ float angle;
+ Spatial lightMdl;
+ Spatial teapot;
+ Geometry frustumMdl;
+ WireFrustum frustum;
+ boolean active=true;
+ FilterPostProcessor fpp;
+
+ public static void main(String[] args){
+ TestCrossHatch app = new TestCrossHatch();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ // put the camera in a bad position
+ cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f));
+ 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));
+
+
+
+
+ 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);
+
+ 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);
+ CrossHatchFilter chf=new CrossHatchFilter();
+
+
+
+ viewPort.addProcessor(fpp);
+ fpp.addFilter(chf);
+ initInputs();
+
+ }
+
+ private void initInputs() {
+ inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
+
+ ActionListener acl = new ActionListener() {
+
+ 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/engine/src/test/jme3test/post/TestDepthOfField.java b/engine/src/test/jme3test/post/TestDepthOfField.java
new file mode 100644
index 0000000..5426a33
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestDepthOfField.java
@@ -0,0 +1,200 @@
+package jme3test.post;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.collision.CollisionResult;
+import com.jme3.collision.CollisionResults;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.AnalogListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.light.DirectionalLight;
+import com.jme3.material.Material;
+import com.jme3.math.*;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.DepthOfFieldFilter;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.terrain.geomipmap.TerrainQuad;
+import com.jme3.terrain.heightmap.AbstractHeightMap;
+import com.jme3.terrain.heightmap.ImageBasedHeightMap;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture.WrapMode;
+import com.jme3.util.SkyFactory;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * test
+ * @author Nehon
+ */
+public class TestDepthOfField extends SimpleApplication {
+
+ private FilterPostProcessor fpp;
+ private Vector3f lightDir = new Vector3f(-4.9236743f, -1.27054665f, 5.896916f);
+ TerrainQuad terrain;
+ Material matRock;
+ DepthOfFieldFilter dofFilter;
+
+ public static void main(String[] args) {
+ TestDepthOfField app = new TestDepthOfField();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+
+
+ Node mainScene = new Node("Main Scene");
+ rootNode.attachChild(mainScene);
+
+ createTerrain(mainScene);
+ DirectionalLight sun = new DirectionalLight();
+ sun.setDirection(lightDir);
+ sun.setColor(ColorRGBA.White.clone().multLocal(1.7f));
+ mainScene.addLight(sun);
+
+ DirectionalLight l = new DirectionalLight();
+ l.setDirection(Vector3f.UNIT_Y.mult(-1));
+ l.setColor(ColorRGBA.White.clone().multLocal(0.3f));
+ mainScene.addLight(l);
+
+ flyCam.setMoveSpeed(50);
+ cam.setFrustumFar(3000);
+ cam.setLocation(new Vector3f(-700, 100, 300));
+ cam.setRotation(new Quaternion().fromAngles(new float[]{FastMath.PI * 0.06f, FastMath.PI * 0.65f, 0}));
+
+
+ Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
+ sky.setLocalScale(350);
+ mainScene.attachChild(sky);
+
+
+
+ fpp = new FilterPostProcessor(assetManager);
+ // fpp.setNumSamples(4);
+
+ dofFilter = new DepthOfFieldFilter();
+ dofFilter.setFocusDistance(0);
+ dofFilter.setFocusRange(50);
+ dofFilter.setBlurScale(1.4f);
+ fpp.addFilter(dofFilter);
+ viewPort.addProcessor(fpp);
+
+ inputManager.addListener(new ActionListener() {
+
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if (isPressed) {
+ if (name.equals("toggle")) {
+ dofFilter.setEnabled(!dofFilter.isEnabled());
+ }
+
+
+ }
+ }
+ }, "toggle");
+ inputManager.addListener(new AnalogListener() {
+
+ public void onAnalog(String name, float value, float tpf) {
+ if (name.equals("blurScaleUp")) {
+ dofFilter.setBlurScale(dofFilter.getBlurScale() + 0.01f);
+ System.out.println("blurScale : " + dofFilter.getBlurScale());
+ }
+ if (name.equals("blurScaleDown")) {
+ dofFilter.setBlurScale(dofFilter.getBlurScale() - 0.01f);
+ System.out.println("blurScale : " + dofFilter.getBlurScale());
+ }
+ if (name.equals("focusRangeUp")) {
+ dofFilter.setFocusRange(dofFilter.getFocusRange() + 1f);
+ System.out.println("focusRange : " + dofFilter.getFocusRange());
+ }
+ if (name.equals("focusRangeDown")) {
+ dofFilter.setFocusRange(dofFilter.getFocusRange() - 1f);
+ System.out.println("focusRange : " + dofFilter.getFocusRange());
+ }
+ if (name.equals("focusDistanceUp")) {
+ dofFilter.setFocusDistance(dofFilter.getFocusDistance() + 1f);
+ System.out.println("focusDistance : " + dofFilter.getFocusDistance());
+ }
+ if (name.equals("focusDistanceDown")) {
+ dofFilter.setFocusDistance(dofFilter.getFocusDistance() - 1f);
+ System.out.println("focusDistance : " + dofFilter.getFocusDistance());
+ }
+
+ }
+ }, "blurScaleUp", "blurScaleDown", "focusRangeUp", "focusRangeDown", "focusDistanceUp", "focusDistanceDown");
+
+
+ inputManager.addMapping("toggle", new KeyTrigger(keyInput.KEY_SPACE));
+ inputManager.addMapping("blurScaleUp", new KeyTrigger(keyInput.KEY_U));
+ inputManager.addMapping("blurScaleDown", new KeyTrigger(keyInput.KEY_J));
+ inputManager.addMapping("focusRangeUp", new KeyTrigger(keyInput.KEY_I));
+ inputManager.addMapping("focusRangeDown", new KeyTrigger(keyInput.KEY_K));
+ inputManager.addMapping("focusDistanceUp", new KeyTrigger(keyInput.KEY_O));
+ inputManager.addMapping("focusDistanceDown", new KeyTrigger(keyInput.KEY_L));
+
+ }
+
+ private void createTerrain(Node rootNode) {
+ matRock = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
+ matRock.setBoolean("useTriPlanarMapping", false);
+ matRock.setBoolean("WardIso", true);
+ matRock.setTexture("AlphaMap", assetManager.loadTexture("Textures/Terrain/splat/alphamap.png"));
+ Texture heightMapImage = assetManager.loadTexture("Textures/Terrain/splat/mountains512.png");
+ Texture grass = assetManager.loadTexture("Textures/Terrain/splat/grass.jpg");
+ grass.setWrap(WrapMode.Repeat);
+ matRock.setTexture("DiffuseMap", grass);
+ matRock.setFloat("DiffuseMap_0_scale", 64);
+ Texture dirt = assetManager.loadTexture("Textures/Terrain/splat/dirt.jpg");
+ dirt.setWrap(WrapMode.Repeat);
+ matRock.setTexture("DiffuseMap_1", dirt);
+ matRock.setFloat("DiffuseMap_1_scale", 16);
+ Texture rock = assetManager.loadTexture("Textures/Terrain/splat/road.jpg");
+ rock.setWrap(WrapMode.Repeat);
+ matRock.setTexture("DiffuseMap_2", rock);
+ matRock.setFloat("DiffuseMap_2_scale", 128);
+ Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg");
+ normalMap0.setWrap(WrapMode.Repeat);
+ Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png");
+ normalMap1.setWrap(WrapMode.Repeat);
+ Texture normalMap2 = assetManager.loadTexture("Textures/Terrain/splat/road_normal.png");
+ normalMap2.setWrap(WrapMode.Repeat);
+ matRock.setTexture("NormalMap", normalMap0);
+ matRock.setTexture("NormalMap_1", normalMap2);
+ matRock.setTexture("NormalMap_2", normalMap2);
+
+ AbstractHeightMap heightmap = null;
+ try {
+ heightmap = new ImageBasedHeightMap(heightMapImage.getImage(), 0.25f);
+ heightmap.load();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ terrain = new TerrainQuad("terrain", 65, 513, heightmap.getHeightMap());
+ List<Camera> cameras = new ArrayList<Camera>();
+ cameras.add(getCamera());
+ terrain.setMaterial(matRock);
+ terrain.setLocalScale(new Vector3f(5, 5, 5));
+ terrain.setLocalTranslation(new Vector3f(0, -30, 0));
+ terrain.setLocked(false); // unlock it so we can edit the height
+
+ terrain.setShadowMode(ShadowMode.Receive);
+ rootNode.attachChild(terrain);
+
+ }
+
+ @Override
+ public void simpleUpdate(float tpf) {
+ Vector3f origin = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.0f);
+ Vector3f direction = cam.getWorldCoordinates(new Vector2f(settings.getWidth() / 2, settings.getHeight() / 2), 0.3f);
+ direction.subtractLocal(origin).normalizeLocal();
+ Ray ray = new Ray(origin, direction);
+ CollisionResults results = new CollisionResults();
+ int numCollisions = terrain.collideWith(ray, results);
+ if (numCollisions > 0) {
+ CollisionResult hit = results.getClosestCollision();
+ fpsText.setText(""+hit.getDistance());
+ dofFilter.setFocusDistance(hit.getDistance()/10.0f);
+ }
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestFBOPassthrough.java b/engine/src/test/jme3test/post/TestFBOPassthrough.java
new file mode 100644
index 0000000..fee11fe
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestFBOPassthrough.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2009-2010 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.material.Material;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.Renderer;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.shape.Sphere;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture2D;
+import com.jme3.ui.Picture;
+
+/**
+ * Demonstrates FrameBuffer usage.
+ * The scene is first rendered to an FB with a texture attached,
+ * the texture is then rendered onto the screen in ortho mode.
+ *
+ * @author Kirill
+ */
+public class TestFBOPassthrough extends SimpleApplication {
+
+ private Node fbNode = new Node("Framebuffer Node");
+ private FrameBuffer fb;
+
+ public static void main(String[] args){
+ TestFBOPassthrough app = new TestFBOPassthrough();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ int w = settings.getWidth();
+ int h = settings.getHeight();
+
+ //setup framebuffer
+ fb = new FrameBuffer(w, h, 1);
+
+ Texture2D fbTex = new Texture2D(w, h, Format.RGBA8);
+ fb.setDepthBuffer(Format.Depth);
+ fb.setColorTexture(fbTex);
+
+ // setup framebuffer's scene
+ Sphere sphMesh = new Sphere(20, 20, 1);
+ Material solidColor = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
+
+ Geometry sphere = new Geometry("sphere", sphMesh);
+ sphere.setMaterial(solidColor);
+ fbNode.attachChild(sphere);
+
+ //setup main scene
+ Picture p = new Picture("Picture");
+ p.setPosition(0, 0);
+ p.setWidth(w);
+ p.setHeight(h);
+ p.setTexture(assetManager, fbTex, false);
+
+ rootNode.attachChild(p);
+ }
+
+ @Override
+ public void simpleUpdate(float tpf){
+ fbNode.updateLogicalState(tpf);
+ fbNode.updateGeometricState();
+ }
+
+ @Override
+ public void simpleRender(RenderManager rm){
+ Renderer r = rm.getRenderer();
+
+ //do FBO rendering
+ r.setFrameBuffer(fb);
+
+ rm.setCamera(cam, false); // FBO uses current camera
+ r.clearBuffers(true, true, true);
+ rm.renderScene(fbNode, viewPort);
+ rm.flushQueue(viewPort);
+
+ //go back to default rendering and let
+ //SimpleApplication render the default scene
+ r.setFrameBuffer(null);
+ }
+
+}
diff --git a/engine/src/test/jme3test/post/TestFog.java b/engine/src/test/jme3test/post/TestFog.java
new file mode 100644
index 0000000..220a070
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestFog.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2009-2010 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.asset.plugins.HttpZipLocator;
+import com.jme3.asset.plugins.ZipLocator;
+import com.jme3.input.KeyInput;
+import com.jme3.input.controls.ActionListener;
+import com.jme3.input.controls.AnalogListener;
+import com.jme3.input.controls.KeyTrigger;
+import com.jme3.light.DirectionalLight;
+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.FogFilter;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.util.SkyFactory;
+import java.io.File;
+
+public class TestFog extends SimpleApplication {
+
+ private FilterPostProcessor fpp;
+ private boolean enabled=true;
+ private FogFilter fog;
+
+ // set default for applets
+ private static boolean useHttp = true;
+
+ public static void main(String[] args) {
+ File file = new File("wildhouse.zip");
+ if (file.exists()) {
+ useHttp = false;
+ }
+ TestFog app = new TestFog();
+ app.start();
+ }
+
+ public void simpleInitApp() {
+ this.flyCam.setMoveSpeed(10);
+ Node mainScene=new Node();
+ cam.setLocation(new Vector3f(-27.0f, 1.0f, 75.0f));
+ cam.setRotation(new Quaternion(0.03f, 0.9f, 0f, 0.4f));
+
+ // load sky
+ mainScene.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
+
+ // create the geometry and attach it
+ // load the level from zip or http zip
+ if (useHttp) {
+ assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip", HttpZipLocator.class.getName());
+ } else {
+ assetManager.registerLocator("wildhouse.zip", ZipLocator.class.getName());
+ }
+ Spatial scene = assetManager.loadModel("main.scene");
+
+ DirectionalLight sun = new DirectionalLight();
+ Vector3f lightDir=new Vector3f(-0.37352666f, -0.50444174f, -0.7784704f);
+ sun.setDirection(lightDir);
+ sun.setColor(ColorRGBA.White.clone().multLocal(2));
+ scene.addLight(sun);
+
+
+ mainScene.attachChild(scene);
+ rootNode.attachChild(mainScene);
+
+ fpp=new FilterPostProcessor(assetManager);
+ //fpp.setNumSamples(4);
+ fog=new FogFilter();
+ fog.setFogColor(new ColorRGBA(0.9f, 0.9f, 0.9f, 1.0f));
+ fog.setFogDistance(155);
+ fog.setFogDensity(2.0f);
+ fpp.addFilter(fog);
+ viewPort.addProcessor(fpp);
+ initInputs();
+ }
+
+ private void initInputs() {
+ inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addMapping("DensityUp", new KeyTrigger(KeyInput.KEY_Y));
+ inputManager.addMapping("DensityDown", new KeyTrigger(KeyInput.KEY_H));
+ inputManager.addMapping("DistanceUp", new KeyTrigger(KeyInput.KEY_U));
+ inputManager.addMapping("DistanceDown", new KeyTrigger(KeyInput.KEY_J));
+
+
+ ActionListener acl = new ActionListener() {
+
+ public void onAction(String name, boolean keyPressed, float tpf) {
+ if (name.equals("toggle") && keyPressed) {
+ if(enabled){
+ enabled=false;
+ viewPort.removeProcessor(fpp);
+ }else{
+ enabled=true;
+ viewPort.addProcessor(fpp);
+ }
+ }
+
+ }
+ };
+
+ AnalogListener anl=new AnalogListener() {
+
+ public void onAnalog(String name, float isPressed, float tpf) {
+ if(name.equals("DensityUp")){
+ fog.setFogDensity(fog.getFogDensity()+0.001f);
+ System.out.println("Fog density : "+fog.getFogDensity());
+ }
+ if(name.equals("DensityDown")){
+ fog.setFogDensity(fog.getFogDensity()-0.010f);
+ System.out.println("Fog density : "+fog.getFogDensity());
+ }
+ if(name.equals("DistanceUp")){
+ fog.setFogDistance(fog.getFogDistance()+0.5f);
+ System.out.println("Fog Distance : "+fog.getFogDistance());
+ }
+ if(name.equals("DistanceDown")){
+ fog.setFogDistance(fog.getFogDistance()-0.5f);
+ System.out.println("Fog Distance : "+fog.getFogDistance());
+ }
+
+ }
+ };
+
+ inputManager.addListener(acl, "toggle");
+ inputManager.addListener(anl, "DensityUp","DensityDown","DistanceUp","DistanceDown");
+
+ }
+}
+
diff --git a/engine/src/test/jme3test/post/TestHDR.java b/engine/src/test/jme3test/post/TestHDR.java
new file mode 100644
index 0000000..4b26069
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestHDR.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009-2010 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.material.Material;
+import com.jme3.math.Vector3f;
+import com.jme3.post.HDRRenderer;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+import com.jme3.ui.Picture;
+
+public class TestHDR extends SimpleApplication {
+
+ private HDRRenderer hdrRender;
+ private Picture dispQuad;
+
+ public static void main(String[] args){
+ TestHDR app = new TestHDR();
+ app.start();
+ }
+
+ public Geometry createHDRBox(){
+ Box boxMesh = new Box(Vector3f.ZERO, 1, 1, 1);
+ Geometry box = new Geometry("Box", boxMesh);
+
+// Material mat = assetManager.loadMaterial("Textures/HdrTest/Memorial.j3m");
+// box.setMaterial(mat);
+
+ Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+ mat.setTexture("ColorMap", assetManager.loadTexture("Textures/HdrTest/Memorial.hdr"));
+ box.setMaterial(mat);
+
+ return box;
+ }
+
+// private Material disp;
+
+ @Override
+ public void simpleInitApp() {
+ hdrRender = new HDRRenderer(assetManager, renderer);
+ hdrRender.setSamples(0);
+ hdrRender.setMaxIterations(20);
+ hdrRender.setExposure(0.87f);
+ hdrRender.setThrottle(0.33f);
+
+ viewPort.addProcessor(hdrRender);
+
+// config.setVisible(true);
+
+ rootNode.attachChild(createHDRBox());
+ }
+
+ public void simpleUpdate(float tpf){
+ if (hdrRender.isInitialized() && dispQuad == null){
+ dispQuad = hdrRender.createDisplayQuad();
+ dispQuad.setWidth(128);
+ dispQuad.setHeight(128);
+ dispQuad.setPosition(30, cam.getHeight() - 128 - 30);
+ guiNode.attachChild(dispQuad);
+ }
+ }
+
+// public void displayAvg(Renderer r){
+// r.setFrameBuffer(null);
+// disp = prepare(-1, -1, settings.getWidth(), settings.getHeight(), 3, -1, scene64, disp);
+// r.clearBuffers(true, true, true);
+// r.renderGeometry(pic);
+// }
+
+}
diff --git a/engine/src/test/jme3test/post/TestLightScattering.java b/engine/src/test/jme3test/post/TestLightScattering.java
new file mode 100644
index 0000000..cd07952
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestLightScattering.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2009-2010 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.app.StatsView;
+import com.jme3.font.BitmapText;
+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.LightScatteringFilter;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.shadow.PssmShadowRenderer;
+import com.jme3.util.SkyFactory;
+import com.jme3.util.TangentBinormalGenerator;
+
+public class TestLightScattering extends SimpleApplication {
+
+ public static void main(String[] args) {
+ TestLightScattering app = new TestLightScattering();
+
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ // put the camera in a bad position
+ cam.setLocation(new Vector3f(55.35316f, -0.27061665f, 27.092093f));
+ cam.setRotation(new Quaternion(0.010414706f, 0.9874893f, 0.13880467f, -0.07409228f));
+// cam.setDirection(new Vector3f(0,-0.5f,1.0f));
+// cam.setLocation(new Vector3f(0, 300, -500));
+ //cam.setFrustumFar(1000);
+ flyCam.setMoveSpeed(10);
+ Material mat = assetManager.loadMaterial("Textures/Terrain/Rocky/Rocky.j3m");
+ Spatial scene = assetManager.loadModel("Models/Terrain/Terrain.mesh.xml");
+ TangentBinormalGenerator.generate(((Geometry)((Node)scene).getChild(0)).getMesh());
+ scene.setMaterial(mat);
+ scene.setShadowMode(ShadowMode.CastAndReceive);
+ scene.setLocalScale(400);
+ scene.setLocalTranslation(0, -10, -120);
+
+ rootNode.attachChild(scene);
+
+ // load sky
+ rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/FullskiesBlueClear03.dds", false));
+
+ DirectionalLight sun = new DirectionalLight();
+ Vector3f lightDir = new Vector3f(-0.12f, -0.3729129f, 0.74847335f);
+ sun.setDirection(lightDir);
+ sun.setColor(ColorRGBA.White.clone().multLocal(2));
+ scene.addLight(sun);
+
+ PssmShadowRenderer pssmRenderer = new PssmShadowRenderer(assetManager,1024,4);
+ pssmRenderer.setDirection(lightDir);
+ pssmRenderer.setShadowIntensity(0.55f);
+ // viewPort.addProcessor(pssmRenderer);
+
+ FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
+// SSAOFilter ssaoFilter= new SSAOFilter(viewPort, new SSAOConfig(0.36f,1.8f,0.84f,0.16f,false,true));
+// fpp.addFilter(ssaoFilter);
+
+
+// Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+// mat2.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
+//
+// Sphere lite=new Sphere(8, 8, 10.0f);
+// Geometry lightSphere=new Geometry("lightsphere", lite);
+// lightSphere.setMaterial(mat2);
+ Vector3f lightPos = lightDir.multLocal(-3000);
+// lightSphere.setLocalTranslation(lightPos);
+ // rootNode.attachChild(lightSphere);
+ LightScatteringFilter filter = new LightScatteringFilter(lightPos);
+ LightScatteringUI ui = new LightScatteringUI(inputManager, filter);
+ fpp.addFilter(filter);
+//fpp.setNumSamples(4);
+ //fpp.addFilter(new RadialBlurFilter(0.3f,15.0f));
+ // SSAOUI ui=new SSAOUI(inputManager, ssaoFilter.getConfig());
+
+ viewPort.addProcessor(fpp);
+ }
+
+ @Override
+ public void simpleUpdate(float tpf) {
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestMultiRenderTarget.java b/engine/src/test/jme3test/post/TestMultiRenderTarget.java
new file mode 100644
index 0000000..5b31bdd
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestMultiRenderTarget.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2009-2010 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.light.PointLight;
+import com.jme3.material.Material;
+import com.jme3.math.*;
+import com.jme3.post.SceneProcessor;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture2D;
+import com.jme3.ui.Picture;
+
+public class TestMultiRenderTarget extends SimpleApplication implements SceneProcessor {
+
+ private FrameBuffer fb;
+ private Texture2D diffuseData, normalData, specularData, depthData;
+ private Geometry sphere;
+ private Picture display1, display2, display3, display4;
+
+ private Picture display;
+ private Material mat;
+
+ public static void main(String[] args){
+ TestMultiRenderTarget app = new TestMultiRenderTarget();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ viewPort.addProcessor(this);
+ renderManager.setForcedTechnique("GBuf");
+
+// flyCam.setEnabled(false);
+ cam.setLocation(new Vector3f(4.8037705f, 4.851632f, 10.789033f));
+ cam.setRotation(new Quaternion(-0.05143692f, 0.9483723f, -0.21131563f, -0.230846f));
+
+ Node tank = (Node) assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml");
+
+ //tankMesh.getMaterial().setColor("Specular", ColorRGBA.Black);
+ rootNode.attachChild(tank);
+
+ display1 = new Picture("Picture");
+ display1.move(0, 0, -1); // make it appear behind stats view
+ display2 = (Picture) display1.clone();
+ display3 = (Picture) display1.clone();
+ display4 = (Picture) display1.clone();
+ display = (Picture) display1.clone();
+
+ ColorRGBA[] colors = new ColorRGBA[]{
+ ColorRGBA.White,
+ ColorRGBA.Blue,
+ ColorRGBA.Cyan,
+ ColorRGBA.DarkGray,
+ ColorRGBA.Green,
+ ColorRGBA.Magenta,
+ ColorRGBA.Orange,
+ ColorRGBA.Pink,
+ ColorRGBA.Red,
+ ColorRGBA.Yellow
+ };
+
+ for (int i = 0; i < 3; i++){
+ PointLight pl = new PointLight();
+ float angle = 0.314159265f * i;
+ pl.setPosition( new Vector3f(FastMath.cos(angle)*2f, 0,
+ FastMath.sin(angle)*2f));
+ pl.setColor(colors[i]);
+ pl.setRadius(5);
+ rootNode.addLight(pl);
+ display.addLight(pl);
+ }
+ }
+
+ public void initialize(RenderManager rm, ViewPort vp) {
+ reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight());
+ viewPort.setOutputFrameBuffer(fb);
+ guiViewPort.setClearFlags(true, true, true);
+ guiNode.attachChild(display);
+// guiNode.attachChild(display1);
+// guiNode.attachChild(display2);
+// guiNode.attachChild(display3);
+// guiNode.attachChild(display4);
+ guiNode.updateGeometricState();
+ }
+
+ public void reshape(ViewPort vp, int w, int h) {
+ diffuseData = new Texture2D(w, h, Format.RGBA8);
+ normalData = new Texture2D(w, h, Format.RGBA8);
+ specularData = new Texture2D(w, h, Format.RGBA8);
+ depthData = new Texture2D(w, h, Format.Depth);
+
+ mat = new Material(assetManager, "Common/MatDefs/Light/Deferred.j3md");
+ mat.setTexture("DiffuseData", diffuseData);
+ mat.setTexture("SpecularData", specularData);
+ mat.setTexture("NormalData", normalData);
+ mat.setTexture("DepthData", depthData);
+
+ display.setMaterial(mat);
+ display.setPosition(0, 0);
+ display.setWidth(w);
+ display.setHeight(h);
+
+ display1.setTexture(assetManager, diffuseData, false);
+ display2.setTexture(assetManager, normalData, false);
+ display3.setTexture(assetManager, specularData, false);
+ display4.setTexture(assetManager, depthData, false);
+
+ display1.setPosition(0, 0);
+ display2.setPosition(w/2, 0);
+ display3.setPosition(0, h/2);
+ display4.setPosition(w/2, h/2);
+
+ display1.setWidth(w/2);
+ display1.setHeight(h/2);
+
+ display2.setWidth(w/2);
+ display2.setHeight(h/2);
+
+ display3.setWidth(w/2);
+ display3.setHeight(h/2);
+
+ display4.setWidth(w/2);
+ display4.setHeight(h/2);
+
+ guiNode.updateGeometricState();
+
+ fb = new FrameBuffer(w, h, 1);
+ fb.setDepthTexture(depthData);
+ fb.addColorTexture(diffuseData);
+ fb.addColorTexture(normalData);
+ fb.addColorTexture(specularData);
+ fb.setMultiTarget(true);
+
+ /*
+ * Marks pixels in front of the far light boundary
+ Render back-faces of light volume
+ Depth test GREATER-EQUAL
+ Write to stencil on depth pass
+ Skipped for very small distant lights
+ */
+
+ /*
+ * Find amount of lit pixels inside the volume
+ Start pixel query
+ Render front faces of light volume
+ Depth test LESS-EQUAL
+ Don’t write anything – only EQUAL stencil test
+ */
+
+ /*
+ * Enable conditional rendering
+ Based on query results from previous stage
+ GPU skips rendering for invisible lights
+ */
+
+ /*
+ * Render front-faces of light volume
+ Depth test - LESS-EQUAL
+ Stencil test - EQUAL
+ Runs only on marked pixels inside light
+ */
+ }
+
+ public boolean isInitialized() {
+ return diffuseData != null;
+ }
+
+ public void preFrame(float tpf) {
+ Matrix4f inverseViewProj = cam.getViewProjectionMatrix().invert();
+ mat.setMatrix4("ViewProjectionMatrixInverse", inverseViewProj);
+ }
+
+ public void postQueue(RenderQueue rq) {
+ }
+
+ public void postFrame(FrameBuffer out) {
+ }
+
+ public void cleanup() {
+ }
+
+}
diff --git a/engine/src/test/jme3test/post/TestMultiViewsFilters.java b/engine/src/test/jme3test/post/TestMultiViewsFilters.java
new file mode 100644
index 0000000..d2ef9d4
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestMultiViewsFilters.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2009-2010 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.math.ColorRGBA;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.*;
+import com.jme3.post.ssao.SSAOFilter;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.util.SkyFactory;
+
+public class TestMultiViewsFilters extends SimpleApplication {
+
+ public static void main(String[] args) {
+ TestMultiViewsFilters app = new TestMultiViewsFilters();
+ app.start();
+ }
+ private boolean filterEnabled = true;
+
+ public void simpleInitApp() {
+ // create the geometry and attach it
+ Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj");
+ teaGeom.scale(3);
+ teaGeom.getMaterial().setColor("GlowColor", ColorRGBA.Green);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setColor(ColorRGBA.White);
+ dl.setDirection(Vector3f.UNIT_XYZ.negate());
+
+ rootNode.addLight(dl);
+ rootNode.attachChild(teaGeom);
+
+ // Setup first view
+ cam.setViewPort(.5f, 1f, 0f, 0.5f);
+ cam.setLocation(new Vector3f(3.3212643f, 4.484704f, 4.2812433f));
+ cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f));
+
+ // Setup second view
+ Camera cam2 = cam.clone();
+ cam2.setViewPort(0f, 0.5f, 0f, 0.5f);
+ cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f));
+ cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f));
+
+ final ViewPort view2 = renderManager.createMainView("Bottom Left", cam2);
+ view2.setClearFlags(true, true, true);
+ view2.attachScene(rootNode);
+
+ // Setup third view
+ Camera cam3 = cam.clone();
+ cam3.setName("cam3");
+ cam3.setViewPort(0f, .5f, .5f, 1f);
+ cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f));
+ cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f));
+
+ final ViewPort view3 = renderManager.createMainView("Top Left", cam3);
+ view3.setClearFlags(true, true, true);
+ view3.attachScene(rootNode);
+
+
+ // Setup fourth view
+ Camera cam4 = cam.clone();
+ cam4.setName("cam4");
+ cam4.setViewPort(.5f, 1f, .5f, 1f);
+
+ cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f));
+ cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f));
+
+ final ViewPort view4 = renderManager.createMainView("Top Right", cam4);
+ view4.setClearFlags(true, true, true);
+ view4.attachScene(rootNode);
+
+// Camera cam5 = new Camera(200, 200);
+// cam5.setFrustumPerspective(45f, (float)cam.getWidth() / cam.getHeight(), 1f, 1000f);
+// cam5.setName("cam5");
+// cam5.setViewPort(5.23f, 6.33f, 0.56f, 1.66f);
+// this.setViewPortAreas(5.23f, 6.33f, 0.56f, 1.66f);
+// this.setViewPortCamSize(200, 200);
+// 1046,1266,112,332
+ Camera cam5 = cam.clone();
+ cam5.setName("cam5");
+ cam5.setViewPort(1046f/settings.getWidth(), 1266f/settings.getWidth(), 112f/settings.getHeight(), 332f/settings.getHeight());
+ cam5.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f));
+ cam5.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f));
+
+ final ViewPort view5 = renderManager.createMainView("center", cam5);
+ view5.setClearFlags(true, true, true);
+ view5.attachScene(rootNode);
+
+
+
+ rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
+
+ final FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
+ final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager);
+ final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager);
+ final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager);
+ final FilterPostProcessor fpp5 = new FilterPostProcessor(assetManager);
+
+
+ // fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1)));
+ fpp3.addFilter(new CartoonEdgeFilter());
+
+ fpp2.addFilter(new CrossHatchFilter());
+ final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2);
+ fpp.addFilter(ff);
+
+ final RadialBlurFilter rbf = new RadialBlurFilter(1, 10);
+ // rbf.setEnabled(false);
+ fpp.addFilter(rbf);
+
+
+ SSAOFilter f = new SSAOFilter(1.8899765f, 20.490374f, 0.4699998f, 0.1f);;
+ fpp4.addFilter(f);
+ SSAOUI ui = new SSAOUI(inputManager, f);
+
+ fpp5.addFilter(new BloomFilter(BloomFilter.GlowMode.Objects));
+
+ viewPort.addProcessor(fpp);
+ view2.addProcessor(fpp2);
+ view3.addProcessor(fpp3);
+ view4.addProcessor(fpp4);
+ view5.addProcessor(fpp5);
+
+
+
+ inputManager.addListener(new ActionListener() {
+
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if (name.equals("press") && isPressed) {
+ if (filterEnabled) {
+ viewPort.removeProcessor(fpp);
+ view2.removeProcessor(fpp2);
+ view3.removeProcessor(fpp3);
+ view4.removeProcessor(fpp4);
+ view5.removeProcessor(fpp5);
+ } else {
+ viewPort.addProcessor(fpp);
+ view2.addProcessor(fpp2);
+ view3.addProcessor(fpp3);
+ view4.addProcessor(fpp4);
+ view5.addProcessor(fpp5);
+ }
+ filterEnabled = !filterEnabled;
+ }
+ if (name.equals("filter") && isPressed) {
+ ff.setEnabled(!ff.isEnabled());
+ rbf.setEnabled(!rbf.isEnabled());
+ }
+ }
+ }, "press", "filter");
+
+ inputManager.addMapping("press", new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addMapping("filter", new KeyTrigger(KeyInput.KEY_F));
+
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestMultiplesFilters.java b/engine/src/test/jme3test/post/TestMultiplesFilters.java
new file mode 100644
index 0000000..87e4c4a
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestMultiplesFilters.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2009-2010 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.asset.plugins.HttpZipLocator;
+import com.jme3.asset.plugins.ZipLocator;
+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.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.ColorOverlayFilter;
+import com.jme3.post.ssao.SSAOFilter;
+import com.jme3.scene.Spatial;
+import com.jme3.util.SkyFactory;
+import com.jme3.water.WaterFilter;
+import java.io.File;
+
+public class TestMultiplesFilters extends SimpleApplication {
+
+ private static boolean useHttp = false;
+
+ public static void main(String[] args) {
+ File file = new File("wildhouse.zip");
+ if (!file.exists()) {
+ useHttp = true;
+ }
+ TestMultiplesFilters app = new TestMultiplesFilters();
+ app.start();
+ }
+ SSAOFilter ssaoFilter;
+ FilterPostProcessor fpp;
+ boolean en = true;
+
+ public void simpleInitApp() {
+ this.flyCam.setMoveSpeed(10);
+ cam.setLocation(new Vector3f(6.0344796f, 1.5054002f, 55.572033f));
+ cam.setRotation(new Quaternion(0.0016069f, 0.9810479f, -0.008143323f, 0.19358753f));
+
+ // load sky
+ rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
+
+ // create the geometry and attach it
+ // load the level from zip or http zip
+ if (useHttp) {
+ assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip", HttpZipLocator.class.getName());
+ } else {
+ assetManager.registerLocator("wildhouse.zip", ZipLocator.class.getName());
+ }
+ Spatial scene = assetManager.loadModel("main.scene");
+
+
+ DirectionalLight sun = new DirectionalLight();
+ sun.setDirection(new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f));
+ sun.setColor(ColorRGBA.White.clone().multLocal(2));
+ scene.addLight(sun);
+
+ fpp = new FilterPostProcessor(assetManager);
+ // fpp.setNumSamples(4);
+ ssaoFilter = new SSAOFilter(0.92f, 2.2f, 0.46f, 0.2f);
+ final WaterFilter water=new WaterFilter(rootNode,new Vector3f(-0.4790551f, -0.39247334f, -0.7851566f));
+ water.setWaterHeight(-20);
+ SSAOUI ui=new SSAOUI(inputManager,ssaoFilter);
+ final BloomFilter bloom = new BloomFilter();
+ final ColorOverlayFilter overlay = new ColorOverlayFilter(ColorRGBA.LightGray);
+
+
+ fpp.addFilter(ssaoFilter);
+
+ fpp.addFilter(water);
+
+ fpp.addFilter(bloom);
+
+ fpp.addFilter(overlay);
+
+ viewPort.addProcessor(fpp);
+
+ rootNode.attachChild(scene);
+
+ inputManager.addListener(new ActionListener() {
+
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if ("toggleSSAO".equals(name) && isPressed) {
+ if (ssaoFilter.isEnabled()) {
+ ssaoFilter.setEnabled(false);
+ } else {
+ ssaoFilter.setEnabled(true);
+ }
+ }
+ if ("toggleWater".equals(name) && isPressed) {
+ if (water.isEnabled()) {
+ water.setEnabled(false);
+ } else {
+ water.setEnabled(true);
+ }
+ }
+ if ("toggleBloom".equals(name) && isPressed) {
+ if (bloom.isEnabled()) {
+ bloom.setEnabled(false);
+ } else {
+ bloom.setEnabled(true);
+ }
+ }
+ if ("toggleOverlay".equals(name) && isPressed) {
+ if (overlay.isEnabled()) {
+ overlay.setEnabled(false);
+ } else {
+ overlay.setEnabled(true);
+ }
+ }
+ }
+ }, "toggleSSAO", "toggleBloom", "toggleWater","toggleOverlay");
+ inputManager.addMapping("toggleSSAO", new KeyTrigger(KeyInput.KEY_1));
+ inputManager.addMapping("toggleWater", new KeyTrigger(KeyInput.KEY_2));
+ inputManager.addMapping("toggleBloom", new KeyTrigger(KeyInput.KEY_3));
+ inputManager.addMapping("toggleOverlay", new KeyTrigger(KeyInput.KEY_4));
+
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestPostFilters.java b/engine/src/test/jme3test/post/TestPostFilters.java
new file mode 100644
index 0000000..6b41059
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestPostFilters.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2009-2010 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.*;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.ColorOverlayFilter;
+import com.jme3.post.filters.FadeFilter;
+import com.jme3.post.filters.RadialBlurFilter;
+import com.jme3.renderer.Caps;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.Spatial.CullHint;
+import com.jme3.scene.shape.Box;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture.WrapMode;
+import com.jme3.util.SkyFactory;
+import com.jme3.util.TangentBinormalGenerator;
+
+public class TestPostFilters extends SimpleApplication implements ActionListener {
+
+ private FilterPostProcessor fpp;
+ private Vector3f lightDir = new Vector3f(-1, -1, .5f).normalizeLocal();
+ FadeFilter fade;
+
+ public static void main(String[] args) {
+ TestPostFilters app = new TestPostFilters();
+ app.start();
+ }
+
+ public void setupFilters() {
+ if (renderer.getCaps().contains(Caps.GLSL100)) {
+ fpp = new FilterPostProcessor(assetManager);
+ // fpp.setNumSamples(4);
+ fpp.addFilter(new ColorOverlayFilter(ColorRGBA.LightGray));
+ fpp.addFilter(new RadialBlurFilter());
+ //fade=new FadeFilter(1.0f);
+ //fpp.addFilter(fade);
+
+
+ viewPort.addProcessor(fpp);
+ }
+ }
+
+ public void setupSkyBox() {
+ Texture envMap;
+ if (renderer.getCaps().contains(Caps.FloatTexture)) {
+ envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.hdr");
+ } else {
+ envMap = assetManager.loadTexture("Textures/Sky/St Peters/StPeters.jpg");
+ }
+ rootNode.attachChild(SkyFactory.createSky(assetManager, envMap, new Vector3f(-1, -1, -1), true));
+ }
+
+ public void setupLighting() {
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(lightDir);
+
+ dl.setColor(new ColorRGBA(.9f, .9f, .9f, 1));
+
+ rootNode.addLight(dl);
+
+ dl = new DirectionalLight();
+ dl.setDirection(new Vector3f(1, 0, -1).normalizeLocal());
+
+ dl.setColor(new ColorRGBA(.4f, .4f, .4f, 1));
+
+ rootNode.addLight(dl);
+ }
+
+ public void setupFloor() {
+ Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m");
+ mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat);
+ mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat);
+ mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat);
+ Box floor = new Box(Vector3f.ZERO, 50, 1f, 50);
+ TangentBinormalGenerator.generate(floor);
+ floor.scaleTextureCoordinates(new Vector2f(5, 5));
+ Geometry floorGeom = new Geometry("Floor", floor);
+ floorGeom.setMaterial(mat);
+ floorGeom.setShadowMode(ShadowMode.Receive);
+ rootNode.attachChild(floorGeom);
+ }
+
+ public void setupSignpost() {
+ Spatial signpost = assetManager.loadModel("Models/Sign Post/Sign Post.mesh.xml");
+ Material mat = assetManager.loadMaterial("Models/Sign Post/Sign Post.j3m");
+ signpost.setMaterial(mat);
+ signpost.rotate(0, FastMath.HALF_PI, 0);
+ signpost.setLocalTranslation(12, 3.5f, 30);
+ signpost.setLocalScale(4);
+ signpost.setShadowMode(ShadowMode.CastAndReceive);
+ rootNode.attachChild(signpost);
+ }
+
+ @Override
+ public void simpleInitApp() {
+ cam.setLocation(new Vector3f(-32.295086f, 54.80136f, 79.59805f));
+ cam.setRotation(new Quaternion(0.074364014f, 0.92519957f, -0.24794696f, 0.27748522f));
+ cam.update();
+
+ cam.setFrustumFar(300);
+ flyCam.setMoveSpeed(30);
+
+ rootNode.setCullHint(CullHint.Never);
+
+ setupLighting();
+ setupSkyBox();
+
+
+ setupFloor();
+
+ setupSignpost();
+
+ setupFilters();
+
+ initInput();
+
+ }
+
+ protected void initInput() {
+ flyCam.setMoveSpeed(3);
+ //init input
+ inputManager.addMapping("fadein", new KeyTrigger(KeyInput.KEY_I));
+ inputManager.addListener(this, "fadein");
+ inputManager.addMapping("fadeout", new KeyTrigger(KeyInput.KEY_O));
+ inputManager.addListener(this, "fadeout");
+
+ }
+
+ public void onAction(String name, boolean value, float tpf) {
+ if (name.equals("fadein") && value) {
+ fade.fadeIn();
+ System.out.println("fade in");
+
+ }
+ if (name.equals("fadeout") && value) {
+ fade.fadeOut();
+ System.out.println("fade out");
+ }
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestPosterization.java b/engine/src/test/jme3test/post/TestPosterization.java
new file mode 100644
index 0000000..e2c24e8
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestPosterization.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009-2010 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.PosterizationFilter;
+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 TestPosterization extends SimpleApplication {
+
+ float angle;
+ Spatial lightMdl;
+ Spatial teapot;
+ Geometry frustumMdl;
+ WireFrustum frustum;
+ boolean active=true;
+ FilterPostProcessor fpp;
+
+ public static void main(String[] args){
+ TestPosterization app = new TestPosterization();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ // put the camera in a bad position
+ cam.setLocation(new Vector3f(-2.336393f, 11.91392f, -7.139601f));
+ 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));
+
+
+
+
+ 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);
+
+ 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);
+ PosterizationFilter pf=new PosterizationFilter();
+
+
+
+ viewPort.addProcessor(fpp);
+ fpp.addFilter(pf);
+ initInputs();
+
+ }
+
+ private void initInputs() {
+ inputManager.addMapping("toggle", new KeyTrigger(KeyInput.KEY_SPACE));
+
+ ActionListener acl = new ActionListener() {
+
+ 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/engine/src/test/jme3test/post/TestRenderToMemory.java b/engine/src/test/jme3test/post/TestRenderToMemory.java
new file mode 100644
index 0000000..4a97844
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestRenderToMemory.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (c) 2009-2010 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.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.post.SceneProcessor;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.RenderManager;
+import com.jme3.renderer.ViewPort;
+import com.jme3.renderer.queue.RenderQueue;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+import com.jme3.system.AppSettings;
+import com.jme3.system.JmeContext.Type;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture2D;
+import com.jme3.util.BufferUtils;
+import com.jme3.util.Screenshots;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import java.nio.ByteBuffer;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+/**
+ * This test renders a scene to an offscreen framebuffer, then copies
+ * the contents to a Swing JFrame. Note that some parts are done inefficently,
+ * this is done to make the code more readable.
+ */
+public class TestRenderToMemory extends SimpleApplication implements SceneProcessor {
+
+ private Geometry offBox;
+ private float angle = 0;
+
+ private FrameBuffer offBuffer;
+ private ViewPort offView;
+ private Texture2D offTex;
+ private Camera offCamera;
+ private ImageDisplay display;
+
+ private static final int width = 800, height = 600;
+
+ private final ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4);
+ private final byte[] cpuArray = new byte[width * height * 4];
+ private final BufferedImage image = new BufferedImage(width, height,
+ BufferedImage.TYPE_4BYTE_ABGR);
+
+ private class ImageDisplay extends JPanel {
+
+ private long t;
+ private long total;
+ private int frames;
+ private int fps;
+
+ @Override
+ public void paintComponent(Graphics gfx) {
+ super.paintComponent(gfx);
+ Graphics2D g2d = (Graphics2D) gfx;
+
+ if (t == 0)
+ t = timer.getTime();
+
+// g2d.setBackground(Color.BLACK);
+// g2d.clearRect(0,0,width,height);
+
+ synchronized (image){
+ g2d.drawImage(image, null, 0, 0);
+ }
+
+ long t2 = timer.getTime();
+ long dt = t2 - t;
+ total += dt;
+ frames ++;
+ t = t2;
+
+ if (total > 1000){
+ fps = frames;
+ total = 0;
+ frames = 0;
+ }
+
+ g2d.setColor(Color.white);
+ g2d.drawString("FPS: "+fps, 0, getHeight() - 100);
+ }
+ }
+
+ public static void main(String[] args){
+ TestRenderToMemory app = new TestRenderToMemory();
+ app.setPauseOnLostFocus(false);
+ AppSettings settings = new AppSettings(true);
+ settings.setResolution(1, 1);
+ app.setSettings(settings);
+ app.start(Type.OffscreenSurface);
+ }
+
+ public void createDisplayFrame(){
+ SwingUtilities.invokeLater(new Runnable(){
+ public void run(){
+ JFrame frame = new JFrame("Render Display");
+ display = new ImageDisplay();
+ display.setPreferredSize(new Dimension(width, height));
+ frame.getContentPane().add(display);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ frame.addWindowListener(new WindowAdapter(){
+ public void windowClosed(WindowEvent e){
+ stop();
+ }
+ });
+ frame.pack();
+ frame.setLocationRelativeTo(null);
+ frame.setResizable(false);
+ frame.setVisible(true);
+ }
+ });
+ }
+
+ public void updateImageContents(){
+ cpuBuf.clear();
+ renderer.readFrameBuffer(offBuffer, cpuBuf);
+
+ synchronized (image) {
+ Screenshots.convertScreenShot(cpuBuf, image);
+ }
+
+ if (display != null)
+ display.repaint();
+ }
+
+ public void setupOffscreenView(){
+ offCamera = new Camera(width, height);
+
+ // create a pre-view. a view that is rendered before the main view
+ offView = renderManager.createPreView("Offscreen View", offCamera);
+ offView.setBackgroundColor(ColorRGBA.DarkGray);
+ offView.setClearFlags(true, true, true);
+
+ // this will let us know when the scene has been rendered to the
+ // frame buffer
+ offView.addProcessor(this);
+
+ // create offscreen framebuffer
+ offBuffer = new FrameBuffer(width, height, 1);
+
+ //setup framebuffer's cam
+ offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
+ offCamera.setLocation(new Vector3f(0f, 0f, -5f));
+ offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
+
+ //setup framebuffer's texture
+// offTex = new Texture2D(width, height, Format.RGBA8);
+
+ //setup framebuffer to use renderbuffer
+ // this is faster for gpu -> cpu copies
+ offBuffer.setDepthBuffer(Format.Depth);
+ offBuffer.setColorBuffer(Format.RGBA8);
+// offBuffer.setColorTexture(offTex);
+
+ //set viewport to render to offscreen framebuffer
+ offView.setOutputFrameBuffer(offBuffer);
+
+ // setup framebuffer's scene
+ Box boxMesh = new Box(Vector3f.ZERO, 1,1,1);
+ Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m");
+ offBox = new Geometry("box", boxMesh);
+ offBox.setMaterial(material);
+
+ // attach the scene to the viewport to be rendered
+ offView.attachScene(offBox);
+ }
+
+ @Override
+ public void simpleInitApp() {
+ setupOffscreenView();
+ createDisplayFrame();
+ }
+
+ @Override
+ public void simpleUpdate(float tpf){
+ Quaternion q = new Quaternion();
+ angle += tpf;
+ angle %= FastMath.TWO_PI;
+ q.fromAngles(angle, 0, angle);
+
+ offBox.setLocalRotation(q);
+ offBox.updateLogicalState(tpf);
+ offBox.updateGeometricState();
+ }
+
+ public void initialize(RenderManager rm, ViewPort vp) {
+ }
+
+ public void reshape(ViewPort vp, int w, int h) {
+ }
+
+ public boolean isInitialized() {
+ return true;
+ }
+
+ public void preFrame(float tpf) {
+ }
+
+ public void postQueue(RenderQueue rq) {
+ }
+
+ /**
+ * Update the CPU image's contents after the scene has
+ * been rendered to the framebuffer.
+ */
+ public void postFrame(FrameBuffer out) {
+ updateImageContents();
+ }
+
+ public void cleanup() {
+ }
+
+
+}
diff --git a/engine/src/test/jme3test/post/TestRenderToTexture.java b/engine/src/test/jme3test/post/TestRenderToTexture.java
new file mode 100644
index 0000000..ccc993a
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestRenderToTexture.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2009-2010 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.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.FastMath;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector3f;
+import com.jme3.renderer.Camera;
+import com.jme3.renderer.ViewPort;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.shape.Box;
+import com.jme3.texture.FrameBuffer;
+import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture2D;
+
+/**
+ * This test renders a scene to a texture, then displays the texture on a cube.
+ */
+public class TestRenderToTexture extends SimpleApplication implements ActionListener {
+
+ private static final String TOGGLE_UPDATE = "Toggle Update";
+ private Geometry offBox;
+ private float angle = 0;
+ private ViewPort offView;
+
+ public static void main(String[] args){
+ TestRenderToTexture app = new TestRenderToTexture();
+ app.start();
+ }
+
+ public Texture setupOffscreenView(){
+ Camera offCamera = new Camera(512, 512);
+
+ offView = renderManager.createPreView("Offscreen View", offCamera);
+ offView.setClearFlags(true, true, true);
+ offView.setBackgroundColor(ColorRGBA.DarkGray);
+
+ // create offscreen framebuffer
+ FrameBuffer offBuffer = new FrameBuffer(512, 512, 1);
+
+ //setup framebuffer's cam
+ offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
+ offCamera.setLocation(new Vector3f(0f, 0f, -5f));
+ offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
+
+ //setup framebuffer's texture
+ Texture2D offTex = new Texture2D(512, 512, Format.RGBA8);
+ offTex.setMinFilter(Texture.MinFilter.Trilinear);
+ offTex.setMagFilter(Texture.MagFilter.Bilinear);
+
+ //setup framebuffer to use texture
+ offBuffer.setDepthBuffer(Format.Depth);
+ offBuffer.setColorTexture(offTex);
+
+ //set viewport to render to offscreen framebuffer
+ offView.setOutputFrameBuffer(offBuffer);
+
+ // setup framebuffer's scene
+ Box boxMesh = new Box(Vector3f.ZERO, 1,1,1);
+ Material material = assetManager.loadMaterial("Interface/Logo/Logo.j3m");
+ offBox = new Geometry("box", boxMesh);
+ offBox.setMaterial(material);
+
+ // attach the scene to the viewport to be rendered
+ offView.attachScene(offBox);
+
+ return offTex;
+ }
+
+ @Override
+ public void simpleInitApp() {
+ cam.setLocation(new Vector3f(3, 3, 3));
+ cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
+
+ //setup main scene
+ Geometry quad = new Geometry("box", new Box(Vector3f.ZERO, 1,1,1));
+
+ Texture offTex = setupOffscreenView();
+
+ Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+ mat.setTexture("ColorMap", offTex);
+ quad.setMaterial(mat);
+ rootNode.attachChild(quad);
+ inputManager.addMapping(TOGGLE_UPDATE, new KeyTrigger(KeyInput.KEY_SPACE));
+ inputManager.addListener(this, TOGGLE_UPDATE);
+ }
+
+ @Override
+ public void simpleUpdate(float tpf){
+ Quaternion q = new Quaternion();
+
+ if (offView.isEnabled()) {
+ angle += tpf;
+ angle %= FastMath.TWO_PI;
+ q.fromAngles(angle, 0, angle);
+
+ offBox.setLocalRotation(q);
+ offBox.updateLogicalState(tpf);
+ offBox.updateGeometricState();
+ }
+ }
+
+ @Override
+ public void onAction(String name, boolean isPressed, float tpf) {
+ if (name.equals(TOGGLE_UPDATE) && isPressed) {
+ offView.setEnabled(!offView.isEnabled());
+ }
+ }
+
+
+}
diff --git a/engine/src/test/jme3test/post/TestSSAO.java b/engine/src/test/jme3test/post/TestSSAO.java
new file mode 100644
index 0000000..e9cef98
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestSSAO.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009-2010 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.light.AmbientLight;
+import com.jme3.material.Material;
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Quaternion;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.ssao.SSAOFilter;
+import com.jme3.scene.Geometry;
+import com.jme3.texture.Texture;
+
+public class TestSSAO extends SimpleApplication {
+
+ Geometry model;
+
+ public static void main(String[] args) {
+ TestSSAO app = new TestSSAO();
+ app.start();
+ }
+
+ @Override
+ public void simpleInitApp() {
+ cam.setLocation(new Vector3f(68.45442f, 8.235511f, 7.9676695f));
+ cam.setRotation(new Quaternion(0.046916496f, -0.69500375f, 0.045538206f, 0.7160271f));
+
+
+ flyCam.setMoveSpeed(50);
+
+ Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
+ Texture diff = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg");
+ diff.setWrap(Texture.WrapMode.Repeat);
+ Texture norm = assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall_normal.jpg");
+ norm.setWrap(Texture.WrapMode.Repeat);
+ mat.setTexture("DiffuseMap", diff);
+ mat.setTexture("NormalMap", norm);
+ mat.setFloat("Shininess", 2.0f);
+
+
+ AmbientLight al = new AmbientLight();
+ al.setColor(new ColorRGBA(1.8f, 1.8f, 1.8f, 1.0f));
+
+ rootNode.addLight(al);
+
+ model = (Geometry) assetManager.loadModel("Models/Sponza/Sponza.j3o");
+ model.getMesh().scaleTextureCoordinates(new Vector2f(2, 2));
+
+ model.setMaterial(mat);
+
+ rootNode.attachChild(model);
+
+ FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
+ SSAOFilter ssaoFilter = new SSAOFilter(12.940201f, 43.928635f, 0.32999992f, 0.6059958f);
+ fpp.addFilter(ssaoFilter);
+ SSAOUI ui = new SSAOUI(inputManager, ssaoFilter);
+
+ viewPort.addProcessor(fpp);
+ }
+
+ @Override
+ public void simpleUpdate(float tpf) {
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestTransparentCartoonEdge.java b/engine/src/test/jme3test/post/TestTransparentCartoonEdge.java
new file mode 100644
index 0000000..46ba0ac
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestTransparentCartoonEdge.java
@@ -0,0 +1,97 @@
+package jme3test.post;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.light.AmbientLight;
+import com.jme3.light.DirectionalLight;
+import com.jme3.material.Material;
+import com.jme3.math.*;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.filters.CartoonEdgeFilter;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Node;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.shape.Quad;
+import com.jme3.texture.Texture;
+
+public class TestTransparentCartoonEdge extends SimpleApplication {
+
+ public static void main(String[] args){
+ TestTransparentCartoonEdge app = new TestTransparentCartoonEdge();
+ app.start();
+ }
+
+ public void simpleInitApp() {
+ renderManager.setAlphaToCoverage(true);
+ cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f));
+ cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f));
+
+// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f));
+// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f));
+
+ viewPort.setBackgroundColor(ColorRGBA.DarkGray);
+
+ Quad q = new Quad(20, 20);
+ q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5));
+ Geometry geom = new Geometry("floor", q);
+ Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
+ geom.setMaterial(mat);
+
+ geom.rotate(-FastMath.HALF_PI, 0, 0);
+ geom.center();
+ geom.setShadowMode(ShadowMode.Receive);
+ rootNode.attachChild(geom);
+
+ // create the geometry and attach it
+ Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o");
+ teaGeom.setQueueBucket(Bucket.Transparent);
+ teaGeom.setShadowMode(ShadowMode.Cast);
+ makeToonish(teaGeom);
+
+ AmbientLight al = new AmbientLight();
+ al.setColor(ColorRGBA.White.mult(2));
+ rootNode.addLight(al);
+
+ DirectionalLight dl1 = new DirectionalLight();
+ dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal());
+ dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
+ rootNode.addLight(dl1);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
+ dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
+ rootNode.addLight(dl);
+
+ rootNode.attachChild(teaGeom);
+
+ FilterPostProcessor fpp=new FilterPostProcessor(assetManager);
+ CartoonEdgeFilter toon=new CartoonEdgeFilter();
+ toon.setEdgeWidth(0.5f);
+ toon.setEdgeIntensity(1.0f);
+ toon.setNormalThreshold(0.8f);
+ fpp.addFilter(toon);
+ viewPort.addProcessor(fpp);
+ }
+
+ public void makeToonish(Spatial spatial){
+ if (spatial instanceof Node){
+ Node n = (Node) spatial;
+ for (Spatial child : n.getChildren())
+ makeToonish(child);
+ }else if (spatial instanceof Geometry){
+ Geometry g = (Geometry) spatial;
+ Material m = g.getMaterial();
+ if (m.getMaterialDef().getName().equals("Phong Lighting")){
+ Texture t = assetManager.loadTexture("Textures/ColorRamp/toon.png");
+// t.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
+// t.setMagFilter(Texture.MagFilter.Nearest);
+ m.setTexture("ColorRamp", t);
+ m.setBoolean("UseMaterialColors", true);
+ m.setColor("Specular", ColorRGBA.Black);
+ m.setColor("Diffuse", ColorRGBA.White);
+ m.setBoolean("VertexLighting", true);
+ }
+ }
+ }
+}
diff --git a/engine/src/test/jme3test/post/TestTransparentSSAO.java b/engine/src/test/jme3test/post/TestTransparentSSAO.java
new file mode 100644
index 0000000..3d45b4a
--- /dev/null
+++ b/engine/src/test/jme3test/post/TestTransparentSSAO.java
@@ -0,0 +1,74 @@
+package jme3test.post;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.light.AmbientLight;
+import com.jme3.light.DirectionalLight;
+import com.jme3.material.Material;
+import com.jme3.math.*;
+import com.jme3.post.FilterPostProcessor;
+import com.jme3.post.ssao.SSAOFilter;
+import com.jme3.renderer.queue.RenderQueue.Bucket;
+import com.jme3.renderer.queue.RenderQueue.ShadowMode;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Spatial;
+import com.jme3.scene.shape.Quad;
+
+public class TestTransparentSSAO extends SimpleApplication {
+
+ public static void main(String[] args) {
+ TestTransparentSSAO app = new TestTransparentSSAO();
+ app.start();
+ }
+
+ public void simpleInitApp() {
+ renderManager.setAlphaToCoverage(true);
+ cam.setLocation(new Vector3f(0.14914267f, 0.58147097f, 4.7686534f));
+ cam.setRotation(new Quaternion(-0.0044764364f, 0.9767943f, 0.21314798f, 0.020512417f));
+
+// cam.setLocation(new Vector3f(2.0606942f, 3.20342f, 6.7860126f));
+// cam.setRotation(new Quaternion(-0.017481906f, 0.98241085f, -0.12393151f, -0.13857932f));
+
+ viewPort.setBackgroundColor(ColorRGBA.DarkGray);
+
+ Quad q = new Quad(20, 20);
+ q.scaleTextureCoordinates(Vector2f.UNIT_XY.mult(5));
+ Geometry geom = new Geometry("floor", q);
+ Material mat = assetManager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");
+ geom.setMaterial(mat);
+
+ geom.rotate(-FastMath.HALF_PI, 0, 0);
+ geom.center();
+ geom.setShadowMode(ShadowMode.Receive);
+ rootNode.attachChild(geom);
+
+ // create the geometry and attach it
+ Spatial teaGeom = assetManager.loadModel("Models/Tree/Tree.mesh.j3o");
+ teaGeom.setQueueBucket(Bucket.Transparent);
+ teaGeom.setShadowMode(ShadowMode.Cast);
+
+ AmbientLight al = new AmbientLight();
+ al.setColor(ColorRGBA.White.mult(2));
+ rootNode.addLight(al);
+
+ DirectionalLight dl1 = new DirectionalLight();
+ dl1.setDirection(new Vector3f(1, -1, 1).normalizeLocal());
+ dl1.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
+ rootNode.addLight(dl1);
+
+ DirectionalLight dl = new DirectionalLight();
+ dl.setDirection(new Vector3f(-1, -1, -1).normalizeLocal());
+ dl.setColor(new ColorRGBA(0.965f, 0.949f, 0.772f, 1f).mult(0.7f));
+ rootNode.addLight(dl);
+
+ rootNode.attachChild(teaGeom);
+
+ FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
+
+ SSAOFilter ssao = new SSAOFilter(0.49997783f, 42.598858f, 35.999966f, 0.39299846f);
+ fpp.addFilter(ssao);
+
+ SSAOUI ui = new SSAOUI(inputManager, ssao);
+
+ viewPort.addProcessor(fpp);
+ }
+}