OpenGL 4.5如何绑定VBO



  OpenGL 4.3 的更新中,使用 glVertexAttribFormat 和 glBindVertexBuffer 取代 glVertexAttribPointer 来将 VBO 绑定到 VAO。由于老是忘记写法,故记录下来。本文使用 OpenGL 4.5 新增的 DSA 函数,最后会贴出与 4.3 函数的关系表,它们是一一对应的。

glVertexAttribPointer 的缺陷

  glVertexAttribPointer 函数有两个缺陷
  第一个缺陷是它依赖于 GL_ARRAY_BUFFER 的内容。调用 glVertexAttribPointer 前,必须绑定 vbo,然后将特定被绑定 vbo 的索引、格式信息复制到 vao 中。这是一种非常笨拙的方式,因为这样 vao 和特定 vbo 处于绑死的关系,一旦对这个特定 vbo 有任何修改,都要重新绑定 vbo 的信息到 vao 中(根据实现有所不同),这一点上很容易产生 bug,云风的博客也说明过这个问题。
  不仅如此,glVertexAttribPointer 最后一个参数使用指针而不是整数来表示偏移量。使用时都要加一个丑陋的转换,相信很多人都碰到过下述的写法。

  第二个缺点是它将逻辑上分离的两个操作合在一起:获取数据、组织数据。这也带来性能的浪费。如果只要改变组织数据的方式,比如改变偏移量,也必须一次性指定 buffer 信息和组织格式;切换绑定的 buffer 也是如此。
  话虽如此,即使在写 OpenGL 4.5 程序的时候,这两个操作几乎是永远伴随在一起的(大笑)。这也是早期定义 glVertexAttribPointer 的原因,更先进的 OpenGL 将它们区分开,给予程序员选择的自由。
  

获取数据

  OpenGL 4.5 可以使用 glVertexArrayVertexBuffer 来将 vbo 绑定到 vao 独有的绑定点,与 ubo 的绑定点相似,但相互不干扰。然后使用 glVertexArrayAttribBinding 将 glsl 中的 attrib 变量绑定到同一个绑定点即可。

组织数据

  glVertexArrayAttribFormat 被用来指定 attrib 的组织形式。它是绑定到 attrib 上的,而不是 bindingindex 上。

  比如,对于下面的例子,位置、颜色和纹理坐标存储在一个 vbo 中。

  就可以使用下面的方式组织数据。

  

比较

  既然上述函数是拆分后的结果,就可以用新函数来表示老函数,如下所示。

附:函数对照表

OpenGL 4.5 OpenGL 4.3
glVertexArrayVertexBuffer glBindVertexBuffer
glVertexArrayAttribBinding glVertexAttribBinding
glVertexArrayAttribFormat glVertexAttribFormat


About the Author

说点什么

avatar