WebGL 中的 VBO 和 EBO 状态
VBO and EBO state in WebGL
在 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 中缺少它。
如果没有 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 具有 VAOs as an extension which is available on most devices and there's a polyfill,您可以使用它来让它看起来无处不在,所以如果您习惯使用 VAO,我建议您使用 polyfill。
How does an EBO will know from which buffer to take the data?
EBO 不从缓冲区获取数据,它们只是指定索引。属性从缓冲区中获取数据。当您调用 vertexAttribPointer
时,属性会记录当前的 ARRAY_BUFFER
绑定。也就是说
gl.bindBuffer(ARRAY_BUFFER, bufferA);
gl.vertexAttribPointer(positionLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferB);
gl.vertexAttribPointer(normalLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferC);
gl.vertexAttribPointer(texcoordLocation, ...);
在这种情况下,位置将来自缓冲区 A,法线来自缓冲区 B,纹理坐标来自缓冲区 C。有或没有 VAO 都是一样的。 VAO 和无 VAO 之间的区别在于属性状态(和 EBO 绑定)是全局的还是每个 VAO。
在 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 中缺少它。
如果没有 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 具有 VAOs as an extension which is available on most devices and there's a polyfill,您可以使用它来让它看起来无处不在,所以如果您习惯使用 VAO,我建议您使用 polyfill。
How does an EBO will know from which buffer to take the data?
EBO 不从缓冲区获取数据,它们只是指定索引。属性从缓冲区中获取数据。当您调用 vertexAttribPointer
时,属性会记录当前的 ARRAY_BUFFER
绑定。也就是说
gl.bindBuffer(ARRAY_BUFFER, bufferA);
gl.vertexAttribPointer(positionLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferB);
gl.vertexAttribPointer(normalLocation, ...);
gl.bindBuffer(ARRAY_BUFFER, bufferC);
gl.vertexAttribPointer(texcoordLocation, ...);
在这种情况下,位置将来自缓冲区 A,法线来自缓冲区 B,纹理坐标来自缓冲区 C。有或没有 VAO 都是一样的。 VAO 和无 VAO 之间的区别在于属性状态(和 EBO 绑定)是全局的还是每个 VAO。