Direct State access with vertex buffers

做~自己de王妃 提交于 2019-12-05 15:55:36

Since OpenGL 4.3 most of the VAO states can be set using direct state access. Have a look at the following functions:

void glVertexArrayAttribBinding  (GLuint vaobj, GLuint attribindex, GLuint bindingindex);

void glVertexArrayVertexBuffer   (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
void glVertexArrayBindingDivisor (GLuint vaobj, GLuint bindingindex, GLuint divisor);

void glEnableVertexArrayAttrib   (GLuint vaobj, GLuint attribindex);
void glDisableVertexArrayAttrib  (GLuint vaobj, GLuint attribindex);
void glVertexArrayAttribFormat   (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
void glVertexArrayAttribIFormat  (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
void glVertexArrayAttribLFormat  (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);

You can find some examples on how to use them in this thread.

In principle "old" VAO code can be translated 1-1 to DSA code. Assume we have an example like this

glBindVertexArray(vao);
glEnableVertexAttribArray(att_idx); //att_idx comes from shader
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(att_idx, 4, GL_FLOAT, GL_FALSE, sizeof(vec4), 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

then this could look in DSA code as follows

//glBindVertexArray(vao);
//No translation needed, since we don't want to bind :)

//glEnableVertexAttribArray(att_idx);
glEnableVertexArrayAttrib(vao, att_idx);

That was the easy part.

//glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(vec4));

Specifies the binding-point <-> buffer correspondance. Here the second parameter is a binding point. You can choose here basically what you want as long as it is < GL_MAX_VERTEX_ATTRIB_BINDINGS. But I normally recommend to use the same index that the attribute has. Parameter 3 and 4 (Stride, Offset) are the same values as in glVertexAttribPointer. Note, that glVertexArrayVertexBuffer does, in contrast to glVertexAttribPointer, not allow a stride of 0 to indicate tightly packed data. Even when the data is tightly packed, the stride has to be specified in bytes.

glVertexArrayAttribFormat(vao, att_idx, 4, GL_FLOAT, GL_FALSE, 0);

This defines the format of an attribute. Values 3-5 are similar to their correspondances in glVertexAttribPointer. The last parameter is the relativeoffset between elements in the buffer.

glVertexArrayAttribBinding(vao, att_idx, 0);

This line creates a correspondence between the attribute index and the binding point used in glVertexArrayVertexBuffer.

The last thing missing is the index buffer:

//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glVertexArrayElementBuffer(vao, ibo);

Now the vao should be in the same state as it was with the old code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!