2017-09-27 30 views
0

这个问题是特定于WebGL,并假定VAOs不可用。WebGL - 当我调用bindBuffer和vertexAttribPointer?

我试图通过限制低层次的状态变化的数量做出了3D引擎的一些小的改进。但事实证明,我是一个有点困惑使用bindBuffervertexAttribPointer的正确方法。

比方说,我要画两个对象:

  • 的第一个对象使用两个缓冲区一个ç与元素缓冲è;
  • 第二对象使用缓冲器Ç用相同的要素缓冲器ë

缓冲器使用相同的布局,并且两者都通过引用的位置0,而Ç由位置引用1.

最初,ARRAY_BUFFER_BINDING点到零而ELEMENT_ARRAY_BUFFER_BINDINGE

冗余检验器输出具有(ÇÈ)=(3,6,5,2)执行以下操作:

WebGL Inspector trace

这意味着即:

  1. bindBuffer(ELEMENT_ARRAY_BUFFER, [Buffer 2])是不必要的
  2. vertexAttribPointer(1, 2, FLOAT, false, 0, 0)可能已经避免

由于WebGL的可直接ELEMENT_ARRAY_BUFFER_BINDING知道索引存储在何处,1。对我来说很有意义。

但是,2.意味着缓冲器布局存储内部的VBO,这是错误的,因为缓冲不会被视为冗余上线15和30(几个帧被渲染的已,所以他们应该保持自己的状态)

我觉得我很困惑如何drawElements知道使用什么缓冲何处/何时缓冲布局存储

什么是bindBuffervertexAttribPointer这个例子的情况下,为什么最佳使用?

回答

0

其实我想通过简单地看看redundancy checker的来源找出来。

有2件知道重要的事情:

  • 缓冲区布局必然每个位置而不是每个VBO。
  • 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)不需要了,因为我们没有做任何事的。)