Jinyu Li a personal journal

VAO 和 VBO

OpenGL 中有两个对象一直傻傻分不清楚,一个叫 VertexArrayObject (VAO) ,另一个叫 VertexBufferObject (VBO) 。

在现代的绘制管线中,一般要把顶点数据整块传递给图形硬件,而不是采用老旧的逐条命令指定顶点数据的方式。这种方式下,我们会建立一块内存来存储顶点数据,然后将它传递给一个 VertexBufferObject 。也就是说 VBO 做的是下面的事情(伪代码):

Vertex vertices[n_vertices]; // VBO

而将若干个 VBO 的信息集合在一起,方便在绘制时一次性调用的,则是 VAO 。例如可以在 VAO 中预先将顶点位置、法向等 VBO 分别绑定好。用伪代码表示就是:

struct Geometries {
    Vertex *vertices;
    Normal *normals;
    // …
};
Geometries g; // VAO
g.vertices = vertices; // bind VBO to VAO (via glVertexAttribPointer)

可以发现,VBO 表示的是具体的数据,VAO 则是这些数据对象的集合容器。类似的,Texture/RenderBuffer 是具体的数据,FBO 则是若干 Texture/RenderBuffer 的集合。如这篇文章1 中介绍的,OpenGL 对这两类对象进行了划分,表示具体数据的可以称为 Regular Objects,而代表 Regular Objects 集合的则对应 Container Objects 。