Why no glVertexAttribPointer for index buffer object?

hello everyone!

I am here to clear out some confusions regarding opengl from experts. I appreciate your help!


private int vbo;
private int ibo;
 
vbo = glGenBuffers();
ibo = glGenBuffers();
 
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(vertices), GL_STATIC_DRAW);
 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW);
  
 
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
glVertexAttribPointer(0, 3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, false, Vertex.SIZE * 4, 12);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

 
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
 
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

The vertex shader code looks like


#version 330
 
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
 
out vec2 texCoord0;
 
uniform mat4 transform;
 
void main()
{
    gl_Position = transform * vec4(position, 1.0);
    texCoord0 = texCoord;
}

So, here is my understanding. The purpose of glVertexAttribPointer is to define the format of data in the vertex buffer object. So, in vbo it stores data as follows


buffer.put(vertices[i].getPos().getX());
buffer.put(vertices[i].getPos().getY());
buffer.put(vertices[i].getPos().getZ());
buffer.put(vertices[i].getTexCoord().getX());
buffer.put(vertices[i].getTexCoord().getY());
buffer.put(vertices[i].getNormal().getX());
buffer.put(vertices[i].getNormal().getY());
buffer.put(vertices[i].getNormal().getZ());

So, we have two glVertexAttribPointer lines because we have two variables defined in the vertex shader. So basically we are defining what these two variables point to. So, the first glVertexAttribPointer defines that the first variable “position” is a vertex with three coordinates each being float. The second glVertexAttribPointer defines the second variable “texCoord” being a pair of texture coordinates each being float.

Now what confuses me is that we are using glVertexAttribPointer to make sense of data stored in vbo to opengl. Now, why dont we also use another glVertexAttribPointer or similar code to make sense of data in ibo. Why is this buffer object left alone?

I appreciate any help. Thanks a lot!

Should probably call those vertex attributes to avoid confusion with the more general term “variable”.

why dont we also use another glVertexAttribPointer or similar code to make sense of data in ibo. Why is this buffer object left alone?

By design, I suppose. Consider what an index is or, rather, what it isn’t: it’s not a vertex attribute. The index stores information on how to “connect the dots”, so it cannot be part of the vertex shader which only operates on individual vertices and not assembled primitives. But by itself lacks the information needed that defines the data stored in the IBO. There is no “IndexPointer” method; you do, however, use something similar:


glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);

All the “Elements” family of Draw calls require that a buffer exists bound to a VAO’s GL_ELEMENT_ARRAY_BUFFER binding point and (some of) the parameters you send to these methods tell gl how to read the IBO’s data.

Thank you for the explanation. That makes sense that since index buffer can just have one type of data i.e indices of the vertices it doesn’t need a glVertexAttribPointer to define the data but the vbo can have any types of data for eg. vertices, texture coordinates, normals etc so we need to define the data explicitly using glVertexAttribPointer. Isn’t that true?

Mostly. There is an index type (which is specified in the indexed draw call – e.g. GL_UNSIGNED_SHORT, GL_UNSIGNED_INT, etc.), but there’s no number of components (“size”), stride, normalized flag, attribute index, etc. And the index type is just specified as a parameter to the glDrawElements call.

Thanks! for the reply. Now i get it.