Rendering
How do you render the generated quads? The answer to this question is in the render method of the HeightMap class; see Listing Eight. All you need to do is go through the table of quads and render them at their given position in space. The user of the render method may supply a transform to be applied to each quad after the local transform, which is only putting each quad in its own place. Finally, you place the water mesh at the height level defined during heightmap creation.
public void render(Graphics3D g3d, Transform t) { for(int x = 0; x < map.length - 1; x++) { for(int y = 0; y < map[x].length - 1; y++) { localTransform.setIdentity(); localTransform.postTranslate(x * 5.0f, 0.0f, (mapHeight- y) * -5.0f); localTransform.postMultiply(t); g3d.render(map[x][y], localTransform); } } localTransform.setIdentity(); localTransform.postScale(255, 255, 255); localTransform.postRotate(-90, 1.0f, 0.0f, 0.0f); g3d.render(water, localTransform); }
Putting It All Together
Now you are finally ready to use the HeightMap class to load and render a heightmap from an existing grayscale image; see Listing Nine. Nothing out of the ordinary here. You just load the heightmap and do some transforms on it, since the transform is supplied to the HeightMap's render method later on. We want to scale it a lot since terrain is normally huge.
private void createScene() { try { // We're using a pretty high resolution. If you want to test this on an actual // handheld, try using a lower resolution, such as 0.20 or 0.10 hm = new HeightMap("/res/heightmap4.png", 0.30f, 40); t.postTranslate(0.0f, -2.0f, -5.0f); t.postScale(0.01f, 0.01f, 0.01f); camTrans.postTranslate(0.0f, 5.0f, 0.0f); //camTrans.postTranslate(0.0f, 5.0f, 2.0f); } catch(Exception e) { System.out.println("Heightmap error: " + e.getMessage()); e.printStackTrace(); TutorialMidlet.die(); } }
It is also important to note that for clarity, the HeightMap I present here is rendered without culling, something needed with large terrains. Finally, Listing Ten presents the draw method for rendering the HeightMap. While the HeightMap.render(g3d, t) method is straightforward, the controls might be unfamiliar. Move the camera with the joystickup, down, and rotate left and right. To move the camera forward, use the FIRE key.
// Get the Graphics3D context g3d = Graphics3D.getInstance(); // First bind the graphics object. We use our pre-defined rendering hints. g3d.bindTarget(g, true, RENDERING_HINTS); // Clear background g3d.clear(back); // Bind camera at fixed position in origo g3d.setCamera(cam, camTrans); // Render everything hm.render(g3d, t); // Check controls for camera movement if(key[UP]) { camTrans.postTranslate(0.0f, 1.0f, 0.0f); } if(key[DOWN]) { camTrans.postTranslate(0.0f, -1.0f, 0.0f); } if(key[LEFT]) { camTrans.postRotate(5, 0.0f, 1.0f, 0.0f); } if(key[RIGHT]) { camTrans.postRotate(-5, 0.0f, 1.0f, 0.0f); } // Fly forward if(key[FIRE]) camTrans.postTranslate(0.0f, 0.0f, -1.0f);
Conclusion
At this point, why don't you load the other heightmaps supplied in the source code files available electronically? See what kind of terrains come out. Or even better, create your own heightmap image!