gpt4 book ai didi

javascript - 如何将gl.drawElements "find"对应的顶点数组缓冲?

转载 作者:行者123 更新时间:2023-11-29 23:31:21 25 4
gpt4 key购买 nike

提前谢谢你。

我是 Webgl 的新手,我不太了解 drawElements 方法和我要绘制的当前顶点缓冲区之间的联系。我大致了解 drawArray 方法发生了什么(例如创建缓冲区,将其绑定(bind)到上下文,用数据填充它,指向相应的属性,绘制它)。但是当我尝试对索引数组和较少的顶点数据执行相同操作时,我遇到了这种类型的错误:

[.Offscreen-For-WebGL-0x7fae2b940800]GL ERROR :GL_INVALID_OPERATION : glDrawElements: bound to target 0x8893 : no buffer

也许我的代码提示可以帮助您。

    const cube = new Program(renderer.gl, vertex3d, fragment); // my webgl program
const cubeData = new Cube(); // Only array of vertices/indices
const cubeVertexPosition = new ArrayBuffer(renderer.gl, cubeData.vertices, 'STATIC_DRAW'); // ARRAY_BUFFER
const cubeVertexIndices = new IndexBuffer(renderer.gl, renderer.gl.UNSIGNED_SHORT, cubeData.indices, 'STATIC_DRAW'); // ELEMENT_ARRAY_BUFFER
cubeVertexPosition.attribute('aPosition', 3, 'FLOAT', false); // define attribute corresponding in vertex shader
cubeVertexPosition.attributePointer(cube); // enableVertexAttribArray + vertexAttribPointer
[...]
cubeVertexIndices.draw('TRIANGLES', 0, 36); // drawElements with gl.UNSIGNED_SHORT type

我成功地用 drawArray 绘制了它:)

([...] 只是制服的矩阵变换);

也许你有一个快速提示可以帮助我理解这个黑魔法,

非常感谢!

最佳答案

drawArray 仅使用一个或多个 ARRAY_BUFFER 从中绘制顶点,以便它们在缓冲区中,来自 first 参数 count 参数。

drawElements 使用一个或多个 ARRAY_BUFFER AND 一个包含指向 ARRAY_BUFFER 的索引的 ELEMENT_ARRAY_BUFFER 要绘制的顶点。在 drawElements 中,count 参数指定要在 ELEMENT_ARRAY_BUFFER 中读取的索引数,而 offset 指定偏移量以字节为单位从哪里开始读取 ELEMENT_ARRAY_BUFFER(通常是 FirstIndex*sizeof(type),其中 type 可以是 UNSIGNED_BYTE (1 个字节)、UNSIGNED_SHORT(2 个字节)或 UNSIGNED_INT(4 个字节)。

ELEMENT_ARRAY_BUFFER:

[0][1][2][1][2][0][1][2][3][3][1][2][3][4][5][...

ARRAY_BUFFER:

|   0   |   1    |    2   |    3   |    4   | ...
[x][y][z][x][y][z][x][y][z][x][y][z][x][y][z][...

要正常工作,offset + count*sizeof(type) 不应大于 ELEMENT_ARRAY_BUFFER 字节大小。此外,ELEMENT_ARRAY_BUFFER 中的元素索引应小于 ARRAY_BUFFER 中包含的顶点数。

drawArray 一样,drawElements 将当前绑定(bind)的缓冲区(配置了属性指针)作为数据源。 drawElements 的不同之处在于,您必须使用 ELEMENT_ARRAY_BUFFER 目标指定一个额外的元素(索引)缓冲区,如下所示:

gl.bindBuffer(gl.ARRAY_BUFFER, myVerticesA);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, myIndicesA);
// configure attributes pointers here
gl.drawElements(gl.TRIANGLES, 12345, gl.UNSIGNED_SHORT, 0);

drawElements 将根据存储在 ELEMENT_ARRAY_BUFFER 中的索引获取 ARRAY_BUFFER 缓冲区中的属性,具体取决于您如何配置属性指针。

假设以下顶点缓冲区具有交错的位置、法线和纹理坐标:

|    p0    ||    n0    ||  t0  ||    p1    ||    n1    ||  t1  |
[px][py][pz][nx][ny][nz][tu][tv][px][py][pz][nx][ny][nz][tu][tv][...

我们定义属性指针如下:

let stride = 8*4;  // 8*float (8 * 4 bytes)
let offp = 0; // positions at beginning
let offn = 3*4; // normals after 3*float position.
let offt = 6*4; // tex coords after 3*float position + 3*float normal
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, stride, offp);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, stride, offn);
gl.vertexAttribPointer(2, 2, gl.FLOAT, false, stride, offt);

使用元素(索引)缓冲区,GL 将根据存储在 ELEMENT_ARRAY_BUFFER 缓冲区中的索引简单地移动指针位置:

 // pseudo-code
for(let i = start_elem; i < start_elem+count_elem; i++) {

let index = ELEMENT_ARRAY_BUFFER[i];

attrib[0] = ARRAY_BUFFER[(index*stride)+offp];
attrib[1] = ARRAY_BUFFER[(index*stride)+offn];
attrib[2] = ARRAY_BUFFER[(index*stride)+offt];

}

关于javascript - 如何将gl.drawElements "find"对应的顶点数组缓冲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47232671/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com