Total n00b app

OK I was familiar with JME 0.1 (not scenegraph based) & I’ve been playing with xith (scenegraph based) so I’m familiar with scenegraphs.



Is it Ok if I post regarding writing a new app using jme 0.5/0.6? - might be useful for others. Just something simple that uses terrain, a model & some collision.



I’ve seen the userguide which seems to have been last updated around the new year.



I see that SimpleGame has predefined cam, rootnode, etc… What is the difference between BaseGame & AbstractGame? Which should I use?

Is it Ok if I post regarding writing a new app using jme 0.5/0.6? - might be useful for others. Just something simple that uses terrain, a model & some collision.

I've seen the userguide which seems to have been last updated around the new year.


Please do! That would be fantastic. You're right the User's Guide is horribly out of date and I am going to start up again real soon (and this time try to get everyone envolved to make sure it doesn't fall apart like the last attempt).

I see that SimpleGame has predefined cam, rootnode, etc.. What is the difference between BaseGame & AbstractGame? Which should I use?


AbstractGame simply defines the structure of a the game methods, some options dialog stuff, and versions. The BaseGame defines the main game loop but nothing else. So it would be the basic level game. The loop is basically: 1. initialize 2. update data 3. render 4. End? yes 5, no 2 5. Clean up

You would want to use BaseGame unless you want to define a different game loop.

There is also FixedFramerate that limits the framerate to a given number. Keeps CPU usage down. FixLogicrate does the updates at a fixed rate, but lets the renderer go as fast as possible. VariableTimestepGame is similar to BaseGame in that the loop goes as fast as possible, but it also provides the time between frames as method parameters, that is, handles the timer for you.

Ok thanks - so I did the following to replace what you had in the 1st chapter of the manual:



import com.jme.renderer.*;
import com.jme.system.*;
import com.jme.app.*;


public class TestApp02 extends BaseGame {

   
   public static void main(String[] args) {
      TestApp02 app = new TestApp02();
      app.start();
    }

   protected void update(float interpolation) {}

   protected void render(float interpolation)
   {
      display.getRenderer().clearBuffers();
   }
 
   protected void initSystem()
   {
      try{
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
            display.createWindow(800,600,16,60,false);
        }
      catch (JmeException e)
      {
            e.printStackTrace();
            System.exit(1);
        }
   }


   protected void initGame() {}

   protected void reinit() {}

   protected void cleanup() {}

}




So if i wanted to add some terrain now I would need to add these things first:

1) a root node for the scenegraph - Node class
2) backface culling - CullState
3) A camera/view - Camera
4) some sort of lighting so I can see it - Slopelighting
1) a root node for the scenegraph - Node class


Correct, however if you are ONLY renderering terrain, the terrain COULD be the root node. However, it is recommended that you have a Node root for future children. I just want to let it be known that you can render at any level.

2) backface culling - CullState


I would also say AlphaState as a minimum as well. Otherwise, there will be some major artifacting.

3) A camera/view - Camera


Right, you have two choices, Camera and CameraNode. Camera is just the base level Camera object, while CameraNode is a scene node that controls a camera object. That means you can attach other objects to the camera itself.

4) some sort of lighting so I can see it - Slopelighting


Lighting is not required to see it, with no lighting the scene will be fully lit. However, for realisms sake, lighting should be used. SlopeLighting no longer exisits. Instead, you can create LightStates that contains a number of lights. The terrain will automatically light based on the light state. As a more advanced feature, you can create a LightNode that can be added to the scenegraph and moved dynamically.

Ok. If I’m staying static to view my terrain, I assume I won’t need to call or put anything in update(), but with regards to render() do I render the root node here I assume.



This what I have (aploogies for the terrain hack - I’m trying to understand the other stuff first) - it’s working fine but I can’t see the terrain - I’m not sure why as the camera is from the same position as the Terraintest/Simplegame Example, so should be OK.








import com.jme.renderer.*;
import com.jme.system.*;
import com.jme.app.*;
import com.jme.math.*;
import com.jme.scene.Node;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.terrain.TerrainBlock;
import com.jme.terrain.util.MidPointHeightMap;
import com.jme.terrain.util.ProceduralTextureGenerator;
import com.jme.util.TextureManager;
import com.jme.bounding.BoundingBox;
import com.jme.light.PointLight;
import com.jme.image.Texture;
import com.jme.scene.state.LightState;
import javax.swing.ImageIcon;


public class TestApp02 extends BaseGame {

   private Camera cam;
   private Node rootNode;
   private LightState lightState;
   
   public static void main(String[] args) {
      TestApp02 app = new TestApp02();
      app.start();
    }

   protected void update(float interpolation) {}

   protected void render(float interpolation)
   {
      display.getRenderer().clearBuffers();
      display.getRenderer().draw(rootNode);
   }
 
   protected void initSystem()
   {
      try{
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
            display.createWindow(800,600,16,60,false);
         cam = display.getRenderer().getCamera(
            800, 600);
        }
      catch (JmeException e)
      {
            e.printStackTrace();
            System.exit(1);
        }

      // setup our camera
      cam.setFrustum(1.0f, 1000.0f, -0.55f, 0.55f, 0.4125f, -0.4125f);
      Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
      Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
      cam.setFrame(loc, left, up, dir);
      display.getRenderer().setCamera(cam);

   }


   protected void initGame()
   {
      rootNode = new Node("rootNode");

      CullState cs = display.getRenderer().getCullState();
      cs.setCullMode(CullState.CS_NONE);
      cs.setEnabled(true);

      PointLight light = new PointLight();
      light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
       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().getLightState();
      lightState.setEnabled(true);
      lightState.attach(light);
      
      lightState.setTwoSidedLighting(true);
      rootNode.setRenderState(lightState);


      MidPointHeightMap heightMap = new MidPointHeightMap(128, 1.9f);
      TerrainBlock tb = new TerrainBlock("Terrain", heightMap.getSize(), 5,
                                 heightMap.getHeightMap(),
                                 new Vector3f(0, 0, 0), false);
      tb.setDetailTexture(1, 4);
      tb.setModelBound(new BoundingBox());
      tb.updateModelBound();
      rootNode.attachChild(tb);
      rootNode.setRenderState(cs);

      ProceduralTextureGenerator pt = new ProceduralTextureGenerator(
         heightMap);
      pt.addTexture(new ImageIcon(TestApp02.class.getClassLoader()
                           .getResource("data/grassb.png")),
                 -128, 0, 128);
      pt.addTexture(new ImageIcon(TestApp02.class.getClassLoader()
                           .getResource("data/dirt.jpg")),
                 0, 128, 255);
      pt.addTexture(new ImageIcon(TestApp02.class.getClassLoader()
                           .getResource("data/highest.jpg")),
                 128, 255,
                 384);

      pt.createTexture(512);

      TextureState ts = display.getRenderer().getTextureState();
      ts.setEnabled(true);
      Texture t1 = TextureManager.loadTexture(pt.getImageIcon().getImage(),
                                    Texture.MM_LINEAR,
                                    Texture.FM_LINEAR, true, true);
      ts.setTexture(t1, 0);

      Texture t2 = TextureManager.loadTexture(TestApp02.class
                                    .getClassLoader()
                                    .getResource(
         "data/Detail.jpg"),
                                    Texture.MM_LINEAR,
                                    Texture.FM_LINEAR, true);
      ts.setTexture(t2, 1);
      t2.setWrap(Texture.WM_WRAP_S_WRAP_T);

      t1.setApply(Texture.AM_COMBINE);
      t1.setCombineFuncRGB(Texture.ACF_MODULATE);
      t1.setCombineSrc0RGB(Texture.ACS_TEXTURE);
      t1.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
      t1.setCombineSrc1RGB(Texture.ACS_PRIMARY_COLOR);
      t1.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
      t1.setCombineScaleRGB(0);

      t2.setApply(Texture.AM_COMBINE);
      t2.setCombineFuncRGB(Texture.ACF_ADD_SIGNED);
      t2.setCombineSrc0RGB(Texture.ACS_TEXTURE);
      t2.setCombineOp0RGB(Texture.ACO_SRC_COLOR);
      t2.setCombineSrc1RGB(Texture.ACS_PREVIOUS);
      t2.setCombineOp1RGB(Texture.ACO_SRC_COLOR);
      t2.setCombineScaleRGB(0);
      rootNode.setRenderState(ts);

      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();
   }

   protected void reinit() {}

   protected void cleanup() {}

}

You problem is your camera location. Terrain heights tend to be around 150-250…



so try something like:



Vector3f loc = new Vector3f(100, 200, 500);



or similar.

Thank you :slight_smile: next input control.



I think it will be a good idea if I started a new thread each time I asked something new.

I think it will be a good idea if I started a new thread each time I asked something new.


Sounds like a good idea.