Sign in to follow this  
speciesUnknown

Terrain vertices (triangle list) look wrong

Recommended Posts

Hi,

I have this code for initialising and drawing my terrain, from an array of height data:

[code]

protected short make1dIndex(short x, short y)
{
short accum = y;
accum = (short)(accum * width);
accum += x;
return accum;
}

protected void initialise(Renderer3D r)
{
// build verts
heightVertList = new VertexPositionColorTexture[this.width * this.length];
triangleListIndices = new short[(this.width - 1) * (this.length - 1) * 6];

for (short x = 0; x < width; x++)
for (short z = 0; z < length; z++)
{
int ind1d = z * width + x;

heightVertList[ind1d].Position.X = x * cell_size;
heightVertList[ind1d].Position.Y = (float) height_data[ind1d].R;
heightVertList[ind1d].Position.Z = z * cell_size;

heightVertList[ind1d].TextureCoordinate.X = x;
heightVertList[ind1d].TextureCoordinate.Y = z;

heightVertList[ind1d].Color = height_data[ind1d];
}

// build indices
int i = 0;
for (short x = 0; x < width - 1; x++)
for (short z = 0; z < length - 1; z++)
{
triangleListIndices[i] = make1dIndex( (short) x, (short) z);
triangleListIndices[i + 1] = make1dIndex( (short) (x + 1), (short) z);
triangleListIndices[i + 2] = make1dIndex( (short) (x + 1), (short) (z + 1) );

triangleListIndices[i + 3] = make1dIndex( (short) (x), (short) (z) );
triangleListIndices[i + 4] = make1dIndex( (short) (x + 1), (short) (z + 1) );
triangleListIndices[i + 5] = make1dIndex( (short) x, (short) (z + 1) );
i += 6;
}

this.basic_effect = new BasicEffect(r.GraphicsDevice, null);

// Initialize the vertex buffer, allocating memory for each vertex.
this.vertexBuffer = new VertexBuffer
(
r.GraphicsDevice,
VertexPositionColorTexture.SizeInBytes * (heightVertList.Length),
BufferUsage.None
);

// Set the vertex buffer data to the array of vertices.
vertexBuffer.SetData<VertexPositionColorTexture>(heightVertList);

this.vertexDeclaration = new VertexDeclaration
(
r.GraphicsDevice,
VertexPositionColorTexture.VertexElements
);

this.initialised = true;
}

public void draw(float delta, Renderer3D r)
{
if (!initialised)
initialise(r);

GraphicsDevice graphics = r.GraphicsDevice;

// tell graphics device to use our vertex buffer
graphics.Vertices[0].SetSource
(
this.vertexBuffer, 0, VertexPositionColorTexture.SizeInBytes
);

graphics.VertexDeclaration = this.vertexDeclaration;

// set Up the properties of our shaders
basic_effect.View = r.ViewMatrix.Current;
basic_effect.Projection = r.ProjectionMatrix.Current;
basic_effect.World = r.WorldMatrix.Current;
basic_effect.TextureEnabled = false;
basic_effect.VertexColorEnabled = true;
basic_effect.LightingEnabled = false;

basic_effect.CommitChanges();

basic_effect.Begin();
foreach (EffectPass ep in basic_effect.CurrentTechnique.Passes)
{
ep.Begin();

graphics.DrawUserIndexedPrimitives<VertexPositionColorTexture>
(
PrimitiveType.TriangleList,
heightVertList,
0,
(this.width) * (this.length),
triangleListIndices,
0,
(this.width - 1) * (this.length - 1) * 2
);

ep.End();
}
basic_effect.End();
}
[/code]


The results are not correct:
[img]http://img97.imageshack.us/img97/6299/wrongindices.png[/img]

There are odd triangles extending all the way across the scene, as if my indices are off by 1 point or more, but I cant see in my code where this accidental offset is coming from. The large triangle extending right across the middle is the most obvious wrong triangle, but there are other visible triangles across the middle.
The colouration matches the colour of the pixel in the height map.

Share this post


Link to post
Share on other sites
I noticed when you create your indices, you create the array with -1 to the width and length? Why are you doing that? Looks like you might be stopping a bit short.

This sort of thing happens when you aren't sending the amount of data that Direct3D is expecting.

Share this post


Link to post
Share on other sites
[quote name='Flimflam' timestamp='1306887007' post='4818090']
I noticed when you create your indices, you create the array with -1 to the width and length? Why are you doing that? Looks like you might be stopping a bit short.

This sort of thing happens when you aren't sending the amount of data that Direct3D is expecting.
[/quote]

If the terrain is n points wide, it is n-1 pairs of triangles wide; likewise for the height.
It has occurred to me that this is where I am going wrong, but ive tried various things without it working.

Share this post


Link to post
Share on other sites
I fixed the problem; it was caused by an overflow on the space of a short integer. My height maps are 257^2 which was causing the indices I was giving to overflow (a C# short is16 bit signed)

My GPU must have been wrapping the indices round, resulting in the offset of 1 point.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this