glVertexAttribIPointer
glVertexAttribPointer for integer attributes: the values reach the shader as ints, not converted to float.
Signature
void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
How it works
glVertexAttribPointer always delivers floats: an int 3 in the buffer arrives as 3.0 (or as 0.0118 if normalized). For data that must stay an exact integer, such as the bone indices of a skinned mesh used to index an array of matrices, that conversion is wrong. glVertexAttribIPointer (note the I) keeps them as integers, and the shader declares the input as int, ivec4, uint or uvec4.
Parameters
Attribute location, as layout(location = N) in the shader.
Components per vertex: 1 to 4.
An integer type only: GL_INT, GL_UNSIGNED_INT, GL_SHORT, GL_UNSIGNED_BYTE…
Bytes from one vertex to the next.
Byte offset of this attribute inside a vertex.
Tips & pitfalls
Using the float version with an ivec4 input is the classic skinning bug: indices arrive as garbage and the mesh explodes.
There is no normalized argument: integers are never normalized here.
Errors
When the call is invalid it does nothing and sets an error, which glGetError returns:
- GL_INVALID_ENUM
- type is a float type such as GL_FLOAT.
- GL_INVALID_VALUE
- index ≥ GL_MAX_VERTEX_ATTRIBS or size outside 1–4.
Example
1// GLSL: layout(location = 3) in ivec4 aBoneIds;
2glVertexAttribIPointer(3, 4, GL_INT, sizeof(SkinnedVertex),
3 (void *)offsetof(SkinnedVertex, boneIds));
4glEnableVertexAttribArray(3);