如何在WebGL中实现VBO双缓冲?

时间:2015-04-10 15:17:00

标签: webgl

我希望通过设置VBO双缓冲来提高WebGL项目的性能。虽然有很多关于这个主题的文章,但我没有找到一个带有编码示例的文章。

我尝试了以下内容:

// Initial setup...

var buff1 = gl.createBuffer();
var buff2 = gl.createBuffer();
var buffActive = buff1;

// For each frame, change the verticies data and then ...

gl.bindBuffer(gl.ARRAY_BUFFER, buffActive);
gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.DYNAMIC_DRAW);
gl.drawArrays(gl.TRIANGLES, start, count);

buffActive = (buffActive === buff2) ? buff1 : buff2;

gl.bindBuffergl.bufferData的调用工作正常。但是,gl.drawArrays始终只使用buff1中的数据进行渲染。我假设gl.drawArrays将使用当前绑定到gl.ARRAY_BUFFER的VBO进行渲染,但显然情况并非如此。

有人看到我失踪的东西吗?

2 个答案:

答案 0 :(得分:1)

此处的问题是您已将buff1buff2绑定到同一缓冲区vertArray。 更好的做法是创建两个顶点数组(例如,vertArray1vertArray2)和 在初始设置期间将每个顶点数组绑定到单独的缓冲区对象(而不是每个帧,因为 bufferData()销毁并重新初始化缓冲区对象的数据,这些数据可能是 昂贵的操作,如果这样做需要将数据上传到GPU)。

以下是一个例子:

// Initial setup
var buff1 = gl.createBuffer();
var buff2 = gl.createBuffer();
// Associate the buffer data once during initial setup.
// Note that we use two vertex arrays, vertArray1 and vertArray2,
// rather than one
gl.bindBuffer(gl.ARRAY_BUFFER, buff1);
gl.bufferData(gl.ARRAY_BUFFER, vertArray1, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, buff2);
gl.bufferData(gl.ARRAY_BUFFER, vertArray2, gl.DYNAMIC_DRAW);
var buffActive = buff1;
var vertArrayActive = vertArray1;

// For each frame:
gl.bindBuffer(gl.ARRAY_BUFFER, buffActive);
// No need to re-load the buffer data
gl.drawArrays(gl.TRIANGLES, start, count);
buffActive = (buffActive === buff2) ? Buff1 : buff2;
vertArrayActive = (vertArrayActive === vertArray2) ? VertArray1 : vertArray2;

答案 1 :(得分:0)

如果您实施VBO双缓冲,那么您需要确保每次VBO切换时都会调用gl.vertexAttribPointergl.enableVertexAttribArray来调查顶点属性数据(存储为vertArray中的交错数据) ,而不仅仅是在安装过程中。否则,您的顶点属性指针将始终引用第一个VBO中的数据,并且VBO现在将仅由于双缓冲而每隔一帧更新一次。现在必须在切换VBO之后和gl.vertexAttribPointer之前调用gl.enableVertexAttribArraygl.drawArrays