使用glVertexAttribBinding将单个顶点属性关联多个VBO的技术疑问
OpenGL VAO多VBO绑定问题解答
首先给出问题中的顶点结构体与核心代码:
struct Vertex { glm::vec3 position; glm::vec3 normal; glm::vec3 color; };
VBO绑定代码:
glVertexArrayVertexBuffer(vao, 0, vbo1, 0, sizeof(Vertex)); glVertexArrayVertexBuffer(vao, 1, vbo2, 0, sizeof(Vertex));
属性绑定代码:
// Position glVertexArrayAttribBinding(vao, 0, 0); glVertexArrayAttribBinding(vao, 0, 1); // Normal glVertexArrayAttribBinding(vao, 1, 0); glVertexArrayAttribBinding(vao, 1, 1); // Color glVertexArrayAttribBinding(vao, 2, 0); glVertexArrayAttribBinding(vao, 2, 1);
问题解答
两个VBO不会同时作为数据源,第一个会被第二个替换
glVertexArrayAttribBinding的作用是将顶点属性索引与VAO的绑定索引关联,且每个属性索引只能绑定到一个绑定索引。后续对同一属性的绑定调用会直接覆盖之前的设置:比如属性0最后关联的是绑定索引1(对应vbo2),属性1、2同理。最终整个VAO只会从vbo2读取顶点数据,vbo1的绑定会被完全忽略。不存在两个VBO顶点拼接的顺序
因为最终仅使用vbo2作为数据源,顶点顺序就是vbo2内部的交错存储顺序(VNCVNC...),和vbo1没有任何关系。这种方式不能实现批渲染
批渲染的核心是一次Draw调用绘制多个网格,而此方法每个属性只能绑定一个VBO,无法同时读取多个VBO的数据。正确的批渲染方式通常是:- 将多个网格的顶点数据合并到同一个VBO中,通过
glDrawArrays的first/count参数,或glDrawElements的indices偏移来分别绘制不同网格; - 若网格结构相同,可使用实例化渲染(
glDrawArraysInstanced等),通过实例属性传递不同网格的偏移、变换等数据; - 若网格结构不同,可切换VAO(VAO切换开销极低)来依次绘制,而非试图将多个VBO绑定到同一VAO的同一属性。
- 将多个网格的顶点数据合并到同一个VBO中,通过
内容的提问来源于stack exchange,提问作者Geraldo Christiano
相关产品推荐
相关产品推荐

