Terrain not showing up in gamestates

I'm having an issue with one of my game states … the idea is to have a state for logging in … the game lobby and the game itself … the log-in and lobby states seem to work fine, after a successful log-in the user should is taken to the actual game(state) where a large terrain should be visible … but it's not … here is some code … 



first the terrain class which is a subclass of Node

package terrain;

import gameWorld.World;

import javax.swing.ImageIcon;

import mainApp.MainApp;

import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.DistanceSwitchModel;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.lod.DiscreteLodNode;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.ImageBasedHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;

public class Terrain extends Node {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   DistanceSwitchModel dsm;
   DiscreteLodNode dln;
   private TerrainPage terrain;
   private Spatial terrainSpatial;
   private World myWorld;

   public Terrain() {
      this.setName("TerrainNode");

      build();

   }

   private void process() {

   }

   public TerrainPage getTerrainPage() {
      return terrain;
   }

   public Spatial getTerrainSpatial() {
      return terrainSpatial;
   }

   public int getTerrainSize() {
      return terrain.getSize();
   }

   public void setUpPhysics() {

   }

   public void build() {
      TextureState ts = DisplaySystem.getDisplaySystem().getRenderer()
            .createTextureState();

      // This grayscale image will be our terrain
      java.net.URL africaScale = MainApp.class.getClassLoader().getResource(
            "cloud.jpg");

      // Create an image height map based on the gray scale of our image.
      ImageBasedHeightMap africaheightMap = new ImageBasedHeightMap(
            new ImageIcon(africaScale).getImage());

      Vector3f terrainScale = new Vector3f(10, 1, 10);

      terrain = new TerrainPage("Terrain");

      terrain.setName("TerrainModel");
      terrain.setDetailTexture(1, 257);

      ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
            africaheightMap);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/nicegrass.jpg")), 0, 70, 200);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/dirt.jpg")), 150, 200, 260);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/highest.jpg")), 250, 260, 275);

      pt.createTexture(1024);

      ts.setEnabled(true);

      Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
            Texture.MinificationFilter.Trilinear,
            Texture.MagnificationFilter.Bilinear, true);

      t1.setStoreTexture(true);
      ts.setTexture(t1, 0);

      Texture t2 = TextureManager.loadTexture(MainApp.class.getClassLoader()
            .getResource("jmetest/data/texture/Detail.jpg"),
            Texture.MinificationFilter.Trilinear,
            Texture.MagnificationFilter.Bilinear);

      ts.setTexture(t2, 1);
      t2.setWrap(Texture.WrapMode.Repeat);

      t1.setApply(Texture.ApplyMode.Combine);
      t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate);
      t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
      t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
      t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor);
      t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);

      t2.setApply(Texture.ApplyMode.Combine);
      t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned);
      t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
      t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
      t2.setCombineSrc1RGB(Texture.CombinerSource.Previous);
      t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);

      terrain.setRenderState(ts);
      terrain.setLightCombineMode(LightCombineMode.Off);
      terrain.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
      terrain.setModelBound(new BoundingSphere());
      terrain.updateModelBound();
      terrain.lockBounds();
      terrain.lockTransforms();
      terrain.lockShadows();

      this.attachChild(terrain);
      this.updateRenderState();
      this.updateGeometricState(0, true);

      float center = terrain.getSize() * 2;

   }

}



All the code for the terrain class works fine if I use a SimpleGame

Now in the gameState class I have a method that is called in the constructor call initWorld() here it is ...

protected void initWorld() {

      terrain = new Terrain();
      terrain.setLightCombineMode(LightCombineMode.Off);
      terrain.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
      rootNode.attachChild(terrain);
            
      Sphere sp = new Sphere("Test", 50, 50, 10);
      sp.setDefaultColor(ColorRGBA.darkGray);
      sp.setLocalTranslation(0, 0, 0);
      sp.setLightCombineMode(LightCombineMode.Off);
      sp.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
      rootNode.attachChild(sp);
      
      //System.out.print("Build terrain");

      cam.setFrustumPerspective(45.0f, (float) display.getWidth()
            / (float) display.getHeight(), 1f, farPlane);
      cam.setLocation(new Vector3f(10, 20, 10));
      cam.lookAt(terrain.getLocalTranslation(), Vector3f.UNIT_Y);
      cam.update();
   }



now just for a test I added the Sphere (sp) the odd thing is the Sphere shows up but the terrain does not ... anyone have any insight on this one??

I'm still looking for a solution to this situation … I changed a few things around and still no luck. I was surprised that I didn't get a response to this problem so I kept at it to no avail. I figured maybe I didn't supply enough code in the first post so below is basically the whole project minus a few gamestates that are not important here because I have them working well at this time.



The following code is my entry point into the game … it is take right from the jme examples …




 package mainApp;

import gameStates.InGameState;

import java.util.concurrent.Callable;

import terrain.Terrain;

import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
import com.jme.util.GameTaskQueueManager;
import com.jmex.game.StandardGame;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameStateManager;

public class MainApp1 {
   public static void main(String[] args) throws Exception {
        StandardGame game = new StandardGame("TestGame");   // Create our game
        game.start();   // Start the game thread
       
        GameTaskQueueManager.getManager().update(new Callable<Void>(){

         public Void call() throws Exception {
            InGameState gameState = new InGameState("mainGameClass");   // Create our game state
            GameStateManager.getInstance().attachChild(gameState);   // Attach it to the GameStateManager
            gameState.setActive(true);   // Activate it
                        
            return null;
         }
       });
    }
}



now the InGameSate class ... it is derived from DebugGameSate to get all the basic I need at this time ...


package gameStates;

import inputHandlers.KeyHandler;
import jmetest.effects.water.TestQuadWater;
import jmetest.game.state.MenuState;
import terrain.Globe;
import terrain.Terrain;

import com.jme.image.Texture;
import com.jme.input.AbsoluteMouse;
import com.jme.input.Mouse;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.Text;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameState;

public class InGameState extends DebugGameState {
   /** The cursor node which holds the mouse gotten from input. */
   private Node cursor;

   /** Our display system. */
   private DisplaySystem display = DisplaySystem.getDisplaySystem();;
   private Text text;
   private Mouse mouse;
   private Terrain terrain;
   // sky box
   public Skybox skybox;
   private Camera cam = display.getRenderer().getCamera();

   public InGameState(String name) {
      // super(name);

      // initInput();
      initCursor();
      initText();

      buildSkyBox();
      rootNode.attachChild(skybox);

      initWorld();

      rootNode.setLightCombineMode(Spatial.LightCombineMode.Off);
      rootNode.setRenderQueueMode(Renderer.QUEUE_ORTHO);
      rootNode.updateGeometricState(0, true);
      rootNode.updateRenderState();
   }

   /**
    * @see com.jmex.game.state.CameraGameState#onActivate()
    */
   public void onActivate() {
      display.setTitle("Test Game State System - In Game State");
      // super.onActivate();
   }

   protected void initWorld() {
      terrain = new Terrain();
      rootNode.attachChild(terrain);

      Globe g = new Globe();
      rootNode.attachChild(g);
   }

   /**
    * Inits the input handler we will use for navigation of the menu.
    */
   protected void initInput() {
      input = new KeyHandler(this, cam);

      DisplaySystem display = DisplaySystem.getDisplaySystem();
      mouse = new AbsoluteMouse("Mouse Input", display.getWidth(), display
            .getHeight());
      mouse.registerWithInputHandler(input);
   }

   /**
    * Creates a pretty cursor.
    */
   private void initCursor() {
      mouse = new AbsoluteMouse("Mouse Input", display.getWidth(), display
            .getHeight());
      mouse.registerWithInputHandler(input);

      Texture texture = TextureManager.loadTexture(MenuState.class
            .getClassLoader()
            .getResource("jmetest/data/cursor/cursor1.png"),
            Texture.MinificationFilter.Trilinear,
            Texture.MagnificationFilter.Bilinear);

      TextureState ts = display.getRenderer().createTextureState();
      ts.setEnabled(true);
      ts.setTexture(texture);

      BlendState alpha = display.getRenderer().createBlendState();
      alpha.setBlendEnabled(true);
      alpha.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
      alpha.setDestinationFunction(BlendState.DestinationFunction.One);
      alpha.setTestEnabled(true);
      alpha.setTestFunction(BlendState.TestFunction.GreaterThan);
      alpha.setEnabled(true);

      mouse.setRenderState(ts);
      mouse.setRenderState(alpha);
      mouse.setLocalScale(new Vector3f(1, 1, 1));

      cursor = new Node("Cursor");
      cursor.attachChild(mouse);

      rootNode.attachChild(cursor);
   }

   /**
    * Inits the button placed at the center of the screen.
    */
   private void initText() {
      text = Text.createDefaultTextLabel("info");
      text
            .print("We are now in the main game state this is where the game will take place press enter");
      text.getLocalTranslation().set(100, 100, 0);

      rootNode.attachChild(text);
   }

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

      String dir = "jmetest/data/skybox1/";
      Texture north = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "1.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);
      Texture south = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "3.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);
      Texture east = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "2.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);
      Texture west = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "4.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);
      Texture up = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "6.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);
      Texture down = TextureManager.loadTexture(TestQuadWater.class
            .getClassLoader().getResource(dir + "5.jpg"),
            Texture.MinificationFilter.BilinearNearestMipMap,
            Texture.MagnificationFilter.Bilinear);

      skybox.setTexture(Skybox.Face.North, north);
      skybox.setTexture(Skybox.Face.West, west);
      skybox.setTexture(Skybox.Face.South, south);
      skybox.setTexture(Skybox.Face.East, east);
      skybox.setTexture(Skybox.Face.Up, up);
      skybox.setTexture(Skybox.Face.Down, down);
      skybox.preloadTextures();

      CullState cullState = display.getRenderer().createCullState();
      cullState.setCullFace(null);
      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(LightCombineMode.Off);
      skybox.setTextureCombineMode(TextureCombineMode.Replace);
      skybox.updateRenderState();

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

   /**
    * Updates input and button.
    *
    * @param tpf
    *            The time since last frame.
    * @see GameState#update(float)
    */
   protected void stateUpdate(float tpf) {
   
   }
   
   
   public void update(float tpf) {
      super.update(tpf);
      skybox.getLocalTranslation().set(cam.getLocation());
      skybox.updateGeometricState(0.0f, true);
   }
   
   public void render(float tpf) {
      super.render(tpf);
      DisplaySystem.getDisplaySystem().getRenderer().draw(terrain);
   }
   
}



as you can see its a pretty basic gamestate ... the only thing I really do here is add a terrain and a Globe(for testing) in the intWorld method to what I believe to be the rootNode of the gamestate.

now the terrain class ... It builds a basic terrain with the TerrainPage class, this class works fine in a SimpleGame implimentation and builds me a nice terrain.



package terrain;

import gameWorld.World;

import javax.swing.ImageIcon;

import mainApp.MainApp;

import com.jme.bounding.BoundingSphere;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.DistanceSwitchModel;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.lod.DiscreteLodNode;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jmex.terrain.TerrainPage;
import com.jmex.terrain.util.ImageBasedHeightMap;
import com.jmex.terrain.util.ProceduralTextureGenerator;

public class Terrain extends Node {
   /**
    *
    */
   private static final long serialVersionUID = 1L;
   DistanceSwitchModel dsm;
   DiscreteLodNode dln;
   private TerrainPage terrain;
   private Spatial terrainSpatial;
   private World myWorld;
   private DisplaySystem display = DisplaySystem.getDisplaySystem();;
   
   public Terrain() {
      this.setName("TerrainNode");

      build();
   
   }

   private void process() {

   }

   public TerrainPage getTerrainPage() {
      return terrain;
   }

   public Spatial getTerrainSpatial() {
      return terrainSpatial;
   }

   public int getTerrainSize() {
      return terrain.getSize();
   }

   public void setUpPhysics() {

   }

   public void build() {
      TextureState ts = DisplaySystem.getDisplaySystem().getRenderer()
            .createTextureState();

      // This grayscale image will be our terrain
      java.net.URL africaScale = MainApp.class.getClassLoader().getResource(
            "cloud.jpg");

      // Create an image height map based on the gray scale of our image.
      ImageBasedHeightMap africaheightMap = new ImageBasedHeightMap(
            new ImageIcon(africaScale).getImage());

      Vector3f terrainScale = new Vector3f(10, 1, 10);

      terrain = new TerrainPage("Terrain");
      
      this.attachChild(terrain);
      
      terrain.setName("TerrainModel");
      terrain.setDetailTexture(1, 257);

      ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
            africaheightMap);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/nicegrass.jpg")), 0, 70, 200);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/dirt.jpg")), 150, 200, 260);
      pt.addTexture(new ImageIcon(MainApp.class.getClassLoader().getResource(
            "textures/terrain/highest.jpg")), 250, 260, 275);

      pt.createTexture(1024);

      ts.setEnabled(true);

      Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
            Texture.MinificationFilter.Trilinear,
            Texture.MagnificationFilter.Bilinear, true);

      t1.setStoreTexture(true);
      ts.setTexture(t1, 0);

      Texture t2 = TextureManager.loadTexture(MainApp.class.getClassLoader()
            .getResource("jmetest/data/texture/Detail.jpg"),
            Texture.MinificationFilter.Trilinear,
            Texture.MagnificationFilter.Bilinear);

      ts.setTexture(t2, 1);
      t2.setWrap(Texture.WrapMode.Repeat);

      t1.setApply(Texture.ApplyMode.Combine);
      t1.setCombineFuncRGB(Texture.CombinerFunctionRGB.Modulate);
      t1.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
      t1.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
      t1.setCombineSrc1RGB(Texture.CombinerSource.PrimaryColor);
      t1.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);

      t2.setApply(Texture.ApplyMode.Combine);
      t2.setCombineFuncRGB(Texture.CombinerFunctionRGB.AddSigned);
      t2.setCombineSrc0RGB(Texture.CombinerSource.CurrentTexture);
      t2.setCombineOp0RGB(Texture.CombinerOperandRGB.SourceColor);
      t2.setCombineSrc1RGB(Texture.CombinerSource.Previous);
      t2.setCombineOp1RGB(Texture.CombinerOperandRGB.SourceColor);

      terrain.setRenderState(ts);
            
      
      terrain.setLightCombineMode(LightCombineMode.Off);
      terrain.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
      terrain.setModelBound(new BoundingSphere());
      terrain.updateModelBound();
      //terrain.lockBounds();
      //terrain.lockTransforms();
      //terrain.lockShadows();

      
      this.updateRenderState();
      //this.updateGeometricState(0, true);

      float center = terrain.getSize() * 2;

   }

}



now I didn't include the globe class here becasue it works fine and is just a basic class that extends a node and attaches a jme sphere to it. I can see the globe model when the game loads, the issue as I said is the terrain ... it does not show up at all. My skybox is also visible. I'm thinking I have to put somthing in the render or update methods of the gamestate ... but I have tried everything form ...

DisplaySystem.getDisplaySystem().getRenderer().draw(terrain)
terrain..updateRenderState()
terrain.updateGeometricState(tpf, true)

nothing seems to work. I'm stumped ... I really need to figure this out so I can continue with my work. Somthing is obviously missing here.

Thanks for your time ... :)