WebGL:glDrawElements 超出顶点边界
WebGL: glDrawElements exceeding vertex bounds
我在 WebGL 中构建了一个二维网格。它有 5 列和 24 行。我的网格中的每个 "cell" 都是四个顶点和六个索引:
所以对于每个单元格,我做:
var addCell = function(x, y, w, h, colorArray) {
len = vertices.length;
vertices.push(x, y, zIndex);
vertices.push(x, y - h, zIndex);
vertices.push(x + w, y - h, zIndex);
vertices.push(x + w, y, zIndex);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
indices.push(len, len + 1, len + 2);
indices.push(len, len + 2, len + 3);
}
其中 x 和 y 是单元格的坐标,"colors" 是指定 rgba 的四元素数组。所以我从左到右创建第一行,然后是第二行,依此类推。当我创建索引缓冲区时,我会:
indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
当我画场景时,我说:
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);
当我这样做时,它只呈现前 12 3/4 行(共 24 行)。这是因为每个单元格有 4 个顶点(相邻单元格不共享顶点)。所以前 12+ 行包含:
12.75 * 5 * 4 = 255 <- GL_UNSIGNED_BYTE.
的最大值
所以对我来说,这是一个显而易见的结果,因为我选择了类型。我自然而然地认为解决方案是更改为 gl.UNSIGNED_SHORT 并将我创建的缓冲区更改为:
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
但是这会导致 "glDrawElements: attempt to access out of range vertices in attribute 0"。
我盯着我的 index/vertex-building 代码看了一会儿,想看看我是否添加了一个指向不存在的顶点元素的索引。我没有发现该代码有任何问题,这让我认为它与我选择的 type 有关。任何方向将不胜感激。
UNSIGNED_SHORT
你走在正确的轨道上。 See this answer 关于您收到的新错误的含义:存在引用不存在的顶点的索引。
这是因为您的 len
已关闭。每个索引引用一个顶点,每个顶点由 3 个值组成。所以索引 0 引用前 3 个值,索引 1 引用第二个 3,等等
改变
len = vertices.length;
至
len = vertices.length / 3;
应该修复它。
我在 WebGL 中构建了一个二维网格。它有 5 列和 24 行。我的网格中的每个 "cell" 都是四个顶点和六个索引:
所以对于每个单元格,我做:
var addCell = function(x, y, w, h, colorArray) {
len = vertices.length;
vertices.push(x, y, zIndex);
vertices.push(x, y - h, zIndex);
vertices.push(x + w, y - h, zIndex);
vertices.push(x + w, y, zIndex);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
Array.prototype.push.apply(colors, colorArray);
indices.push(len, len + 1, len + 2);
indices.push(len, len + 2, len + 3);
}
其中 x 和 y 是单元格的坐标,"colors" 是指定 rgba 的四元素数组。所以我从左到右创建第一行,然后是第二行,依此类推。当我创建索引缓冲区时,我会:
indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
当我画场景时,我说:
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);
当我这样做时,它只呈现前 12 3/4 行(共 24 行)。这是因为每个单元格有 4 个顶点(相邻单元格不共享顶点)。所以前 12+ 行包含: 12.75 * 5 * 4 = 255 <- GL_UNSIGNED_BYTE.
的最大值所以对我来说,这是一个显而易见的结果,因为我选择了类型。我自然而然地认为解决方案是更改为 gl.UNSIGNED_SHORT 并将我创建的缓冲区更改为:
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
但是这会导致 "glDrawElements: attempt to access out of range vertices in attribute 0"。
我盯着我的 index/vertex-building 代码看了一会儿,想看看我是否添加了一个指向不存在的顶点元素的索引。我没有发现该代码有任何问题,这让我认为它与我选择的 type 有关。任何方向将不胜感激。
UNSIGNED_SHORT
你走在正确的轨道上。 See this answer 关于您收到的新错误的含义:存在引用不存在的顶点的索引。
这是因为您的 len
已关闭。每个索引引用一个顶点,每个顶点由 3 个值组成。所以索引 0 引用前 3 个值,索引 1 引用第二个 3,等等
改变
len = vertices.length;
至
len = vertices.length / 3;
应该修复它。