OpenGL. Updating vertex buffer with glBufferData
Asked Answered
N

2

17

I'm using OpenGL to implement some kind of batched drawing. For this I create a vertex buffer to store data.

Note: this buffer generally will update on each frame, but will never decrease size (but still can increase).

My question is: is it technically correct to use glBufferData (with streaming write-only mode) for updating it (instead of e.g. glMapBuffer)? I suppose there's no need to map it, since full data is updated, so I just send a full pack at once. And if the current buffer size is less, than I'm sending, it will automatically increase, won't it? I'm just now sure about the way it really works (maybe it will recreate buffer on each call, no?).

Nan answered 4/1, 2013 at 10:45 Comment(0)
D
15

It would be better to have buffer with fixed size and do not recreate it every frame.

You can achieve this by:

  • creating buffer with max size, for instance space for 1000 verts
  • update only the beginning of the buffer with new data. So if you changed data for 500 verts then fill ony first half of the buffer using glMapBuffer
  • change count of drawn vertices when drawing. You can, for instance, use only some range of verts (eg. from 200 to 500) from the whole 1000 verts buffer. Use glDrawArrays(mode, first, count)

ideas from comments:

  • glMapBufferRange and glBufferSubData could also help
  • also consider double buffering of buffers

link: http://hacksoflife.blogspot.com/2010/02/double-buffering-vbos.html

hope that helps

Drought answered 4/1, 2013 at 11:11 Comment(8)
Thank you for reply! But this was a little bit different thing: it is impossible to create a max sized buffer. But probability of changing it's size is incredibly low, so that's now a problem. As for drawing ranges - that's what i do now. But may I ask a question about your second option (to update only a range of verts): in this case I always have my data stored in a continuous block (on CPU), so that I can just update a buffer with the same glBufferData, but with smaller size specified - the same result? Won't it ruin the buffer or recreate it? Thank youNan
Surely you'll get better performance between GPU/CPU by dropping a buffer each frame and creating a new one? Won't updating a buffer that might be in use result in some potential blocking, if the GPU is currently using it?Micropaleontology
here is some interesting link: hacksoflife.blogspot.com/2010/02/double-buffering-vbos.html, there is also a glMapBufferRange function that could help.Drought
Hmm. I suppose GPU will not be using it at the moment of update: it will be updated only once on each frame. I thought that creating and allocating memory for a new buffer is very slow, isn't it?Nan
@Celestis: Yes, like all memory allocations glBufferData is a slow operation. glBufferSubData however is quite fast, as is glMapBuffer[Range] and glUnmapBuffer. BTW, allocating memory on the client/CPU side is slow, too; and if you tell OpenGL to allocate some memory it must do this on both the GPU and the CPU side. So it's better avoided. Preallocating a large buffer of which only a subset is used is the way to go.Isochromatic
@datenwolf, thank you, seems like glBufferSubData is the thing I need! So, I think, I will generally update a buffer using it, and if it rarely happens to the buffer to be increased, I will reuse glBufferData.Nan
@Celestis: Yes, that's the general idea. However if you're constantly updating your data, you should use 2 or maybe 3 buffers, in which you update the data in a cycle. For example only over the last 2 days I wrote a small "oscilloscope" to visualize the waveform the DAQ system in a experiment delivers… at a rate of 1.5GSamples/sec; i.e. I've to update the VBOs at a rate of 1.5GByte/s.Isochromatic
I've just updated the entry with your ideas - glBufferSubData and double bufferingDrought
S
5

In addition to what fen and datenwolf said, see Chapter 22 of OpenGL Insights; in particular, it includes timings for a variety of hardware & techniques.

Shipment answered 5/1, 2013 at 0:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.