/// <summary> /// Creates a new terrain /// </summary> /// <param name="size">The size of the terrain</param> public Terrain(Vector2 size) { Position = Vector2.Zero; this._size = size; Vertices = new TerrainVertex[(int)(size.X * size.Y)]; //Generate vertices for (int y = 0; y < size.Y; y++) { for (int x = 0; x < size.X; x++) { this[x, y] = GenerateVertex(x, y); } } //Generate the indices List <uint> indices = new List <uint>(); //Adds a single index to the list based on the position of the vertex void AddIndex(int x, int y) { indices.Add((uint)(x + y * size.Y)); } //Generate all the indices for (int y = 0; y < size.Y - 1; y++) { for (int x = 0; x < size.X - 1; x++) { AddIndex(x, y); AddIndex(x + 1, y + y % 2); AddIndex(x, y + 1); if (x != 0) { AddIndex(x, y); AddIndex(x, y + 1); AddIndex(x - 1, y + (y + 1) % 2); } } } Vao = new VertexArray(); VertexBuffer vbo = new VertexBuffer(); IndexBuffer ibo = new IndexBuffer(); BufferLayout layout = new BufferLayout(); //Initialize the buffer objects Vao.Init(); vbo.Init(Vertices); ibo.Init(indices.ToArray()); //Set up the layout of the data layout.AddLayoutItem(VertexAttribPointerType.Float, 3); layout.AddLayoutItem(VertexAttribPointerType.Float, 4); //Add the buffers to the VAO Vao.Vbo = vbo; Vao.Ibo = ibo; Vao.Layout = layout; }
/// <summary> /// Generate the terrain vertex information based on the position /// </summary> /// <param name="x">The x position of the vertex</param> /// <param name="y">The y position of the vertex</param> /// <returns>The information for the terrain vertex</returns> public static TerrainVertex GetVertex(float x, float y) { //Create the vertex TerrainVertex vertex = new TerrainVertex(); //Get the biome float humidity, temperature; void GetHumidityAndTemperature(float xOffset, float yOffset) { humidity = MathHelper.Clamp(_humidity.GetValueFractal(x + xOffset, y + yOffset) + 0.5f, 0f, 1f); temperature = MathHelper.Clamp(_temperature.GetValueFractal(x + xOffset, y + yOffset) + 0.5f, 0f, 1f); } GetHumidityAndTemperature(0, 0); Biome biome = ModLoader.GetBiome(humidity, temperature); //Set the data for the vertex float GetYPosition(Biome bio, float xOffset, float yOffset) { _height.SetFrequency(bio.Topology.Frequency); return((_height.GetSimplexFractal(x + xOffset, y + yOffset) + 0.5f) * bio.Topology.Amplitude + bio.Topology.MinHeight); } vertex.Position = new Vector3(x, GetYPosition(biome, 0, 0), y); vertex.Color = biome.Color; //Check for biome blending void BlendBiomes(float xOffset, float yOffset) { Vector2 checkOffset = new Vector2(xOffset, yOffset); float thisY = 0; //Step 1: Check when the border of the biomes are while (xOffset != 0 || yOffset != 0) { //Get the humidity and temperature GetHumidityAndTemperature(xOffset, yOffset); //Check if it is within the original biome if (biome.boundary.Contains(new Vector2(humidity, temperature))) { if (xOffset == checkOffset.X && yOffset == checkOffset.Y) { return; } break; } //Move one step closer to no offset xOffset -= xOffset > 0 ? 1 : xOffset < 0 ? -1 : 0; yOffset -= yOffset > 0 ? 1 : yOffset < 0 ? -1 : 0; } //(We need to put the x- and yOffset one back) thisY = GetYPosition(biome, xOffset, yOffset); xOffset += checkOffset.X > 0 ? 1 : checkOffset.X < 0 ? -1 : 0; yOffset += checkOffset.Y > 0 ? 1 : checkOffset.Y < 0 ? -1 : 0; //Step 2: Get the new biome GetHumidityAndTemperature(xOffset, yOffset); Biome b = ModLoader.GetBiome(humidity, temperature); //Step 3: Calculate the blend proportion float blendProportion = 1; if (xOffset != checkOffset.X) { blendProportion = xOffset / checkOffset.X; } if (yOffset != checkOffset.Y) { blendProportion *= yOffset / checkOffset.Y; } //Step 4: Blend the biomes float otherY = GetYPosition(b, xOffset, yOffset); Vector3 position = vertex.Position; position.Y = ((otherY - thisY) / 2 + thisY) * (1 - blendProportion) + position.Y * blendProportion; vertex.Position = position; } BlendBiomes(10, 0); BlendBiomes(-10, 0); BlendBiomes(0, 10); BlendBiomes(0, -10); return(vertex); }