using
System;
using
System.Collections.Generic;
using
System.Text;
using
Microsoft.Xna.Framework.Graphics;
using
Microsoft.Xna.Framework;
namespace
WindowsGame1
{
internal
class
Landscape
{
private
float
[,] heights;
private
int
verticesCount;
private
int
indicesCount;
private
int
width;
private
int
height;
private
GraphicsDevice device;
private
VertexBuffer vb;
private
IndexBuffer ib;
private
BasicEffect effect;
public
Landscape(GraphicsDevice graphics)
{
device = graphics;
effect =
new
BasicEffect(device,
null
);
}
public
Texture2D texture
{
get
;
set
;
}
public
void
LoadTerrain(Texture2D tex,
double
heightScale)
{
width = tex.Width;
height = tex.Height;
heights =
new
float
[width, height];
Color[] b =
new
Color[width * height];
tex.GetData<Color>(b);
for
(
int
y = 0; y <= height - 1; y++)
{
for
(
int
x = 0; x <= width - 1; x++)
{
var
_with1 = b[x + y * width];
heights[x, y] = (
int
)(heightScale / 255 * (Convert.ToDouble(_with1.R) + Convert.ToDouble(_with1.G) + Convert.ToDouble(_with1.B)) / 3);
}
}
PrepareVertexBuffer();
PrepareIndexBuffer();
}
private
void
PrepareVertexBuffer()
{
verticesCount = width * height;
vb =
new
VertexBuffer(device,
typeof
(VertexPositionTexture), verticesCount, BufferUsage.WriteOnly);
VertexPositionTexture[] verts =
new
VertexPositionTexture[verticesCount];
for
(
int
y = 0; y <= height - 1; y++)
{
for
(
int
x = 0; x <= width - 1; x++)
{
var
_with1 = verts[x + y * width];
_with1.Position =
new
Vector3(x, heights[x, y], y);
}
}
vb.SetData<VertexPositionTexture>(verts);
}
private
void
PrepareIndexBuffer()
{
indicesCount = (width - 1) * (height - 1) * 6;
ib =
new
IndexBuffer(device,
typeof
(
int
), indicesCount, BufferUsage.WriteOnly);
int
[] indices =
new
int
[indicesCount];
int
k = 0;
for
(
int
y = 0; y <= height - 2; y++)
{
for
(
int
x = 0; x <= width - 2; x++)
{
int
b = x + y * width;
indices[k] = b;
indices[k + 1] = b + 1;
indices[k + 2] = b + 1 + width;
indices[k + 3] = b;
indices[k + 4] = b + 1 + width;
indices[k + 5] = b + width;
k += 6;
}
}
ib.SetData<
int
>(indices);
}
public
void
Draw(Matrix world, Matrix view, Matrix proj)
{
effect.World = world;
effect.View = view;
effect.Projection = proj;
device.RenderState.FillMode = FillMode.WireFrame;
effect.Begin(SaveStateMode.None);
effect.TextureEnabled =
true
;
effect.Texture = texture;
foreach
(EffectPass pass
in
effect.CurrentTechnique.Passes)
{
pass.Begin();
device.VertexDeclaration =
new
VertexDeclaration(device, VertexPositionTexture.VertexElements);
device.Vertices[0].SetSource(vb, 0, VertexPositionTexture.SizeInBytes);
device.Indices = ib;
device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, verticesCount, 0, indicesCount / 3);
pass.End();
}
effect.End();
}
}
}