Revision: 41854
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
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#