PDA

View Full Version : glDrawElements() and the built-in gl_VertexID



shapeare
01-10-2012, 11:45 PM
I have some problems with using glDrawElements and the built-in shader variable gl_VertexID.

I am doing hair rendering. I saved the positions of the vertices in ONE array, and used the following code to draw the hair model:


int pointIndex = 0;
for ( int hairIndex=0; hairIndex < hairCount; hairIndex++ )
{
glDrawArrays( GL_LINE_STRIP, pointIndex, segmentCount+1 );
pointIndex += segmentCount+1;
}

the variable hairCount represents the number of hair strand in this model, and the segmentCount represents the number of line segments in each hair strand, which is the same for all the hair strands.

But now I want to take advantage of the built-in GLSL variable gl_VertexID, so I replaced glDrawArrays with glDrawElements, and constructed an indices array as follows:


GLuint *hairElementsIndex = new GLuint[POINT_COUNT];
for(int i=0; i<POINT_COUNT; ++i)
hairElementsIndex[i]=i;

the constant POINT_COUNT is the number of vertices in the hair model.
And changed the drawing call to:


for ( int hairIndex=0; hairIndex < hairCount; hairIndex++ )
{
glDrawElements( GL_LINE_STRIP, segmentCount+1, GL_UNSIGNED_INT,
(GLvoid *)(hairIndex * (segmentCount+1)) );
}

However, the rendering result is not as expected, the end points of some hair strands seem to connect with the beginning points of some other hair strands. I cannot find any differences between these two drawing calls. Could anyone help me?



Another question is, if I sed glDrawElements, would gl_VertexID equal to the value in the indices array. In my case, I called glDrawElements several times. Will gl_VertexID restart from zero at each glDrawElements call? (Actually, I want gl_VertexID to equal to the index into the position array of the hair vertices.)

dorbie
01-11-2012, 11:43 AM
gl_Vertex_ID is not incompatible with glDrawArrays, the number is implicitly incremented for each vertex.

Are you are confusing data indices with the vertex count in the index array?

shapeare
01-11-2012, 07:17 PM
Sorry, I did confuse these terms. I make it clear now.

If I use the following code to draw the hair model:


int pointIndex = 0;
for ( int hairIndex=0; hairIndex < hairCount; hairIndex++ )
{
glDrawArrays( GL_LINE_STRIP, pointIndex, segmentCount+1 );
pointIndex += segmentCount+1;
}

gl_VertexID will restart from zero at each call of glDrawArrays. As I saved the positions of all the hair vertices in a single array, when rendering a vertex I want to get the ID of that vertex. I used glVertexAttribPointer() like this:


glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0,
(const GLvoid *)0);

to make gl_VertexID increase every time a vertex is rendered(three numbers are extracted).

The GLSL specification description of gl_VertexID says it was "explicitly generated from the content of the GL_ELEMENT_ARRAY_BUFFER by commands such as glDrawElements". So I constructed an element index array, wishing gl_VertexID would not restart at each call of glDrawElements.