using System; using System.IO; using ImageSharp; using ImageSharp.PixelFormats; using OpenTK.Graphics.OpenGL4; using OpenTK; using org.niclasundharald.engine; using org.niclasundharald.engine.graphics; namespace nhengine { public class SquaredMap : WorldObject { private static float edge = 64; private int width, height; private float[] heightMap; private MapModel3D model; public SquaredMap(int width,int height) { this.width = width; this.height = height; this.heightMap = new float[ (width + 1) * (height + 1) ]; generateHeightMap(); computeModel(); } public override Model3D getModel3D() { return this.model; } public SquaredMap(Image heightMap) { this.width = heightMap.Width-1; this.height = heightMap.Height-1; this.heightMap = new float[ (width + 1) * (height + 1) ]; loadHeightMap(heightMap); computeModel(); } public void generateHeightMap(){ Random rand = new Random(); for (int y = 0; y <= height; y++) { for (int x = 0; x <= width; x++) { float h = (float)rand.NextDouble(); heightMap[x + (y * width)] = (float)(256 * (h * h)); } } } public void loadHeightMap(Image _heightMap){ Rgba32[] pixels = _heightMap.Pixels; for (int y = 0; y <= height; y++) { for (int x = 0; x <= width; x++) { Rgba32 pixel = pixels[ x + (y * (width + 1))]; float h = (pixel.R + pixel.G + pixel.B) / 3; heightMap[x + (y * (width + 1))] = (float)(h); } } } public void computeModel(){ float left, right, bottom, top, vcenter, hcenter; Vector3[] vertexes = new Vector3[ 18 * width * height ]; Console.WriteLine("Creating geometry"); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int i = x + ((width + 1) * y); int j = x + ((width + 1) * (y + 1)); float[] h = new float[4]; h[0] = heightMap[i]; h[1] = heightMap[i+1]; h[2] = heightMap[j]; h[3] = heightMap[j+1]; float ah = (h[0] + h[1] + h[2] + h[3]) / 4.0f; left = edge * x; right = edge * (x + 1); bottom = edge * y; top = edge * (y + 1); vcenter = (top + bottom) / 2.0f; hcenter = (left + right) / 2.0f; int b = 4 * (x + (width * y)); Model3D.setTriangle( vertexes, b, new Vector3(left, top, h[2]), new Vector3(right, top, h[3]), new Vector3(hcenter,vcenter,ah) ); Model3D.setTriangle( vertexes, b + 1, new Vector3(right, top, h[3]), new Vector3(right, bottom, h[1]), new Vector3(hcenter, vcenter, ah) ); Model3D.setTriangle( vertexes, b + 2, new Vector3(right, bottom, h[1]), new Vector3(left, bottom, h[0]), new Vector3(hcenter, vcenter, ah) ); Model3D.setTriangle( vertexes, b + 3, new Vector3(left, bottom, h[0]), new Vector3(left, top, h[2]), new Vector3(hcenter, vcenter, ah) ); } } /* Console.WriteLine("Coloring..."); for (int n = 0; n < vertices.Length / 3;n++){ float _h = vertices[(3 * n) + 2] / 512.0f; setColor( n, ) } */ this.model = new MapModel3D( vertexes ); this.Position = new Vector3(-(width)*edge,-(height)*edge,0); } } class MapModel3D : Model3D { int nDraw; public MapModel3D(Vector3[] vertexes){ Vector4[] colors = new Vector4[ vertexes.Length ]; for (int n=0; n< vertexes.Length; n++){ if (vertexes[n].Z >= 256 ){ Console.WriteLine("Max. Height : {0}",vertexes[n].Z / 256); } colors[n] = new Vector4( 0.50f + (0.2f * vertexes[n].Z / 256), 0.25f + (0.50f * vertexes[n].Z / 256), 0.10f + (0.80f * vertexes[n].Z / 256), 1.0f ); } bind(vertexes, colors); } public override void draw() { nDraw+= nTriangles >> 8; if (nDraw > nTriangles){ nDraw = 0; } nDraw = nTriangles; GL.BindVertexArray(this.vao); GL.DrawArrays(PrimitiveType.Triangles, 0, nDraw * 3); GL.BindVertexArray(0); } } }