Home | History | Annotate | Download | only in post
      1 /*
      2  * Copyright (c) 2009-2010 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package jme3test.post;
     34 
     35 import com.jme3.app.SimpleApplication;
     36 import com.jme3.light.PointLight;
     37 import com.jme3.material.Material;
     38 import com.jme3.math.*;
     39 import com.jme3.post.SceneProcessor;
     40 import com.jme3.renderer.RenderManager;
     41 import com.jme3.renderer.ViewPort;
     42 import com.jme3.renderer.queue.RenderQueue;
     43 import com.jme3.scene.Geometry;
     44 import com.jme3.scene.Node;
     45 import com.jme3.texture.FrameBuffer;
     46 import com.jme3.texture.Image.Format;
     47 import com.jme3.texture.Texture2D;
     48 import com.jme3.ui.Picture;
     49 
     50 public class TestMultiRenderTarget extends SimpleApplication implements SceneProcessor {
     51 
     52     private FrameBuffer fb;
     53     private Texture2D diffuseData, normalData, specularData, depthData;
     54     private Geometry sphere;
     55     private Picture display1, display2, display3, display4;
     56 
     57     private Picture display;
     58     private Material mat;
     59 
     60     public static void main(String[] args){
     61         TestMultiRenderTarget app = new TestMultiRenderTarget();
     62         app.start();
     63     }
     64 
     65     @Override
     66     public void simpleInitApp() {
     67         viewPort.addProcessor(this);
     68         renderManager.setForcedTechnique("GBuf");
     69 
     70 //        flyCam.setEnabled(false);
     71         cam.setLocation(new Vector3f(4.8037705f, 4.851632f, 10.789033f));
     72         cam.setRotation(new Quaternion(-0.05143692f, 0.9483723f, -0.21131563f, -0.230846f));
     73 
     74         Node tank = (Node) assetManager.loadModel("Models/HoverTank/Tank2.mesh.xml");
     75 
     76         //tankMesh.getMaterial().setColor("Specular", ColorRGBA.Black);
     77         rootNode.attachChild(tank);
     78 
     79         display1 = new Picture("Picture");
     80         display1.move(0, 0, -1); // make it appear behind stats view
     81         display2 = (Picture) display1.clone();
     82         display3 = (Picture) display1.clone();
     83         display4 = (Picture) display1.clone();
     84         display  = (Picture) display1.clone();
     85 
     86         ColorRGBA[] colors = new ColorRGBA[]{
     87             ColorRGBA.White,
     88             ColorRGBA.Blue,
     89             ColorRGBA.Cyan,
     90             ColorRGBA.DarkGray,
     91             ColorRGBA.Green,
     92             ColorRGBA.Magenta,
     93             ColorRGBA.Orange,
     94             ColorRGBA.Pink,
     95             ColorRGBA.Red,
     96             ColorRGBA.Yellow
     97         };
     98 
     99         for (int i = 0; i < 3; i++){
    100             PointLight pl = new PointLight();
    101             float angle = 0.314159265f * i;
    102             pl.setPosition( new Vector3f(FastMath.cos(angle)*2f, 0,
    103                                          FastMath.sin(angle)*2f));
    104             pl.setColor(colors[i]);
    105             pl.setRadius(5);
    106             rootNode.addLight(pl);
    107             display.addLight(pl);
    108         }
    109     }
    110 
    111     public void initialize(RenderManager rm, ViewPort vp) {
    112         reshape(vp, vp.getCamera().getWidth(), vp.getCamera().getHeight());
    113         viewPort.setOutputFrameBuffer(fb);
    114         guiViewPort.setClearFlags(true, true, true);
    115         guiNode.attachChild(display);
    116 //        guiNode.attachChild(display1);
    117 //        guiNode.attachChild(display2);
    118 //        guiNode.attachChild(display3);
    119 //        guiNode.attachChild(display4);
    120         guiNode.updateGeometricState();
    121     }
    122 
    123     public void reshape(ViewPort vp, int w, int h) {
    124         diffuseData  = new Texture2D(w, h, Format.RGBA8);
    125         normalData   = new Texture2D(w, h, Format.RGBA8);
    126         specularData = new Texture2D(w, h, Format.RGBA8);
    127         depthData    = new Texture2D(w, h, Format.Depth);
    128 
    129         mat = new Material(assetManager, "Common/MatDefs/Light/Deferred.j3md");
    130         mat.setTexture("DiffuseData",  diffuseData);
    131         mat.setTexture("SpecularData", specularData);
    132         mat.setTexture("NormalData",   normalData);
    133         mat.setTexture("DepthData",    depthData);
    134 
    135         display.setMaterial(mat);
    136         display.setPosition(0, 0);
    137         display.setWidth(w);
    138         display.setHeight(h);
    139 
    140         display1.setTexture(assetManager, diffuseData, false);
    141         display2.setTexture(assetManager, normalData, false);
    142         display3.setTexture(assetManager, specularData, false);
    143         display4.setTexture(assetManager, depthData, false);
    144 
    145         display1.setPosition(0, 0);
    146         display2.setPosition(w/2, 0);
    147         display3.setPosition(0, h/2);
    148         display4.setPosition(w/2, h/2);
    149 
    150         display1.setWidth(w/2);
    151         display1.setHeight(h/2);
    152 
    153         display2.setWidth(w/2);
    154         display2.setHeight(h/2);
    155 
    156         display3.setWidth(w/2);
    157         display3.setHeight(h/2);
    158 
    159         display4.setWidth(w/2);
    160         display4.setHeight(h/2);
    161 
    162         guiNode.updateGeometricState();
    163 
    164         fb = new FrameBuffer(w, h, 1);
    165         fb.setDepthTexture(depthData);
    166         fb.addColorTexture(diffuseData);
    167         fb.addColorTexture(normalData);
    168         fb.addColorTexture(specularData);
    169         fb.setMultiTarget(true);
    170 
    171         /*
    172          * Marks pixels in front of the far light boundary
    173             Render back-faces of light volume
    174             Depth test GREATER-EQUAL
    175             Write to stencil on depth pass
    176             Skipped for very small distant lights
    177          */
    178 
    179         /*
    180          * Find amount of lit pixels inside the volume
    181              Start pixel query
    182              Render front faces of light volume
    183              Depth test LESS-EQUAL
    184              Dont write anything  only EQUAL stencil test
    185          */
    186 
    187         /*
    188          * Enable conditional rendering
    189             Based on query results from previous stage
    190             GPU skips rendering for invisible lights
    191          */
    192 
    193         /*
    194          * Render front-faces of light volume
    195             Depth test - LESS-EQUAL
    196             Stencil test - EQUAL
    197             Runs only on marked pixels inside light
    198          */
    199     }
    200 
    201     public boolean isInitialized() {
    202         return diffuseData != null;
    203     }
    204 
    205     public void preFrame(float tpf) {
    206         Matrix4f inverseViewProj = cam.getViewProjectionMatrix().invert();
    207         mat.setMatrix4("ViewProjectionMatrixInverse", inverseViewProj);
    208     }
    209 
    210     public void postQueue(RenderQueue rq) {
    211     }
    212 
    213     public void postFrame(FrameBuffer out) {
    214     }
    215 
    216     public void cleanup() {
    217     }
    218 
    219 }
    220