Canox
Canox

Reputation: 559

Monogame - repeat texture on mesh when scaled

currently I'm developing a first person shooter with 3D meshes building my world. My meshes can have a texture on each side (front, back, left, right, top, bottom). That works very well. This is the code:

    public Block()
    {
        vertexData = new List<VertexPositionNormalTexture>();

        //front
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(-0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0.0f, 1.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0.0f, 0.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(1.0f, 1.0f)));

        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(1.0f, 1.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(-0.5f, 0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(0.0f, 0.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(0, 0, 1), new Vector2(1.0f, 0.0f)));

        SetUp(TexType.front);
        vertexData = new List<VertexPositionNormalTexture>();

        //right
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, -0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0.0f, 1.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0.0f, 0.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(1, 0, 0), new Vector2(1.0f, 1.0f)));

        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, -0.5f, -0.5f), new Vector3(1, 0, 0), new Vector2(1.0f, 1.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, 0.5f, 0.5f), new Vector3(1, 0, 0), new Vector2(0.0f, 0.0f)));
        vertexData.Add(new VertexPositionNormalTexture(new Vector3(0.5f, 0.5f, -0.5f), new Vector3(1, 0, 0), new Vector2(1.0f, 0.0f)));

        SetUp(TexType.right);
        vertexData = new List<VertexPositionNormalTexture>();

  //and so on for the remaining faces...
  }


    public void SetUp(TexType texType)
    {
        vertexBuffer = new VertexBuffer(Basic.gDevice, typeof(VertexPositionNormalTexture), vertexData.Count, BufferUsage.WriteOnly);
        vertexBuffer.SetData(vertexData.ToArray());

        buffers.Add(new Tuple<VertexBuffer, TexType>(vertexBuffer, texType));
    }

    public void Draw(Matrix world)
    {
            foreach (var buffer in buffers)
            {
                string texName = textures[buffer.Item2.ToString()];
                GameScreen.effect.Texture = Textures.textures[texName];

                SetEffectsAndDraw(world, buffer.Item1, buffer.Item1.VertexCount);
            }
    }
    private void SetEffectsAndDraw(Matrix world, VertexBuffer buffer, int primitiveCount)
    {
        GameScreen.effect.View = GameScreen.camera.view;
        GameScreen.effect.Projection = GameScreen.camera.projection;
        GameScreen.effect.EnableDefaultLighting();
        GameScreen.effect.World = world;

        GameScreen.effect.FogEnabled = true;
        GameScreen.effect.FogColor = Color.Black.ToVector3();
        GameScreen.effect.FogStart = 4.0f;
        GameScreen.effect.FogEnd = 12.0f;

        //GameScreen.effect.TextureEnabled = true;

        GameScreen.effect.CurrentTechnique.Passes[0].Apply();

        Basic.gDevice.SetVertexBuffer(buffer);
        Basic.gDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, primitiveCount / 3);
    }

Now I can scale my meshes on every axis. My problem here is, the texture on the mesh is getting stretched. How can I repeat the texture on a mesh face when the mesh gets scaled? For example when I scale a mesh with scale.Y = 10 then the texture looks very ugly. Is there maybe a possibility to switch between strechted and repeated textures? I searched around a lot but could not find a solution.

I also tried this but it didn't change anything:

        sampler = new SamplerState();
        sampler.Filter = TextureFilter.Point;
        sampler.AddressU = TextureAddressMode.Wrap;
        sampler.AddressV = TextureAddressMode.Wrap;

        gDevice.SamplerStates[0] = sampler;

Thank you in advance!

Upvotes: 1

Views: 140

Answers (0)

Related Questions