glBufferData x glVertexPointer

Hi, I’m new to OpenGL and I have a question about the diference of glBufferData and glVertexPointer.
I’m reading a book that says that to use VBO I need to create a buffer, bind it, store data, render and delete.

My problem is on the store part…
For what i understood, the glBufferData() fills the buffer with the data parameter, correct me if I’m wrong.
After that I saw this glVertexPointer, which seems to do the same thing.

I don’t know if I missed somthing here or not, but I still didn’t get it.

I’m doing a paper about OpenGL using VBO and to continue I need this solved, :dejection:
Thank you for the help!

The gl*Pointer set of routines registers a data block which already contains the data for a vertex attribute. This can be a:

[ol]
[li]A CPU-pointer to a memory block in your application’s memory space (in the compatibility profile), OR [/li][li]An offset into the VBO (vertex buffer object) bound to the GL_ARRAY_BUFFER bind point with glBindBuffer. [/li][/ol]

If you choose option 2, then you need to have created, populated, and bound a buffer object already containing the data to the GL_ARRAY_BUFFER bind point. You’d create and populate it with glGenBuffers and glBufferData.

glVertexPointer = Register a data block to be read in the next Draw call for vertex position data (legacy attribute)
glColorPointer = Register a data block to read in the next Draw call for color value data (legacy attribute)

glVertexAttribPointer = Register a data block to be read in the next Draw call for generic vertex attribute #N

glGenBuffers = Create one or more buffer object handles
glBufferData = Allocate and fill the contents of a buffer object
glBufferSubData = Fill the contents of a buffer object (no allocation)

[QUOTE=Dark Photon;1248153]The gl*Pointer set of routines registers a data block which already contains the data for a vertex attribute. This can be a:

[ol]
[li]A CPU-pointer to a memory block in your application’s memory space (in the compatibility profile), OR
[/li][li]An offset into the VBO (vertex buffer object) bound to the GL_ARRAY_BUFFER bind point with glBindBuffer.
[/li][/ol]

If you choose option 2, then you need to have created, populated, and bound a buffer object already containing the data to the GL_ARRAY_BUFFER bind point. You’d create and populate it with glGenBuffers and glBufferData.

glVertexPointer = Register a data block to be read in the next Draw call for vertex position data (legacy attribute)
glColorPointer = Register a data block to read in the next Draw call for color value data (legacy attribute)

glVertexAttribPointer = Register a data block to be read in the next Draw call for generic vertex attribute #N

glGenBuffers = Create one or more buffer object handles
glBufferData = Allocate and fill the contents of a buffer object
glBufferSubData = Fill the contents of a buffer object (no allocation)[/QUOTE]

Let me just say an example for you to see if i got this right…

Let’s say I have 2 arrays, one of the color, and the other of the vertex. When I use the glBufferData I’ll need to set it’s size with at least color.length + vertex.length, right?
After that I can use glBufferSubData to fill my buffer with tha color and vertex data.

And the last thing, if i got this right, I’ll need to set the pointer to the color and vertex… If both arrays have 20 of length and I added first the 20 vertex and affter the 20 color, I could use it like this:
void glVertexPointer(vertex.length, GL_FLOAT, 0, BUFFER_OFFSET(0));
void glColorPointer(color.length, GL_FLOAT, 0, BUFFER_OFFSET(20));

What do you say? Am I in the right way?

If you’re going to store both attributes in the same VBO, yes (e.g. interleave them: VCVCVCVC, or store one right after the other: VVVVCCCC). You don’t have to, but it’s generally recommended to for best performance.

After that I can use glBufferSubData to fill my buffer with tha color and vertex data.

Or you can just populate them when you do the original glBufferData() call. You’d use glBufferSubData if you wanted to populate (or repopulate) part of the buffer after you’ve already created it.

And the last thing, if i got this right, I’ll need to set the pointer to the color and vertex… If both arrays have 20 of length and I added first the 20 vertex and affter the 20 color, I could use it like this:
void glVertexPointer(vertex.length, GL_FLOAT, 0, BUFFER_OFFSET(0));
void glColorPointer(color.length, GL_FLOAT, 0, BUFFER_OFFSET(20));
What do you say? Am I in the right way?

Exactly. Just keep in mind that when a VBO is bound to GL_ARRAY_BUFFER (as in this case) the last argument is a byte offset into the buffer. So this would be correct if you’re storing your attributes “non-interleaved” (e.g. VVVVCCCC) tightly packed in the buffer, and the vertex list took <= 20 bytes.

Also bench storing your vertices interleaved (VCVCVCVC). This is where the stride parameter comes in.

If you’re going to store both attributes in the same VBO, yes (e.g. interleave them: VCVCVCVC, or store one right after the other: VVVVCCCC). You don’t have to, but it’s generally recommended to for best performance.

So the best way is to put all the vertex attributes in the same buffer?
Is there any performance diference between the interleaving and put one right after the other?

[QUOTE=vgeorgo;1248170]So the best way is to put all the vertex attributes in the same buffer?
Is there any performance diference between the interleaving and put one right after the other?[/QUOTE]
I’ll defer to someone who’s benched recently. Last time I did was years ago on older-gen hardware.

Real test results on your target hardware are the most important criteria for choosing. But consider, with attribs in same buffer, you need one bind, not N. Binds can get expensive (thus NV bindless extensions). Also, just think about memory fetch efficiency: linear fetching from one stream is often the most efficient. Though linear fetching from multiple disjoint streams shouldn’t be near as bad as completely random fetching. Another factor to consider is that (particularly on GPUs with faster-clocked memory) you’re not often vertex fetch-bound. So this isn’t typically the bottleneck. All that said, I interleave when possible.

[QUOTE=Dark Photon;1248188]I’ll defer to someone who’s benched recently. Last time I did was years ago on older-gen hardware.

Real test results on your target hardware are the most important criteria for choosing. But consider, with attribs in same buffer, you need one bind, not N. Binds can get expensive (thus NV bindless extensions). Also, just think about memory fetch efficiency: linear fetching from one stream is often the most efficient. Though linear fetching from multiple disjoint streams shouldn’t be near as bad as completely random fetching. Another factor to consider is that (particularly on GPUs with faster-clocked memory) you’re not often vertex fetch-bound. So this isn’t typically the bottleneck. All that said, I interleave when possible.[/QUOTE]

Ok then, my problem is solved, thank you, :smiley:
What can I do to close this thread?