GLVERTEXATTRIBPOINTE(3G)

πŸ‘‘ GLVERTEXATTRIBPOINTE(3G) β€” ok bestie, this is the glVertexAttribPointer glow-up

So you found a page in the OpenGL manual set (3G) and it's literally about telling the GPU where your vertex attribute data lives. No cap, this is one of those functions that ate and left no crumbs β€” every vertex you've ever drawn went through something like this. Let's go πŸ’…


✨ NAME ✨

glVertexAttribPointer β€” define an array of generic vertex attribute data. That's it, that's the whole vibe. πŸŽ€


🧚 C SPECIFICATION 🧚

Three sisters, one page. Here's the whole squad:

void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
                           GLboolean normalized, GLsizei stride,
                           const GLvoid * pointer);

void glVertexAttribIPointer(GLuint index, GLint size, GLenum type,
                            GLsizei stride, const GLvoid * pointer);

void glVertexAttribLPointer(GLuint index, GLint size, GLenum type,
                            GLsizei stride, const GLvoid * pointer);

Note the I one and the L one don't take a normalized arg β€” they said "not me, we're built different" 😌


πŸ¦‹ PARAMETERS πŸ¦‹

  • index β€” the index of the generic vertex attribute you're modifying. It's like the seat number in the group chat, everyone's gotta have their own.
  • size β€” how many components each generic vertex attribute has. Must be 1, 2, 3, 4. AND β€” plot twist β€” the symbolic constant GL_BGRA is also accepted, but only by glVertexAttribPointer. The initial value is 4.
  • type β€” the data type of each component in the array. GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, and GL_UNSIGNED_INT are accepted by glVertexAttribPointer and glVertexAttribIPointer. On top of that, GL_HALF_FLOAT, GL_FLOAT, GL_DOUBLE, GL_FIXED, GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV and GL_UNSIGNED_INT_10F_11F_11F_REV are accepted by glVertexAttribPointer. And GL_DOUBLE is also accepted by glVertexAttribLPointer β€” in fact it's the only token accepted for the type parameter of that function. main character energy fr. The initial value is GL_FLOAT.
  • normalized β€” for glVertexAttribPointer only, bestie. Says whether fixed-point data values should be normalized (GL_TRUE) or converted directly as fixed-point values (GL_FALSE) when they're accessed. Choose wisely πŸ’–
  • stride β€” the byte offset between consecutive generic vertex attributes. If stride is 0, the generic vertex attributes are understood to be tightly packed in the array (iconic, no gaps, snug). The initial value is 0.
  • pointer β€” specifies a offset of the first component of the first generic vertex attribute in the array, in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. The initial value is 0.

🌸 DESCRIPTION 🌸

glVertexAttribPointer, glVertexAttribIPointer and glVertexAttribLPointer specify the location and data format of the array of generic vertex attributes at index index to use when rendering. That's the whole job. size says how many components per attribute and must be 1, 2, 3, 4, or GL_BGRA. type says the data type of each component, and stride says the byte stride from one attribute to the next β€” which is how you get to pack vertices and attributes into a single array, or store them in separate arrays. Both are valid, both slay. 🫢

For glVertexAttribPointer, if normalized is set to GL_TRUE, that means values stored in an integer format get mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they're accessed and converted to floating point. Otherwise, values are converted to floats directly, no normalization, no filter. πŸͺž

For glVertexAttribIPointer, only the integer types GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, GL_UNSIGNED_INT are accepted. And values are always left as integer values. Periodt. πŸ”₯

glVertexAttribLPointer specifies state for a generic vertex attribute array associated with a shader attribute variable declared with 64-bit double precision components. type must be GL_DOUBLE. And index, size, and stride behave exactly as described for glVertexAttribPointer and glVertexAttribIPointer. Consistent queen. πŸ‘‘

Now the part everyone forgets, so listen up:

If pointer is not NULL, a non-zero named buffer object must be bound to the GL_ARRAY_BUFFER target (see glBindBuffer()), otherwise an error is generated. Not a vibe. 😭

pointer is treated as a byte offset into the buffer object's data store. The buffer object binding (GL_ARRAY_BUFFER_BINDING) is saved as generic vertex attribute array state (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) for index index.

When a generic vertex attribute array is specified, size, type, normalized, stride, and pointer are saved as vertex array state β€” in addition to the current vertex array buffer object binding. Everything gets remembered, she takes receipts πŸ’…

To enable and disable a generic vertex attribute array, call glEnableVertexAttribArray() and

glDisableVertexAttribArray with index. If enabled, the generic vertex attribute array is used when glDrawArrays(), glMultiDrawArrays(), glDrawElements(), glMultiDrawElements(), or glDrawRangeElements() is called. That's the whole pipeline, bestie. 🌈


πŸ’€ NOTES πŸ’€

  • Each generic vertex attribute array is initially disabled and isn't accessed when glDrawElements(), glDrawRangeElements(), glDrawArrays(), glMultiDrawArrays(), or glMultiDrawElements() is called. Like a private account, nobody's seeing it until you enable it. πŸ™ˆ
  • GL_UNSIGNED_INT_10F_11F_11F_REV is accepted for type only if the GL version is 4.4 or higher. Version check first, always. ⭐

πŸ“ ERRORS πŸ“

Buckle up, this list is long but every single one matters:

  • GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.
  • GL_INVALID_VALUE is generated if size is not 1, 2, 3, 4 or (for glVertexAttribPointer), GL_BGRA.
  • GL_INVALID_ENUM is generated if type is not an accepted value.
  • GL_INVALID_VALUE is generated if stride is negative. (negative stride is not the move, bestie 🚫)
  • GL_INVALID_OPERATION is generated if size is GL_BGRA and type is not GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV.
  • GL_INVALID_OPERATION is generated if type is GL_INT_2_10_10_10_REV or GL_UNSIGNED_INT_2_10_10_10_REV and size is not 4 or GL_BGRA.
  • GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_INT_10F_11F_11F_REV and size is not 3.
  • GL_INVALID_OPERATION is generated by glVertexAttribPointer if size is GL_BGRA and noramlized is GL_FALSE. (yes, noramlized β€” that spelling is straight from the source, I don't make the rules 😭)
  • GL_INVALID_OPERATION is generated if zero is bound to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL. (see above, this is the consequence πŸ‘€)

πŸ” ASSOCIATED GETS πŸ”

Everything you can ask the GPU to spill about this state:

  • glGet() with argument GL_MAX_VERTEX_ATTRIBS
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_ENABLED
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_SIZE
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_TYPE
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_STRIDE
  • glGetVertexAttrib() with arguments index and GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
  • glGet() with argument GL_ARRAY_BUFFER_BINDING
  • glGetVertexAttribPointerv() with arguments index and GL_VERTEX_ATTRIB_ARRAY_POINTER

🌟 VERSION SUPPORT 🌟

(The original ships this as a whole table β€” I'm giving you the same tea in list form, no facts lost, promise 🫢)

glVertexAttribIPointer

  • OpenGL 2.0 β€” - (nope)
  • OpenGL 2.1 β€” - (nope)
  • OpenGL 3.0 β€” βœ”
  • OpenGL 3.1 β€” βœ”
  • OpenGL 3.2 β€” βœ”
  • OpenGL 3.3 β€” βœ”
  • OpenGL 4.0 β€” βœ”
  • OpenGL 4.1 β€” βœ”
  • OpenGL 4.2 β€” βœ”
  • OpenGL 4.3 β€” βœ”
  • OpenGL 4.4 β€” βœ”
  • OpenGL 4.5 β€” βœ”

glVertexAttribLPointer

  • OpenGL 2.0 β€” -
  • OpenGL 2.1 β€” -
  • OpenGL 3.0 β€” -
  • OpenGL 3.1 β€” -
  • OpenGL 3.2 β€” -
  • OpenGL 3.3 β€” -
  • OpenGL 4.0 β€” -
  • OpenGL 4.1 β€” βœ”
  • OpenGL 4.2 β€” βœ”
  • OpenGL 4.3 β€” βœ”
  • OpenGL 4.4 β€” βœ”
  • OpenGL 4.5 β€” βœ”

glVertexAttribPointer

  • OpenGL 2.0 β€” βœ”
  • OpenGL 2.1 β€” βœ”
  • OpenGL 3.0 β€” βœ”
  • OpenGL 3.1 β€” βœ”
  • OpenGL 3.2 β€” βœ”
  • OpenGL 3.3 β€” βœ”
  • OpenGL 4.0 β€” βœ”
  • OpenGL 4.1 β€” βœ”
  • OpenGL 4.2 β€” βœ”
  • OpenGL 4.3 β€” βœ”
  • OpenGL 4.4 β€” βœ”
  • OpenGL 4.5 β€” βœ”

Original table column header was just: function / feature name, then OpenGL Version 2.0 2.1 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3 4.4 4.5. πŸŽ€


πŸ”— SEE ALSO πŸ”—

Go read these next, bestie:

  • glBindAttribLocation()
  • glBindBuffer()
  • glDisableVertexAttribArray
  • glDrawArrays()
  • glDrawElements()
  • glDrawRangeElements()
  • glEnableVertexAttribArray()
  • glMultiDrawArrays()
  • glMultiDrawElements()
  • glVertexAttrib()

Copyright Β© 2003-2005 3Dlabs Inc. Ltd. Copyright Β© 2010-2014 Khronos Group. This material may be distributed subject to the terms and conditions set forth in the Open Publication License, v 1.0, 8 June 1999. http://opencontent.org/openpub/.

Copyright Β© 2003-2005 3Dlabs Inc. Ltd. Copyright Β© 2010-2014 Khronos Group


okay that's the whole page, you're officially caught up πŸ’œ This one came from [FIXME: source], dated 08/09/2021, and lives at GLVERTEXATTRIBPOINTE(3G) β€” go bind some buffers, bestie, you got this πŸ’…βœ¨

πŸ“¦ where this page comes from