<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(), &models[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(), &models[0], GL_DYNAMIC_DRAW);

```

The reason I don't like the above aproach is because according to [Khronos](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferSubData.xhtml)

> 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](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBufferStorage.xhtml) and on [Stackoverflow](https://stackoverflow.com/questions/27810542/what-is-the-difference-between-glbufferstorage-and-glbufferdata).

> 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**: @username_0: 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.  

---

