/ Published in: C#
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
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; 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; indexBuffer = new IndexBuffer(GraphicsDevice, IndexElementSize.ThirtyTwoBits, nIndices, BufferUsage.WriteOnly); getHeights(); createVertices(); createIndices(); genNormals(); vertexBuffer.SetData<VertexPositionNormalTexture>(vertices); indexBuffer.SetData<int>(indices); } private void getHeights() { heightMap.GetData<Color>(heigthMapData); 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() { 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++) { } } private void createIndices() { 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; } } }