PDA

View Full Version : Questions about VBO



Alessandro_dup1
04-05-2005, 01:58 PM
I'd like to use VBO with dynamic data. Actually i'm using them to load a terrain map (i.e. a static object).
My program looks like this:

Init()
{
glGenBuffersARB( 1, &buffer ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer );
glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(data),d ata,GL_STATIC_DRAW_ARB);
}

Draw()
{
glEnableClientState( GL_VERTEX_ARRAY ); Arrays
glBindBufferARB( GL_ARRAY_BUFFER_ARB, buffer );
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
glDisableClientState( GL_VERTEX_ARRAY ); }
My question is how do i go from here if the data array is dynamic ? I tried to move the init() routine in the main loop but performances are horrible.

SirKnight
04-05-2005, 06:48 PM
Have you tried GL_DYNAMIC_DRAW_ARB?

-SirKnight

Humus
04-05-2005, 07:35 PM
Also, use glBufferSubDataARB() for updating the buffer rather than glBufferDataARB().

Alessandro_dup1
04-05-2005, 11:14 PM
Thanks, i'll try those !

Alessandro_dup1
04-06-2005, 04:58 AM
I started using VBO but still have some issues:

I have the following array:


#define POLYS 2902 //number of polygons to draw
#define POINTS=4 // each poly has 4 vertices
#define COORD=3 // each point has 3 coords, xyz
GLfloat data[POLYS*POINTS*COORD];
I draw (successfully) an object made of a series of quad strips looping through the vertices like this:


for (int tt1=0; tt1<(POLYS*POINTS*COORD); tt1+=12))
{
glBegin(GL_QUAD_STRIP);
glVertex3f(data[tt1+0],data[tt1+1],data[tt1+2]);
glVertex3f(data[tt1+3],data[tt1+4],data[tt1+5]);
glVertex3f(data[tt1+6],data[tt1+7],data[tt1+8]);
glVertex3f(data[tt1+9],data[tt1+10],data[tt1+11]);
glEnd();
}
I later tried to user VBO so i converted the code and used the following, but the object rendered has lot of faces more than it should be:


glGenBuffersARB(1, &amp;buffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW_ARB);
glEnableClientState( GL_VERTEX_ARRAY );
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
glDrawArrays(GL_QUAD_STRIP, 0, POLYS*POINTS*COORD);
glDisableClientState( GL_VERTEX_ARRAY ); Packing data in VBO seems to be straightforward, i just have a mega array with sequential vertices, but for some reason there must be an error somewhere.
Any help is greatly appreciated, is about a week i'm trying to solve this matter. Thanks again

Humus
04-06-2005, 03:27 PM
Originally posted by penetrator:
glDrawArrays(GL_QUAD_STRIP, 0, POLYS*POINTS*COORD);The last parameter is the number of vertices, so that *COORD should not be there.

Alessandro_dup1
04-07-2005, 12:36 AM
Thanks, i got it to work. I also had to re-organize the data arrays and now the whole thing works. However, using objects with less than 5000 polys i didn't notice much fps improvement between VBO and immediate mode. Is it possible that VBO are particularly efficient only when throwing thousands triangles ?

yooyo
04-07-2005, 02:07 AM
Try to setup VBO once and later in every frame just do glDraw... calls. As I can see from your code you always copy vertex data to VBO.



// put this in init
glGenBuffersARB(1, &amp;buffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(data), data, GL_STATIC_DRAW_ARB);

// put this in render loop
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
glDrawArrays(GL_QUAD_STRIP, 0, POLYS*POINTS);
glDisableClientState( GL_VERTEX_ARRAY ); yooyo

Alessandro_dup1
04-08-2005, 03:05 AM
I upload data to the VBO every loop because they are dynamic (stencil shadows).
I got it to work (with an improvement of about 25% respect to immediate mode) as it follows:

void RenderShadows()
{
glDepthMask(GL_FALSE);
glDepthFunc(GL_LEQUAL);
glEnable(GL_STENCIL_TEST);
glColorMask(0, 0, 0, 0);
glStencilFunc(GL_ALWAYS, 1, 0xffffffff);

// 1st pass
glFrontFace(GL_CCW);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(dati_ombra), dati_ombra, GL_DYNAMIC_DRAW_ARB); //swiched from STATIC to DYNAMIC
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer);
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
glDrawArrays(GL_QUADS, 0, polys_to_be_drawn*4);
}

// 2nd pass
glFrontFace(GL_CW);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
glDrawArrays(GL_QUADS, 0, polys_to_be_drawn*4);
glDisableClientState( GL_VERTEX_ARRAY );

//draw a shadowing rectangle covering the entire screen
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glLoadIdentity();
glBegin(GL_TRIANGLE_STRIP);
glVertex3f(-0.1f, 0.1f,-0.10f);
glVertex3f(-0.1f,-0.1f,-0.10f);
glVertex3f( 0.1f, 0.1f,-0.10f);
glVertex3f( 0.1f,-0.1f,-0.10f);
glEnd();
glFrontFace(GL_CCW);
glColorMask(1, 1, 1, 1);
}

Probably the code can be still optimized some more, but i'm not very experienced.
Also, i still have a problem with infinite shadow volumes: i cant set them up, i have read also some articles on Gamasutra but did not understand much of it. I'm going to ask this in a separate thread.

SirKnight
04-08-2005, 09:12 AM
Yeah VBO works the best when you throw an arse load of triangles at it b/c at that point you are AGP bound...I think that's the term.

There is a way to do shadow volumes completely on the GPU where for each edge of your model, you stick a degenerate quad at the edge and then you just "stretch" the quad to make the volume. I seem to remember some NVIDIA presentations talking about that.

-SirKnight