예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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);
        }