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
\$\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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.