我希望通过设置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.bindBuffer
和gl.bufferData
的调用工作正常。但是,gl.drawArrays
始终只使用buff1
中的数据进行渲染。我假设gl.drawArrays
将使用当前绑定到gl.ARRAY_BUFFER
的VBO进行渲染,但显然情况并非如此。
有人看到我失踪的东西吗?
答案 0 :(得分:1)
此处的问题是您已将buff1
和buff2
绑定到同一缓冲区vertArray
。
更好的做法是创建两个顶点数组(例如,vertArray1
和vertArray2
)和
在初始设置期间将每个顶点数组绑定到单独的缓冲区对象(而不是每个帧,因为
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.vertexAttribPointer
和gl.enableVertexAttribArray
来调查顶点属性数据(存储为vertArray
中的交错数据) ,而不仅仅是在安装过程中。否则,您的顶点属性指针将始终引用第一个VBO中的数据,并且VBO现在将仅由于双缓冲而每隔一帧更新一次。现在必须在切换VBO之后和gl.vertexAttribPointer
之前调用gl.enableVertexAttribArray
和gl.drawArrays
。