1

I am trying to update a large VBO in OpenGL which has about 4,000,000 floats in it, but I only need to update the elements which are changing (<1%), and this needs to happen at run time.

I have pre-computed the indices which need changing, but because they are fragmented throughout the VBO I have to send 1000 individual glBufferSubDataARB calls with the appropriate index offsets (i'm not sure if this is a problem or not)

I have set the VBO to use STREAM_DRAW_ARB because the update to the VBO occurs every 5 seconds.

Even if I update just 1000 of the objects in the VBO (so about 16,000 floats spread over 1000 calls) I notice a small but noticable latency.

I believe this maybe due to the VBO being used for drawing whilst it is being updated as I've heard this can result in latency. I only know of solutions to this problem when you are updating the entire VBO - for example: OpenGL VBO updating data

However, because my VBO is so large, I would think sending 4,000,000 data elements every 5 seconds would be a lot slower and use up a lot of the CPU-GPU bandwidth. So I was wondering if anybody knows how to avoid the VBO waiting for the GPU to finish for it to be updated doing it the way I am - fragmented over a VBO, updated over about a thousand calls.

Anyway, the following is a section of my code which updates the buffer every 5 seconds with usually around 16,000 floats of the 4,000,000 present (but as I say, using about 1000 calls).

for(unsigned int kkkk = 0;kkkk < surf_props.quadrant_indices[0].size();kkkk++)
{
temp_surf_base_colour[0] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[1] = 1.0;
temp_surf_base_colour[2] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[3] = 1.0;
temp_surf_base_colour[4] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[5] = 1.0;
temp_surf_base_colour[6] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[7] = 1.0;
temp_surf_base_colour[8] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[9] = 1.0;
temp_surf_base_colour[10] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[11] = 1.0;
temp_surf_base_colour[12] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[13] = 1.0;
temp_surf_base_colour[14] = surf_props.quadrant_brightness[0][kkkk];
temp_surf_base_colour[15] = 1.0;

glBindBufferARB(GL_ARRAY_BUFFER_ARB, vb_colour_surf);       
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,  sizeof(GLfloat) * ((numb_surf_prims * 4) + surf_props.quadrant_indices[0][kkkk] * 16)), sizeof(GLfloat) * 16, temp_surf_base_colour);  
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
Community
  • 1
  • 1
Single Entity
  • 2,925
  • 3
  • 37
  • 66
  • What about vertex displacement textures use in this case? – j-p Mar 20 '14 at 13:29
  • Do those `glBindBufferARB` calls need to be inside the loop? – GuyRT Mar 20 '14 at 13:48
  • You could also try `GL_DYNAMIC_DRAW` instead of `GL_STREAM_DRAW` – GuyRT Mar 20 '14 at 13:51
  • No the bind buffer shouldn't be inside the loop, but that was an experimental change I did to try and fix the problem and which made no difference, good spot though thanks. – Single Entity Mar 20 '14 at 14:01
  • And I have also tried changing it to GL_DYNAMIC_DRAW as well, this makes no difference. – Single Entity Mar 20 '14 at 14:01
  • 3
    I'm not confident to write this as an answer (as I haven't tried this myself), but you could try using two buffers and asynchronous buffer transfers (described in depth here: http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf). The idea being that you render using one buffer, and write (all of) your data to a second one, then start using the second one once the transfer is complete. – GuyRT Mar 20 '14 at 15:57
  • I'll certainly give that a read thank you. I was hoping for an easy solution as I figured this was a problem many people would have come across when updating VBO data in real time, but none-the-less that reference looks very useful. Thanks – Single Entity Mar 20 '14 at 17:16

0 Answers0