From 083333ac6e864e3cca2ddaeaf2be8dd9e41f2d39 Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Fri, 6 May 2011 23:08:10 +0000 Subject: [PATCH] - Fixed viewPort positioning and scaling for ortho cam and added multiple gui viewports to TestMultiViews - Filters can now be added to multiple viewports, added a TestMultiViewsFilters git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7457 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../com/jme3/post/FilterPostProcessor.java | 31 ++-- .../core/com/jme3/renderer/RenderManager.java | 29 ++-- .../jme3test/post/TestMultiViewsFilters.java | 144 ++++++++++++++++++ .../jme3test/renderer/TestMultiViews.java | 26 +++- 4 files changed, 199 insertions(+), 31 deletions(-) create mode 100644 engine/src/test/jme3test/post/TestMultiViewsFilters.java diff --git a/engine/src/core/com/jme3/post/FilterPostProcessor.java b/engine/src/core/com/jme3/post/FilterPostProcessor.java index 49b4e3a1b..3e6131961 100644 --- a/engine/src/core/com/jme3/post/FilterPostProcessor.java +++ b/engine/src/core/com/jme3/post/FilterPostProcessor.java @@ -72,6 +72,8 @@ public class FilterPostProcessor implements SceneProcessor, Savable { private FrameBuffer outputBuffer; private int width; private int height; + private int bottom; + private int left; private int lastFilterIndex = -1; /** @@ -90,11 +92,11 @@ public class FilterPostProcessor implements SceneProcessor, Savable { public void addFilter(Filter filter) { filters.add(filter); - + if (isInitialized()) { initFilter(filter, viewPort); } - if(filter.isEnabled()){ + if (filter.isEnabled()) { lastFilterIndex = filters.size() - 1; } } @@ -115,7 +117,11 @@ public class FilterPostProcessor implements SceneProcessor, Savable { viewPort = vp; fsQuad = new Picture("filter full screen quad"); - reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight()); + Camera cam = vp.getCamera(); + //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()); + cam.setViewPort(0, 1, 0, 1); + reshape(vp, cam.getWidth(), cam.getHeight()); } private void initFilter(Filter filter, ViewPort vp) { @@ -140,8 +146,12 @@ public class FilterPostProcessor implements SceneProcessor, Savable { fsQuad.setHeight(buff.getHeight()); filterCam.resize(buff.getWidth(), buff.getHeight(), true); } + + fsQuad.setMaterial(mat); fsQuad.updateGeometricState(); + filterCam.setName("filterCam"); + //fsQuad.setPosition(640, 360); renderManager.setCamera(filterCam, true); r.setFrameBuffer(buff); r.clearBuffers(true, true, true); @@ -217,7 +227,7 @@ 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); + // renderer.applyRenderState(RenderState.DEFAULT); if (renderFrameBufferMS != null && !renderer.getCaps().contains(Caps.OpenGL31)) { renderer.copyFrameBuffer(renderFrameBufferMS, renderFrameBuffer); } @@ -262,16 +272,20 @@ public class FilterPostProcessor implements SceneProcessor, Savable { 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.setOutputFrameBuffer(outputBuffer); viewPort = null; } } public void reshape(ViewPort vp, int w, int h) { - - width = Math.max(1, w); - height = Math.max(1, h); - vp.getCamera().resize(width, height, true); + Camera cam = vp.getCamera(); + width = (int) (w * (Math.abs(cam.getViewPortRight() - cam.getViewPortLeft()))); + height = (int) (h * (Math.abs(cam.getViewPortBottom() - cam.getViewPortTop()))); + width = Math.max(1, width); + height = Math.max(1, height); + // vp.getCamera().resize(width, height, true); computeDepth = false; if (renderFrameBuffer == null) { @@ -333,7 +347,6 @@ public class FilterPostProcessor implements SceneProcessor, Savable { updateLastFilterIndex(); } - /** * Sets the number of samples for antialiasing * @param numSamples the number of Samples diff --git a/engine/src/core/com/jme3/renderer/RenderManager.java b/engine/src/core/com/jme3/renderer/RenderManager.java index a96d887b7..bee04ed59 100644 --- a/engine/src/core/com/jme3/renderer/RenderManager.java +++ b/engine/src/core/com/jme3/renderer/RenderManager.java @@ -422,7 +422,7 @@ public class RenderManager { } else if (forcedMaterial != null) { // use forced material forcedMaterial.render(g, this); - } else { + } else { g.getMaterial().render(g, this); } //re applying default render state at the end of the render to avoid depth write issues, MUST BE A BETTER WAY @@ -611,14 +611,15 @@ public class RenderManager { cam.clearViewportChanged(); prevCam = cam; - float translateX = viewWidth == viewX ? 0 : -(viewWidth + viewX) / (viewWidth - viewX); - float translateY = viewHeight == viewY ? 0 : -(viewHeight + viewY) / (viewHeight - viewY); - float scaleX = viewWidth == viewX ? 1f : 2f / (viewWidth - viewX); - float scaleY = viewHeight == viewY ? 1f : 2f / (viewHeight - viewY); + +// float translateX = viewWidth == viewX ? 0 : -(viewWidth + viewX) / (viewWidth - viewX); +// float translateY = viewHeight == viewY ? 0 : -(viewHeight + viewY) / (viewHeight - viewY); +// float scaleX = viewWidth == viewX ? 1f : 2f / (viewWidth - viewX); +// float scaleY = viewHeight == viewY ? 1f : 2f / (viewHeight - viewY); orthoMatrix.loadIdentity(); - orthoMatrix.setTranslation(translateX, translateY, 0); - orthoMatrix.setScale(scaleX, scaleY, /*-1f*/ 0f); -// System.out.println(orthoMatrix); + orthoMatrix.setTranslation(-1f, -1f, 0f); + orthoMatrix.setScale(2f / cam.getWidth(), 2f / cam.getHeight(), 0f); + System.out.println(orthoMatrix); } } @@ -672,9 +673,9 @@ public class RenderManager { } public void renderViewPort(ViewPort vp, float tpf) { - if (!vp.isEnabled()) { - return; - } + if (!vp.isEnabled()) { + return; + } List processors = vp.getProcessors(); if (processors.size() == 0) { processors = null; @@ -692,12 +693,12 @@ public class RenderManager { renderer.setFrameBuffer(vp.getOutputFrameBuffer()); setCamera(vp.getCamera(), false); if (vp.isClearDepth() || vp.isClearColor() || vp.isClearStencil()) { - if (vp.isClearColor()){ + if (vp.isClearColor()) { renderer.setBackgroundColor(vp.getBackgroundColor()); } renderer.clearBuffers(vp.isClearColor(), - vp.isClearDepth(), - vp.isClearStencil()); + vp.isClearDepth(), + vp.isClearStencil()); } List scenes = vp.getScenes(); diff --git a/engine/src/test/jme3test/post/TestMultiViewsFilters.java b/engine/src/test/jme3test/post/TestMultiViewsFilters.java new file mode 100644 index 000000000..48a62337b --- /dev/null +++ b/engine/src/test/jme3test/post/TestMultiViewsFilters.java @@ -0,0 +1,144 @@ +/* + * 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 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.renderer.Camera; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Geometry; + +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); + + 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)); + + 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)); + + 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)); + + ViewPort view4 = renderManager.createMainView("Top Right", cam4); + view4.setClearFlags(true, true, true); + view4.attachScene(rootNode); + + final FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + FilterPostProcessor fpp2 = new FilterPostProcessor(assetManager); + FilterPostProcessor fpp3 = new FilterPostProcessor(assetManager); + FilterPostProcessor fpp4 = new FilterPostProcessor(assetManager); + + fpp.addFilter(new ColorOverlayFilter(ColorRGBA.Red)); + fpp2.addFilter(new ColorOverlayFilter(ColorRGBA.Green)); + fpp3.addFilter(new ColorOverlayFilter(ColorRGBA.Blue)); + fpp4.addFilter(new ColorOverlayFilter(ColorRGBA.Yellow)); + + + 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); + } else { + viewPort.addProcessor(fpp); + } + filterEnabled = !filterEnabled; + } + } + }, "press"); + + inputManager.addMapping("press", new KeyTrigger(KeyInput.KEY_SPACE)); + + } +} diff --git a/engine/src/test/jme3test/renderer/TestMultiViews.java b/engine/src/test/jme3test/renderer/TestMultiViews.java index 73f3bdc8e..aa6b67eb5 100644 --- a/engine/src/test/jme3test/renderer/TestMultiViews.java +++ b/engine/src/test/jme3test/renderer/TestMultiViews.java @@ -29,7 +29,6 @@ * 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.renderer; import com.jme3.app.SimpleApplication; @@ -43,7 +42,7 @@ import com.jme3.scene.Geometry; public class TestMultiViews extends SimpleApplication { - public static void main(String[] args){ + public static void main(String[] args) { TestMultiViews app = new TestMultiViews(); app.start(); } @@ -52,7 +51,7 @@ public class TestMultiViews extends SimpleApplication { // create the geometry and attach it Geometry teaGeom = (Geometry) assetManager.loadModel("Models/Teapot/Teapot.obj"); teaGeom.scale(3); - + DirectionalLight dl = new DirectionalLight(); dl.setColor(ColorRGBA.White); dl.setDirection(Vector3f.UNIT_XYZ.negate()); @@ -64,20 +63,20 @@ public class TestMultiViews extends SimpleApplication { viewPort.setBackgroundColor(ColorRGBA.Blue); 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)); + cam.setRotation(new Quaternion(-0.07680723f, 0.92299235f, -0.2564353f, -0.27645364f)); // Setup second view - Camera cam2 = cam.clone(); + 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)); - + ViewPort view2 = renderManager.createMainView("Bottom Left", cam2); view2.setClearFlags(true, true, true); view2.attachScene(rootNode); // Setup third view - Camera cam3 = cam.clone(); + Camera cam3 = cam.clone(); 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)); @@ -87,7 +86,7 @@ public class TestMultiViews extends SimpleApplication { view3.attachScene(rootNode); // Setup fourth view - Camera cam4 = cam.clone(); + Camera cam4 = cam.clone(); 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)); @@ -95,5 +94,16 @@ public class TestMultiViews extends SimpleApplication { ViewPort view4 = renderManager.createMainView("Top Right", cam4); view4.setClearFlags(true, true, true); view4.attachScene(rootNode); + + //test multiview for gui + guiViewPort.getCamera().setViewPort(.5f, 1f, .5f, 1f); + + // Setup second gui view + Camera guiCam2 = guiViewPort.getCamera().clone(); + guiCam2.setViewPort(0f, 0.5f, 0f, 0.5f); + ViewPort guiViewPort2 = renderManager.createPostView("Gui 2", guiCam2); + guiViewPort2.setClearFlags(false, false, false); + guiViewPort2.attachScene(guiViewPort.getScenes().get(0)); + } }