VBO的定义
VBO,全称Vertex Buffer Object,中文名叫顶点缓冲区对象,是位于显卡中的一块内存区,这个内存区存放的是顶点相关的数据,比如坐标、颜色、法向量等。
相关概念
Buffer Object,缓冲区对象,即显卡中的一块内存区。
这个内存区可以存放不同的东西,当存放顶点相关的数据时,就是上面的顶点缓冲区对象VBO。
当这个内存区存放Uniform变量的时候,就叫统一缓冲区对象(Uniform buffer object), 简称UBO。
这个内存区还可以存放像素数据(例如,纹理贴图或像素块),那就叫Pixel Buffer Object ? PBO ?
实际内存 和 显卡内存
实际内存
在写程序时,实际内存的使用很简单,比如下面这样的:
int *a = new int[2];
a[0] = 1;
a[1] = 2;
delete []a;
这里,先是开辟内存,然后通过数组首地址指针a和数组下标操作符[],给数组赋值,这样很轻松的访问到了内存。
显卡内存
而显卡的内存,却不是通过指针来访问的,而是通过一个ID号来访问。如下所示:
GLfloat vertices[] = {
-1.0, -1.0,
1.0, -1.0,
0.0, 1.0};
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glDeleteBuffers(1, &vertexBuffer);
上面代码,在显卡中开辟了一个内存块,内存块用vertexBuffer标识,然后将vertices这个数组中的数据,存放到vertexBuffer对应的显卡内存块中。
具体例子
下面的例子,是将三角形的三个顶点的坐标值,存放到显卡中,然后使用显卡中的数据渲染出三角形。
#include <gl/glew.h>
#include <gl/freeglut.h>
GLfloat vertices[] = {
-1.0, -1.0,
1.0, -1.0,
0.0, 1.0
};
GLuint vertexBuffer;
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexPointer(2, GL_FLOAT, 0, 0);
glEnable(GL_VERTEX_ARRAY);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2, 2, -2, 2, -2, 2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("vbo");
if (glewInit())
{
return -1;
}
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
上述代码中,主要分成三步:
一、 在显卡中开辟一块内存区,并将顶点坐标拷贝到该内存区中。
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
二、 告诉OpenGL如何解析内存中的数据。
glVertexPointer(2, GL_FLOAT, 0, 0);
glEnable(GL_VERTEX_ARRAY);
三、 告诉OpenGL,使用刚才的那个内存区,绘制一个三角形。
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glDrawArrays(GL_TRIANGLES, 0, 3);