首页 > 解决方案 > (WebGL)如何将顶点添加到已经初始化的顶点缓冲区?

问题描述

我正在关注 WebGL 教程。我有一个初始化的顶点缓冲区,缓冲区数据的用途设置为gl.STATIC_DRAW. 据我从描述使用的 MDN 文档中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);

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

我有使用 as 的想法gl.DYNAMIC_DRAW,正如他们在 MDN 文档中所述:

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

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

先感谢您。

标签: javascriptgraphicswebgl

解决方案


你有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是一个提示。驱动程序可能会或可能不会对这个提示做任何有用的事情。

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

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

PS:您可能会发现这些教程很有帮助。


推荐阅读