[SOLVED] Texture Coordinates aren't working properly

I’m trying to add textures to a wall for a group project. The problem is, no matter the coordinates I input, the texture always looks wonky unless I use 0 to 1 as coordinates.

A wall with a texture with coordinates, and the texture with 0-1 coordinates.

I want to be able to use texture coordinates to place a grid of the texture file on the wall, as I think is what’s supposed to happen.

Here are the different pieces of code used:

private void BuildWallBuffer()
{
    List<VertexPositionTexture> wallVertexList = new List<VertexPositionTexture>();

    for (int x = 0; x < mazeWidth; x++)
    {
        for (int y = 0; y < mazeHeight; y++)
        {
            foreach (VertexPositionTexture vertex in BuildMazeWall(x, y))
            {
                wallVertexList.Add(vertex);
            }
        }
    }

    wallBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration, wallVertexList.Count, BufferUsage.WriteOnly);
    wallBuffer.SetData<VertexPositionTexture>(wallVertexList.ToArray());
}

This is for making the vertexbuffer used in the draw method.

private List<VertexPositionTexture> BuildMazeWall(int x, int y)
{
    List<VertexPositionTexture> triangles = new List<VertexPositionTexture>();

    if (MazeCells[x, y].Walls[0] > 0)
    {
        triangles.Add(CalcPoint(0, x, y, new Vector2(1, 0)));
        triangles.Add(CalcPoint(4, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(2, x, y, new Vector2(1, 1)));
        triangles.Add(CalcPoint(4, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(6, x, y, new Vector2(0, 1)));
        triangles.Add(CalcPoint(2, x, y, new Vector2(1, 1)));
    }
    if (MazeCells[x, y].Walls[1] > 0)
    {
        triangles.Add(CalcPoint(4, x, y, new Vector2(1, 0)));
        triangles.Add(CalcPoint(5, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(6, x, y, new Vector2(1, 1)));
        triangles.Add(CalcPoint(5, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(7, x, y, new Vector2(0, 1)));
        triangles.Add(CalcPoint(6, x, y, new Vector2(1, 1)));
    }

    if (MazeCells[x, y].Walls[2] > 0)
    {
        triangles.Add(CalcPoint(5, x, y, new Vector2(1, 0)));
        triangles.Add(CalcPoint(1, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(7, x, y, new Vector2(1, 1)));
        triangles.Add(CalcPoint(1, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(3, x, y, new Vector2(0, 1)));
        triangles.Add(CalcPoint(7, x, y, new Vector2(1, 1)));
    }
    if (MazeCells[x, y].Walls[3] > 0)
    {
        triangles.Add(CalcPoint(1, x, y, new Vector2(1, 0)));
        triangles.Add(CalcPoint(0, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(3, x, y, new Vector2(1, 1)));
        triangles.Add(CalcPoint(0, x, y, new Vector2(0, 0)));
        triangles.Add(CalcPoint(2, x, y, new Vector2(0, 1)));
        triangles.Add(CalcPoint(3, x, y, new Vector2(1, 1)));
    }
    return triangles;

}

A rather convaluted method for creating the vertices for each wall in our “maze”.

private VertexPositionTexture CalcPoint(int wallPoint, int xOfset, int yOffset, Vector2 textureCoordinates)
{
    return new VertexPositionTexture(wallPoints[wallPoint] + new Vector3(xOfset, 0, yOffset), textureCoordinates);
}

The actual vertices being made. “wallPoints” is a list of vertex coordinates.

    wallPoints[0] = new Vector3(0, 1, 0);
    wallPoints[1] = new Vector3(0, 1, 1);
    wallPoints[2] = new Vector3(0, 0, 0);
    wallPoints[3] = new Vector3(0, 0, 1);
    wallPoints[4] = new Vector3(1, 1, 0);
    wallPoints[5] = new Vector3(1, 1, 1);
    wallPoints[6] = new Vector3(1, 0, 0);
    wallPoints[7] = new Vector3(1, 0, 1);

Then it all gets drawn.

    groundEffect.View = camera.View;
    groundEffect.Projection = camera.Projection;
    groundEffect.TextureEnabled = true;
    groundEffect.Texture = wallTexture;
    foreach (EffectPass pass in groundEffect.CurrentTechnique.Passes)
    {
        pass.Apply();
        device.SetVertexBuffer(wallBuffer);
        device.DrawPrimitives(PrimitiveType.TriangleList, 0, wallBuffer.VertexCount / 3);
    }

Maybe texture sampler mirror or wrap will do, what you try?

Yes, it looks like you want the samplerstate to be LinearWrap rather than LinearClamp.

GraphicsDevice.SamplerStates[i] = SamplerState.LinearWrap;

Where ‘i’ is the sampler slot, probably 0 in your case.

That did it! Thank you. It’s a shame I don’t really understand what I changed exactly, but at least now I know more!

A sampler can read from a texture in different ways. The parameter that’s relevant here is the TextureAddressMode which determines what a sampler does when the texture coordinates are actually outside of the texture. Texture coordinates are normalized. That means they range from 0 to 1 within the texture, so values outside that range the TextureAddressMode comes into play. The default value for it is clamp, which means the sampler takes the outer bounds of the texture from where it went off. For example a texture coordinate of (0.6, 1.2) will be clamped to (0.6, 1.0). In your case since you want the texture to tile you want the sampler to wrap around. That’s what the LinearWrap SamplerState does. For (0.6, 1.2) the sampler will wrap and use (0.6, 0.2).