Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript WebGL:优化更改值的顶点缓冲区&;每帧顶点计数_Javascript_Opengl Es 2.0_Webgl - Fatal编程技术网

Javascript WebGL:优化更改值的顶点缓冲区&;每帧顶点计数

Javascript WebGL:优化更改值的顶点缓冲区&;每帧顶点计数,javascript,opengl-es-2.0,webgl,Javascript,Opengl Es 2.0,Webgl,我想实现一个带有顶点缓冲区的渲染器,它将在应用程序端每帧更新一次。此外,每个帧的顶点数(即三角形数)也将发生变化 我的方法是将所需的最大值作为Float32Array预先分配一次,然后只更新更改的值,并使用bufferSubData更新缓冲区数据。然后通过从索引缓冲区发送一个范围来绘制我想要的 作为一个最小的例子,假设我为Float32Array中的两个独立三角形分配了位置顶点,对于这个帧,我只想移动并绘制第二个三角形。我想我会: arrPos[9] += 1.0; // move the X

我想实现一个带有顶点缓冲区的渲染器,它将在应用程序端每帧更新一次。此外,每个帧的顶点数(即三角形数)也将发生变化

我的方法是将所需的最大值作为Float32Array预先分配一次,然后只更新更改的值,并使用bufferSubData更新缓冲区数据。然后通过从索引缓冲区发送一个范围来绘制我想要的

作为一个最小的例子,假设我为Float32Array中的两个独立三角形分配了位置顶点,对于这个帧,我只想移动并绘制第二个三角形。我想我会:

arrPos[9] += 1.0; // move the X coordinates in the Float32Array
arrPos[12] += 1.0;
arrPos[15] += 1.0;
gl.bindBuffer(gl.ARRAY_BUFFER, bufPos); // tell GL which buffer to use
gl.bufferSubData( gl.ARRAY_BUFFER, 3 * 3 * 4, arrPos ); // update the vertices - ERROR

// then just draw the 2nd traingle by sending its indices only
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufId); // tell GL which buffer to use
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 3 * 2); // draw just this range
问题是,bufferSubData抛出错误:“GL错误:GL\U无效值:glBufferSubData:超出范围”

我尝试过使用偏移量3、9、12作为缓冲子数据,只是为了见鬼,但它们都给了我相同的错误

另一个注意事项是:如果我能让它工作起来,那么在我看来,如果我想在重新使用这个预先分配的Float32Array时,在每一帧绘制一个可变数量的三角形,我需要更新数组末尾的值,而不是开始的值,因为我只能为bufferSubData指定偏移量,而不是开始索引。我希望有人能告诉我这种方法是否可行,或者我是否完全偏离了轨道,应该停止浪费时间。

好吧,我想我刚刚意识到问题所在。我认为您不能指定一个Float32Array的范围来缓冲子数据;相反,它必须占用整个阵列。(小于缓冲区的Float32Array可用于更新缓冲区的范围。)

换句话说,我认为每次要更新的顶点数量发生变化时都必须创建一个新的Float32Array。这对我来说似乎很不合适,但我想就是这样。在我看来,这种区别应该在OpenGL文档中得到更好的解释

DavidVanBrink建议使用ArrayBufferView创建Float32Array的子数组,从我最初的测试来看,它似乎可以工作。只需执行以下操作即可修复我以前的代码:

arrPos[9] += 1.0; // move the X coordinates in the Float32Array
arrPos[12] += 1.0;
arrPos[15] += 1.0;
var arrView = arrPos.subarray(9); // specify a range of the Float32Array
gl.bindBuffer(gl.ARRAY_BUFFER, bufPos); // tell GL which buffer to use
gl.bufferSubData( gl.ARRAY_BUFFER, 3 * 3 * 4, arrView ); // update the vertices

// then just draw the 2nd traingle by sending its indices only
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufId); // tell GL which buffer to use
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 3 * 2); // draw just this range

最大的问题是
gl.bufferSubData(gl.ARRAY\u BUFFER,3*3*4,arrPos)您将要以偏移量上载整个阵列。这当然太大了。这篇文章已经有好几年的历史了,但它可能会帮助其他人

你可能在找这个:

var offset = 3 * 3 * 4;
var count = 7 * 4;  // x1, y1, z1, x2, y2, z2, x3    (arrPos[9] -> arrPos[15])
gl.bufferSubData(this.gl.ARRAY_BUFFER, offset, arrView, offset, count);

ArrayBufferView可能是这里缺少的技巧吗?我在缓冲区管理方面还不是很流利,但我很确定你可以重用你的缓冲区,并根据你的需要进行部分更新。。。谢谢你的提问,现在我想了解更多!啊哈!是的,这似乎有效!因此,我们可以使用Float32Array.subarray方法选择源数组范围,并使用bufferSubData指定目标替换范围。然后,我们需要创建每个帧的唯一“新”对象是ArrayBufferView。非常感谢,我没有想到要研究类型Darray方法,doh。