Replacing Vertex Attributes (glBufferData vs glBufferSubData)
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:


The vertex format for each attribute.
The offset within the buffer for each attribute.
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 ;)