How to efficiently update texture coordinates when using DrawPrimitives?

Hello

I’m trying to do something like this:

class TriangleStripBuffer
{
    private VertexBuffer buffer;
    private BasicEffect effect;
    private int nbrVertices;

    public void Update(GraphicsDevice device, VertexPositionTexture[] vertices)
    {
        buffer = new VertexBuffer(
            device,
            typeof(VertexPositionTexture),
            vertices.Length,
            BufferUsage.WriteOnly);
        buffer.SetData<VertexPositionTexture>(vertices);
        nbrVertices = vertices.Length;

        float w = (float)device.Viewport.Width;
        float h = (float)device.Viewport.Height;

        effect = new BasicEffect(device)
        {
            World = Matrix.Identity,
            View = Matrix.CreateLookAt(new Vector3(w / 2, h / 2, -10.0f), new Vector3(w / 2, h / 2, 0), -Vector3.Up),
            Projection = Matrix.CreateOrthographic(w, h, 1.0f, 10.0f)
        };
    }

    public void Draw(GraphicsDevice device, Texture2D texture, int pos)
    {
        device.BlendState = BlendState.AlphaBlend;
        device.DepthStencilState = DepthStencilState.Default;
        device.SamplerStates[0] = SamplerState.LinearWrap;

        effect.Texture = texture;
        effect.TextureEnabled = true;

        effect.CurrentTechnique.Passes[0].Apply();
        device.SetVertexBuffer(buffer);
        device.DrawPrimitives(PrimitiveType.TriangleStrip, pos, nbrVertices - 2);
    }
}

I create a TriangleStripBuffer object in game1.cs, update it once in Loadcontent and then call Draw in Draw().
If I want to change the position of the texture, I do it like this:
(Game1.cs)

        VertexPositionTexture[] buffer = new VertexPositionTexture[4];

        buffer[0] = new VertexPositionTexture(new Vector3(300, 300, 0), new Vector2(1 + pos.X, 1 + pos.Y));
        buffer[1] = new VertexPositionTexture(new Vector3(0, 300, 0), new Vector2(0 + pos.X, 1 + pos.Y));
        buffer[2] = new VertexPositionTexture(new Vector3(300, 0, 0), new Vector2(1 + pos.X, 0 + pos.Y));
        buffer[3] = new VertexPositionTexture(new Vector3(0, 0, 0), new Vector2(0 + pos.X, 0 + pos.Y));

with new values in pos X and Y. Then call update:

        tristripBuffer.Update(GraphicsDevice, buffer);

I’m wondering if it is possible to move the texture without rebuilding the VertexPositionTexture[] every time?

Sincerely
Richard

Hi @rich-bit,
You can shift the texture in a custom shader.
Performance-wise that’s much better than updating the vertex buffer.

2 Likes

Yes, it’s possible and it will be more efficient.

Allocate and setup the buffer once in constructor.

… then set the UV directly in the buffer,
buffer[0].textureCoordinate.X = pos.X +1;
// etc

Do not create a BasicEffect on every Update. Create it once in the constructor and Update the World / View / Projection in Update().

Do the same with the buffer. Create it once and call SetDate() when you need to update it.
Consider using a DynamicVertexBuffer if the updates are frequent.

1 Like

Yeah what you are saying works, and I am using a DynamicVertexBuffer now instead. Thank you so much.

Don’t see the need to update World/View/Projection though.

1 Like

You only need to update it on ClientSizeChanged.

1 Like