ARB_vertex_program: Attribute question

Do I need to make calls to VertexAttrib*ARB() to set up my attributes, or can I just use the general/conventional ones?

In other words, lets say all I have an OpenGL program with nothing but vertex colors and vertices. No lighting, no textures, no normals, etc. I want to execute the following code and use my vertex program:

glBegin( GL_LINES );
glColor3f( … );
glVertex3f( … );
glVertex3f( … );
glEnd();

Do I need to call VertexAttrib*ARB() instead, or can I just use:
EnableVertexAttribArrayARB(0); // position
EnableVertexAttribArrayARB(3); // color
… in my main program and then use:
vertex.position
vertex.color
… in my vertex program?

  • Jon

Array enables and immediate mode issue are orthogonal. Nothing different will be done to your immediate mode issued geometry just because you enabled (or didn’t) some specific array.

Here’s some quotes from the vertex_program spec:

Implementations may, but do not necessarily, use the same storage for the
current values of generic and certain conventional vertex attributes.
When any generic vertex attribute other than zero is specified, the
current values for the corresponding conventional attribute in Table X.1
become undefined.  Additionally, when a conventional vertex attribute is
specified, the current values for the corresponding generic vertex
attribute in Table X.1 become undefined.  For example, setting the current
normal will leave generic vertex attribute 2 undefined, and vice versa.

OK, I need to get a couple things straight.

First off, I can’t say something like:
MOV result.position, vertex.position
… because I need to declare them first like so:
ATTRIB inpos = vertex.position
OUTPUT outpos = result.position
MOV outpos, inpos

… Right?

I also can’t just make calls to glVertex3f() becuase it will undefine my attributes, right?

About the functions,
EnableVertexAttribArrayARB() is used in special conjunction with VertexAttribPointerARB() to implement vertex arrays for vertex programs, right? If this is true, then what call do I make to draw the contents of my array? What would be the equivalent of glDrawElements( GL_TRIANGLE_LIST, sizeof(indices)>>1, GL_UNSIGNED_SHORT, indices);?

Confused,
Jon

[This message has been edited by JONSKI (edited 10-21-2002).]

First off, I can’t say something like:
MOV result.position, vertex.position

That’s perfectly legal. You can use result and vertex attribute registers without declaring them. See the grammar in the ARB_v_p spec.

I also can’t just make calls to glVertex3f() becuase it will undefine my attributes, right?

That’s not true. You can use glVertex and access the values from the vertex program with vertex.position. Actually, it says somewhere in the spec that vertex.position and vertex.attrib[0] are equivalent. I’m not sure, but I think this means that glVertex and generic vertex attribute 0 are aliased. But this is the only case where that is true. All the other generic attributes do not necessarily have to alias to conventional attributes. See this thread http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/007676.html

In general, I think it’s safest to just always use generic attributes and be done with it. Then you don’t have to worry about implementation-dependent aliasing.

About the functions,
EnableVertexAttribArrayARB() is used in special conjunction with VertexAttribPointerARB() to implement vertex arrays for vertex programs, right?

Yes. All enabled arrays are drawn when you call glDrawElements & Co.

[edit - fixed some typos]

[This message has been edited by Asgard (edited 10-22-2002).]

As Asgard already pointed out, it is permissible to include any single vertex attribute or result binding in executable program instructions. Think of it as an automatic variable declaration. It is also allowable to include program parameter (constant) bindings, except for multiple-element arrays (single elements of matrices are OK). So, the classic 4x4 matrix transform can be written something like:

DP4 result.position.x, vertex.position, state.matrix.mvp[0];
DP4 result.position.y, vertex.position, state.matrix.mvp[1];
DP4 result.position.z, vertex.position, state.matrix.mvp[2];
DP4 result.position.w, vertex.position, state.matrix.mvp[3];

In this example, you might want to declare variables so the instructions aren’t so long. But we put this functionality in so you didn’t have to worry about declaring every single little binding you use in the program. There’s no ambiguity when you say “vertex.position” in a program, so there is little benefit to requiring variable declarations.

The only variables that need to be declared are temporaries and address register variables, since these have no “bindings”.

As for attribute aliasing, use whatever fits into your application the best.

If you are using vertex programs pretty much exclusively, generic attributes are probably the way to go.

If you are giving the same geometry to both vertex programs and the fixed-function pipe, you should probably use conventional attributes as much as possible – a vertex program can still refer to the conventional color as “vertex.color”.

If conventional attributes make sense, but you have a couple attributes that you use only for vertex programs, put them in attribute slots that don’t alias with the attributes you use. In general, attributes 6 and 7 are always free. Plus, if you use only 4 texture coordinates, slots 12-15 are free.

Conventional and generic vertex attribute arrays play together – you can enable both and get both to your program. For example, if you used conventional vertex position and generic attribute 7, you could render with vertex arrays using:

glVertexPointer(…);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexAttribPointerARB(7,…);
glEnableVertexAttribArrayARB(7);
glDrawArrays(…); // or whatever

The array state itself does not alias – setting the color pointer doesn’t ever set the pointer for vertex attribute 3. However, if the color and attribute 3 arrays are both enabled, aliasing behavior still applies and the generic attribute “wins” in the sense that it is defined. Think of array rendering in this case as though you called:

glColor(…);
glVertexAttribARB(3,…);

The second call leaves the current color undefined due to aliasing.

Be careful not to rely on the aliasing behavior – setting attribute 3 will also set “vertex.color” on NVIDIA platforms, but not on ATI platforms, for example.

The spec helps you avoid this a little bit by disallowing programs that refer both to “vertex.color” and “vertex.attrib[3]”.
But there is no mechanism to prevent you from using glVertexAttrib(3,…) when your program (or fixed-function GL) wants to use glColor(), or vice versa.

I finally got it running. It doesn’t look look right, but now that it’s running I can play with it and see what’s going on.

I really appreciate your help.

Thanks,
Jon

[This message has been edited by JONSKI (edited 10-22-2002).]

Originally posted by pbrown:
DP4 result.position.x, vertex.position, state.matrix.mvp[0];
DP4 result.position.y, vertex.position, state.matrix.mvp[1];
DP4 result.position.z, vertex.position, state.matrix.mvp[2];
DP4 result.position.w, vertex.position, state.matrix.mvp[3];

You forgot the “.row”:
DP4 result.position.x, vertex.position, state.matrix.mvp.row[0];

[This message has been edited by JONSKI (edited 10-22-2002).]

Originally posted by JONSKI:
[b] You forgot the “.row”:
DP4 result.position.x, vertex.position, state.matrix.mvp.row[0];

[This message has been edited by JONSKI (edited 10-22-2002).][/b]

Oops – my bad.

It’s not like I edited the spec or anything. :slight_smile: