glEnableVertexAttribArray but not using the array

Hi,

I have a Vertex Array Object (VAO) and a bunch of
vertex attribute arrays enabled in this VAO for
vertices, normals and stuff.

I wonder what could happen when I only use one of
these vertex attribute arrays in the active shader
(i.e. there is only an attribute variable declared
for the vertex array but not for the normal array)?

The thing is that I switch from a shader that uses
all of the enabled attribute arrays to a wireframe
shader which only needs the vertex array and I
wonder if I have to disable all the unused arrays
in the VAO or if I could keep them enabled for
the wireframe shader without crashing the system
on one of the many video cards around.

Your help is really appreciated!

Yes, you can keep them enabled without consequence.

You cannot enable/disable attribute arrays inside VAO at will. This is the purpose of VAO, to collect client states. You should create another VAO with appropriate attributes enabled, and activate it before drawing wireframe objects.

Or, maybe it is better to cease using VAO. It would be a faster solution. :slight_smile:

If attribute arrays are enabled but not properly initialize, it would crash the application for sure. But, if buffers are valid, and you are using proper indices for the attributes, it will probably work.

Hi,

first thanks for your comments.

  1. I’m a little bit confused now because one said it will
    not crash and the other “it could crash”. I use “proper”
    indices for the attributes but for the wireframe shader
    they are not bound after linking since there is no
    attribute variable in the shader except for vertices.
    So could this crash or not? :slight_smile:

  2. Secondly if you say it is not possible to enable/disable
    attribute arrays inside VAO at will, does this mean if I
    have enabled a vertex attribute array once for a VAO I
    could never disable it again for this VAO? So a call
    to glDisableVertexAttribArray inside a bound VAO is
    just ignored?

  3. You say in this case it is maybe better to cease using
    VAO. But isn’t an active VAO mandatory in OpenGL 3.2 core
    profile? I remember that nothing worked as soon as I had
    no VAO enabled and then read in the 3.2 core profile spec
    that a VAO must always be enabled.

Thanks for your help! :slight_smile:

You cannot enable/disable attribute arrays inside VAO at will.

You must certainly can. The object is fully mutable.

So a call to glDisableVertexAttribArray inside a bound VAO is just ignored?

No it isn’t. Ignore him; he’s writing nonsense.

Ok thanks Alfonse. Btw the switch to wireframe shader without
disabling the unused attribute arrays works fine here.
And since you said it should also work on any other system
I’ll go the lazy way without creating another VAO :slight_smile:

It should work, but you could have problems if you try to increase the size of just one array + use the same VAO without disabling unused attribute arrays, because the spec says that elements from each enabled array are transferred to the GL; it doesn’t say anything about not sending enabled but unused attribute array elements.

If the enabled but unused attribute array elements really are transferred, then it might be worth benchmarking to see if it’s faster to disable them. If they aren’t transferred if unused, then maybe the spec should reflect this.

Hello Alfonse!
The life is boring without quarreling with you. :slight_smile:

Yes, I know what I’m talking about, but I’m sorry because the post was too short to elaborate what I meant.

Of course that VAO is mutable, but it has to be selected (bound) and changed. It is an expensive operation compared to just enabling/disabling vertex attributes. That is what I meant when I said at will (meaning outside VAO). Sorry, “inside” was not a proper word.

I’m using GL 3.3/4.1 core profiles with forward compatibility bit set, and it works without VAOs. Please, can you point me to the page in the spec where it is written that VAO is mandatory? I’m using NVIDIA drivers and they work just fine without VAO.

And for the performance issues of the VAO, just search this forum to find out what the others mean. :slight_smile:

Hey, Schnulla, OpenGL is not a rocket science. You do not have to spend millions of dollars and kill many people to find out if it works. This is why I like programming - you can everything get checked by yourself! :slight_smile:

Just to encourage you, no, you probably cannot crash the application. What I was talking about is misuse of attributes’ indices. Sorry for the confusion!

Appendix E of the OpenGL core spec contains:

E.2.2 Removed Features

Client vertex and index arrays - all vertex array attribute and element array
index pointers must refer to buffer objects. The default vertex array object
(the name zero) is also deprecated. Calling VertexAttribPointer when no
buffer object or no vertex array object is bound will generate an INVALID_-
OPERATION error, as will calling any array drawing command when no vertex
array object is bound.

NVidia isn’t following (the appendices of) the spec, so it’s something you have to watch out for if you decide to deploy to other vendors who are following the spec in this case. Creating a dummy VAO + binding + forgetting about it is a quick way to follow the spec. It’s not really clear to me why disallowing 0 was required though.

Thanks Dan that is the part I meant.
On my ATI Radeon HD 5850 card it does not work without a VAO.

That’s a good call. And I also wonder to which location the
data of unused arrays is transferred since there is no
“space” (variable) defined in the shader?

Of course that VAO is mutable, but it has to be selected (bound) and changed. It is an expensive operation compared to just enabling/disabling vertex attributes.

Is it? How much more expensive is it? Got any data on that?

And I also wonder to which location the
data of unused arrays is transferred since there is no
“space” (variable) defined in the shader?

You’re assuming that vertex attributes in GLSL are special locations. They’re really just a block of memory that’s formatted as an array of 16 vec4’s. Which ones GLSL happens to use depend on what attributes were used with the program object when it was linked.

Attributes in unused arrays would be transferred to those compartments of the attribute memory block. The fact that GLSL doesn’t bother to read that location would be inconsequential.

Although English is not my native language, as far as I understand the spec, this is NOT what you said. “Client vertex and index arrays” is related to VA (vertex arrays) what is really deprecated feature. I have to draw your attention to “OR” in the spec. Please read it again and carefully. VBOs can be used without VAOs also according to the spec!

P.S. Maybe it doesn’t work with ATI, but that’s another problem. Hm, probably one more reason to adhere to NVIDIA, at least when OpenGL is concerned.

Exactly:


if (!vbo_bound || !vao_bound) {
    fail();
}

If it were phrased “when no buffer object or [!] vertex array object is bound” then it would be:


if (! (vbo_bound || vao_bound)) {
   fail();
}

But really it’s pretty darned ambiguous.

I think the relevant parts of the paragraph are:

and:

I think this clearly says that there is no default VAO, and that attempting to draw without a VAO bound will result in an error. An application that does this should not run on a core context.

Perhaps this could be more clearly spelled out elsewhere in the specification.