此问题特定于WebGL,并假设VAO不可用。
我试图通过限制低级别状态更改的数量来对3D引擎进行一些改进。但事实证明我对使用bindBuffer
和vertexAttribPointer
的正确方法感到困惑。
假设我想绘制2个对象:
缓冲区 A 和 B 使用相同的布局,并且都由位置0引用,而 C 由位置1引用。
最初,ARRAY_BUFFER_BINDING
指向null,而ELEMENT_ARRAY_BUFFER_BINDING
指向 E 。
冗余检查器输出以下内容( A , B , C , E )=(3 ,6,5,2):
这意味着:
bindBuffer(ELEMENT_ARRAY_BUFFER, [Buffer 2])
是不必要的vertexAttribPointer(1, 2, FLOAT, false, 0, 0)
可以避免由于WebGL可以直接阅读ELEMENT_ARRAY_BUFFER_BINDING
以了解索引的存储位置,1。对我来说很有意义。
然而,2。暗示缓冲区布局存储在内部 VBO中,这是错误的,因为看不到缓冲区 A 和 B 在第15和30行是多余的。(已经渲染了几个帧,因此它们应该保持其状态)
我认为我对drawElements
如何知道使用什么缓冲区和何时/何时存储缓冲区布局感到困惑。
此示例案例中bindBuffer
和vertexAttribPointer
的最佳用途是什么?为什么?
答案 0 :(得分:0)
实际上,我想通过简单地查看redundancy checker的来源就可以找到答案。
有两件重要的事情要知道:
vertexAttribPointer
也将当前缓冲区分配给指定位置在内部,WebGL每个位置保留6个参数:
VERTEX_ATTRIB_ARRAY_SIZE_X
VERTEX_ATTRIB_ARRAY_TYPE_X
VERTEX_ATTRIB_ARRAY_NORMALIZED_X
VERTEX_ATTRIB_ARRAY_STRIDE_X
VERTEX_ATTRIB_ARRAY_POINTER_X
VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_X
以下是vertexAttribPointer
的作用:
function vertexAttribPointer(indx, size, type, normalized, stride, offset) {
this.stateCache["VERTEX_ATTRIB_ARRAY_SIZE_" + indx] = size;
this.stateCache["VERTEX_ATTRIB_ARRAY_TYPE_" + indx] = type;
this.stateCache["VERTEX_ATTRIB_ARRAY_NORMALIZED_" + indx] = normalized;
this.stateCache["VERTEX_ATTRIB_ARRAY_STRIDE_" + indx] = stride;
this.stateCache["VERTEX_ATTRIB_ARRAY_POINTER_" + indx] = offset;
this.stateCache["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_" + indx] = this.stateCache["ARRAY_BUFFER_BINDING"];
}
最后,WebGL Inspector是真的!状态更改第15行和第30行是必要的,因为VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_0
正在发生变化。
这是最佳追踪:
bindBuffer(ARRAY_BUFFER, A)
vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
bindBuffer(ARRAY_BUFFER, B)
vertexAttribPointer(0, 3, FLOAT, false, 0, 0)
drawElements(TRIANGLES, 768, UNSIGNED_BYTE, 0)
(不再需要bindBuffer(ARRAY_BUFFER, C)
,因为我们没有对它做任何事情。)