如何调整 WebGlBuffer 的大小?

How to resize a WebGlBuffer?

我正在编写一些 WebGL 代码,其中一部分是处理 WebGlBuffer 的实例以保存顶点属性。

我不知道(先验)缓冲区必须保存的数据量,因此 WebGlBuffer 会随着更多三角形添加到场景中而增长,例如:

/// Init the WebGlBuffer
var buff = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, buff);
gl.bufferData(gl.ARRAY_BUFFER, 1024, this._gl.DYNAMIC_DRAW);

/// Push data for some triangles
gl.bufferSubData(gl.ARRAY_BUFFER,   0, new Float32Array( dataForVertex0 ));
gl.bufferSubData(gl.ARRAY_BUFFER, 128, new Float32Array( dataForVertex1 ));
gl.bufferSubData(gl.ARRAY_BUFFER, 256, new Float32Array( dataForVertex2 ));


/// A few seconds later, room for more triangles is needed

gl.bindBuffer(gl.ARRAY_BUFFER, buff);
gl.bufferData(gl.ARRAY_BUFFER, 2048, this._gl.DYNAMIC_DRAW);

/// ... so I can keep adding data for more triangles
gl.bufferSubData(gl.ARRAY_BUFFER, 1024, new Float32Array( dataForVertex0 ));
gl.bufferSubData(gl.ARRAY_BUFFER, 1152, new Float32Array( dataForVertex1 ));
gl.bufferSubData(gl.ARRAY_BUFFER, 1280, new Float32Array( dataForVertex2 ));

我的问题是每次调用 gl.bufferData() 都会用零覆盖 WebGlBuffer 的当前内容。 bufferSubData 不会自动调整缓冲区大小,而是触发缓冲区溢出警告。

据我所知,操作 WebGlBuffer 内容的唯一方法是 bufferDatabufferSubData.

出于性能原因,我想避免将 ArrayBuffer 与数据副本一起保存(因为缓冲区将使用大量内存)。

有什么方法可以(有效地)调整 WebGlBuffer 实例的大小,或者将较小的 WebGlBuffer 的内容复制到更大的 WebGlBuffer 中?我是否遗漏了 WebGL 的任何功能 API,或者我必须回去保留重复数据?

不,不幸的是,WebGL 缺乏这样的能力。如果你想调整缓冲区的大小,你会丢失它的内容,没有办法解决这个问题。您所能做的就是尝试预先分配足够的 space 以供将来使用。在我的项目中,我这样做并且还保留缓冲区内容的副本以应对可能的 "out of memory" 情况(它也有助于批处理缓冲区更新)。但是我的几何数据比较少

WebGL2 也有 copyBufferSubData 调用。