PDA

View Full Version : glEnableVertexAttribArray but not using the array



Schnulla
08-12-2010, 02:46 PM
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!

Alfonse Reinheart
08-12-2010, 03:21 PM
Yes, you can keep them enabled without consequence.

Aleksandar
08-12-2010, 03:29 PM
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. :)

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.

Schnulla
08-12-2010, 03:48 PM
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? :)

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! :)

Alfonse Reinheart
08-12-2010, 05:45 PM
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.

Schnulla
08-12-2010, 06:10 PM
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 :)

Dan Bartlett
08-12-2010, 07:29 PM
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.



2.8.3 Drawing Commands
The command "void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );"
does not exist in the GL, but is used to describe functionality in the rest of this section.
This command constructs a sequence of geometric primitives by transferring
elements first through (first + count - 1) of each enabled array to the GL.

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.

Aleksandar
08-13-2010, 05:49 AM
No it isn't. Ignore him; he's writing nonsense.
Hello Alfonse!
The life is boring without quarreling with you. :)

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.


But isn't an active VAO mandatory in OpenGL 3.2 core profile?
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. :)


So could this crash or not?
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! :)

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!

Dan Bartlett
08-13-2010, 08:12 AM
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.

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.

Schnulla
08-13-2010, 09:53 AM
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.

Schnulla
08-13-2010, 09:57 AM
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.

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?

Alfonse Reinheart
08-13-2010, 10:24 AM
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.

Aleksandar
08-13-2010, 10:34 AM
[
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.

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.

hound
08-13-2010, 11:20 AM
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.

Graham Sellers
08-23-2010, 03:02 PM
I think the relevant parts of the paragraph are:

... The default vertex array object (the name zero) is also deprecated. ...
and:

... will generate an INVALID_OPERATION error, as will calling any array drawing command when no vertex array object is bound. ...
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.