What is the purpose of `glEnableVertexAttribArray(GLuint index)` in OpenGL?

假装没事ソ 提交于 2019-11-28 12:58:53

The setting makes complete sense. There are very valid use cases for both having it enabled and disabled.

The name of the entry point already gives a strong hint why that is. Note the Array part in glEnableVertexAttribArray(). This call does not "enable the attribute". It enables using vertex attribute values from an array, meaning:

  • If it's enabled, a separate value from an array is used for each vertex.
  • If it's disabled, the current value of the attribute is used for all vertices.

The current value of an attribute is set with calls of the glVertexAttrib[1234]f() family. A typical code sequence for the use case where you want to use the same attribute value for all vertices in the next draw call is:

glDisableVertexAttribArray(loc);
glVertexAttrib4f(loc, colR, colG, colB, colA);

Compared to the case where each vertex gets its own attribute value from an array:

glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, ...);

Now, it is certainly much more common to source attributes from an array. So you could argue that the default is unfortunate for modern OpenGL use. But the setting, and the calls to change it, are definitely still very useful.

Remember GL has evolved from an underlying API which is over 20 years old and a huge amount of stuff is kept for for backwards compatibility, including a programming style which involves binding and state enables.

The hardware today is totally different to the original hardware the API was designed for, so in many cases there isn't a sensible "why" - that's just how the API works. Hence the move the new Vulkan API which drops all of the legacy support, and has a very different programming model ...

Why must we enable it using an extra function?

... because that is how the API works.

Can someone name a case, where this is useful?

... if you don't enable it it doesn't work, so I suspect that counts as useful.

Attribute locations are stored in the VAO.

VAO's didn't exist in the original API; they came along later, and really they just cache set of existing attribarray settings for VBOs, so you still need this API to set up what is referenced in the VAO.

If you you ask "why" a lot with OpenGL you'll go insane - it's not a very "clean" API from a programmers model point of view, and has evolved over multiple iterations while maintaining backwards compatibility in many cases. There are multiple ways of doing things, and many things which don't make sense if you try and use both at the same time. In most cases it's impossible to answer "why" accurately without finding out what someone was thinking 20 years ago when the original API was designed.

However you could imagine a theoretical use case where separate enables are useful. For example, imaging a case where you are rendering a model with 5 attribute arrays, and then a different model with 4 attribute arrays. For that second model what does the hardware do with the 5th attribute? Naively it might copy it into the GPU, so software needs to tell hardware not to do that. You could have an API where you write a special attribute (e.g. a NULL pointer, with zero length), or you have an API with an enable setting which simply tells the hardware not to read something.

Given an enable is probably just a bitmask in a register, then the enables are actually more efficient for the driver than having to decode a special case vertex attribute.

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