Separate attribute format

With OpenGL 4.3, we have an alternate (arguably better) way of specifying the vertex array object state (attribute format, enabled attributes, and buffers). In the previous example, the glVertexAttribPointer function does two important things. First, it indirectly specifies which buffer contains the data for the attribute which is the buffer currently bound (at the time of the call) to GL_ARRAY_BUFFER. Secondly, it specifies the format of that data (type, offset, stride, and so on).

It is arguably clearer to separate these two concerns into their own functions. This is exactly what has been implemented in OpenGL 4.3. For example, to implement the same functionality as in step 3 of the previous How to do it... section, we would use the following code:

glGenVertexArrays(1, &vaoHandle); 
glBindVertexArray(vaoHandle); 
glEnableVertexAttribArray(0); 
glEnableVertexAttribArray(1); 
 
glBindVertexBuffer(0, positionBufferHandle, 0, sizeof(GLfloat)*3); 
glBindVertexBuffer(1, colorBufferHandle, 0, sizeof(GLfloat)*3); 
 
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); 
glVertexAttribBinding(0, 0); 
glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0); 
glVertexAttribBinding(1, 1); 

The first four lines of the previous code are exactly the same as in the first example. We create and bind to the VAO, then enable attributes 0 and 1. Next, we bind our two buffers to two different indexes within the vertex buffer binding point using glBindVertexBuffer. Note that we're no longer using the GL_ARRAY_BUFFER binding point. Instead, we now have a new binding point specifically for vertex buffers. This binding point has several indexes (usually from 0 - 15), so we can bind multiple buffers to this point. The first argument to glBindVertexBuffer specifies the index within the vertex buffer binding point. Here, we bind our position buffer to index 0 and our color buffer to index 1.

The indexes within the vertex buffer binding point need not be the same as the attribute locations.

The other arguments to glBindVertexBuffer are as follows. The second argument is the buffer to be bound, the third is the offset from the beginning of the buffer to where the data begins, and the fourth is the stride, which is the distance between successive elements within the buffer. Unlike glVertexAttribPointer, we can't use a 0 value here for tightly packed data, because OpenGL can't determine the size of the data without more information, so we need to specify it explicitly here.

Next, we call glVertexAttribFormat to specify the format of the data for the attribute. Note that this time, this is decoupled from the buffer that stores the data. Instead, we're just specifying the format to expect for this attribute. The arguments are the same as the first four arguments to glVertexAttribPointer.

The glVertexAttribBinding function specifies the relationship between buffers that are bound to the vertex buffer binding point and attributes. The first argument is the attribute location, and the second is the index within the vertex buffer binding point. In this example, they are the same, but they don't need to be.

Also note that the buffer bindings of the vertex buffer binding point (specified by glBindVertexBuffer) are part of the VAO state, unlike the binding to GL_ARRAY_BUFFER.

This version is arguably clearer and easier to understand. It removes the confusing aspects of the invisible pointers that are managed in the VAO, and makes the relationship between attributes and buffers much clearer with glVertexAttribBinding. Additionally, it separates concerns that really don't need to be combined.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.98.71