Просмотр исходного кода

Post process filters :
- re-implemented multiview filters another way (filters are now correctly rendered to the size of the viewport, and that's much faster)
- fixed an issue the was messing the filter render when using setEnabled on a filter prior FilterProcessor init
- fixed a deprecated m_ mat in WaterFilter

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7476 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 14 лет назад
Родитель
Сommit
792f44cf9f

+ 14 - 13
engine/src/core/com/jme3/post/Filter.java

@@ -81,17 +81,17 @@ public abstract class Filter implements Savable {
             if (numSamples > 1 && caps.contains(Caps.FrameBufferMultisample) && caps.contains(Caps.OpenGL31)) {
                 renderFrameBuffer = new FrameBuffer(width, height, numSamples);
                 renderedTexture = new Texture2D(width, height, numSamples, textureFormat);
-              //  depthTexture = new Texture2D(width, height, numSamples, depthBufferFormat);
+                //  depthTexture = new Texture2D(width, height, numSamples, depthBufferFormat);
             } else {
                 renderFrameBuffer = new FrameBuffer(width, height, 1);
-                renderedTexture = new Texture2D(width, height, textureFormat);                
+                renderedTexture = new Texture2D(width, height, textureFormat);
 //                depthTexture = new Texture2D(width, height,  depthBufferFormat);
             }
-            
+
             renderFrameBuffer.setColorTexture(renderedTexture);
             renderFrameBuffer.setDepthBuffer(depthBufferFormat);
-  //          renderFrameBuffer.setDepthTexture(depthTexture);
-            
+            //          renderFrameBuffer.setDepthTexture(depthTexture);
+
         }
 
         public void init(Renderer renderer, int width, int height, Format textureFormat, Format depthBufferFormat) {
@@ -111,7 +111,6 @@ public abstract class Filter implements Savable {
             return false;
         }
 
-
         public void beforeRender() {
         }
 
@@ -126,7 +125,6 @@ public abstract class Filter implements Savable {
         public Texture2D getDepthTexture() {
             return depthTexture;
         }
-        
 
         public Texture2D getRenderedTexture() {
             return renderedTexture;
@@ -160,15 +158,15 @@ public abstract class Filter implements Savable {
         this("filter");
     }
 
-    public void init(FilterPostProcessor parentProcessor, AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
+    public void init(AssetManager manager, RenderManager renderManager, ViewPort vp, int w, int h) {
         //  cleanup(renderManager.getRenderer());
         defaultPass = new Pass();
-        defaultPass.init(renderManager.getRenderer(),w, h, getDefaultPassTextureFormat(), getDefaultPassDepthFormat());
-        processor = parentProcessor;
+        defaultPass.init(renderManager.getRenderer(), w, h, getDefaultPassTextureFormat(), getDefaultPassDepthFormat());
         initFilter(manager, renderManager, vp, w, h);
     }
 
     public void cleanup(Renderer r) {
+        processor = null;
         if (defaultPass != null) {
             defaultPass.cleanup(r);
         }
@@ -279,9 +277,9 @@ public abstract class Filter implements Savable {
     }
 
     public void setEnabled(boolean enabled) {
-        if(processor!=null){
+        if (processor != null) {
             processor.setFilterState(this, enabled);
-        }else{
+        } else {
             this.enabled = enabled;
         }
     }
@@ -289,5 +287,8 @@ public abstract class Filter implements Savable {
     public boolean isEnabled() {
         return enabled;
     }
-    
+
+    protected void setProcessor(FilterPostProcessor proc) {
+        processor = proc;
+    }
 }

+ 54 - 22
engine/src/core/com/jme3/post/FilterPostProcessor.java

@@ -72,9 +72,14 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     private FrameBuffer outputBuffer;
     private int width;
     private int height;
-    private int bottom;
-    private int left;
+    private float bottom;
+    private float left;
+    private float right;
+    private float top;
+    private int originalWidth;
+    private int originalHeight;
     private int lastFilterIndex = -1;
+    private boolean cameraInit = false;
 
     /**
      * Create a FilterProcessor constructor
@@ -92,13 +97,14 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
 
     public void addFilter(Filter filter) {
         filters.add(filter);
+        filter.setProcessor(this);
 
         if (isInitialized()) {
             initFilter(filter, viewPort);
         }
-        if (filter.isEnabled()) {
-            lastFilterIndex = filters.size() - 1;
-        }
+
+        setFilterState(filter, filter.isEnabled());
+
     }
 
     public void removeFilter(Filter filter) {
@@ -118,14 +124,19 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
         fsQuad = new Picture("filter full screen quad");
 
         Camera cam = vp.getCamera();
+        left = cam.getViewPortLeft();
+        right = cam.getViewPortRight();
+        top = cam.getViewPortTop();
+        bottom = cam.getViewPortBottom();
         //Changing the viewPort to the filter cam an reseting the viewport of the viewport cam
-        filterCam.setViewPort(cam.getViewPortLeft(), cam.getViewPortRight(), cam.getViewPortBottom(), cam.getViewPortTop());
+        originalWidth = cam.getWidth();
+        originalHeight = cam.getHeight();
         cam.setViewPort(0, 1, 0, 1);
         reshape(vp, cam.getWidth(), cam.getHeight());
     }
 
     private void initFilter(Filter filter, ViewPort vp) {
-        filter.init(this, assetManager, renderManager, vp, width, height);
+        filter.init(assetManager, renderManager, vp, width, height);
         if (filter.isRequiresDepthTexture()) {
             if (!computeDepth && renderFrameBuffer != null) {
                 depthTexture = new Texture2D(width, height, Format.Depth24);
@@ -137,24 +148,25 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     }
 
     private void renderProcessing(Renderer r, FrameBuffer buff, Material mat) {
-        if (buff == null) {
+        if (buff == outputBuffer) {
             fsQuad.setWidth(width);
             fsQuad.setHeight(height);
-            filterCam.resize(width, height, true);
+            filterCam.resize(originalWidth, originalHeight, true);
+            fsQuad.setPosition(left * originalWidth, bottom * originalHeight);
         } else {
             fsQuad.setWidth(buff.getWidth());
             fsQuad.setHeight(buff.getHeight());
             filterCam.resize(buff.getWidth(), buff.getHeight(), true);
+            fsQuad.setPosition(0, 0);
         }
 
 
         fsQuad.setMaterial(mat);
         fsQuad.updateGeometricState();
-        filterCam.setName("filterCam");
-        //fsQuad.setPosition(640, 360);
+
         renderManager.setCamera(filterCam, true);
         r.setFrameBuffer(buff);
-        r.clearBuffers(true, true, true);
+        r.clearBuffers(false, true, true);
         renderManager.renderGeometry(fsQuad);
     }
 
@@ -163,12 +175,14 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     }
 
     public void postQueue(RenderQueue rq) {
+
         for (Iterator<Filter> it = filters.iterator(); it.hasNext();) {
             Filter filter = it.next();
             if (filter.isEnabled()) {
                 filter.preRender(renderManager, viewPort);
             }
         }
+
     }
 
     public void renderFilterChain(Renderer r) {
@@ -225,31 +239,45 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
     }
 
     public void postFrame(FrameBuffer out) {
-        //Added this to fix the issue where the filter were not rendered when an object in the scene had a DepthWrite to false. (particles for example)
-        //there should be a better way...
-        //   renderer.applyRenderState(RenderState.DEFAULT);
+
+
         if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL31)) {
             renderer.copyFrameBuffer(renderFrameBufferMS, renderFrameBuffer);
         }
         renderFilterChain(renderer);
+
     }
 
     public void preFrame(float tpf) {
         if (filters.isEmpty() || lastFilterIndex == -1) {
-            viewPort.setOutputFrameBuffer(outputBuffer);
+            //If the camera is initialized and there are no filter to render, the camera viewport is restored as it was
+            if (cameraInit) {
+                viewPort.getCamera().resize(originalWidth, originalHeight, true);
+                viewPort.getCamera().setViewPort(left, right, bottom, top);
+                viewPort.setOutputFrameBuffer(outputBuffer);
+                cameraInit = false;
+            }
+
         } else {
             if (renderFrameBufferMS != null) {
                 viewPort.setOutputFrameBuffer(renderFrameBufferMS);
             } else {
                 viewPort.setOutputFrameBuffer(renderFrameBuffer);
             }
+            //init of the camera if it wasn't already
+            if (!cameraInit) {
+                viewPort.getCamera().resize(width, height, true);
+                viewPort.getCamera().setViewPort(0, 1, 0, 1);
+            }
         }
+
         for (Iterator<Filter> it = filters.iterator(); it.hasNext();) {
             Filter filter = it.next();
             if (filter.isEnabled()) {
                 filter.preFrame(tpf);
             }
         }
+
     }
 
     protected void setFilterState(Filter filter, boolean enabled) {
@@ -267,25 +295,29 @@ public class FilterPostProcessor implements SceneProcessor, Savable {
                 return;
             }
         }
-
+        if (lastFilterIndex == -1) {
+            cleanup();
+        }
     }
 
     public void cleanup() {
         if (viewPort != null) {
             //reseting the viewport camera viewport to its initial value
-            viewPort.getCamera().setViewPort(filterCam.getViewPortLeft(), filterCam.getViewPortRight(), filterCam.getViewPortBottom(), filterCam.getViewPortTop());
+            viewPort.getCamera().resize(originalWidth, originalHeight, true);
+            viewPort.getCamera().setViewPort(left, right, bottom, top);
             viewPort.setOutputFrameBuffer(outputBuffer);
             viewPort = null;
         }
+
     }
 
     public void reshape(ViewPort vp, int w, int h) {
-        Camera cam = vp.getCamera();
-        width = (int) (w * (Math.abs(cam.getViewPortRight() - cam.getViewPortLeft())));
-        height = (int) (h * (Math.abs(cam.getViewPortBottom() - cam.getViewPortTop())));
+        width = (int) (w * (Math.abs(right - left)));
+        height = (int) (h * (Math.abs(bottom - top)));
         width = Math.max(1, width);
         height = Math.max(1, height);
-        // vp.getCamera().resize(width, height, true);
+        vp.getCamera().resize(width, height, true);
+        cameraInit = true;
         computeDepth = false;
 
         if (renderFrameBuffer == null) {

+ 2 - 2
engine/src/desktop-fx/com/jme3/water/WaterFilter.java

@@ -233,8 +233,8 @@ public class WaterFilter extends Filter {
         material.setBoolean("UseSpecular", useSpecular);
         material.setBoolean("UseFoam", useFoam);
         material.setBoolean("UseRefraction", useRefraction);
-        material.setFloat("m_ReflectionDisplace", reflectionDisplace);
-        material.setFloat("m_FoamIntensity", foamIntensity);
+        material.setFloat("ReflectionDisplace", reflectionDisplace);
+        material.setFloat("FoamIntensity", foamIntensity);
 
     }
 

+ 42 - 15
engine/src/test/jme3test/post/TestMultiViewsFilters.java

@@ -31,22 +31,24 @@
  */
 package jme3test.post;
 
-import jme3test.renderer.*;
 import com.jme3.app.SimpleApplication;
 import com.jme3.input.KeyInput;
 import com.jme3.input.controls.ActionListener;
-import com.jme3.input.controls.InputListener;
 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.Filter;
 import com.jme3.post.FilterPostProcessor;
-import com.jme3.post.filters.ColorOverlayFilter;
+import com.jme3.post.filters.BloomFilter;
+import com.jme3.post.filters.CartoonEdgeFilter;
+import com.jme3.post.filters.FogFilter;
+import com.jme3.post.filters.RadialBlurFilter;
+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 {
 
@@ -79,7 +81,7 @@ public class TestMultiViewsFilters extends SimpleApplication {
         cam2.setLocation(new Vector3f(-0.10947256f, 1.5760219f, 4.81758f));
         cam2.setRotation(new Quaternion(0.0010108891f, 0.99857414f, -0.04928594f, 0.020481428f));
 
-        ViewPort view2 = renderManager.createMainView("Bottom Left", cam2);
+        final ViewPort view2 = renderManager.createMainView("Bottom Left", cam2);
         view2.setClearFlags(true, true, true);
         view2.attachScene(rootNode);
 
@@ -90,7 +92,7 @@ public class TestMultiViewsFilters extends SimpleApplication {
         cam3.setLocation(new Vector3f(0.2846221f, 6.4271426f, 0.23380789f));
         cam3.setRotation(new Quaternion(0.004381671f, 0.72363687f, -0.69015175f, 0.0045953835f));
 
-        ViewPort view3 = renderManager.createMainView("Top Left", cam3);
+        final ViewPort view3 = renderManager.createMainView("Top Left", cam3);
         view3.setClearFlags(true, true, true);
         view3.attachScene(rootNode);
 
@@ -103,42 +105,67 @@ public class TestMultiViewsFilters extends SimpleApplication {
         cam4.setLocation(new Vector3f(4.775564f, 1.4548365f, 0.11491505f));
         cam4.setRotation(new Quaternion(0.02356979f, -0.74957186f, 0.026729556f, 0.66096294f));
 
-        ViewPort view4 = renderManager.createMainView("Top Right", cam4);
+        final ViewPort view4 = renderManager.createMainView("Top Right", cam4);
         view4.setClearFlags(true, true, true);
         view4.attachScene(rootNode);
 
+        rootNode.attachChild(SkyFactory.createSky(assetManager, "Textures/Sky/Bright/BrightSky.dds", false));
+
         final FilterPostProcessor fpp = new FilterPostProcessor(assetManager);
-        FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager);
-        FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager);
-        FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager);
+        final FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager);
+        final FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager);
+        final FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager);
+
+
+        //  fpp.addFilter(new WaterFilter(rootNode, Vector3f.UNIT_Y.mult(-1)));
+        fpp3.addFilter(new CartoonEdgeFilter());
+
+        fpp2.addFilter(new BloomFilter());
+        final FogFilter ff = new FogFilter(ColorRGBA.Yellow, 0.7f, 2);
+        fpp.addFilter(ff);
 
-        fpp.addFilter(new ColorOverlayFilter(ColorRGBA.Red));
-        fpp2.addFilter(new ColorOverlayFilter(ColorRGBA.Green));
-        fpp3.addFilter(new ColorOverlayFilter(ColorRGBA.Blue));
-        fpp4.addFilter(new ColorOverlayFilter(ColorRGBA.Yellow));
+        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);
+
         viewPort.addProcessor(fpp);
         view2.addProcessor(fpp2);
         view3.addProcessor(fpp3);
         view4.addProcessor(fpp4);
 
 
+
         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);
                     } else {
                         viewPort.addProcessor(fpp);
+                        view2.addProcessor(fpp2);
+                        view3.addProcessor(fpp3);
+                        view4.addProcessor(fpp4);
                     }
                     filterEnabled = !filterEnabled;
                 }
+                if (name.equals("filter") && isPressed) {
+                    ff.setEnabled(!ff.isEnabled());
+                    rbf.setEnabled(!rbf.isEnabled());
+                }
             }
-        }, "press");
+        }, "press", "filter");
 
         inputManager.addMapping("press", new KeyTrigger(KeyInput.KEY_SPACE));
+        inputManager.addMapping("filter", new KeyTrigger(KeyInput.KEY_F));
 
     }
 }