Return to Snippet

Revision: 41854
at February 24, 2011 01:57 by badescuga


Initial Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace WindowsGame1
{
    class Terrain
    {
        VertexPositionNormalTexture[] vertices;
        VertexBuffer vertexBuffer;
        int[] indices;
        IndexBuffer indexBuffer;
        float[,] heights;
        float height;
        float cellSize;
        public int width, length;
        int nVertices, nIndices;
        Effect effect;
        GraphicsDevice GraphicsDevice;
        Texture2D heightMap;
        Texture2D baseTexture;
        float textureTiling;
        Vector3 lightDirection;

        public Terrain(Texture2D HeightMap, float CellSize, float Height, GraphicsDevice GraphicsDevice, ContentManager Content)
        {
            this.heightMap = HeightMap;
            this.width = HeightMap.Width;
            this.length = HeightMap.Height;
            this.cellSize = CellSize;
            this.height = Height;
            this.GraphicsDevice = GraphicsDevice;
            effect = Content.Load<Effect>("TerrainEffect");
            //1 vertex per pixel 
            nVertices = width * length;
            nIndices = (width - 1) * (length - 1) * 6;
            vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionNormalTexture), nVertices, BufferUsage.WriteOnly);
            indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, nIndices, BufferUsage.WriteOnly);
            getHeights();
            createVertices();
            createIndices();
            genNormals();
            vertexBuffer.SetData<VertexPositionNormalTexture>(vertices);
            indexBuffer.SetData<int>(indices);
        }

         public Terrain(Texture2D HeightMap, float CellSize, float Height, Texture2D BaseTexture, float TextureTiling, Vector3 LightDirection, GraphicsDevice GraphicsDevice, ContentManager Content)
    {
             this.baseTexture = BaseTexture;
             this.textureTiling = TextureTiling;
             this.lightDirection = LightDirection;
            this.heightMap = HeightMap;
            this.width = HeightMap.Width;
            this.length = HeightMap.Height;
            this.cellSize = CellSize;
            this.height = Height;
            this.GraphicsDevice = GraphicsDevice;
            effect = Content.Load<Effect>("TerrainEffect2");

             if(effect.Parameters["BaseTexture"] != null )
            effect.Parameters["BaseTexture"].SetValue(baseTexture);
             if (effect.Parameters["TextureTiling"] != null)
             effect.Parameters["TextureTiling"].SetValue(textureTiling);
             if (effect.Parameters["LightDirection"] != null)
             effect.Parameters["LightDirection"].SetValue(lightDirection);

            
            
             //1 vertex per pixel 
            nVertices = width * length;
            nIndices = (width - 1) * (length - 1) * 6;
            vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionNormalTexture), nVertices, BufferUsage.WriteOnly);
            indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, nIndices, BufferUsage.WriteOnly);
            getHeights();
            createVertices();
            createIndices();
            genNormals();
            vertexBuffer.SetData<VertexPositionNormalTexture>(vertices);
            indexBuffer.SetData<int>(indices);
        }

        private void getHeights()
        {
        Color[] heigthMapData = new Color[width * length];
            heightMap.GetData<Color>(heigthMapData);
            heights = new float[width,length];
            for(int y=0;y<length;y++)
                for(int x=0;x<width;x++)
                {
                float amt=heigthMapData[y * width + x].R;
                    amt /=255.0f;
                    heights[x,y]=amt * height;
                }
        }

        private void createVertices()
        {
        vertices = new VertexPositionNormalTexture[nVertices];
            Vector3 offsetToCenter = - new Vector3(((float)width / 2.0f) * cellSize, 0 ,((float) length / 2.0f) * cellSize );
        //Vector3 offsetToCenter = Vector3.Zero;
            for(int z=0;z<length;z++)
                for(int x=0;x<width;x++)
                {
                Vector3 position = new Vector3(x*cellSize,heights[x,z],z * cellSize ) + offsetToCenter;
                    Vector2 uv= new Vector2((float)x / width, (float) z / length );
                    vertices[z*width + x] = new VertexPositionNormalTexture(position,Vector3.Zero,uv);

                
                
                }
        
        }

        private void createIndices()
        {
        indices = new int[nIndices];
            int i=0;
            for(int x=0;x<width -1; x++)
                for(int z=0;z<length -1;z++)
                {
                    int upperLeft = z * width + x;
                    int upperRight = upperLeft +1;
                    int lowerLeft = upperLeft + width;
                    int lowerRight = lowerLeft +1;


                    //upperTriangle
                    indices[i++]= upperLeft;
                    indices[i++]=upperRight;
                    indices[i++] = lowerLeft;

                    //lowerTriangle
                    indices[i++]=lowerLeft;
                    indices[i++]=upperRight;
                    indices[i++]=lowerRight;
                
                }
        
        }

        private void genNormals()
        {
        for(int i=0;i<nIndices;i+=3)
        {
            Vector3 v1 = vertices[indices[i]].Position;
            Vector3 v2=vertices[indices[i+1]].Position;
            Vector3 v3=vertices[indices[i+2]].Position;
        
            Vector3 normal= Vector3.Cross(v1-v2,v1-v3);
            normal.Normalize();

            //add influence of the normal to each vertex in the triangle
            vertices[indices[i]].Normal += normal;
            vertices[indices[i+1]].Normal += normal;
            vertices[indices[i+2]].Normal += normal;
        }
            for(int i=0;i<nVertices;i++)
                vertices[i].Normal.Normalize();
        
        
        
        }

        public void Draw(Camera camera)
        {

            effect.Parameters["World"].SetValue(Matrix.Identity * Matrix.CreateScale(10000));
            effect.Parameters["Projection"].SetValue(camera.projectionMatrix);
            effect.Parameters["View"].SetValue(camera.viewMatrix);

        GraphicsDevice.SetVertexBuffer(vertexBuffer);
        GraphicsDevice.Indices = indexBuffer;
        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Apply();
            GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,0, 0, vertexBuffer.VertexCount , 0,  indexBuffer.IndexCount / 3);
            
        }
        GraphicsDevice.SetVertexBuffer(null);
        GraphicsDevice.Indices = null;
        
        }

        

     




        

    }
}

Initial URL


Initial Description


Initial Title
snip code for XNA

Initial Tags


Initial Language
C#