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 。