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;

应该修复它。