• Advertisement
Sign in to follow this  

Linux and Vertex Buffer Objects

This topic is 3734 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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().

Share this post


Link to post
Share on other sites
A more explicit example following on from your code:

// Creating and populating the VBOs

glGenBuffers(2, grass_vbo_ids); // 0 for verticies, 1 for indicies

glBindBuffer(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 buffer
glBindBuffer(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 0
glVertexPointer(3, GL_FLOAT, 0, 0);

glEnableClientState(GL_VERTEX_ARRAY);

// Bind the index buffer
glBindBuffer(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);


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement