VertexBuffer and IndexBuffer For Height Map

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();
}
}
}



Answer this question

VertexBuffer and IndexBuffer For Height Map

  • kaanuki

    Thanks for the code. Indeed I am using a line strip just to see if it would draw anything. I still can't figure out the problem. I've used VertexBuffers in other projects with success.

  • Liu Feng

    Remember that you are in a right-handed coordinate system. The camera starts out at 0,0,0, looking down negative Z. Meanwhile, your vertices extend from 0,0,0 up in the positive direction. Thus, unless you change your view (or model) matrix, you will not be looking at the data.

    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

    I am changing the view matrix accordingly, but I'll check out Pix to see if it can help me.

  • LumberJack_Jon

    Did you solve this Are you setting up BasicEffect correctly I don't see you setting any light attributes, or calling EnableDefaultLighting(). Are you using a black Clear color and seeing nothing, or CornFlowerBlue with nothing If the former, then the mesh may be rendering, but rendering in black, which would point towards BasicEffect not being set up correctly.

  • trai_mv

    Sorry. I just noticed you use LineStrips as primitive types. Forget what I said about you not having the indexes right.



  • Jamie Thomson

    First, your indices are all wrong. If you want to have a grid of Height / Width cells, you will have
    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);
    }

    }

    }


  • VertexBuffer and IndexBuffer For Height Map