After calling glVertexAttribPointer(GLuint index, ...) the vertex attribute is disabled by default as the docs say
By default, all client-side capabilities are disabled, including all generic vertex attribute arrays.
Why must we enable it using an extra function? Can someone name a case, where this is useful?
When researching I learned the following:
By using the
layout(location = x)qualifier in GLSL orglBindAttribLocationwe can set the location explicitly rather then letting OpenGL generate it. But this is not the point of my question.glEnableVertexAttribArraycan not be used to draw one VAO with multiple shaders. As attribute locations are queried using a program object, one would assume that locations are shader-specific; then one would expect, we can enable the right attributes locations before running the right shader. But testing this, I noticed, that one location value can occur more than one time in different shaders; furthermore the output looked wrong. If you wish to see the code, just ask.Attribute locations are stored in the VAO.
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.
来源:https://stackoverflow.com/questions/39264296/what-is-the-purpose-of-glenablevertexattribarraygluint-index-in-opengl