(WebGL) 如何将顶点添加到已初始化的顶点缓冲区?

(WebGL) How to add vertices to an already initialized vertex buffer?

我正在学习 WebGL 教程。我有一个初始化的顶点缓冲区,缓冲区数据的用途设置为 gl.STATIC_DRAW。据我所读 MDN's documentation which describes usage,如果我的顶点数据使用 gl.STATIC_DRAW 在整个应用程序中没有变化。正如他们所说:

The contents are intended to be specified once by the application, and used many times as the source for WebGL drawing and image specification commands.

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

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 文档中所述:

The contents are intended to be respecified repeatedly by the application, and used many times as the source for WebGL drawing and image specification commands.

但是如果我使用这个值作为我的用法,我将如何为当前缓冲区提供新的顶点并重绘?我找不到任何示例来说明这一点。

提前致谢。

您有 2 个选择

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

    这会重新分配缓冲区并将您的数据复制到

  2. 调用 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 末尾的值是 提示 。驱动程序可能会或可能不会对该提示做任何有用的事情。

我还要补充一点,最常见的用例是缓冲区数据永远不会更新。而是为每个要绘制的东西创建一个或多个缓冲区,"tree"、"house"、"person"、"triangle"、"square"、"circle", "star" 然后切换缓冲区来绘制不同的东西。

我并不是说您不应该更改缓冲区的内容。只是你说你是 WebGL 的新手所以我想我会传递大多数应用程序不会改变缓冲区的内容,即使是那些改变缓冲区内容的应用程序通常也是他们绘制的大多数东西的例外。

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