I'm trying to create a heightmap from an image using a VertexBuffer and IndexBuffer but it isn't working. When I run my program, I just see a blank screen. Any ideas
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace HeightmapDemo
{
public class Heightmap
{
public static float HeightScale = 50f;
public static float CellSize = 20f;
protected VertexPositionNormalTexture[] vertices;
protected short[] indices;
protected VertexDeclaration vertDecl;
protected VertexBuffer vertBuffer;
protected IndexBuffer indexBuffer;
protected BasicEffect effect;
public void GenerateModel(GraphicsDevice graphicsDevice, Texture2D texture)
{
Color[] colors = new Color[texture.Width * texture.Height];
texture.GetData<Color>(colors);
vertices = new VertexPositionNormalTexture[texture.Width * texture.Height];
int x, z;
for (x = 0; x < texture.Width; ++x)
{
for (z = 0; z < texture.Height; ++z)
{
vertices[x * texture.Width + z] = new VertexPositionNormalTexture(
new Vector3(
(float)x * CellSize,
0,
(float)z * CellSize
),
Vector3.Up,
new Vector2(
(float)x,
(float)z
)
);
}
}
vertBuffer = new VertexBuffer(
graphicsDevice,
VertexPositionNormalTexture.SizeInBytes * vertices.Length,
ResourceUsage.None,
ResourceManagementMode.Automatic
);
vertBuffer.SetData<VertexPositionNormalTexture>(vertices);
vertDecl = new VertexDeclaration(graphicsDevice, VertexPositionNormalTexture.VertexElements);
indices = new short[vertices.Length];
for (x = 0; x < texture.Width; ++x)
{
for (z = 0; z < texture.Height; ++z)
{
if (z % 2 == 0)
indices[x * texture.Width + z] = (short)(x * texture.Width + z);
else
indices[x * texture.Width + z] = (short)(x * texture.Width - z);
}
}
indexBuffer = new IndexBuffer(
graphicsDevice,
sizeof(short) * indices.Length,
ResourceUsage.None,
IndexElementSize.SixteenBits
);
indexBuffer.SetData<short>(indices);
effect = new BasicEffect(graphicsDevice, null);
effect.DiffuseColor = new Vector3(1f, 0f, 0f);
}
public void Draw(GraphicsDevice graphicsDevice, Matrix projectionMatrix, Matrix viewMatrix)
{
graphicsDevice.Vertices[0].SetSource(
vertBuffer,
0,
VertexPositionNormalTexture.SizeInBytes
);
graphicsDevice.VertexDeclaration = vertDecl;
graphicsDevice.Indices = indexBuffer;
effect.Projection = projectionMatrix;
effect.View = viewMatrix;
effect.World = Matrix.Identity;
effect.Begin();
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Begin();
graphicsDevice.DrawIndexedPrimitives(
PrimitiveType.LineStrip,
0,
0,
vertices.Length,
0,
vertices.Length - 1
);
pass.End();
}
effect.End();
}
}
}

VertexBuffer and IndexBuffer For Height Map
kaanuki
Liu Feng
To debug these kinds of problems, Pix for Windows is a great tool. It comes free with the DirectX SDK download. You point it at your application, and set it to capture a full frame when you press a hot-key. Then you can analyze that frame, step through the drawing instructions, and, best of all, look at the "mesh" that gets rendered (including pre- and post-shader vertex and pixel values) in mesh space, in addition to viewport space.
The quick solution for you is to set your view matrix to something like Matrix.CreateTranslation(-500, -500, -500).
Btw: for height maps, I use DDS files with format "R32F." This means that I can get better resolution than with a Color format texture, at the same storage size.
Paul Diston
LumberJack_Jon
trai_mv
Jamie Thomson
Height * Width vertices, 2 * Height * Width Triangles => 6*Height * Width indices (3 indices for each triangles).
Also, the way you use them, the indices describe degenerate triangles, I think.
Here's how I generate a grid of (dimension * dimension) cells:
public void GenerateStructures()
{
vertices = new VertexPositionNormalTexture[(dimension + 1) * (dimension + 1)];
indices = new short[dimension * dimension * 6];
for (int i = 0; i < dimension+1; i++)
{
for (int j = 0; j < dimension+1; j++)
{
VertexPositionNormalTexture vert = new VertexPositionNormalTexture();
vert.Position = new Vector3(i * cellSize, 0, j * cellSize);
vert.Normal = Vector3.Up;
vert.TextureCoordinate = new Vector2(i,j);
vertices[i * (dimension + 1) + j] = vert;
}
}
for (int i = 0; i < dimension; i++)
{
for (int j = 0; j < dimension; j++)
{
indices[6 * (i * dimension + j)] =(short)( i * (dimension + 1) + j);
indices[6 * (i * dimension + j)+2] =(short)( i * (dimension + 1) + j+1);
indices[6 * (i * dimension + j) + 1] = (short)((i + 1) * (dimension + 1) + j + 1);
indices[6 * (i * dimension + j)+3] =(short)( i * (dimension + 1) + j);
indices[6 * (i * dimension + j)+5] =(short)( (i+1) * (dimension + 1) + j+1);
indices[6 * (i * dimension + j)+4] =(short)( (i+1) * (dimension + 1) + j);
}
}
}