2
\$\begingroup\$

I have started to learn game development, using the jMonkey engine. I am able to create single tile of terrain using TerrainQuad, but in the next step, I'm stuck at making it infinite. I have gone through the wiki and a tutorial, and want to use the TerrainGrid class, but my code does not seem to work. I have looked around on the web, and searched other forums, but cannot find any other code example to help.

I believe in the below code; ImageTileLoader returns an image, which is the height map 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.

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";
        }
    }));

This is the result, when I use TerrainQuad:

My result with terrain quad


This is my full 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 TerrainGrid("terrain", patchSize, 513, 
            new ImageTileLoader(assetManager, new Namer() {
            public String getName(int x, int y) {
                System.out.println("X = " + x + ", Y = " + y);
                return "Textures/heightmap.png";
                // set to return the same height map 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);
    }
}
\$\endgroup\$
  • \$\begingroup\$ Hello! Welcome to the GameDev StackExchange. We hope that you enjoy your time here on this site. If you haven't already, we recommend that you read the site guide. Keep in mind that the more research you put into your questions, the better results you will get. Have fun! \$\endgroup\$ – Nick Caplinger Jun 8 '13 at 18:45
3
\$\begingroup\$

I just had the same problem and i managed to solve it. You have to use TerrainGridLodControl to make it work, as TerrainLodControl doesn't work. Looks like we failed to notice that when changing from TerrainQuad to TerrainGrid.

\$\endgroup\$
1
\$\begingroup\$

So, I worked further on my problem and was able to achieve what I wanted to. But I still cannot understand what was the error on my first code. Below is the final code that I got by modifying the TerrainGrid example from here. Below is the final code for anyone who falls into the same situation. It is not the final thing but does answer my question above.

public class TerrainGridTest extends SimpleApplication {

    private Material mat_terrain;
    private TerrainGrid terrain;
    private float grassScale = 64;
    private float dirtScale = 16;

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

    @Override
    public void simpleInitApp() {
        this.flyCam.setMoveSpeed(100f);
        initMaterial();
        initTerrain();
        this.getCamera().setLocation(new Vector3f(0, 200, 0));
        this.getCamera().lookAt(new Vector3f(0,0,0), Vector3f.UNIT_Y);
        this.viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
        initLight();
    }

    @Override
    public void simpleUpdate(final float tpf) {

    }

    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));

        // ROCK texture
        //Texture rock = this.assetManager.loadTexture("Textures/Terrain/Rock2/rock.jpg");
        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);
    }

    private void initLight() {
        DirectionalLight light = new DirectionalLight();
        light.setDirection((new Vector3f(-0.5f, -1f, -0.5f)).normalize());
        rootNode.addLight(light);
    }

    private void initTerrain() {
        this.terrain = new TerrainGrid("terrain", 65, 257, new ImageTileLoader(assetManager, new Namer() {

            public String getName(int x, int y) {
               //return "Interface/Scenes/TerrainMountains/terrain_" + x + "_" + y + ".png";
                return "Textures/heightmap.png";
            }
        }));

        this.terrain.setMaterial(mat_terrain);
        this.terrain.setLocalTranslation(0, 0, 0);
        this.terrain.setLocalScale(3f, 1.5f, 3f);
        this.rootNode.attachChild(this.terrain);

        TerrainLodControl control = new TerrainGridLodControl(this.terrain, getCamera());
        control.setLodCalculator( new DistanceLodCalculator(65, 2.7f) ); // patch size, and a multiplier
        this.terrain.addControl(control);
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.