Quads
To convert heightmaps into something you can render, you need to read the pixels of the heightmap, then create surfaces that reflect the variations in height. An easy-to-use surface in this problem is a "quad"two triangles put together to form a rectangular surface.
Figure 3 is a quad that consists of two triangles. As you can see, the quad has four endpoints that are disjointed because we are using two triangles to represent it. These four corners can be given different heights; thus, you have the beginning of describing heights in a 3D world. Because one quad isn't enough to describe an entire terrain, you'll use lots of them if you want the terrain to look realistic.
public static Mesh createQuad(short[] heights, int cullFlags) { // The vertrices of the quad short[] vertrices = {-255, heights[0], -255, 255, heights[1], -255, 255, heights[2], 255, -255, heights[3], 255};
// Create the model's vertex colors VertexArray colorArray = new VertexArray(color.length/3, 3, 1); colorArray.set(0, color.length / 3, color); // Compose VertexBuffer out of previous vertrices // and texture coordinates VertexBuffer vertexBuffer = new VertexBuffer(); vertexBuffer.setPositions(vertexArray, 1.0f, null); vertexBuffer.setColors(colorArray); // Create indices and face lengths int indices[] = new int[] {0, 1, 3, 2}; int[] stripLengths = new int[] {4}; // Create the model's triangles triangles = new TriangleStripArray(indices, stripLengths);
// Create the appearance Appearance appearance = new Appearance(); PolygonMode pm = new PolygonMode(); pm.setCulling(cullFlags); pm.setPerspectiveCorrectionEnable(true); pm.setShading(PolygonMode.SHADE_SMOOTH); appearance.setPolygonMode(pm);
To implement a quad, I start with an x-z plane with variable y-coordinates for varying height. I introduce the method createQuad to my MeshFactory (available in the full source code archive at http://www.ddj.com/code/). All createQuad needs to know is the different heights at the different corners of the quad, along with the culling flags. Listing One is a quad consisting of four vertices, each with varying y-components but static x and z. Listing Two creates the arrays necessary for describing a Mesh in an M3G system. The VertexBuffer holds two vertex arraysthe color array and position array. Listing Three, the next step in creating the quad, includes standard appearance stuff. However, the smooth shading means that colors of the vertices are interpolated over the whole surface, creating a smooth appearance. Now all that's left is to create the Mesh, which is straightforward:
// Finally create the Mesh Mesh mesh = new Mesh(vertexBuffer, triangles, appearance);