PDA

View Full Version : glMultiDrawElements + VBO



Alessandro_dup1
02-13-2012, 01:59 AM
I'm currently using glMultiDrawElements rendering arrays directly:



glPushMatrix();
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, verts);
glMultiDrawElements(GL_LINE_STRIP, globalIndexCount, GL_UNSIGNED_INT, (const void **) &globalIndices[0], globalIndices.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glPopMatrix();


To get better performances, I'd like to render the elements with VBO's: I think buffer are properly initialized and bind, but I can't figure out how the glMultiDrawElements call should look like.
The one posted below doesn't work, anybody can help please?



// bind buffers
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, fullHairCounter*HAIRPOINTS*sizeof(vector3_t), verts, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iboId);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, globalIndices.size() *sizeof(unsigned int), (const void **) &globalIndices[0], GL_STATIC_DRAW_ARB);




// render buffers
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iboId);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, verts);
glPushMatrix();
glMultiDrawElements(GL_LINE_STRIP, NULL, GL_UNSIGNED_INT, (const void **) &globalIndices[0], NULL );
glPopMatrix();
glDisableClientState( GL_VERTEX_ARRAY );
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);


Thanks for any help.

V-man
02-13-2012, 06:29 AM
If you are going to put your vertices in a VBO, then the address you pass to glVertexPointer should not be a CPU address. It should be the start of the VBO address, which is 0 or whatever higher address in the VBO you want.

The same applies to indices. Addresses are 0 based.
Don't pass CPU addresses.

For further info
http://www.opengl.org/wiki/Vertex_Buffer_Object

Alessandro_dup1
02-13-2012, 09:07 AM
Hi V-man, thanks for the answer and sorry for the typo.
I wrote
glVertexPointer(3, GL_FLOAT, 0, verts); because it was like that for the non-VBO version; obviously that is
glVertexPointer(3, GL_FLOAT, 0, 0);.

I've read also the paper you sent me, but still can't make the glMultiDrawElements to work. To note that I just want to use it so that I can draw all the items (GL_LINE_STRIP) at once, instead to loop glDrawRangeElements n times...

It's just that glMultiDrawElements call that puzzles me: I thought the one I did was ok, instead doesn't draw anything on screen. Clearly data is not passed as it expects...

mbentrup
02-13-2012, 09:33 AM
IIRC you have to pass a CPU array for the counts and indexes parameters, only the addresses _in_ the indexes array are VBO addresses/offsets.

If it's not an index (e.g. a number of indexes or an offset of an index), it is not stored in the GL_ELEMENT_ARRAY_BUFFER !

Also you pass NULL (== 0) as primcount, which explains why your program didn't crash although you passed a NULL for the counts parameter.

Alessandro_dup1
02-13-2012, 10:06 AM
Well, maybe I could show more in detail what I'm doing. As I wrote earlier, it's just the VBO implementation that doesn't work: glMultiDrawElements in CPU mode work just fine.



// fill array with data

int *globalIndexCount;
std::vec <int> globalIndices;

globalIndexCount=new int[fullHairCounter];
for (int i=0; i<fullHairCounter; i++)
{
globalIndexCount[i]=HAIRPOINTS;
globalIndices.push_back(indices+i*HAIRPOINTS);
}

// update VBO's
if (isVBOsupported==true)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, fullHairCounter*HAIRPOINTS*sizeof(vector3_t), verts, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iboId);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, globalIndices.size() *sizeof(unsigned int), (const void **) &amp;globalIndices[0], GL_STATIC_DRAW_ARB);
}

// rendering without VBO's works fine, so data is properly initialized and set
glPushMatrix();
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, verts);
glMultiDrawElements(GL_LINE_STRIP, globalIndexCount, GL_UNSIGNED_INT, (const void **) &amp;globalIndices[0], globalIndices.size() );
glDisableClientState( GL_VERTEX_ARRAY );
glPopMatrix();

// rendering with VBO's doesn't produce any output: it should be just a minimal change and yet it doesn't work
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iboId);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, 0);
glPushMatrix();
glMultiDrawElements(GL_LINE_STRIP, globalIndexCount, GL_UNSIGNED_INT, (const void **) &amp;globalIndices[0], globalIndices.size() );
glPopMatrix();
glDisableClientState( GL_VERTEX_ARRAY );
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

V-man
02-13-2012, 10:45 AM
You would have to check the contents of your globalIndices array.
Do they contain VBO address or is a CPU address?

Look at globalIndices[0]. It should probably be 0.