using System; using System.IO; using System.Collections.Generic; using ImageSharp; using ImageSharp.PixelFormats; using OpenTK.Graphics.OpenGL4; using OpenTK; using org.niclasundharald.engine; namespace org.niclasundharald.engine.graphics { public class SquaredMap : WorldObject { public static SquaredMap activeMap; private static float edge = 5; private static float maxHeight = 128.0f; private int width, height; private float[] heightMap; private MapModel3D model; public SquaredMap(int width,int height) { activeMap = this; 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) { activeMap = this; 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)(maxHeight * (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) * maxHeight / 768; heightMap[x + (y * (width + 1))] = (float)(h); } } } public void computeModel(){ float left, right, bottom, top, vcenter, hcenter; Vector3[] vertexes = new Vector3[ 12 * 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) ); } } this.model = new MapModel3D( vertexes ); } private int indHeightMap(int x,int y){ return x + ((width + 1) * y); } public Vector3 ground(Vector2 _xy){ Vector2 xy = _xy / edge; int i1 = indHeightMap((int)xy.X,(int)xy.Y); int i2 = indHeightMap((int)xy.X,(int)xy.Y+1); if ((xy.X < 0)||(xy.Y<0)||(xy.X>=width)||(xy.Y>=height)){ throw new OutOfWorldException(); } float h = heightMap[i1] + heightMap[i1 + 1] + heightMap[i2] + heightMap[i2 + 1]; h /= 4; Vector3 v3 = new Vector3(_xy.X,_xy.Y,h); Console.WriteLine("Grounding: {0}",v3); return v3; } } 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 ); } Vector3[] normals = Model3D.computeNormals(vertexes); Dictionary> dNormals = new Dictionary>(); foreach (Vector3 v in vertexes){ if (!dNormals.ContainsKey(v)){ dNormals.Add(v,new List()); } } for (int n=0;n> 8; if (nDraw > nTriangles){ nDraw = 0; } nDraw = nTriangles; GL.BindVertexArray(this.vao); GL.DrawArrays(PrimitiveType.Triangles, 0, nDraw * 3); GL.BindVertexArray(0); } } }