Fun with EXT_vertex_shader

I’m having troubles with EXT_vertex_shader on my Radeon 8500. I wonder if it’s me, or if the documentation is really bad. I’m so confused i can’t believe it… anyone, enlighten me :

I’m simply trying to make a world-space displacement vector applied by the vertex shader. I’m trying to use variant arrays.

First confusion; in ATI’s tutorials Hardware Shading with EXT_vertex_shader and ATI_fragment_shader, it is written:

If rendering with vertex arrays, the application can specify the values of the variant in the following manner:

glVariantPointerEXT(var1, stride, type, addr)

However, in the EXT_vertex_shader specification:

Variant arrays are specified by the call:

void VariantPointerEXT( uint id, enum type, uint stride, void *addr )

Type and stride are reverted, wtf? I’m assuming the specifcation is correct, so let’s continue for more fun:

In the specification we find an identifier
VARIANT_ARRAY_EXT (0x87E8) which is only used in IsVariantEnabled. Nowhere it’s mentionned that i need to use glEnable(GL_VARIANT_ARRAY_EXT) or glDisable… it seems the correct way is to just enable the variant array with glEnableVariantClientStateEXT, but that doesn’t sound logical… why would there be a IsVariantEnabled if you can’t enable/disable it ?!

But it’s not finished. Fun, fun and more fun:
in the specification…

The type and stride parameters hold the same meaning as all other array calls. The size parameter is missing as in NormalPointer, and the size is fixed at 4. The id parameter specifies which variant this array is to be used with.

It was already bad, but now i’m just lost. What’s up with “size fixed at 4” ? 4 components in a variant array ? So basically it’s not possible to build a scalar array ? Although it’s possible to declare the variant id with GenSymbolsEXT(GL_SCALAR_EXT, …) as in:

This is done by calling
uint GenSymbolsEXT( enum datatype, enum storagetype, enum range, uint components );

where datatype can be one of SCALAR_EXT, VECTOR_EXT, MATRIX_EXT, and storagetype can be one of VARIANT_EXT, INVARIANT_EXT, LOCAL_CONSTANT_EXT, LOCAL_EXT, range can be NORMALIZED_RANGE_EXT or FULL_RANGE_EXT

Ok, now i’ve described what’s confusing me, but here’s my problem. I want to submit a displacement vector per-vertex, and just add it to the world position in the vertex shader. This works well if i try with a local constant; but as soon as i use a variant array, it’s as if the displacement vector was 0.

Here’s my code:

/// variant array declaration…
vertex = glBindParameterEXT(GL_CURRENT_VERTEX_EXT);
modelview = glBindParameterEXT(GL_MODELVIEW_MATRIX);
projection = glBindParameterEXT(GL_PROJECTION_MATRIX);
m_weightsID = glGenSymbolsEXT(GL_VECTOR_EXT, GL_VARIANT_EXT, GL_FULL_RANGE_EXT, 1);

/// shader definition:
glBindVertexShaderEXT(m_shader); glBeginVertexShaderEXT();
GLuint eyeVertex = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);
glShaderOp2EXT(GL_OP_ADD_EXT, eyeVertex, vertex, m_weightsID);
glShaderOp2EXT(GL_OP_MULTIPLY_MATRIX_EXT, eyeVertex, modelview, eyeVertex);
glShaderOp2EXT(GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_VERTEX_EXT, projection, eyeVertex);
glEndVertexShaderEXT();

/// Finally, the drawElements call:
glEnable(GL_VERTEX_SHADER_EXT);
glBindVertexShaderEXT(m_shader);
glEnableVariantClientStateEXT(m_weightsID);
glVariantPointerEXT(m_weightsID, GL_FLOAT, 0, m_weights);
glDrawElements(GL_TRIANGLES, m_nbExtIndices, GL_UNSIGNED_INT, m_extIndices);
glDisable(GL_VERTEX_SHADER_EXT);
glDisableVariantClientStateEXT(m_weightsID);

The array m_weights is filled with constant scalars (20.0f). I have the same behavior wether i try to use a scalar variant array, or a vector variant array.

Y.

My suggestion is that you move over to GL_ARB_vertex_program and forget about the EXT_vertex_shader.

True, i shall try… but given the similarities of the two specs, i’ll run into the same problem… won’t i ?

Y.

There aren’t a whole lot of similarities between GL_EXT_vertex_shader and GL_ARB_vertex_program. I think you’ll get going much quicker with the GL_ARB_vertex_program.

A couple things you might want to try…

1st, generate all symbols after you generate and after you bind your vertex shader; and before you begin your shader definition except for locals, like so…
m_shader = glGenVertexShadersEXT(1);
glBindVertexShaderEXT(m_shader);
vertex = glBindParameterEXT(GL_CURRENT_VERTEX_EXT);
mvp = glBindParameterEXT(GL_MVP_MATRIX_EXT);
m_weightsID = glGenSymbolsEXT(GL_VECTOR_EXT, GL_VARIANT_EXT, GL_FULL_RANGE_EXT, 1);

glBeginVertexShaderEXT();
GLuint eyeVertex = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1);

glEndVertexShaderEXT();

2nd, use the MVP matrix instead doing an extra matrix multiplications.

3rd, if you need a ‘scalar’ array, you can always hijack a texture coordinate set (i.e., use a component of a texture coordinate that you don’t usually need)

Dan

Thanks, but as i said, it’s not as if the shader was not working. It works, it’s just that the weights data is not well submitted to it…

I think i’m going to give a try to the ARB extension instead. I might get more help, and more support for it, if i find the same problem.

Y.

ARB_vertex_program looks much nicer but…

How am i supposed to submit my geometry with VAO ? (by that i mean, what’s the equivalent of VertexAttribPointerARB with VAO?).

Y.

[This message has been edited by Ysaneya (edited 11-26-2002).]

Originally posted by Ysaneya:
[b]ARB_vertex_program looks much nicer but…

How am i supposed to submit my geometry with VAO ? (by that i mean, what’s the equivalent of VertexAttribPointerARB with VAO?).

Y.

[This message has been edited by Ysaneya (edited 11-26-2002).][/b]
Get a pointer to your VAO data with the (undocumented) GL_ATI_map_object_buffer extension. You can even write to it

Have a peek at the glati.h header, should be easy to figure out.

(map/unmap works similarly to GL_EXT_compiled_vertex_arry wrt lock/unlock)

[This message has been edited by zeckensack (edited 11-26-2002).]

i know i feel stupid to ask this, but where do i get glATI.h? sorry, didn’t found it on the ati page somehow…

Originally posted by Ysaneya:
[b]ARB_vertex_program looks much nicer but…

How am i supposed to submit my geometry with VAO ? (by that i mean, what’s the equivalent of VertexAttribPointerARB with VAO?).
[/b]

Use the ATI_vertex_attrib_array_object extension. It defines the missing entry point required to get ARB_vp and VAO to work together. The spec has not been released yet ( I don’t have it ) but it’s straightforward to use. I managed to piece together the function by looking at the VAO and ARB_vp specs.

I have been using ARB_vp exclusively on both ATI and NV hardware for quite a while now. Vendor specific extensions are nice to have when the cards are new and you want to try out all the new features. Dropping support for NV_vp and EXT_vs has really made things much easier to maintain .

I just wish ATI would be quicker in releasing the specs for extensions that are present in the drivers.

Originally posted by davepermen:
i know i feel stupid to ask this, but where do i get glATI.h? sorry, didn’t found it on the ati page somehow…

http://www.ati.com/developer/sdk/radeonSDK/html/info/Prog3D.html

It’s near the top of the page ( glATI.h underlined ).

Originally posted by PH:
[b] http://www.ati.com/developer/sdk/radeonSDK/html/info/Prog3D.html

It’s near the top of the page ( glATI.h underlined ).[/b]

thanks i even whas there yet, the font was just too small somehow to note that thanks a lot…

I’m already using the map object buffer extension… but honnestly i don’t feel it’s safe to use it to get a pointer to video memory so i can submit it using the standard vertex arrays mechanism… the map object buffer is supposed to be a lock / unlock to write data to it, not reading…

PH: thanks, that’s exactly what i was seeking for. I have no reason to not use the ARB version now. I got all my shaders working in less than one hour, what a dream

Y.

[This message has been edited by Ysaneya (edited 11-26-2002).]