TerrainPage in BaseGame

Hi everyone,



I am just trying to get my custom TerrainPage (Heightmap) into BaseGame with waterRenderPass…


/*
 * Copyright (c) 2003-2007 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 prototyp1;
import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.ImageIcon;

import jmetest.terrain.TestTerrain;

import com.jme.app.BaseGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.input.InputHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Plane;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.BasicPassManager;
import com.jme.renderer.pass.RenderPass;
import com.jme.scene.Node;
import com.jme.scene.PassNode;
import com.jme.scene.PassNodeState;
import com.jme.scene.SceneElement;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.GameTaskQueue;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.TextureManager;
import com.jme.util.Timer;
import com.jmex.effects.water.WaterRenderPass;
import com.jmex.terrain.TerrainBlock;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.MidPointHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;
import com.jmex.terrain.util.RawHeightMap;

public class TestIsland extends BaseGame {
   private WaterRenderPass waterEffectRenderPass;
   private Skybox skybox;
   private Quad waterQuad;
   private float farPlane = 10000.0f;
   private float textureScale = 0.02f;
   protected LightState lightState;
   private Spatial splatTerrain;
    
   protected Timer timer;
   private Camera cam;
   private static final Logger logger = Logger.getLogger(Main.class
            .getName());
   protected InputHandler input;
   private float tpf;
   boolean pause;
   private Node rootNode;
   protected BasicPassManager pManager;
    private float globalSplatScale = 90.0f;
   
   
   public static void main( String[] args ) {
      TestIsland app = new TestIsland();
      app.setDialogBehaviour( ALWAYS_SHOW_PROPS_DIALOG );
      app.start();
   }

   protected void cleanup() {
      waterEffectRenderPass.cleanup();
   }

   private void setVertexCoords( float x, float y, float z ) {
      FloatBuffer vertBuf = waterQuad.getVertexBuffer( 0 );
      vertBuf.clear();

      vertBuf.put( x - farPlane ).put( y ).put( z - farPlane );
      vertBuf.put( x - farPlane ).put( y ).put( z + farPlane );
      vertBuf.put( x + farPlane ).put( y ).put( z + farPlane );
      vertBuf.put( x + farPlane ).put( y ).put( z - farPlane );
   }

   private void setTextureCoords( int buffer, float x, float y, float textureScale ) {
      x *= textureScale * 0.5f;
      y *= textureScale * 0.5f;
      textureScale = farPlane * textureScale;
      FloatBuffer texBuf;
      texBuf = waterQuad.getTextureBuffer( 0, buffer );
      texBuf.clear();
      texBuf.put( x ).put( textureScale + y );
      texBuf.put( x ).put( y );
      texBuf.put( textureScale + x ).put( y );
      texBuf.put( textureScale + x ).put( textureScale + y );
   }

   private void setupFog() {
      FogState fogState = display.getRenderer().createFogState();
      fogState.setDensity( 1.0f );
      fogState.setEnabled( true );
      fogState.setColor( new ColorRGBA( 1.0f, 1.0f, 1.0f, 1.0f ) );
      fogState.setEnd( farPlane );
      fogState.setStart( farPlane / 10.0f );
      fogState.setDensityFunction( FogState.DF_LINEAR );
      fogState.setApplyFunction( FogState.AF_PER_VERTEX );
      rootNode.setRenderState( fogState );
   }

   private void buildSkyBox() {
      skybox = new Skybox( "skybox", 10, 10, 10 );

      String dir = "data/skybox/";
      Texture north = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "1.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture south = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "3.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture east = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "2.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture west = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "4.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture up = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "6.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );
      Texture down = TextureManager.loadTexture(
            TestIsland.class.getClassLoader().getResource(
                  dir + "5.jpg" ),
            Texture.MM_LINEAR,
            Texture.FM_LINEAR );

      skybox.setTexture( Skybox.NORTH, north );
      skybox.setTexture( Skybox.WEST, west );
      skybox.setTexture( Skybox.SOUTH, south );
      skybox.setTexture( Skybox.EAST, east );
      skybox.setTexture( Skybox.UP, up );
      skybox.setTexture( Skybox.DOWN, down );
      skybox.preloadTextures();

      CullState cullState = display.getRenderer().createCullState();
      cullState.setCullMode( CullState.CS_NONE );
      cullState.setEnabled( true );
      skybox.setRenderState( cullState );

      ZBufferState zState = display.getRenderer().createZBufferState();
      zState.setEnabled( false );
      skybox.setRenderState( zState );

      FogState fs = display.getRenderer().createFogState();
      fs.setEnabled( false );
      skybox.setRenderState( fs );

      skybox.setLightCombineMode( LightState.OFF );
      skybox.setCullMode( SceneElement.CULL_NEVER );
      skybox.setTextureCombineMode( TextureState.REPLACE );
      skybox.updateRenderState();

      skybox.lockBounds();
      skybox.lockMeshes();
   }

   private void buildTerrain(){
       
      RawHeightMap heightMap = new RawHeightMap(Main.class.getClassLoader().getResource(
      "data/terrain/heights2.raw").getFile(), 129,
      RawHeightMap.FORMAT_16BITLE, false);

      Vector3f terrainScale = new Vector3f(30, 0.001f, 30);
      heightMap.setHeightScale(0.001f);
        // create a terrainblock
      TerrainPage page = new TerrainPage("Terrain", 33, heightMap.getSize(),
                terrainScale, heightMap.getHeightMap(), false);
        page.getLocalTranslation().set(0, 5f, 0);
        page.setDetailTexture(1, 1);

     // create some interesting texturestates for splatting
        TextureState ts1 = createSplatTextureState(
                 "data/terrain/rainforest_t1.jpg", null);

        TextureState ts2 = createSplatTextureState(
                 "data/terrain/rainforest_t1.jpg",
                "data/texture/darkrockalpha.png");

        TextureState ts3 = createSplatTextureState(
                "data/terrain/rainforest_t1.jpg",
                "data/texture/deadalpha.png");

        TextureState ts4 = createSplatTextureState(
                 "data/terrain/rainforest_t1.jpg",
                "data/texture/grassalpha.png");

        TextureState ts5 = createSplatTextureState(
                 "data/terrain/rainforest_t1.jpg",
                "data/texture/grassalpha.png");

        TextureState ts6 = createLightmapTextureState("data/terrain/lightmap.jpg");

        // alpha used for blending the passnodestates together
        AlphaState as = display.getRenderer().createAlphaState();
        as.setBlendEnabled(true);
        as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
        as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
        as.setTestEnabled(true);
        as.setTestFunction(AlphaState.TF_GREATER);
        as.setEnabled(true);

        // alpha used for blending the lightmap
        AlphaState as2 = display.getRenderer().createAlphaState();
        as2.setBlendEnabled(true);
        as2.setSrcFunction(AlphaState.SB_DST_COLOR);
        as2.setDstFunction(AlphaState.DB_SRC_COLOR);
        as2.setTestEnabled(true);
        as2.setTestFunction(AlphaState.TF_GREATER);
        as2.setEnabled(true);

        // //////////////////// PASS STUFF START
        // try out a passnode to use for splatting
        PassNode splattingPassNode = new PassNode("SplatPassNode");
        splattingPassNode.attachChild(page);

        PassNodeState passNodeState = new PassNodeState();
        passNodeState.setPassState(ts1);
        splattingPassNode.addPass(passNodeState);

        passNodeState = new PassNodeState();
        passNodeState.setPassState(ts2);
        passNodeState.setPassState(as);
        splattingPassNode.addPass(passNodeState);

        passNodeState = new PassNodeState();
        passNodeState.setPassState(ts3);
        passNodeState.setPassState(as);
        splattingPassNode.addPass(passNodeState);

        passNodeState = new PassNodeState();
        passNodeState.setPassState(ts4);
        passNodeState.setPassState(as);
        splattingPassNode.addPass(passNodeState);

        passNodeState = new PassNodeState();
        passNodeState.setPassState(ts5);
        passNodeState.setPassState(as);
        splattingPassNode.addPass(passNodeState);

        passNodeState = new PassNodeState();
        passNodeState.setPassState(ts6);
        passNodeState.setPassState(as2);
        splattingPassNode.addPass(passNodeState);
        // //////////////////// PASS STUFF END

        // lock some things to increase the performance
        splattingPassNode.lockBounds();
        splattingPassNode.lockTransforms();
        splattingPassNode.lockShadows();

        splatTerrain = splattingPassNode;
 
   }
    private TextureState createSplatTextureState(String texture, String alpha) {
        TextureState ts = display.getRenderer().createTextureState();

        Texture t0 = TextureManager.loadTexture(TestIsland.class
                .getClassLoader().getResource(texture),
                Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
        t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
        t0.setApply(Texture.AM_MODULATE);
        t0.setScale(new Vector3f(globalSplatScale, globalSplatScale, 1.0f));
        ts.setTexture(t0, 0);

        if (alpha != null) {
            addAlphaSplat(ts, alpha);
        }

        return ts;
    }
   
    private TextureState createLightmapTextureState(String texture) {
        TextureState ts = display.getRenderer().createTextureState();

        Texture t0 = TextureManager.loadTexture(TestIsland.class
                .getClassLoader().getResource(texture),
                Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
        t0.setWrap(Texture.WM_WRAP_S_WRAP_T);
        ts.setTexture(t0, 0);

        return ts;
    }
   
    private void addAlphaSplat(TextureState ts, String alpha) {
        Texture t1 = TextureManager.loadTexture(TestIsland.class
                .getClassLoader().getResource(alpha), Texture.MM_LINEAR_LINEAR,
                Texture.FM_LINEAR);
        t1.setWrap(Texture.WM_WRAP_S_WRAP_T);
        t1.setApply(Texture.AM_COMBINE);
        t1.setCombineFuncRGB(Texture.ACF_REPLACE);
        t1.setCombineSrc0RGB(Texture.ACS_PREVIOUS);
        t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
        t1.setCombineFuncAlpha(Texture.ACF_REPLACE);
        ts.setTexture(t1, ts.getNumberOfSetTextures());
    }
   
   private void setupKeyBindings() {
      KeyBindingManager.getKeyBindingManager().set( "g", KeyInput.KEY_G );
      KeyBindingManager.getKeyBindingManager().set( "e", KeyInput.KEY_E );

      KeyBindingManager.getKeyBindingManager().set( "lower", KeyInput.KEY_H );
      KeyBindingManager.getKeyBindingManager().set( "higher", KeyInput.KEY_Y );

      KeyBindingManager.getKeyBindingManager().set( "1", KeyInput.KEY_1 );
      KeyBindingManager.getKeyBindingManager().set( "2", KeyInput.KEY_2 );

   }

   @Override
   protected void initGame() {
      pManager = new BasicPassManager();
      rootNode = new Node( "rootNode" );

        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
        rootNode.setRenderState( buf );

        PointLight light = new PointLight();
        light.setDiffuse( new ColorRGBA( 0.75f, 0.75f, 0.75f, 0.75f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setLocation( new Vector3f( 100, 100, 100 ) );
        light.setEnabled( true );

        lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );

        timer.reset();
       
        cam.setFrustumPerspective( 45.0f, (float) display.getWidth() / (float) display.getHeight(), 1f, farPlane );
      cam.setLocation( new Vector3f( 100, 50, 100 ) );
      cam.lookAt( new Vector3f( 0, 0, 0 ), Vector3f.UNIT_Y );
      cam.update();

      setupKeyBindings();

      setupFog();
      buildTerrain();
      
      Node reflectedNode = new Node( "reflectNode" );

      buildSkyBox();
      reflectedNode.attachChild( skybox );
      rootNode.attachChild( reflectedNode );

      waterEffectRenderPass = new WaterRenderPass( cam, 4, false, true );
      waterEffectRenderPass.setWaterPlane( new Plane( new Vector3f( 0.0f, 1.0f, 0.0f ), 0.0f ) );

      waterQuad = new Quad( "waterQuad", 1, 1 );
      FloatBuffer normBuf = waterQuad.getNormalBuffer( 0 );
      normBuf.clear();
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );
      normBuf.put( 0 ).put( 1 ).put( 0 );

      waterEffectRenderPass.setWaterEffectOnSpatial( waterQuad );
      rootNode.attachChild( waterQuad );

      waterEffectRenderPass.setReflectedScene( reflectedNode );
      waterEffectRenderPass.setSkybox( skybox );
      pManager.add( waterEffectRenderPass );

      RenderPass rootPass = new RenderPass();
      rootPass.add( rootNode );
      pManager.add( rootPass );

      rootNode.setCullMode( SceneElement.CULL_NEVER);
      rootNode.setRenderQueueMode( Renderer.QUEUE_OPAQUE );
       
        rootNode.updateGeometricState( 0.0f, true );
        rootNode.updateRenderState();
        timer.reset();
      
   }

   @Override
   protected void initSystem() {
      logger.info(getVersion());
        try {
            display = DisplaySystem.getDisplaySystem( properties.getRenderer() );
      
            display.createWindow( properties.getWidth(), properties.getHeight(),
                    properties.getDepth(), properties.getFreq(), properties
                    .getFullscreen() );
            logger.info("Running on: " + display.getAdapter()
                    + "nDriver version: " + display.getDriverVersion() + "n"
                    + display.getDisplayVendor() + " - "
                    + display.getDisplayRenderer() + " - "
                    + display.getDisplayAPIVersion());
           
            cam = display.getRenderer().createCamera( display.getWidth(),
                    display.getHeight() );

        } catch ( JmeException e ) {
            logger.log(Level.SEVERE, "Could not create displaySystem", e);
            System.exit( 1 );
        }
        display.getRenderer().setBackgroundColor(ColorRGBA.blue.clone());
      
      cam.setFrustumPerspective(45.0f, (float)display.getWidth() / (float)display.getHeight(), 1, 1000);
      Vector3f loc = new Vector3f(20.0f, 0.0f, 0.0f);
      Vector3f left = new Vector3f(0.0f, 0.0f, -1.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(-1.0f, 0f, 0.0f);
      cam.setFrame(loc, left, up, dir);
      cam.update();
        display.getRenderer().setCamera( cam );

        FirstPersonHandler firstPersonHandler = new FirstPersonHandler( cam, 50,
                1 );
        input = firstPersonHandler;

        timer = Timer.getTimer();

        /** Sets the title of our display. */
        String className = getClass().getName();
        if ( className.lastIndexOf( '.' ) > 0 ) className = className.substring( className.lastIndexOf( '.' )+1 );
        display.setTitle( className );
       
        display.getRenderer().enableStatistics( true );
       
        KeyBindingManager.getKeyBindingManager().set( "exit",
                KeyInput.KEY_ESCAPE );
    }
   @Override
   protected void reinit() {
      
   }
   @Override
   protected void render(float interpolation) {
      Renderer r = display.getRenderer();
        r.clearStatistics();
        r.clearBuffers();
       
        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.RENDER).execute();
       
        pManager.renderPasses(display.getRenderer());
   }

   @Override
   protected void update(float interpolation) {
      timer.update();
        tpf = timer.getTimePerFrame();

        input.update( tpf );

        GameTaskQueueManager.getManager().getQueue(GameTaskQueue.UPDATE).execute();
       
        if ( KeyBindingManager.getKeyBindingManager().isValidCommand( "exit",
                false ) ) {
            finished = true;
        }
        skybox.getLocalTranslation().set( cam.getLocation() );
      skybox.updateGeometricState( 0.0f, true );

      Vector3f transVec = new Vector3f( cam.getLocation().x, waterEffectRenderPass.getWaterHeight(), cam.getLocation().z );

      setTextureCoords( 0, transVec.x, -transVec.z, textureScale );

      setVertexCoords( transVec.x, transVec.y, transVec.z );
      
      rootNode.updateGeometricState(tpf, true);
      
      pManager.updatePasses(tpf);
   }
}



The water and skybox is working. But there is no terrain on the water. When I use TerrainBlock with this implementation is works but is all black!

Any ideas why the TerrainPage doesn't show anything?

Thanks so much, Rapidm