copenglvertex-buffer-objects

OpenGL VBO orphaning implementation


I'm currently working on a sprite renderer whose data changes every tick, so I've been looking for ways to stream a buffer object, I came across buffer orphaning... which confused me a bit.

  1. Firstly, when you call glBufferData with a NULL pointer, is new memory allocated and as such does it matter if the size of the buffer changes?
  2. Secondly, do you need to call glMap/glUnmap every time you update the buffer or does a single glMap work? And does GL_INVALIDATE_BUFFER do the same than just setting data to NULL?
  3. Finally, Am I missing anything in the following implementation?

    Every tick:

    glBindBuffer(GL_ARRAY_BUFFER, ssb->buffers[1]);
    glBufferData(GL_ARRAY_BUFFER, length, NULL, GL_STREAM_DRAW);
    void* buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    memcpy(buffer, data, length);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    

Solution

  • Firstly, when you call glBufferData with a NULL pointer, is new memory allocated

    Possibly. It depends on whether the current storage is still in use on the GPU and how well optimized the OpenGL implementation is.

    and as such does it matter if the size of the buffer changes?

    Yes, due to the above. Do not change the length of the buffer if you're going to orphan it.

    Secondly, do you need to call glMap/glUnmap every time you update the buffer or does a single glMap work?

    Given your code, you shouldn't bother mapping it at all. Mapping is for when you're going to generate data directly into the buffer's memory (or wherever the mapped pointer comes from). You're generating data into your own memory and just copying it. So it's probably better for you to use glBufferSubData.

    And does GL_INVALIDATE_BUFFER do the same than just setting data to NULL?

    It preserves the length of the buffer, thus making it impossible for you to accidentally change the length, per the above.