0
\$\begingroup\$

After following the tutorial found here:http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series1/VertexBuffer_and_IndexBuffer.php

The code at the bottom of this page is what I am using. (I have changed some things in attempt to fix the issue already, so my code and this are not exactly the same).

I noticed that the height map was actually being rendered upside down. For example, if I wrote "hello" in the height map, when drawn the letters would appear upside down. After fiddling with this for a while I cannot see the problem, and the letters would always appear backwards or upside-down or both.

Basically I am just trying to get the top of the height map to be drawn in the north (either +z or -z, final direction does not matter to me).

    private void LoadHeightData(Texture2D heightMap)
    {
        terrainWidth = heightMap.Width;
        terrainHeight = heightMap.Height;

        Color[] heightMapColors = new Color[terrainWidth * terrainHeight];

        heightMap.GetData(heightMapColors);

        heightData = new float[terrainWidth * terrainHeight];

        for (int i = 0; i < heightData.Length; i++)       
                heightData[i] = heightMapColors[i].R;
    }

    private void SetUpVertices()
    {
        vertices = new VertexPositionColorNormal[terrainWidth * terrainHeight];
        //for (int y = terrainHeight - 1; y > -1; y--)
        for (int z = 0; z < terrainHeight; z++)
        {                
            //for (int x = terrainWidth - 1; x > -1; x--)
            for (int x = 0; x < terrainWidth; x++)
            {                                                                         
                vertices[x + z * terrainWidth].Position = new Vector3(x, heightData[x + z * terrainWidth], -z);
                vertices[x + z * terrainWidth].Color = Color.White;
            }
        }
    }

    private void SetUpIndices()
    {
        indices = new short[(terrainWidth - 1) * (terrainHeight - 1) * 6];
        int counter = 0;

        for (int y = 0; y < terrainHeight - 1; y++)
        {
            for (int x = 0; x < terrainWidth - 1; x++)
            {
                int lowerLeft = x + (y * terrainWidth);
                int lowerRight = (x + 1) + (y * terrainWidth);
                int topLeft = x + ((y + 1) * terrainWidth);
                int topRight = (x + 1) + ((y + 1) * terrainWidth);

                indices[counter++] = (short)topLeft;
                indices[counter++] = (short)lowerRight;
                indices[counter++] = (short)lowerLeft;

                indices[counter++] = (short)topLeft;
                indices[counter++] = (short)topRight;
                indices[counter++] = (short)lowerRight;
            }
        }
    }

    private void CalculateNormals()
    {
        for (int i = 0; i < vertices.Length; i++)
            vertices[i].Normal = new Vector3(0, 0, 0);

        for (int i = 0; i < indices.Length / 3; i++)
        {
            int index1 = indices[i * 3];
            int index2 = indices[i * 3 + 1];
            int index3 = indices[i * 3 + 2];

            Vector3 side1 = vertices[index1].Position - vertices[index3].Position;
            Vector3 side2 = vertices[index1].Position - vertices[index2].Position;
            Vector3 normal = Vector3.Cross(side1, side2);

            vertices[index1].Normal += normal;
            vertices[index2].Normal += normal;
            vertices[index3].Normal += normal;
        }

        for (int i = 0; i < vertices.Length; i++)
            vertices[i].Normal.Normalize();
    }

    public void Draw(GraphicsDevice device, Effect effect)
    {
        foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        {
            pass.Apply();

            device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, indices.Length / 3, VertexPositionColorNormal.VertexDeclaration);
        }
    }

With that code: enter image description here

Any ideas what the bug could be? I can always post more code but this is everything involved except for the camera. Thank you for your time!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Figured it out.

int lowerLeft = x + (y * terrainWidth);
int lowerRight = (x + 1) + (y * terrainWidth);
int topLeft = x + ((y + 1) * terrainWidth);
int topRight = (x + 1) + ((y + 1) * terrainWidth);

The code above creates upside down triangles relative to the height map. (It is very easy to see after drawing it out on paper.) This code should become:

int topLeft = x + (y * terrainWidth);                     // was lower
int topRight = (x + 1) + (y * terrainWidth);             //was lower
int lowerLeft = x + ((y + 1) * terrainWidth);            // was top
int lowerRight = (x + 1) + ((y + 1) * terrainWidth);     //was top

And thus draws the triangles exactly as they should appear. Since the lower left was marked as the upper left, etc., the triangles were being formed upside down.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .