Questions about VBO

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),data,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.

Have you tried GL_DYNAMIC_DRAW_ARB?

-SirKnight

Also, use glBufferSubDataARB() for updating the buffer rather than glBufferDataARB().

Thanks, i’ll try those !

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, &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

Originally posted by penetrator:
glDrawArrays(GL_QUAD_STRIP, 0, POLYSPOINTSCOORD);
The last parameter is the number of vertices, so that *COORD should not be there.

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 ?

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, &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

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.

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