Understanding VAO and VBO I'm reading through Learn OpenGL to refresh the basic concepts as I haven't touched in quite some time.
Specifically I still think I cannot quite understand the meaning of VAO and VBO, the book mainly proceeds through examples it doesn't really give rigorous definitions.
About the VBO:

With the vertex data defined we’d like to send it as input to the
first process of the graphics pipeline: the vertex shader. This is
done by creating memory on the GPU where we store the vertex data,
configure how OpenGL should interpret the memory and specify how to
send the data to the graphics card. The vertex shader then processes
as much vertices as we tell it to from its memory.
We manage this memory via so called vertex buffer objects (VBO) that
can store a large number of vertices in the GPU’s memory. The
advantage of using those buffer objects is that we can send large
batches of data all at once to the graphics card, and keep it there if
there’s enough memory left, without having to send data one vertex at
a time. Sending data to the graphics card from the CPU is relatively
slow, so wherever we can we try to send as much data as possible at
once. Once the data is in the graphics card’s memory the vertex shader
has almost instant access to the vertices making it extremely fast

So my understanding of VBO they're essentially Buffer objects (bunch of bytes to be sent to the GPU) with the difference that VBO are specifically dedicated to Vertex Data. Is this correct?
About the VAO:
Here instead I don't really understand.

A vertex array object (also known as VAO) can be bound just
like a vertex buffer object and any subsequent vertex attribute calls
from that point on will be stored inside the VAO.

What does it mean any subsequent vertex attribute calls from that point on will be stored inside the VAO, I don't understand the &quot;call be stored&quot; bit, does it mean somewhere in the opengl context created we store like some data related to the vertex attribute calls (like the pair input output of the call? the output of the call? something related to the call?).

This has the advantage that when configuring vertex attribute pointers you only
have to make those calls once and whenever we want to draw the object,
we can just bind the corresponding VAO. This makes switching between
different vertex data and attribute configurations as easy as binding
a different VAO. All the state we just set is stored inside the VAO.

I don't understand the advantage here. I understand the &quot;call made once&quot;, because they're stored in the VAO (whatever the &quot;stored part means&quot;). The switching part does maybe mean I can create multiple VAO each one capturing different Vertex Attributes calls and I can just bind each one of these when I need without calling again the vertex attribute?
For reference I've also found this question which I thought had an interesting answer.
So my understanding of VBO they're essentially Buffer objects (bunch of bytes to be sent to the GPU) with the difference that VBO are specifically dedicated to Vertex Data. Is this correct?

A &quot;VBO&quot; is not really a thing, and I really wish tutorials would stop pretending that they are.
You are correct in that there exist buffer objects. These are linear arrays of unformatted data that the GPU stores and can access for various processes. One of those &quot;various processes&quot; that the GPU can use them for is providing array data for vertex rendering operations.
But the buffer itself isn't special. It doesn't become a different thing just because you use it for vertex data, and there is no rule that says that a buffer you're currently using for vertex data cannot be used for other buffer usages too.
Note that this is different from how textures work. When you create a texture object and bind it as a 2D texture, that texture object forever becomes a 2D texture. You cannot later bind it as a 1D or a cubemap or whatever. Buffer objects aren't like that; where you bind them defines only how you're currently using them.

What does it mean &quot;any subsequent vertex attribute calls from that point on will be stored inside the VAO&quot;

This is yet another annoying tutorial trope: that objects &quot;store calls&quot; or are macros or other such nonsense.
Objects in OpenGL don't store calls; they store state. They're like structs; they have data members. Binding an object to the OpenGL context allows OpenGL operations that access certain state to find that state within the bound object. So if you call a function that modifies certain state that is from a bound object, that function will modify the state within the object.
When you bind a VAO, you are binding an object that stores the state used for vertex arrays. When you call a function that modifies the state for vertex arrays, that function will modify the state stored in the VAO currently bound. When you render, the rendering system will use the vertex array state found in the currently bound VAO.