Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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?

share|improve this question
    
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

3 Answers 3

up vote 2 down vote accepted

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.

share|improve this answer
    
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? –  Takumi 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? –  Takumi 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? –  Takumi 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.

share|improve this answer
    
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? –  Takumi 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. –  Takumi 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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.