title: Endless terrain in jMonkey using TerrainGrid
body: <p>I have started to learn game development using jMonkey engine. I am able to create single tile of terrain using TerrainQuad but as the next step i m stuck at making it infinite. I have gone through the wiki and want to use the TerrainGrid class but my code doesnot seem to work. I have looked around on the web and searched other forums but cannot find any other code example to help.</p>
  
  <p>I believe in the below code, ImageTileLoader returns an image which is the heightmap for that tile. i have modified it to return the same image every time. But all i see is a black window.
  The Namer method is not even called. Appreciate if someone can help with some example or tutorial on net.</p>
  
  <pre><code>terrain = new TerrainGrid("terrain", patchSize, 513, new ImageTileLoader(assetManager, new Namer() {
          public String getName(int x, int y) {
              //return "Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
              System.out.println("X = " + x + ", Y = " + y);
              return "Textures/heightmap.png";
          }
      }));
  </code></pre>
  
  <p>These are my sources: 
  <a href="http://hub.jmonkeyengine.org/wiki/doku.php/jme3:beginner:hello_terrain" rel="nofollow noreferrer">jMonkeyEngine 3 Tutorial (10) - Hello Terrain</a>, <a href="https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/test/jme3test/terrain/TerrainGridTest.java" rel="nofollow noreferrer">TerrainGridTest.java</a>, <a href="http://hub.jmonkeyengine.org/javadoc/com/jme3/terrain/geomipmap/grid/ImageTileLoader.html" rel="nofollow noreferrer">ImageTileLoader</a></p>
  
  <p>This is the result when i use TerrainQuad<img src="https://i.stack.imgur.com/49hr5.png" alt="enter image description here"></p>
  
  <p>My full code,</p>
  
  <pre><code>// Sample 10 - How to create fast-rendering terrains from heightmaps, and how to
  // use texture splatting to make the terrain look good.
  public class HelloTerrain extends SimpleApplication {
  
      private TerrainQuad terrain;
      Material mat_terrain;
      private float grassScale = 64;
      private float dirtScale = 32;
      private float rockScale = 64;
  
      public static void main(String[] args) {
          HelloTerrain app = new HelloTerrain();
          app.start();
      }
      private FractalSum base;
      private PerturbFilter perturb;
      private OptimizedErode therm;
      private SmoothFilter smooth;
      private IterativeFilter iterate;
  
      @Override
      public void simpleInitApp() {
          flyCam.setMoveSpeed(200);
  
          initMaterial();
  
          AbstractHeightMap heightmap = null;
          Texture heightMapImage = assetManager.loadTexture("Textures/heightmap.png");
          heightmap = new ImageBasedHeightMap(heightMapImage.getImage());
          heightmap.load();
  
  
          int patchSize = 65;
          //terrain = new TerrainQuad("my terrain", patchSize, 513, heightmap.getHeightMap()); // * This Works but below doesnt work*
  
          terrain = new TerrainGrid("terrain", patchSize, 513, new ImageTileLoader(assetManager, new Namer() {
              public String getName(int x, int y) {
                  //return "Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
                  System.out.println("X = " + x + ", Y = " + y);
                  return "Textures/heightmap.png";
                  // set to return the sme hieghtmap image.
              }
          }));
  
  
  
          terrain.setMaterial(mat_terrain);
          terrain.setLocalTranslation(0,-100, 0);
          terrain.setLocalScale(2f, 1f, 2f);
          rootNode.attachChild(terrain);
  
  
          TerrainLodControl control = new TerrainLodControl(terrain, getCamera());
          terrain.addControl(control);
      }
  
      public void initMaterial() {
          // TERRAIN TEXTURE material
          this.mat_terrain = new Material(this.assetManager, "Common/MatDefs/Terrain/HeightBasedTerrain.j3md");
  
  
          // GRASS texture
          Texture grass = this.assetManager.loadTexture("Textures/white.png");
          grass.setWrap(WrapMode.Repeat);
          this.mat_terrain.setTexture("region1ColorMap", grass);
          this.mat_terrain.setVector3("region1", new Vector3f(-10, 0, this.grassScale));
  
          // DIRT texture
          Texture dirt = this.assetManager.loadTexture("Textures/white.png");
          dirt.setWrap(WrapMode.Repeat);
          this.mat_terrain.setTexture("region2ColorMap", dirt);
          this.mat_terrain.setVector3("region2", new Vector3f(0, 900, this.dirtScale));
  
  
          Texture building = this.assetManager.loadTexture("Textures/building.png");
          building.setWrap(WrapMode.Repeat);
  
  
          this.mat_terrain.setTexture("slopeColorMap", building);
          this.mat_terrain.setFloat("slopeTileFactor", 32);
  
          this.mat_terrain.setFloat("terrainSize", 513);
      }
  }
  </code></pre>