我正在关注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有帮助。