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?).

genpfault
  • 51,148
  • 11
  • 85
  • 139
Celestis
  • 525
  • 1
  • 4
  • 11

2 Answers2

14

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

Sga
  • 3,608
  • 2
  • 36
  • 47
fen
  • 9,835
  • 5
  • 34
  • 57
  • 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 you – Celestis Jan 04 '13 at 11:21
  • 1
    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? – Robinson Jan 04 '13 at 11:21
  • 1
    here is some interesting link: http://hacksoflife.blogspot.com/2010/02/double-buffering-vbos.html, there is also a glMapBufferRange function that could help. – fen Jan 04 '13 at 11:24
  • 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? – Celestis Jan 04 '13 at 11:25
  • 3
    @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. – datenwolf Jan 04 '13 at 11:30
  • @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. – Celestis Jan 04 '13 at 11:32
  • 4
    @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. – datenwolf Jan 04 '13 at 11:37
  • I've just updated the entry with your ideas - glBufferSubData and double buffering – fen Jan 04 '13 at 11:42
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.

Calvin1602
  • 9,413
  • 2
  • 44
  • 55