Vertex arraysGL 3.0

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

indexGLuint

Attribute location, as layout(location = N) in the shader.

sizeGLint

Components per vertex: 1 to 4.

typeGLenum

An integer type only: GL_INT, GL_UNSIGNED_INT, GL_SHORT, GL_UNSIGNED_BYTE…

strideGLsizei

Bytes from one vertex to the next.

pointerconst void *

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

example.cpp
1// GLSL: layout(location = 3) in ivec4 aBoneIds;
2glVertexAttribIPointer(3, 4, GL_INT, sizeof(SkinnedVertex),
3                       (void *)offsetof(SkinnedVertex, boneIds));
4glEnableVertexAttribArray(3);
Official Khronos documentation