我正在关注WebGL教程。我有一个初始化的顶点缓冲区,其缓冲区数据的用途设置为gl.STATIC_DRAW。据我从MDN's documentation which describes usage中读取的内容,如果我的顶点数据是使用gl.STATIC_DRAW
在整个应用程序中不会改变。正如他们所说:


  内容旨在由应用程序指定一次,并多次用作WebGL绘图和图像规范命令的源。


我目前有这段代码来初始化我的顶点缓冲区:

const vertices = new Float32Array([
  -1.0, 1.0,   -1.0, -1.0,   1.0, 1.0,   1.0, -1.0
]);
const n = 4;

const vertexBuffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const aPosition = gl.getAttribLocation(program, 'aPosition');

gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition);


我想更改此缓冲区的内容,例如添加要绘制的新顶点坐标。我不想重新初始化整个顶点缓冲区,因为我认为这样做不会在性能方面很好。

我有将用法用作gl.DYNAMIC_DRAW的想法,正如MDN文档中所述:


  内容旨在由应用程序重复指定,并多次用作WebGL绘图和图像指定命令的源。


但是,如果我使用此值作为用法,如何为当前缓冲区提供新顶点并重绘?我找不到任何显示此内容的示例。

先感谢您。

最佳答案

您有2个选择


调用gl.bufferData并将新数据传递给它

这将重新分配缓冲区并将数据复制到
调用gl.bufferSubData,可以将数据复制到缓冲区的一部分。

在这种情况下,您将首先调用gl.bufferData分配缓冲区,然后调用gl.bufferSubData来更新数据。如果要使用更多或更少的数据,可以通过将不同的计数传递给gl.drawArrays来处理该数据,请对gl.drawElements等使用不同的索引...

例:

const maxSizeInBytes = 100;
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
// allocate a buffer with 100 bytes
gl.bufferData(gl.ARRAY_BUFFER, maxSizeInBytes, gl.DYNAMIC_DRAW);


然后再

gl.bindBuffer(gl.ARRAY_BUFFER, buf);
const data = new Float32Array([123, 456, 789]);
const offsetInBytes = 20;
// update bytes 20 to 31 of the buffer
gl.bufferSubData(gl.ARRAY_BUFFER, offsetInBytes, data);



请注意,gl.bufferData末尾的值是一个提示。驱动程序可能对该提示不做任何有用的事情。

我还要补充一点,最常见的用例是缓冲区数据永远不会更新。而是为每个要绘制的事物(“树”,“房子”,“人”,“三角形”,“正方形”,“圆形”,“星形”)创建一个或多个不同的缓冲区,然后切换缓冲区以绘制不同的缓冲区的东西。

我并不是说您不应该更改缓冲区的内容。只是您说您是WebGL的新手,所以我想我会说,大多数应用程序并不会改变缓冲区的内容,即使是那些执行此操作的应用程序,大多数情况下也是例外。

PS:您可能会发现these tutorials有帮助。

08-06 02:32
查看更多