<p>There is a difference between "can" and "should".</p>

<p>You "should" not use <code>glBufferData</code> to change the size of an existing non-immutable buffer. You <em>can</em> still do so, but don't expect this to be advantageous.</p>

<p>You "can" <em>not</em> change the size of an immutable buffer with any function.</p>

<blockquote>
  <p>How do I replace the whole VBO with my new data, but if my new data is smaller than the old data then how do I reallocated the VBO efficiently?</p>
</blockquote>

<p>Why would you want to? If the size of your data got smaller, then it is entirely possible that a few frames from now it will be <em>bigger</em> again. Perhaps bigger than it was before. That extra storage isn't waste; it is extra storage you're keeping around because you intend to use it at some point in the future.</p>

<p>The cost of <em>allocating</em> memory is high; you should avoid it whenever possible. If you need to increase the size of a buffer, then the implementation must allocate new storage for it. You want to avoid that whenever possible.</p>

<p>What you ought to be doing is figuring out what a reasonable maximum size would be for this data, and then allocate a buffer of <em>that</em> size.</p>

<blockquote>
  <p>Or is there something equivalent to a NULL terminating character where the graphics card can know not to read any further data?</p>
</blockquote>

<p>That's up to you. You tell OpenGL exactly how many vertices to read from a vertex buffer. This is determined based on:</p>

<ol>
<li>The vertex format for each attribute.</li>
<li>The offset within the buffer for each attribute.</li>
<li>The number of vertices you send in the <code>glDraw*</code> command.</li>
</ol>

<p>OpenGL doesn't arbitrarily process data; it reads the data you <em>tell it</em> to read. If you want it to not read past a certain point, stop telling it to read past that point ;)</p>

CC BY-SA 3.0
2018-01-23T00:25:19.650Z
Assume I have a `data store` of size 2MB then I use `glBufferSubData` to add new data which is 1.5MB. Wouldn't there be an extra 0.5MB of data in the `data store` which I don't potentially want to draw?
Archmede
CC BY-SA 3.0
2018-01-23T00:43:22.493Z
or I suppose that where I'd just draw less `primitives` with `glDraw*`. Is that correct?
Archmede
CC BY-SA 3.0
2018-01-23T01:04:24.803Z
@Archmede: Why would you draw using data that you don't want to draw from?
Nicol Bolas
CC BY-SA 3.0
2018-01-23T01:37:57.903Z
My specific scenario is I fill data with terrain (like minecraft) but when I move somewhere else on the map I'll refill the `data store`  with new terrain but this new terrain might contain less data than the old terrain. So wouldn't there be some data from the old terrain left in the `data store` if the new terrain contained less data? Make sense?
Archmede
CC BY-SA 3.0
2018-01-23T01:42:09.520Z
So what if there's old data there? Why would you tell OpenGL to read from the old data? As I said, "You tell OpenGL exactly how many vertices to read from a vertex buffer." So why would you tell OpenGL to read from part of a buffer that doesn't contain relevant data?
Nicol Bolas
CC BY-SA 3.0
2018-01-23T02:12:53.143Z
I understand that. I misread the difference between `glBufferStorage` and `glBufferData`. I assumed `glBufferSubData` can reallocate the `data store` but I was mistaken. Thanks for your help though, it's greatly appreciated.
Archmede
CC BY-SA 3.0
2018-01-22T19:23:56.733Z
2018-01-22T19:23:56.733Z
Nicol Bolas
<p>I'm sending a large number of data to the <code>vertex shader</code>. I use <code>glBufferData</code> to generate my <code>VBO</code>. Later on I have to replace the data in my <code>VBO</code> so I do the following:</p>

<pre><code>glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * models().size(), &amp;models[0], GL_DYNAMIC_DRAW);
</code></pre>

<p>What I noticed is when I used the above code (I'm assuming) that some of the previous data is left in the <code>VBO</code> because I not only draw the new objects I want to but also some of the old ones.</p>

<p>Therefore I had to change my code to the following:</p>

<pre><code>glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * models().size(), &amp;models[0], GL_DYNAMIC_DRAW);
</code></pre>

<p>The reason I don't like the above aproach is because according to <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml" rel="nofollow noreferrer">Khronos</a></p>

<blockquote>
  <p>When replacing the entire data store, consider using glBufferSubData rather than completely recreating the data store with glBufferData. This avoids the cost of reallocating the data store.</p>
</blockquote>

<p>How do I replace the whole <code>VBO</code> with my new data, but if my new data is smaller than the old data then how do I reallocated the <code>VBO</code> efficiently? Or is there something equivalent to a <code>NULL terminating character</code> where the graphics card can know not to read any further data?</p>

<p>The reason I ask this is because from my understanding <code>glBufferStorage</code> is like <code>glBufferData</code> except that the <code>data store</code> generated by <code>glBufferStorage</code> is immutable meaning that the size of the <code>data store</code> cannot be changed, as stated <a href="https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferStorage.xhtml" rel="nofollow noreferrer">on Khronos</a> and on <a href="https://stackoverflow.com/questions/27810542/what-is-the-difference-between-glbufferstorage-and-glbufferdata">Stackoverflow</a>.</p>

<blockquote>
  <p>glBufferStorage and glNamedBufferStorage create a new immutable data store.</p>
</blockquote>

<p>But if <code>glBufferData</code> creates a <code>data store</code> which cannot shrink in size then what's the point of it? (Unless I'm misunderstanding its intended use)</p>

<opengl><vertex-buffer-object><buffers>
Replacing Vertex Attributes (glBufferData vs glBufferSubData)
Archmede
# Replacing Vertex Attributes (glBufferData vs glBufferSubData)

(Asked by: username_0 on 2018-01-21)

I'm sending a large number of data to the vertex shader. I use glBufferData to generate my VBO. Later on I have to replace the data in my VBO so I do the following:
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * models().size(), ⊧[0], GL_DYNAMIC_DRAW);

What I noticed is when I used the above code (I'm assuming) that some of the previous data is left in the VBO because I not only draw the new objects I want to but also some of the old ones.
Therefore I had to change my code to the following:
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * models().size(), ⊧[0], GL_DYNAMIC_DRAW);

The reason I don't like the above aproach is because according to Khronos

When replacing the entire data store, consider using glBufferSubData rather than completely recreating the data store with glBufferData. This avoids the cost of reallocating the data store.

How do I replace the whole VBO with my new data, but if my new data is smaller than the old data then how do I reallocated the VBO efficiently? Or is there something equivalent to a NULL terminating character where the graphics card can know not to read any further data?
The reason I ask this is because from my understanding glBufferStorage is like glBufferData except that the data store generated by glBufferStorage is immutable meaning that the size of the data store cannot be changed, as stated on Khronos and on Stackoverflow.

glBufferStorage and glNamedBufferStorage create a new immutable data store.

But if glBufferData creates a data store which cannot shrink in size then what's the point of it? (Unless I'm misunderstanding its intended use)

**Tags:** opengl, vertex-buffer-object, buffers

---

## 1 answers

### Answer by username_1 on 2018-01-22. Score: 4 | Accepted answer

There is a difference between "can" and "should".

You "should" not use `glBufferData` to change the size of an existing non-immutable buffer. You *can* still do so, but don't expect this to be advantageous.

You "can" *not* change the size of an immutable buffer with any function.

> How do I replace the whole VBO with my new data, but if my new data is smaller than the old data then how do I reallocated the VBO efficiently?

Why would you want to? If the size of your data got smaller, then it is entirely possible that a few frames from now it will be *bigger* again. Perhaps bigger than it was before. That extra storage isn't waste; it is extra storage you're keeping around because you intend to use it at some point in the future.

The cost of *allocating* memory is high; you should avoid it whenever possible. If you need to increase the size of a buffer, then the implementation must allocate new storage for it. You want to avoid that whenever possible.

What you ought to be doing is figuring out what a reasonable maximum size would be for this data, and then allocate a buffer of *that* size.

> Or is there something equivalent to a NULL terminating character where the graphics card can know not to read any further data?

That's up to you. You tell OpenGL exactly how many vertices to read from a vertex buffer. This is determined based on:

1. The vertex format for each attribute.
2. The offset within the buffer for each attribute.
3. The number of vertices you send in the `glDraw*` command.

OpenGL doesn't arbitrarily process data; it reads the data you *tell it* to read. If you want it to not read past a certain point, stop telling it to read past that point ;)

> **Comments:**
> **username_0**: Assume I have a `data store` of size 2MB then I use `glBufferSubData` to add new data which is 1.5MB. Wouldn't there be an extra 0.5MB of data in the `data store` which I don't potentially want to draw?  
> **username_0**: or I suppose that where I'd just draw less `primitives` with `glDraw*`. Is that correct?  
> **username_1**: @Archmede: Why would you draw using data that you don't want to draw from?  
> **username_0**: My specific scenario is I fill data with terrain (like minecraft) but when I move somewhere else on the map I'll refill the `data store`  with new terrain but this new terrain might contain less data than the old terrain. So wouldn't there be some data from the old terrain left in the `data store` if the new terrain contained less data? Make sense?  
> **username_1**: So what if there's old data there? Why would you tell OpenGL to read from the old data? As I said, "You tell OpenGL exactly how many vertices to read from a vertex buffer." So why would you tell OpenGL to read from part of a buffer that doesn't contain relevant data?  
> **username_0**: I understand that. I misread the difference between `glBufferStorage` and `glBufferData`. I assumed `glBufferSubData` can reallocate the `data store` but I was mistaken. Thanks for your help though, it's greatly appreciated.  

---

