2
\$\begingroup\$

I understand the basic sequence: glGenBuffers() creates a "buffer object name," glBindBuffer() creates the actual buffer object (as well as binding the name), glBufferData() "creates and initializes a buffer object's data store," and glVertexAttribPointer() sets the format of the buffer data, as well as saving the buffer object binding as part of vertex attrib array state.

The tricky thing that I'm unsure of is if the glVertexAttribPointer() stuff remains valid if the the "buffer object data store" (but not the buffer object itself) is blown away by a new call to glBufferData(). I'm aware that this isn't usually a good idea - use glBufferSubData() when just rewriting buffers - but glBufferData() seems like the only option if it needs to be resized. Plus, I'm just curious.

The reference pages make it sound like it could go either way - in particular (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):

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. 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.

It seems like both the byte offset and the buffer object binding could remain valid, even if the data store was replaced by something different. But I could also see it being implemented such that at the time of the call, the binding captures a specific pointer into the data store, which becomes invalidated if the data store is replaced. Neither way seems to be precluded by the wording.

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

It appears that glVertexAttribPointer() bindings remain valid, even after subsequent calls to glBufferData(). I determined this by trying it, which isn't 100% proof - it could just be working only in this implementation (NVidia drivers, in my case).

However, with an error message callback and debug mode on, I get the following message on the second call to glBufferData(), which strongly suggests that this situation is expected/designed for:

[LWJGL] OpenGL debug message
    ID: 0x20071
    Source: API
    Type: OTHER
    Severity: NOTIFICATION
    Message: Buffer detailed info: Buffer object 1 (bound to GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1), and GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW) will use VIDEO memory as the source for buffer object operations.

The first two bindings represent my two calls to glVertexAttribPointer(), and aren't present in the message that gets logged the first time I call glBufferData().

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .