WebGL 中的 VBO 和 EBO 状态

VBO and EBO state in WebGL

提问人:ibe 提问时间:8/15/2016 最后编辑:gmanibe 更新时间:9/15/2017 访问量:2527

问:

在 WebGL 中,要使用索引缓冲区绘制一些东西,你会经历这个例程(正如 MDN 所暗示的那样):

设置:

bindBuffer(ARRAY_BUFFER);
bufferData(pass vertex data);
bindBuffer(ELEMENT_ARRAY_BUFFER);
bufferData(pass index data);

绘图:

bindBuffer(ELEMENT_ARRAY_BUFFER);
glDrawElements(...);

没有电话。bindBuffer(ARRAY_BUFFER)

假设我有多个带有顶点数据的 VBO。EBO 如何知道从哪个缓冲区获取数据?

在标准 OpenGL 中,我会将其封装在 VAO 中。但是 WebGL 中缺少它让我感到困惑。

网络GL的

评论


答:

5赞 gman 8/15/2016 #1

如果没有 VAO,您的典型路径是这样的

设置:

create programs and lookup attribute and uniform locations
create buffers
create texture

绘图:

for each model
  for each attribute
    bindBuffer(ARRAY_BUFFER, model's buffer for attribute)
    vertexAttribPointer(...)
  bindBuffer(ELEMENT_ARRAY_BUFFER, model's ebo)
  set uniforms and bind textures 
  glDrawElements

使用 VAO 时,这更改为

设置:

create programs and lookup attribute and uniform locations
create buffers
create texture

for each model 
  create and bind VAO
    for each attribute
      bindBuffer(ARRAY_BUFFER, model's buffer for attribute)
      vertexAttribPointer(...)
    bindBuffer(ELEMENT_ARRAY_BUFFER, model's ebo)

绘图:

for each model
  bindVertexArray(model's VAO)
  set uniforms and bind textures 
  glDrawElements

顺便说一句:WebGL 1 将 VAO 作为扩展,在大多数设备上都可用,并且您可以使用一个 polyfill 来使其看起来无处不在,所以如果您习惯使用 VAO,我建议使用 polyfill。

EBO 如何知道从哪个缓冲区获取数据?

EBO 不从缓冲区获取数据,它们只指定索引。属性从缓冲区获取数据。属性在调用 时记录当前绑定。换句话说ARRAY_BUFFERvertexAttribPointer

gl.bindBuffer(ARRAY_BUFFER, bufferA);
gl.vertexAttribPointer(positionLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferB);
gl.vertexAttribPointer(normalLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferC);
gl.vertexAttribPointer(texcoordLocation, ...);

在这种情况下,仓位将来自 bufferA,法线来自 bufferB,texcoords 来自 bufferC。无论有没有 VAO,这都是一样的。VAO 和无 VAO 之间的区别在于属性状态(和 EBO 绑定)是全局的还是每个 VAO。