【问题标题】:Questions about the second parameter of glBufferData in webgl关于webgl中glBufferData第二个参数的问题
【发布时间】:2019-01-26 09:40:19
【问题描述】:

我一直在阅读著名的 webgl 教程 https://webgl2fundamentals.org/webgl 并学习如何使用 bufferData 将数据放入缓冲区。本教程以这种形式广泛使用bufferData

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

这里的第二个参数是我们要发送到 GPU 缓冲区的实际数组或数据。但是,我今天遇到了 API 的这种新用法。

gl.bufferData(gl.ARRAY_BUFFER, 8*maxNumVertices, gl.STATIC_DRAW);

这里的第二个参数表示缓冲区的大小。

所以我对此感到困惑。我在 MDN https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData 上查看了这个 API,上面写着

// WebGL1: 
void gl.bufferData(target, size, usage); 
void gl.bufferData(target, ArrayBuffer? srcData, usage); 
void gl.bufferData(target, ArrayBufferView srcData, usage); 

// WebGL2: 
void gl.bufferData(target, ArrayBufferView srcData, usage, srcOffset, length);

这是否意味着对于 webgl1.0,我们可以将实际的数据数组或缓冲区的大小作为第二个参数传递给 API。但是对于 WebGL2.0,我们只能将实际的数据数组传递给 API?

我还不清楚这一点。请帮忙。

【问题讨论】:

    标签: graphics webgl webgl2


    【解决方案1】:

    WebGL2 添加到 WebGL1 api,因此 WebGL2 有 4 个版本的 gl.bufferData,来自 WebGL1 的 3 个和一个新版本。

    他们是

    按大小设置

    void gl.bufferData(target, size, usage); 
    

    设置为无类型 ArrayBuffer

    void gl.bufferData(target, ArrayBuffer? srcData, usage); 
    

    使用ArrayBufferView 设置,例如Uint8ArrayFloat32Array 和其他数组缓冲区视图类型。

    void gl.bufferData(target, ArrayBufferView srcData, usage);

    使用带有偏移量和长度的ArrayBufferView 设置

    // WebGL2: 
    void gl.bufferData(target, ArrayBufferView srcData, usage, srcOffset, length);
    

    最后一个可以说是为 WebAssembly 添加的。问题是如果您有很大的ArrayBufferView 并且只想上传一部分,您必须在覆盖您要上传的部分的同一缓冲区上创建一个新的ArrayBufferView。即使在同一个ArrayBuffer 上的ArrayBufferView 相对便宜,仍然有一个视图分配,最终将不得不进行垃圾收集。添加新版本的gl.bufferData 可以消除该问题。您不必为了上传ArrayBuffer 的一部分而创建一个临时的ArrayBufferView

    【讨论】:

    • 感谢您的回复。第二版和第三版我不是很懂。 ArrayBufferViewArrayBuffer 有什么区别。它们都是包含真实数据的数组吗?此外,如果我将数字作为大小传递给bufferData API,它如何知道我的意思是大小而不是任何其他可接受的参数,例如ArrayBufferViewArrayBuffer?
    • 对于 ArrayBufferArrayBufferView 参见 this answer。目前它知道,如果你想在 JS 中编写类似的函数,你可以这样做 function doSomething(dataOrSize) { if (typeof dataOrSize === 'number') { // use as a size } else if (dataOrSize instanceof ArrayBuffer) { // use as ArrayBuffer } else { // use as ArrayBufferView }}
    • 使用无类型的 ArrayBuffer? srcData,第二个arg是可选的,只能用两个args(target,usage)调用?这是为什么呢?
    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2020-12-10
    • 2018-03-22
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    相关资源
    最近更新 更多