Skip to main content
GameDev.net gamedev.net
🔒 Locked 🎮 Unity

Texture drawing wrong on cubes

Started by ChristianFrantz Jul 14, 2013 at 6:16 PM 12 replies 2.7k views
Original Post
ChristianFrantz
ChristianFrantz

This is just a minor issue, but I can't seem to figure it out. I've messed around with the values of my VertexPositionColor variables and nothing seems to be working.

Y6pQa54.png


vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(1, 0)));
            //front left upper corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(1, 1)));
            //front right upper corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(0, 1)));
            //front lower right corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(0, 0)));
            //back left lower corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(0, 1)));
            //back left upper corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 0)));
            //back right upper corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 0)));
            //back right lower corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));

The values I'm looking at are the Vector2s. I don't think it could be my indices, but I could be wrong.

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird

You can't texture a cube this way with only eight vertices. You need distinct ones for each face, so 4*6 = 24 different vertices. Here's an example I just found by gurgling (note, XNA 3.1, the archive link for the 4.0 version is dead).

Edit: The sample uses only 20 vertices, so it still merges some vertices. As soon as you have normals too, you probably want to go for 24 vertices still.

ChristianFrantz
ChristianFrantz

Hmm. This explains why only 2 of the faces are being texture right. Thanks!

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird
Yeah, that's about the best you can get with with 8 vertices wink.png

c1c920265434611.jpg

Since I can't seem to find a fitting example, here's my code for a proper cube (using a self-rolled triangle mesh class). Comes with normals and color. Note, this isn't XNA, but I think you get the idea:

public static TriangleMesh<CustomVertex.PositionNormalTexturedColor> CubePNTC(float size, Color4i color)
{
    var result = new TriangleMesh<CustomVertex.PositionNormalTexturedColor>();
    float s = size * 0.5f;
    Rectanglef tr = Rectanglef.Unit;
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, -s), Normal = new Vector3(-1, 0, 0), Color = color, TexCoord = tr.BottomRight },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, +s), Normal = new Vector3(-1, 0, 0), Color = color, TexCoord = tr.BottomLeft  },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, +s), Normal = new Vector3(-1, 0, 0), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, -s), Normal = new Vector3(-1, 0, 0), Color = color, TexCoord = tr.TopRight    });
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, -s), Normal = new Vector3( 0,+1, 0), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, +s), Normal = new Vector3( 0,+1, 0), Color = color, TexCoord = tr.TopRight    },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, +s), Normal = new Vector3( 0,+1, 0), Color = color, TexCoord = tr.BottomRight },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, -s), Normal = new Vector3( 0,+1, 0), Color = color, TexCoord = tr.BottomLeft  });
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, -s), Normal = new Vector3(+1, 0, 0), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, +s), Normal = new Vector3(+1, 0, 0), Color = color, TexCoord = tr.TopRight    },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, +s), Normal = new Vector3(+1, 0, 0), Color = color, TexCoord = tr.BottomRight },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, -s), Normal = new Vector3(+1, 0, 0), Color = color, TexCoord = tr.BottomLeft  });
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, +s), Normal = new Vector3( 0,-1, 0), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, -s), Normal = new Vector3( 0,-1, 0), Color = color, TexCoord = tr.TopRight    },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, -s), Normal = new Vector3( 0,-1, 0), Color = color, TexCoord = tr.BottomRight },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, +s), Normal = new Vector3( 0,-1, 0), Color = color, TexCoord = tr.BottomLeft  });
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, +s), Normal = new Vector3( 0, 0,+1), Color = color, TexCoord = tr.BottomRight },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, +s), Normal = new Vector3( 0, 0,+1), Color = color, TexCoord = tr.BottomLeft  },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, +s), Normal = new Vector3( 0, 0,+1), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, +s), Normal = new Vector3( 0, 0,+1), Color = color, TexCoord = tr.TopRight    });
    result.AddQuad(new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, -s, -s), Normal = new Vector3( 0, 0,-1), Color = color, TexCoord = tr.BottomLeft  },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(-s, +s, -s), Normal = new Vector3( 0, 0,-1), Color = color, TexCoord = tr.TopLeft     },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, +s, -s), Normal = new Vector3( 0, 0,-1), Color = color, TexCoord = tr.TopRight    },
                    new CustomVertex.PositionNormalTexturedColor() { Position = new Vector3(+s, -s, -s), Normal = new Vector3( 0, 0,-1), Color = color, TexCoord = tr.BottomRight });
    return result;
}
Rectanglef.Unit is just a full tex-coord rectangle (0,0) to (1,1).

This is the AddQuad method (TriangleMesh is indexed).

public void AddQuad(T vertex1, T vertex2, T vertex3, T vertex4)
{
    int n = Vertices.Count;
    Vertices.Add(vertex1);
    Vertices.Add(vertex2);
    Vertices.Add(vertex3);
    Vertices.Add(vertex4);
    Indices.Add(n);
    Indices.Add(n + 1);
    Indices.Add(n + 2);
    Indices.Add(n + 2);
    Indices.Add(n + 3);
    Indices.Add(n);
}
I dump this here to give you some ideas since you still try to merge cubes (your other threads). I recommend rolling a similar mesh class to ease merging. Hint: The above code merges quads into the same mesh.

Cheers.

Edit: removed cruft and improved formatting.
ChristianFrantz
ChristianFrantz

This actually works perfect for what I'm trying to do. I can use it to implement some face culling when I get that part figured out lol

If you see a post from me, you can safely assume its C# and XNA :)
ChristianFrantz
ChristianFrantz

Alright so I created 6 methods which add the faces to my cube and nothing changed with the texture. Did I mess up the order of how the cube or faces are built? Only two sides are being shown correctly

E3glDCl.png


private void SetUpFrontFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            //front left bottom corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(1, 0)));
            //front left upper corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(1, 1)));
            //front right upper corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(0, 1)));
            //front lower right corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(0, 0)));
        }

        private void SetUpBackFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            //back left lower corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(0, 1)));
            //back left upper corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 0)));
            //back right upper corner ok
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 0)));
            //back right lower corner
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));
        }

        private void SetUpLeftFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(1, 0)));
        }

        private void SetUpRightFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));
        }

        private void SetUpTopFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(0, 1)));
        }

        private void SetUpBottomFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(1, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(0, 0)));
        }

        private void SetUpIndicesAndVertices(float x, float y, float z, List<VertexPositionTexture> vertices, List<short> indices)
        {
            short verticesStart = (short)vertices.Count;

            Vector3 cubeInChunkPosition = new Vector3(x, y, z);

            SetUpFrontFace(cubeInChunkPosition, vertices);
            SetUpBackFace(cubeInChunkPosition, vertices);
            SetUpBottomFace(cubeInChunkPosition, vertices);
            SetUpTopFace(cubeInChunkPosition, vertices);
            SetUpLeftFace(cubeInChunkPosition, vertices);
            SetUpRightFace(cubeInChunkPosition, vertices);

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird
Well, obviously tongue.png. My point in using a separated quad function was to not duplicate code. You still have to check the values for each face yourself though, sorry. Either by trial and error (rotating/flipping tex-coords) or by drawing the cube with pen and paper wink.png

To make it easier: Check each face individually first and combine them only later. This way it will be easier to locate the problem(s): E.g. are your texcoords wrong to begin with or is just the merging going bad.

The code really works:

a5b49d265439731.jpg

Admittedly: Can be that this code does not work for you as is. Depends how your textures are oriented and which handedness your renderer uses. Edit: Can indeed be a problem, just realized that XNA uses right-handedness by default. I use left-handed.
ChristianFrantz
ChristianFrantz

Ohhh woops. I was drawing the face from the bottom left corner going clockwise. Maybe thats the issue there. I did have to draw a cube and label the corners which helped a lot lol

http://blogs.msdn.com/b/dawate/archive/2011/01/20/constructing-drawing-and-texturing-a-cube-with-vertices-in-xna-on-windows-phone-7.aspx

That link says that each cube needs 36 vertices...Doesn't make sense to me though if I'm using indices?

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird
Now you sort of ninja'd me laugh.png. It helps to use a "labeling" texture.

3da6d8265443330.jpg

acddab265443332.jpg

That link says that each cube needs 36 vertices...Doesn't make sense to me though if I'm using indices?


Precisely. I found that example too earlier but did not want to post it for that very reason. Yeah, only 24 vertices needed but 36 indices for an indexed mesh.
ChristianFrantz
ChristianFrantz

The texture is too skewed for me to see the numbers in the corners lol. But it is helpful to an extent. Still have no idea why it's happening so I'm gonna mess around with the U,V values tongue.png

Moving around the map with that texture is making my head hurt lmao

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird
I'm sorry about that. It's meant for debugging but maybe I should put a seizure warning.
ChristianFrantz
ChristianFrantz

Well I got all sides except top and bottom to work and I don't know how. Almost there!!

If you see a post from me, you can safely assume its C# and XNA :)
unbird
unbird

Keep going, you can do it!

(I just imagined a group of cheer-leaders encouraging teh programmer by spelling tex-coords or something. Oh boy...)

ChristianFrantz
ChristianFrantz

Oh lawdy. I need some cheerleaders for motivation lol.

I messed everything up tho. Now I get partial textures on some faces and then just gray faces

EDIT: I have everything correct except the SetUpBackFace. I have 4 faces drawn correctly and if I change any values in it, it ruins all the sides somehow.


 private void SetUpFrontFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(1, 0)));
        }

        private void SetUpBackFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));         
        }

        private void SetUpLeftFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(1, 0)));
        }

        private void SetUpRightFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 0)));
        }

        private void SetUpTopFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, 0), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 1, -1), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 1, 0), new Vector2(1, 0)));
        }

        private void SetUpBottomFace(Vector3 cubeInChunkPosition, List<VertexPositionTexture> vertices)
        {
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, 0), new Vector2(0, 0)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(0, 0, -1), new Vector2(0, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, -1), new Vector2(1, 1)));
            vertices.Add(new VertexPositionTexture(cubeInChunkPosition + new Vector3(1, 0, 0), new Vector2(1, 0)));
        }
If you see a post from me, you can safely assume its C# and XNA :)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.