Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glVertexAttribDivisor and index input

guys, I am trying to make use of glVertexAttribDivisor in my OpenGL instanced drawing.

It works in NV card, but it doesn't work in ATI card. Nothing is drawing.

From GlExtensionViewer, it shows both of these cards supports glVertexAttribDivisor/ InstancedStream. There was no error at running.

I don't know if this is due to my wrong usage.

I put the instance data in a separate vertex array buffer, then map it into gl_MultiTexCoord0~3. The instance data is the world matrix.

Code is here.

    for( int i=0;i<3;i++)
    {
        glClientActiveTexture(kGL_TEXTURE0 + i);
        glTexCoordPointer(size, type, stride, i*4*sizeof(float));

        int instanceVertexAttribIndex = i + 8;
        glVertexAttribDivisorARB(instanceVertexAttribIndex, 1);
    }

The key issue is what the right "index" should I give to glVertexAttribDivisorARB if I try to put the instance data on gl_MultiTexCoord0?

like image 606
giggle Avatar asked Sep 01 '11 03:09

giggle


People also ask

What is stored in a VAO?

A Vertex Array Object (VAO) is an OpenGL Object that stores all of the state needed to supply vertex data (with one minor exception noted below). It stores the format of the vertex data as well as the Buffer Objects (see below) providing the vertex data arrays.

When should I call Enablevertexattribarray?

If you're not using VAOs, then you would usually call glVertexAttribPointer (and the corresponding glEnableVertexAttribArray ) right before rendering to setup the state properly.

What is instance rendering?

Instancing allows duplicating a model with variations. In contrast to using the Repeater3D component, the model and its graphics resources are only allocated once. The rendering of the duplicated instances is done at a low level by the GPU.

What is a vertex attribute?

A vertex attribute is an input variable to a shader that is supplied with per-vertex data. In OpenGL core profile, they are specified as in variables in a vertex shader and are backed by a GL_ARRAY_BUFFER . These variable can contain, for example, positions, normals or texture coordinates.


1 Answers

It works on NVIDIA cards because NVIDIA is not implementing the OpenGL specification properly.

glVertexAttrbDivisorARB only works on generic attributes. That is, user-defined shader attributes. It does not work on any attributes other than those specified by glVertexAttrib(I)Pointer.

NVIDIA has long implemented the behavior of attribute aliasing. That gl_MultiTexCoorc[0] also has the attribute index 8. That gl_Vertex, the vertex position input, has the attribute index 0.

The problem? The OpenGL specification does not allow this. It specifically requires implementations to fail and give an error if you try it. When you call glDraw* with these arrays set up, your implementation should give you an error.

Sadly, you got caught in the NVIDIA trap: using non-spec behavior that just so happens to work on their drivers. I imagine you must have gotten the idea from some NVIDIA paper. So now you have to go change all your code to use user-defined attributes instead of the built-in ones.

Oh, and if you're wondering where in the specification it says this, see the OpenGL 3.3 Compatibility Profile, page 94, the very bottom:

It is not possible to alias generic attributes with conventional ones.

like image 100
Nicol Bolas Avatar answered Oct 18 '22 03:10

Nicol Bolas