我正在参与一个webgl项目.当我调用gl.DrawElements时,会显示错误'范围超出缓冲区'.
我当然确保我通过了正确的缓冲区长度或偏移量.但是,仍然出现错误.
我认为有几个原因可能会引起错误.因此,我想问你的项目是否有同样的问题,你检查了什么来解决这个问题?
gma*_*man 14
调用时只有3个原因导致错误 gl.drawElements
您的索引引用的顶点超出了缓冲区的范围
例如,您创建一个缓冲区并在其中放置3个位置值
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
var data = [1,2,3,4,5,6,7,8,9]; // 3 (3 value) positions
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)
由于只有3个位置,唯一可能的索引是0,1和2.所以如果你在索引缓冲区中放入任何其他值,你将得到该错误.
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
var indices = [0,1,3]; // ERROR! That 3 is out of range
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// This will generate an out of bounds error because
// the 3 index we put in the index buffer is out of range
// as the only valid indices are 0, 1, and 2.
gl.drawElements(gl.TRIANGLE, 3, gl.UNSIGNED_SHORT, 0);
Run Code Online (Sandbox Code Playgroud)您试图绘制太多索引或将偏移量设置为超出范围
如果您这样做,请考虑上面的设置
gl.drawElements(gl.TRIANGLE, 4, gl.UNSIGNED_SHORT, 0);
Run Code Online (Sandbox Code Playgroud)
你已经超出了范围,因为你只输了3个指数,但你要求绘制4.同样如果你改变了偏移量
gl.drawElements(gl.TRIANGLE, 3, gl.UNSIGNED_SHORT, 1);
Run Code Online (Sandbox Code Playgroud)
你再次只放了3个索引但你要求它绘制索引1,2和3而不是0,1和2.
您可以设置属性以访问过多数据
我们假设我们将三个3个值位置放在上面.如果我们将属性设置为拉出三个4值位置,就像这样
var size = 4; // ERROR! There are only 3 value per position
gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0);
Run Code Online (Sandbox Code Playgroud)
该设置将尝试访问12个浮点数据(假设您的索引正确),但您只放入9个浮点数据.大小应该等于3
如果你设置步幅或偏移量(最后两个参数为gl.vertexAtrribPointer错误的值),你可能同样陷入困境.几乎所有的WebGL程序总是使用0,0.如果你正在做一些更奇特的事情,请确保你正确设置它们.
您可能没有将数组作为正确的类型传递。人们很容易忘记将顶点或索引从一般的 Javascript 数组转换为显式类型的数组。
例如(改编自 gman 的第一个示例):
var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
var data = [1,2,3, 4,5,6, 7,8,9, 10,11,12]; // 4 3-D positions
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
// ^^^^^^^^^^^^^^^^
// Failure to explicitly construct a typed array here can give this WebGL error,
// if you bind this array to an attribute:
// GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 0
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buf);
var indices = [3,2,1];
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// ^^^^^^^^^^^^^^^
// Failure to explicitly construct a typed array here gives this WebGL error:
// GL_INVALID_OPERATION : glDrawElements: range out of bounds for buffer
gl.drawElements(gl.TRIANGLE, 3, gl.UNSIGNED_SHORT, 0);
Run Code Online (Sandbox Code Playgroud)
在 Javascript 中,每个数字值默认表示为 Number 类型的对象,它是一个 IEEE 64 位浮点数。因此,例如,数组的第一个元素indices,3由以下 64 位表示:
0000 0000 0001 1000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
如果将常规 Javascript 数组传递到元素数组缓冲区中,那么当gl.drawElements()要求将缓冲区解释为无符号短整型(16 位整数)时,它会将前 64 位视为 4 组 16 位,并读出以下内容价值观:
0000 0000 0001 1000 = 24
0000 0000 0000 0000 = 0
0000 0000 0000 0000 = 0
0000 0000 0000 0000 = 0
Run Code Online (Sandbox Code Playgroud)
当然,24 超出了我们的 4 元素顶点位置数组缓冲区的范围。
| 归档时间: |
|
| 查看次数: |
6653 次 |
| 最近记录: |