Linux and Vertex Buffer Objects

Started by
7 comments, last by feti 16 years, 5 months ago
What headers do I need and which libraries do I need to link against in order to get access to vertex buffer object functions? glGenBuffersARB() and related functions all do not exist for me. Everything else seems to be working ok
Advertisement
Normally you just need to link to the opengl library. Which version do you use? AFAIK from 1.5 up, there's no glGenBuffersARB() but only glGenBuffers().
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
Thanks for the reply. Yes, it's a bit bizarre that I don't get direct access to them. I had to check into the SDL_opengl.h code. Apparently it wanted me to define GL_GLEXT_PROTOTYPES in order to use them.

Given the following code to draw a single quad, could you help me implement them? I have the data working with vertex arrays, and I'm guessing I can use the same data to create a VBO.

GLuint  grass_vbo_ids[2];GLubyte grass_indices[4]   = { 0, 1, 2, 3 };GLfloat grass_vertices[12] = { 0,         TILE_SIZE, 0, // bottom left                               TILE_SIZE, TILE_SIZE, 0, // bottom right                               TILE_SIZE, 0,         0, // top right                               0,         0,         0  // top left                             };							 };glGenBuffers(2, &grass_vbo_ids[0]);// need help here creating/binding a buffer then actually using it to draw
You then bind the buffer object with glBindBuffer(...), set the data with glBuffer(Sub)Data(...) and render with glDrawElements(...), i.e.

//initialization
glBindBuffer(...)
glBufferData(...)

//render loop
glBindBuffer(...)
glXXXPointer(...)
glDrawElements(...)

For index buffers you use GL_ELEMENT_ARRAY_BUFFER whereas for vertex buffers you have GL_ARRAY_BUFFER. Then in the glXXXPointer functions you replace the array pointer with the offset into the buffer (e.g. 0 to start at the beginning of the buffer). The same is done with the index array pointer in glDrawElements().
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
A more explicit example following on from your code:
// Creating and populating the VBOsglGenBuffers(2, grass_vbo_ids); // 0 for verticies, 1 for indiciesglBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[0]);glBufferData(GL_ARRAY_BUFFER, 12*sizeof(GLfloat), grass_verticies, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grass_vbo_ids[1]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4*sizeof(GLubyte), grass_indicies, GL_STATIC_DRAW);// Drawing with the VBOs// Bind the vertex bufferglBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[0]);// glVertexPointer used for VBOs. The 4th parameter, instead of being the address of the data, is the offset into the currently bound VBO of our first element - in this case 0glVertexPointer(3, GL_FLOAT, 0, 0);glEnableClientState(GL_VERTEX_ARRAY);// Bind the index bufferglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grass_vbo_ids[1]);// Draw the data - the index pointer of 0 = use the GL_ELEMENT_ARRAY_BUFFER VBO.glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, 0);glDisableClientState(GL_VERTEX_ARRAY);

You guys rock. When I get back to my workstation I'm going to give this a shot to see if it improves the performance I have now.
Ok guys, this is what I've got, and it's going through my loop but it's not rendering the tiles. I know the loop works and the translations, cause when I comment out the vertex buffer data and go back to my glCallList() it renders great.

	// vertex data	GLuint  grass_vbo_ids[3];	GLubyte grass_indices[4]   = { 0, 1, 2, 3 };	GLfloat grass_texcoord[8]  = { 0, 1, // bottom left	                               1, 1, // bottom right								   1, 0, // top right								   0, 0  // top left								 };	GLfloat grass_vertices[12] = { 0,         TILE_SIZE, 0, // bottom left								   TILE_SIZE, TILE_SIZE, 0, // bottom right								   TILE_SIZE, 0,         0, // top right								   0,         0,         0  // top left	                             };		// Creating and populating the VBOs	glGenBuffers(3, &grass_vbo_ids[0]); // 0 for verticies, 1 for indicies		// vertex data	glBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[0]);	glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), grass_vertices, GL_STATIC_DRAW);		// index data	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grass_vbo_ids[1]);	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLubyte), grass_indices, GL_STATIC_DRAW);		// texture coordinate data	glBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[2]);	glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), grass_texcoord, GL_STATIC_DRAW);// -- and the code in the loop:		// draw grass		glBindTexture(GL_TEXTURE_2D, textures[TEX_GRASS]);				// tile info		int link_x     = coord_x / TILE_SIZE;		int link_y     = coord_y / TILE_SIZE;		int link_coord;		int tile_coord;		float tile_distance;		float tile_light;				// enable vertex buffer data		glEnableClientState(GL_VERTEX_ARRAY);		glEnableClientState(GL_TEXTURE_COORD_ARRAY);				// Bind the vertex buffer		glBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[0]);		glVertexPointer(3, GL_FLOAT, 0, 0);				// Bind the texture coordinates		glBindBuffer(GL_ARRAY_BUFFER, grass_vbo_ids[2]);		glTexCoordPointer(2, GL_FLOAT, 0, 0);				// Bind the index buffer		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grass_vbo_ids[1]);				for (int y = 0; y < SCREEN_HEIGHT / TILE_SIZE; y++)		{						glPushMatrix();						glTranslatef(-1.0 * TILE_SIZE, y * TILE_SIZE, 0);						for (int x = 0; x < SCREEN_WIDTH / TILE_SIZE; x++)			{								tile_distance = sqrt(pow(link_x - x,2) + pow(link_y - y, 2));				tile_distance = static_cast<double>((max_distance - tile_distance));				tile_light    = ((tile_distance * 1.0) / (max_distance * 1.0));								glTranslatef(TILE_SIZE, 0, 0);				glColor3f(tile_light, tile_light, tile_light);								//glCallList(lists);								// Draw the data - the index pointer of 0 = use the GL_ELEMENT_ARRAY_BUFFER VBO.				glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, 0);							}						glPopMatrix();					}				glEnableClientState(GL_TEXTURE_COORD_ARRAY);		glDisableClientState(GL_VERTEX_ARRAY);
Quote:Original post by feti
Ok guys, this is what I've got, and it's going through my loop but it's not rendering the tiles. I know the loop works and the translations, cause when I comment out the vertex buffer data and go back to my glCallList() it renders great.

Oops. It looks like you copied my mistake in the code snippet I posted.

glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, 0);

should be

glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, 0);

because your grass_indicies are GLubyte.
Ahhh, there we go. Thanks guys. I switched my tiles and my character to VBOs and got an instant 30 to 35 more fps per second. Guess there is a slight improvement. Appreciate the help.

Now, because I'll be doing an RPG where I need to load map in increments so I can do smooth scrolling, is there any sort of VBO memory limitations on the graphics card that I have to think about? Should I create VBO's and cache the id's and remove those of unused objects and such?

I figure if I'm loading the map and mvoing around and an object goes out of site, it's probably safe to remove the VBO data from the graphics card, and then when the object comes back into sight I can load it back up.

Or is this something I shouldn't be worried about?

This topic is closed to new replies.

Advertisement