OpenGL stride glVertexPointer - opengl

I am working on a OpenGL 2.0 renderer (https://bitbucket.org/mattiascibien/anima-render) and I actually came across smething I cannot understand at all which is the stride for the glVertexPointer() instruction. Actually my code looks like this
glBindBuffer(GL_ARRAY_BUFFER, data.vertex_buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(
3,
GL_FLOAT,
sizeof(GLfloat)*3,
(void*)0
);
but I actually found that by reading OpenGL documentation the stride should actually be 0. Changing it does not change how the model is rendered.
What value is correct? Why does changing this parameter makes no difference?
EDIT: the data is stored in a
std::vector<GLFloat>
same happens with glTexCoordPointer using sizeof(GLfloat)*2 or 0

https://www.opengl.org/sdk/docs/man2/xhtml/glInterleavedArrays.xml gives more infos about it.
If stride is 0, the aggregate elements are stored consecutively. Otherwise, stride bytes occur between the beginning of one aggregate array element and the beginning of the next aggregate array element.
while you are providing a stride, that is 0 or your "struct" size (3*sizeof(GLFloat)) this is the same. Yet I'd go with 0 in this case.

Stride is the distance from the beginning of one entity, to the beginning of the following entity. 0 is special: it means the distance from the end of one entity to the beginning of the next entity is 0. So basically 0 is the same as sizeof(entity).
Basically they packed 2 different mechanisms in one parameter, which I find suboptimal.

Related

Could I change a vertex attribute's target vbo? [duplicate]

OpenGL 4.3 and OpenGL ES 3.1 added several alternative functions for specifying vertex arrays: glVertexAttribFormat, glBindVertexBuffers, etc. But we already had functions for specifying vertex arrays. Namely glVertexAttribPointer.
Why add new APIs that do the same thing as the old ones?
How do the new APIs work?
glVertexAttribPointer has two flaws, one of them semi-subjective, the other objective.
The first flaw is its dependency on GL_ARRAY_BUFFER. This means that the behavior of glVertexAttribPointer is contingent on whatever was bound to GL_ARRAY_BUFFER at the time it was called. But once it is called, what is bound to GL_ARRAY_BUFFER no longer matters; the buffer object's reference is copied into the VAO. All this is very unintuitive and confusing, even to some semi-experienced users.
It also requires you to provide an offset into the buffer object as a "pointer", rather than as an integer byte offset. This means that you perform an awkward cast from an integer to a pointer (which must be matched by an equally awkward cast in the driver).
The second flaw is that it conflates two operations that, logically, are quite separate. In order to define a vertex array that OpenGL can read, you must provide two things:
How to fetch the data from memory.
What that data looks like.
glVertexAttribPointer provides both of these simultaneously. The GL_ARRAY_BUFFER buffer object, plus the offset "pointer" and stride define where the data is stored and how to fetch it. The other parameters describes what a single unit of data looks like. Let us call this the vertex format of the array.
As a practical matter, users are far more likely to change where vertex data comes from than vertex formats. After all, many objects in the scene store their vertices in the same way. Whatever that way may be: 3 floats for position, 4 unsigned bytes for colors, 2 unsigned shorts for tex-coords, etc. Generally speaking, you have only a few vertex formats.
Whereas you have far more locations where you pull data from. Even if the objects all come from the same buffer, you will likely want to update the offset within that buffer to switch from object to object.
With glVertexAttribPointer, you can't update just the offset. You have to specify the whole format+buffer information all at once. Every time.
VAOs mitigate having to make all those calls per object, but it turns out that they don't really solve the problem. Oh sure, you don't have to actually call glVertexAttribPointer. But that doesn't change the fact that changing vertex formats is expensive.
As discussed here, changing vertex formats is pretty expensive. When you bind a new VAO (or rather, when you render after binding a new VAO), the implementation either changes the vertex format regardless or has to compare the two VAOs to see if the vertex formats they define are different. Either way, it's doing work that it doesn't need to be doing.
glVertexAttribFormat and glBindVertexBuffer fix both of these problems. glBindVertexBuffer directly specifies the buffer object and takes the byte offset as an actual (64-bit) integer. So there's no awkward use of the GL_ARRAY_BUFFER binding; that binding is solely used for manipulating the buffer object.
And because the two separate concepts are now separate functions, you can have a VAO that stores a format, bind it, then bind vertex buffers for each object or group of objects that you render with. Changing vertex buffer binding state is cheaper than vertex format state.
Note that this separation is formalized in GL 4.5's direct state access APIs. That is, there is no DSA version of glVertexAttribPointer; you must use glVertexArrayAttribFormat and the other separate format APIs.
The separate attribute binding functions work like this. glVertexAttrib*Format functions provides all of the vertex formatting parameters for an attribute. Each of its parameters have the exact same meaning as the parameters from the equivalent call to glVertexAttrib*Pointer.
Where things get a bit confusing is with glBindVertexBuffer.
Its first parameter is an index. But this is not an attribute location; it is merely a buffer binding point. This is a separate array from attribute locations with its own maximum limit. So the fact that you bind a buffer to index 0 means nothing about where attribute location 0 gets its data from.
The connection between buffer bindings and attribute locations is defined by glVertexAttribBinding. The first parameter is the attribute location, and the second is the buffer binding index to fetch that attribute's location with. Since the function's name starts with "VertexAttrib", you should consider this to be part of the vertex format state and thus is expensive to change.
The nature of offsets may be a bit confusing at first as well. glVertexAttribFormat has an offset parameter. But so too does glBindVertexBuffer. But these offsets mean different things. The easiest way to understand the difference is by using an example of an interleaved data structure:
struct Vertex
{
GLfloat pos[3];
GLubyte color[4];
GLushort texCoord[2];
};
The vertex buffer binding offset specifies the byte offset from the start of the buffer object to the first vertex index. That is, when you render index 0, the GPU will fetch memory from the buffer object's address + the binding offset.
The vertex format offset specifies the offset from the start of each vertex to that particular attribute's data. If the data in the buffer is defined by Vertex, then the offset for each attribute would be:
glVertexAttribFormat(0, ..., offsetof(Vertex, pos)); //AKA: 0
glVertexAttribFormat(1, ..., offsetof(Vertex, color)); //Probably 12
glVertexAttribFormat(2, ..., offsetof(Vertex, texCoord)); //Probably 16
So the binding offset defined where vertex 0 is in memory, while the format offsets define where the each attribute's data comes from within a vertex.
The last thing to understand is that the buffer binding is where the stride is defined. This may seem odd, but think about it from the hardware perspective.
The buffer binding should contain all of the information needed by the hardware to turn a vertex index or instance index into a memory location. Once that's done, the vertex format explains how to interpret the bytes in that memory location.
This is also why the instance divisor is part of the buffer binding state, via glVertexBindingDivisor. The hardware needs to know the divisor in order to convert an instance index into a memory address.
Of course, this also means that you can no longer rely on OpenGL to compute the stride for you. In the above cast, you simply use sizeof(Vertex).
Separate attribute formats completely covers the old glVertexAttribPointer model so well that the old function is now defined entirely in terms of the new:
void glVertexAttrib*Pointer(GLuint index​, GLint size​, GLenum type​, {GLboolean normalized​,} GLsizei stride​, const GLvoid * pointer​)
{
glVertexAttrib*Format(index, size, type, {normalized,} 0);
glVertexAttribBinding(index, index);
GLuint buffer;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, buffer);
if(buffer == 0)
glErrorOut(GL_INVALID_OPERATION); //Give an error.
if(stride == 0)
stride = CalcStride(size, type);
GLintptr offset = reinterpret_cast<GLintptr>(pointer);
glBindVertexBuffer(index, buffer, offset, stride);
}
Note that this equivalent function uses the same index value for the attribute location and the buffer binding index. If you're doing interleaved attributes, you should avoid this where possible; instead, use a single buffer binding for all attributes that are interleaved from the same buffer.

What is the meaning of the index argument in glDrawElements?

There are two OpenGL documentation pages which have slightly different descriptions of the "index" parameter of the glDrawElements function. On www.opengl.org/sdk/docs/man4/ it says:
indices
Specifies a pointer to the location where the indices are stored.
And on www.khronos.org/opengles/sdk/docs/man3 it says:
indices
Specifies a byte offset (cast to a pointer type) into the buffer bound
to GL_ELEMENT_ARRAY_BUFFER to start reading indices from. If no buffer
is bound, specifies a pointer to the location where the indices are stored.
I am on Windows by the way, using OpenGL 4+.
So I've copied my index array into the element buffer object I created, the indices pointer argument I need to supply is the offset in bytes of the first index? So if I want to start drawing at index 3, the argument would be 2 * sizeof(GLuint), cast as a pointer?
I actually went to the effort of creating an EBO for this, but from the looks of it it says that if no EBO is bound the pointer points straight to the location where the indices are, not the EBO. Am I right that this means it will point to your array on the system RAM? (EDIT: I just realised this doesn't make sense, if the pointer is at 0x00000008 it can't go to that address in system memory.) And if so, does it then copy the index array to the graphics card each time in order to be able to use it? Thanks.
As per OpenGL 4.5, core profile, reading from client memory is unsupported (§10.3.10 OpenGL 4.5 core spec):
DrawElements, DrawRangeElements, and DrawElementsInstanced source their indices from the buffer object whose name is bound to
ELEMENT_ARRAY_BUFFER, using their indices parameters as offsets into the buffer object in the same fashion as described in section 10.3.9. [...] If zero is bound to ELEMENT_ARRAY_BUFFER, the result of these drawing commands is undefined.
So your approach of creating an EBO is correct. Except if your 0th index is located at offset zero then the 3rd index is located at offset 3*sizeof(type).
As for your second quotation: in the older OpenGL versions you could pass a pointer to the client memory (in your process virtual address space, not the physical address) and leave ELEMENT_ARRAY_BUFFER unbound.

glVertexAttribPointer and glVertexAttribFormat: What's the difference?

OpenGL 4.3 and OpenGL ES 3.1 added several alternative functions for specifying vertex arrays: glVertexAttribFormat, glBindVertexBuffers, etc. But we already had functions for specifying vertex arrays. Namely glVertexAttribPointer.
Why add new APIs that do the same thing as the old ones?
How do the new APIs work?
glVertexAttribPointer has two flaws, one of them semi-subjective, the other objective.
The first flaw is its dependency on GL_ARRAY_BUFFER. This means that the behavior of glVertexAttribPointer is contingent on whatever was bound to GL_ARRAY_BUFFER at the time it was called. But once it is called, what is bound to GL_ARRAY_BUFFER no longer matters; the buffer object's reference is copied into the VAO. All this is very unintuitive and confusing, even to some semi-experienced users.
It also requires you to provide an offset into the buffer object as a "pointer", rather than as an integer byte offset. This means that you perform an awkward cast from an integer to a pointer (which must be matched by an equally awkward cast in the driver).
The second flaw is that it conflates two operations that, logically, are quite separate. In order to define a vertex array that OpenGL can read, you must provide two things:
How to fetch the data from memory.
What that data looks like.
glVertexAttribPointer provides both of these simultaneously. The GL_ARRAY_BUFFER buffer object, plus the offset "pointer" and stride define where the data is stored and how to fetch it. The other parameters describes what a single unit of data looks like. Let us call this the vertex format of the array.
As a practical matter, users are far more likely to change where vertex data comes from than vertex formats. After all, many objects in the scene store their vertices in the same way. Whatever that way may be: 3 floats for position, 4 unsigned bytes for colors, 2 unsigned shorts for tex-coords, etc. Generally speaking, you have only a few vertex formats.
Whereas you have far more locations where you pull data from. Even if the objects all come from the same buffer, you will likely want to update the offset within that buffer to switch from object to object.
With glVertexAttribPointer, you can't update just the offset. You have to specify the whole format+buffer information all at once. Every time.
VAOs mitigate having to make all those calls per object, but it turns out that they don't really solve the problem. Oh sure, you don't have to actually call glVertexAttribPointer. But that doesn't change the fact that changing vertex formats is expensive.
As discussed here, changing vertex formats is pretty expensive. When you bind a new VAO (or rather, when you render after binding a new VAO), the implementation either changes the vertex format regardless or has to compare the two VAOs to see if the vertex formats they define are different. Either way, it's doing work that it doesn't need to be doing.
glVertexAttribFormat and glBindVertexBuffer fix both of these problems. glBindVertexBuffer directly specifies the buffer object and takes the byte offset as an actual (64-bit) integer. So there's no awkward use of the GL_ARRAY_BUFFER binding; that binding is solely used for manipulating the buffer object.
And because the two separate concepts are now separate functions, you can have a VAO that stores a format, bind it, then bind vertex buffers for each object or group of objects that you render with. Changing vertex buffer binding state is cheaper than vertex format state.
Note that this separation is formalized in GL 4.5's direct state access APIs. That is, there is no DSA version of glVertexAttribPointer; you must use glVertexArrayAttribFormat and the other separate format APIs.
The separate attribute binding functions work like this. glVertexAttrib*Format functions provides all of the vertex formatting parameters for an attribute. Each of its parameters have the exact same meaning as the parameters from the equivalent call to glVertexAttrib*Pointer.
Where things get a bit confusing is with glBindVertexBuffer.
Its first parameter is an index. But this is not an attribute location; it is merely a buffer binding point. This is a separate array from attribute locations with its own maximum limit. So the fact that you bind a buffer to index 0 means nothing about where attribute location 0 gets its data from.
The connection between buffer bindings and attribute locations is defined by glVertexAttribBinding. The first parameter is the attribute location, and the second is the buffer binding index to fetch that attribute's location with. Since the function's name starts with "VertexAttrib", you should consider this to be part of the vertex format state and thus is expensive to change.
The nature of offsets may be a bit confusing at first as well. glVertexAttribFormat has an offset parameter. But so too does glBindVertexBuffer. But these offsets mean different things. The easiest way to understand the difference is by using an example of an interleaved data structure:
struct Vertex
{
GLfloat pos[3];
GLubyte color[4];
GLushort texCoord[2];
};
The vertex buffer binding offset specifies the byte offset from the start of the buffer object to the first vertex index. That is, when you render index 0, the GPU will fetch memory from the buffer object's address + the binding offset.
The vertex format offset specifies the offset from the start of each vertex to that particular attribute's data. If the data in the buffer is defined by Vertex, then the offset for each attribute would be:
glVertexAttribFormat(0, ..., offsetof(Vertex, pos)); //AKA: 0
glVertexAttribFormat(1, ..., offsetof(Vertex, color)); //Probably 12
glVertexAttribFormat(2, ..., offsetof(Vertex, texCoord)); //Probably 16
So the binding offset defined where vertex 0 is in memory, while the format offsets define where the each attribute's data comes from within a vertex.
The last thing to understand is that the buffer binding is where the stride is defined. This may seem odd, but think about it from the hardware perspective.
The buffer binding should contain all of the information needed by the hardware to turn a vertex index or instance index into a memory location. Once that's done, the vertex format explains how to interpret the bytes in that memory location.
This is also why the instance divisor is part of the buffer binding state, via glVertexBindingDivisor. The hardware needs to know the divisor in order to convert an instance index into a memory address.
Of course, this also means that you can no longer rely on OpenGL to compute the stride for you. In the above cast, you simply use sizeof(Vertex).
Separate attribute formats completely covers the old glVertexAttribPointer model so well that the old function is now defined entirely in terms of the new:
void glVertexAttrib*Pointer(GLuint index​, GLint size​, GLenum type​, {GLboolean normalized​,} GLsizei stride​, const GLvoid * pointer​)
{
glVertexAttrib*Format(index, size, type, {normalized,} 0);
glVertexAttribBinding(index, index);
GLuint buffer;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, buffer);
if(buffer == 0)
glErrorOut(GL_INVALID_OPERATION); //Give an error.
if(stride == 0)
stride = CalcStride(size, type);
GLintptr offset = reinterpret_cast<GLintptr>(pointer);
glBindVertexBuffer(index, buffer, offset, stride);
}
Note that this equivalent function uses the same index value for the attribute location and the buffer binding index. If you're doing interleaved attributes, you should avoid this where possible; instead, use a single buffer binding for all attributes that are interleaved from the same buffer.

glbufferdata with Vector of pointers c++

In c++ and openGL4 I can do something like this
std::vector<Vertex> vertices;
Where Vertex is a class that holds the relevant per vertex data.
this->vertices.pushback(Vertex())
....define the rest of the vertices and set position and color data etc
//Opengl code
glBindBuffer(GL_ARRAY_BUFFER, this->vboID[0]);
glBufferData(GL_ARRAY_BUFFER, ( this->vertices.size() * sizeof(Vertex) ) , this->vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer((GLuint)0, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)0); // Set up our vertex attributes pointer
glEnableVertexAttribArray(0);
This works fine and displays what I am rendering fine. Now if I try to make the vector
std::vector<Vertex*> vertices;
this->vertices.push_back(new Vertex());
....
then the shape I want to display never shows up.
My question is this because I use pointers that the data is no longer continuous and so opengl can't read the vertex data or is it possible to alter the openGL code to accept the vector of pointers?
Well, of course. In the first version, you are passing the actual Vertex instances to OpenGL as a byte buffer. In the second version, you are passing pointers to the Vertex instances to OpenGL, and OpenGL won't dereference these pointers for you.
You need to use the first version, there is no way to pass pointers to your Vertices to OpenGL.
OpenGL needs the raw vertex data. It has no conception of how that data is formatted when it is being buffered. It's a dumb buffer. It is not possible for OpenGL to accept the vector of pointers - even if it did, it would still have to extract the vertices and put them into a contiguous array for optimal layout and sending to the graphics hardware.
What you're doing is sending a bunch of raw data to the graphics hardware that will be interpreted as vertices per glVertexAttribPointer. Imagine it is doing a reinterpret_cast behinds the scenes - it is now interpreting some (say, 32-bit integral) pointers as though they were supposed to be sets of 4, 32-bit, floating point values.
I suspect you opted to make a vector of vertex pointers rather than an array of vertices because of the overhead when inserting into the vector? You should pre-size your vector with a call to reserve or resize, whichever is more appropriate so as to pay the reallocation costs once only.
Do not use std::vector <...>::data (...) if you care about portability. That does not exist in older versions of C++. Beginning with C++03, &std::vector <...> [0] is guaranteed to return the address of a contiguous block of data representing the first element stored in the vector. It worked this way long before that, but this was the first time the behavior was absolutely guaranteed.
But your fundamental problem here is that GL is not going to dereference the pointers you stored in your vector when it comes time to get data. That is what your vector stores, after all. You need the vector to store actual data, and not a list of pointers to data.

What is stride in glVertexPointer, glTexCoordPointer in VBO

Hi I have a problem drawing with VBO. So I asked a question a here .I could not find the answer of my problem. But by discussing one answer given there I have now another question about strides in VBO. I am confused about what it is and does.
In here I found someone answered
If you have all your vertex data in one array (array : read as
malloc''ed pointer), all your normals in another array, etc. Then your
stride is 0. For instance if vertex, normals, etc are stored like that
:
[vertex0][vertex1][vertex2]...
[normal0][normal1][normal2]...
[texcoord0][texcoord1][texcoord2]...
If your vertex, normal, etc is packed like that :
[vertex0][normal0][texcoord0][vertex1][normal1][texcoord1][vertex2][normal2][texcoord2]...
Then you should set a non-null stride, which corresponds to the offset
needed to switch from one element to the next. (this stride is counted
as bytes btw)
From that explanation I thought the stride actually means the distance between end of one vertex and the start of another vertex in the buffer. In the first case its 0 because all the vertexes are stored contiguously. Same goes for the textures. But then I read another answer about the definition of strides in that same thread.
There tends to be a bit of confusion regarding VBO stride, mostly
because of its special meaning for 0.
"Stride" in this context means the distance between the beginning of a
value in memory, and the beginning of the next value in memory. It is
not the distance between the end of one and the beginning of the next.
So in a VBO that is an array of a structure, the stride for each
element of that structure will be the sizeof the structure as a whole.
Keep in mind that struct padding can affect this.
which just says the opposite of what the other answer says. Or I am wrong about what the first answer meant? Can anyone please help me solve the problem. I will really appreciate if anyone can give an answer with example. I have given the link of my implementation of VBO in the start of this question which is not solved yet. Thanks.
What the first answer is trying to say is that the "stride" between two elements is the offset in bytes between the beginning of one element and the beginning of the next.
However, if the elements you're passing are contiguous (i.e. there's no space between them), you can pass 0 for the stride parameter.
I would say that it's wrong to claim that "stride is 0" in this case - the stride is sizeof(element), but the value 0 gets special treatment and is taken to mean sizeof(element).
This is most likely done so the poor programmer doesn't have to use two (bug-prone) sizeof parameters in the common case when they are the same.