1/51
Looks like no tags are added yet.
An OpenGL feature that provides methods for uploading vertex data to the video device for rendering
Vertex Buffer Objects
Provides substantial performance as data resides in the video device memory rather than the system memory
Vertex Buffer Objects
To convert an OpenGL program to use Vertex Buffer Objects include additional preprocessor directives:
#include <GL/glew.h> //New GLEW header fileGlew Initialization
int main(int argc, char** argv){
glutInit(&argc, argv);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("simple");
glutDisplayFunc(display);
GLenum err = glewInit(); // <------- Include glew initialization calls before the main loop
if (err == GLEW_OK) {
glutMainLoop();
}
}Initialize the vertices of your model using an array, using our original example we convert it this way (Creating a VBO)
//1. Initialize the triangle using an array
GLfloat trianglevertices[] = {
0.0f, .75f, 0.0f,
-0.75f, 0.0f, 0.0f,
0.75f, 0.0f, 0.0f
};Generate a Vertex Buffer Object ID for your array of vertices and bind it (Creating a VBO)
Using glGenBuffers(), glBindBuffer(), and glBufferData()
//2. Generate a Vertex Buffer Object ID for your array of vertices and bind it
GLuint VBOid;
glGenBuffers(1, &VBOid);
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_STATIC_DRAW);Applications use buffer objects to store vertex data in server memory
glGenBuffers()
void glGenBuffers(GLsizei n, GLuint* buffers);
GLboolean glIsBuffer(GLuint buffer);
glGenBuffers()
glGenBuffers() obtains n buffer identifiers from its pool of unused buffers. n is the number of buffer identifiers desired by the application. glGenBuffers() stores the identifiers in buffers.
glIsBuffer() returns GL_TRUE if buffer is an existing buffer object.
glGenBuffers()
__ obtains n buffer identifiers from its pool of unused buffers. n is the number of buffer identifiers desired by the application. __ stores the identifiers in buffers.
glGenBuffers()
Obtains n buffer identifiers from its pool of unused buffers
glGenBuffers()
__ is the number of buffer identifiers desired by the application
n
Stores the identifiers in buffers
glGenBuffers()
Returns GL_TRUE if buffer is an existing buffer object
glIsBuffer()
glGenBuffers() OpenGL version:
1.5 and later
glGenBuffers() (Creating a VBO)
glGenBuffers(1, &VBOid);void glBindBuffer(GLenum target, GLuint buffer);
glBindBuffer()
Specifies the active buffer object and initializes it if it’s new. Pass a target value ofGL_ARRAY_BUFFER to use the buffer object as vertex array data, and pass a target value ofGL_ELEMENT_ARRAY_BUFFER to use the buffer object as vertex array indices. buffer is the identifier of the buffer object to bind.
glBindBuffer()
Specifies the active buffer object and initializes it if it’s new
glBindBuffer()
Specifies the active buffer object and initializes it if it’s new. Pass a target value of
__ to use the buffer object as vertex array data, and pass a target value of
__ to use the buffer object as vertex array indices. buffer is the identifier of the buffer object to bind.
GL_ARRAY_BUFFER
GL_ELEMENT_ARRAY_BUFFER
glBindBuffer() OpenGL version:
1.5 and later
glBindBuffer() (Creating a VBO)
glBindBuffer(GL_ARRAY_BUFFER, VBOid);Uploads all the array information to the graphics card memory
glBufferData()
glBufferData() (Creating a VBO)
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_STATIC_DRAW);glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_STATIC_DRAW);
Size of our data
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_STATIC_DRAW);
Array to be copied
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_STATIC_DRAW);
Can be:
GL_STREAM_DRAW - The data store contents will be modified once and used at most a few times.
GL_STATIC_DRAW - The data store contents will be modified once and used many times.
GL_DYNAMIC_DRAW - The data store contents will be modified repeatedly and used many times.
The data store contents will be modified once and used at most a few times
GL_STREAM_DRAW
The data store contents will be modified once and used many times
GL_STATIC_DRAW
The data store contents will be modified repeatedly and used many times
GL_DYNAMIC_DRAW
Activate the Vertex Array (Creating a VBO)
//3. Activate and specify pointer to vertex array
glEnableClientState(GL_VERTEX_ARRAY);Since it is on the video cards main memory already we can now render the model (Creating a VBO)
//4. Draw the primitive object
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);Once rendered we can now set the application to normal operation to free up resources (Creating a VBO)
//5. Disable client side capability for normal operation
glDisableClientState(GL_VERTEX_ARRAY);
// bind with 0, so, switch back to normal pointer operation
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &VBOid);What if we have normal arrays like indices for drawElements()
It’s the same we bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state
void triangle() {
//1. Initialize the triangle using an array
GLfloat trianglevertices[] = {
0.0f, .75f, 0.0f,
-0.75f, 0.0f, 0.0f,
0.75f, 0.0f, 0.0f,
-0.75f, -0.75f, 0.0f,
0.0f, 0.0f, 0.0f,
0.75f, -0.75f, 0.0f
};
GLubyte indices[] = {
0,1,2,
3,4,5
};
//2. Generate a Vertex Object ID for your array of vertices and normal arrays and bind it
GLuint VBOid;
glGenBuffers(1, &VBOid);
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*18, trianglevertices, GL_STATIC_DRAW);Binding a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
GLuint VBOindex;
glGenBuffers(1, &VBOindex);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBOindex);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte)*6, indices, GL_STATIC_DRAW);Bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
//3. Activate and specify pointer to vertex array
glEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_NORMAL_ARRAY);
Bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
//4. Draw the primitive object
glVertexPointer(3, GL_FLOAT, 0, 0);glNormalPointer(GL_UNSIGNED_BYTE,0, 0);
Bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
//5.
//glDrawArrays(GL_TRIANGLES,0,6);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
glDisableClientState(GL_VERTEX_ARRAY);glDisableClientState(GL_NORMAL_ARRAY);
Bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
// bind with 0, so, switch back to normal pointer operation
glBindBuffer(GL_ARRAY_BUFFER, 0);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &VBOid);glDeleteBuffers(1, &VBOindex);
}
Bind a VBO for GL_ELEMENT_ARRAY_BUFFER and enable GL_NORMAL_ARRAY client state (Sample Code)
What if we needed to change the vertex data inside the video card’s memory
glMapBuffer()
Map the buffer object into the client’s memory (application)
glMapBuffer()
Syntax: void* glMapBuffer(GLenum target, GLenum access)
glMapBuffer()
Synchronization issue of glMapBuffer()
If GPU is still working with the buffer object, glMapBuffer() will not return until GPU finishes its job
If GPU is still working with the buffer object, __ will not return until GPU finishes its job
glMapBuffer()
After modifying the data of VBO, it must be unmapped the buffer object from the client's memory
Syntax: GLboolean glUnmapBuffer(GLenum target);
#define GLEW_STATIC // <----- define GLEW_STATIC
#include <iostream>
#include <GL/glew.h> // <---- additional header files
#include <GL/glut.h>define GLEW_STATIC
additional header files
void monitorKeyboard(unsigned char key, int x, int y) {
if (key == 27){ //ESC
// Disable client side capability for normal operation
glDisableClientState(GL_VERTEX_ARRAY);
// bind with 0, so, switch back to normal pointer operation
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &VBOid);
exit(0);
}
}If escape was pressed, switch back to normal pointer operation and delete the memory used in the server’s (video card) memory
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glColor4f(.16f,.72f,.08f,1.0f);
triangle();
glFlush();
glutTimerFunc(1000,modifyTriangle,0);
}Display callback
void modifyTriangle(int value) {
triangleUpdate = true;
//Map the array from the server memory (video card) to the local variable
mappedVertices = (GLfloat *) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
mappedVertices[0]+=.01f;
mappedVertices[3]+=.01f;
mappedVertices[6]+=.01f; glUnmapBuffer(GL_ARRAY_BUFFER);
glutPostRedisplay();
}Map the array from the server memory (video card) to the local variable
void triangle() {
if (!triangleUpdate) {
//1. Initialize the triangle using an array
GLfloat trianglevertices[] = {
0.0f, .75f, 0.0f,
-0.75f, 0.0f, 0.0f,
0.75f, 0.0f, 0.0f
};
//2. Generate a Vertex Object ID for your array of vertices and bind it
glGenBuffers(1, &VBOid);
glBindBuffer(GL_ARRAY_BUFFER, VBOid);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9, trianglevertices, GL_DYNAMIC_DRAW);Changing the vertex data inside the video card’s memory (Sample Code)
//3. Activate and specify pointer to vertex array
glEnableClientState(GL_VERTEX_ARRAY);
//4. Draw the primitive object
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES,0,3);
}else {
//When for update just draw the primitive object
glVertexPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_TRIANGLES,0,3);
}
}Changing the vertex data inside the video card’s memory (Sample Code)