public Terrain(Device device, AssetManager assetManager, int width, int length, int maxHeight, string[] textures) { this.heightMap = new HeightMap(width, length, maxHeight); CreatePatches(device); this.materials = textures.Select((texture, i) => new Material("Terrain" + i) { Shader = assetManager.Load(@"Engine\UberShader.fx") as Shader, DiffuseTexture = assetManager.Load(texture) as Texture }).ToList(); this.device = device; }
public Patch(Device device, HeightMap heightMap, int left, int top, int right, int bottom) { int width = right - left; int height = bottom - top; int numFace = (int)(width * height * 2); int numVertex = (int)((width + 1) * (height + 1)); this.mesh = new D3D.Mesh(device.RawDevice, numFace, numVertex, 0, this.terrainFvf); // Create terrain vertices var vertices = this.mesh.LockVertexBuffer(D3D.LockFlags.None); for (int z = top, z0 = 0; z <= bottom; ++z, ++z0) { for (int x = left, x0 = 0; x <= right; ++x, ++x0) { var pos = new Vector3(x, heightMap.GetHeight(x, z), z); var uv = new Vector2(x * 0.2f, z * 0.2f); vertices.Write(new TerrainVertex(pos, uv)); } } this.mesh.UnlockVertexBuffer(); // Calculate terrain indices var indices = this.mesh.LockIndexBuffer(D3D.LockFlags.None); for (int z = top, z0 = 0; z < bottom; ++z, ++z0) { for (int x = left, x0 = 0; x < right; ++x, ++x0) { // Triangle 1 indices.Write((short)(z0 * (width + 1) + x0)); indices.Write((short)((z0 + 1) * (width + 1) + x0)); indices.Write((short)(z0 * (width + 1) + x0 + 1)); // Triangle 2 indices.Write((short)(z0 * (width + 1) + x0 + 1)); indices.Write((short)((z0 + 1) * (width + 1) + x0)); indices.Write((short)((z0 + 1) * (width + 1) + x0 + 1)); } } this.mesh.UnlockIndexBuffer(); // Set attributes var attributes = this.mesh.LockAttributeBuffer(D3D.LockFlags.None); for (int z = top; z < bottom; ++z) { for (int x = left; x < right; ++x) { // Calculate vertices based on height int subset; if (heightMap.GetHeight(x, z) == 0.0f) subset = 0; else if (heightMap.GetHeight(x, z) <= heightMap.MaxHeight * 0.6f) subset = 1; else subset = 2; attributes.Write(subset); attributes.Write(subset); } } this.mesh.UnlockAttributeBuffer(); // Compute normal for the terrain this.mesh.ComputeNormals(); }