# XNA - Update vertices property stored in a VertexBuffer

I've a class that creates a cube using VertexPositionColor and these vertices are stored in a VertexBuffer. Now i would like to dynamically change the color of my vertices. In my class i have a reference to a VertexPositionColor array wich contain all my vertices. I've wrote a SetColor function wich accept a Color in parameter and update each Color property of my vertices. But when i call it, it doesn't work. This is normal because vertices are stored in VertexBuffer and is not updated.

So, how can i update vertices property and keep using VertexBuffer?

• Post some code, please! – r2d2rigo Oct 7 '11 at 10:40
• You need to call SetData(vertices) on the vertex buffer after you have modified the data. It's best to do this only once a frame, IF the data has been modified. – Jonathan Dickinson Oct 9 '11 at 11:19
• Also, investigate DynamicVertexBuffer - you shouldn't be using a regular VertexBuffer for dynamic data. – Jonathan Dickinson Oct 9 '11 at 11:20

To change a vertex buffer it can't be active:

   GraphicsDevice.SetVertexBuffer(null);


To transfer vertex data to the gpu memory:

   VertexBuffer.SetData<VertexPositionColor>(VertexData);


To active the vertex buffer again:

   GraphicsDevice.SetVertexBuffer( VertexBuffer );


Note that if your color change affects every vertex with one unique color, you may consider to pass to a shader a single color as a parameter, and do not modify vertex.

• Call GraphicsDevice.SetVertexBuffer with null parameter works fine. As you say, i can use a shader for changing color. But i would like to change also the position of my vertices. So i need to update the vertex buffer. A question comes to my mind. Call too many times SetVertexBuffer and VertexBuffer.SetData<> function will drop performance? For exemple if i create 1000 cubes and i update theirs position each frame, SetVertexBuffer and VertexBuffer.SetData<> will be called 1000 times. Do you think there's a better solution? – Julien Pires Oct 9 '11 at 22:18
• Use only one vertexbuffer – Blau Oct 9 '11 at 22:43
• You mean to share one instance of VertexBuffer between all my Cube class instance and not create one VertexBuffer per instance? – Julien Pires Oct 10 '11 at 7:31
• One big vertex buffer is usually better than multiple small vertexbuffer. – Blau Oct 10 '11 at 8:48
• I will use one buffer for all my cubes. But i don't know how to do it with my Cube class. Currently one instance haves an array of vertices and an array of indices (so i use only 4 vertices to create a face of the cube), and in my draw method i call GraphicsDevice.indices to set the indices array then GraphicsDevice.SetVertexBuffer and finally DrawIndexedPrimitives. Now if i use only one vertex buffer, i think i need to call SetVertexBuffer one time but how do i set indices and draw my cube? If all my vertices are in the same buffer how the Draw method will know from which vertex to begin? – Julien Pires Oct 10 '11 at 9:48

The only way to change the contents of a VertexBuffer in XNA is by calling VertexBuffer.SetData().

When you need to update your vertex data often, it is recommended you use a DynamicVertexBuffer which streams vertices to the GPU.

Your best bet is to do some profiling using either:

• a DynamicVertexBuffer (stored in VRAM) and DrawPrimitives()
• a simple array (stored in RAM) and DrawUserPrimitives()

And see which one is faster for your specific use case.

• So, each time i want to update the Color or Position of my vertices i have to call SetData of the buffer. This will not decrease performance if i have to update these informations many time? – Julien Pires Oct 7 '11 at 12:05
• When i try to call SetData an InvalidOperationException is throw : You can not call SetData on a resource while it is actively involved in GraphicsDevice. Cancel its association with the device before calling SetData. – Julien Pires Oct 7 '11 at 12:33
• See Blau's answer: to change a vertex buffer, you have to do it while it's not bound to the GPU. Call GraphicsDevice.SetVertexBuffer(null); – Elisée Oct 9 '11 at 10:38

I would do this using two vertex buffers. The first is static and contains the data that won't change, the second dynamic and containing the data that will change. That way you get to minimize the impact of data transfers. I'm not certain what the XNA equivalent of the relevant D3D terminology is, but GraphicsDevice.SetVertexBuffers looks to be what you need.