代码之家  ›  专栏  ›  技术社区  ›  Thomas_

德国劳埃德船级社。抽屉元素“找到”相应的顶点数组缓冲区?

  •  2
  • Thomas_  · 技术社区  · 7 年前

    提前谢谢你。

    我对Webgl很陌生,我真的不理解drawerelements方法和我想要绘制的当前顶点缓冲区之间的链接。

    [.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绘制了它:)

    谢谢!

    2 回复  |  直到 7 年前
        1
  •  1
  •   user8849929 user8849929    7 年前

    drawArray 仅使用一个或多个 ARRAY_BUFFER 从按顶点在缓冲区中的顺序绘制顶点的位置,从 first 的参数 count 参数

    drawElements 使用一个或多个 ARRAY\u缓冲区 ELEMENT_ARRAY_BUFFER 其中包含指向 ARRAY\u缓冲区 要绘制的顶点。在里面 抽屉元件 这个 计数 参数指定要在 元素数组缓冲区 虽然 offset 元素数组缓冲区 (通常 FirstIndex*sizeof(type) 哪里 type UNSIGNED_BYTE (1字节), UNSIGNED_SHORT (2字节)或 UNSIGNED_INT (4字节)。

    元素数组缓冲区 :

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

    ARRAY\u缓冲区 :

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

    为了正常工作 + count*sizeof(type) 不应大于 元素数组缓冲区 大小(字节)。此外,元素索引 元素数组缓冲区 应小于中包含的顶点数 ARRAY\u缓冲区 .

    喜欢 绘图阵列 这个 抽屉元件 将当前绑定的缓冲区(配置了属性指针)作为数据源。与的区别 您必须使用 元素数组缓冲区 目标,就像这样:

    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);
    

    “如何” 抽屉元件 将在 ARRAY\u缓冲区 元素数组缓冲区 取决于您如何配置属性指针。

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

    |    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将根据存储在 元素数组缓冲区 缓冲区:

     // 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];
    
     }
    
        2
  •  1
  •   gman    7 年前

    您发布的代码不是WebGL。您正在使用一些代码中明确的库。比如 Program , IndexBuffer , ArrayBuffer 都是你正在使用的某个图书馆的一部分。图书馆的工作方式取决于图书馆。

    一般来说,WebGL有着色器,一个顶点着色器,负责设置 gl_Position 到每个顶点的剪辑空间坐标和要设置的片段着色器 gl_FragColor 到每个像素的颜色。

    顶点着色器通常从属性获取有关位置的数据。属性通常从缓冲区获取数据。通过首先将缓冲区绑定到 ARRAY_BUFFER 用绑定点 gl.bindBuffer(gl.ARRAY_BUFFER, someBuffer) 然后打电话 gl.vertexAttribPointer 它告诉WebGL如何从该缓冲区中获取数据(数据类型、每个顶点有多少值、顶点之间要跳过多少字节、缓冲区中要开始的距离)。 德国劳埃德船级社。VertexAttribute指针 保存给定属性的所有信息和对绑定到的当前缓冲区的引用 ARRAY\u缓冲区 绑定点,这样您就可以自由地在那里绑定不同的缓冲区来设置另一个属性。

    当你打电话的时候 gl.drawArrays 当您指定着色器的属性时,数据将从缓冲区中提取,着色器每次迭代的一组值

    至于 gl.drawElements 它需要一个额外的缓冲区,绑定到 ELEMENT_ARRAY_BUFFER 当你cll 你告诉它缓冲区中的数据类型( gl.UNSIGNED_BYTE gl.UNSIGNED_SHORT ). 然后,它使用该缓冲区的值从属性缓冲区中提取值。

    德国劳埃德船级社。抽屉元件 与完全相同 德国劳埃德船级社。绘图阵列 如果在缓冲区中放入一个简单的递增值。实例

     const offset  = 0;
     const numVerts = 100;
    
     // process 100 vertices from the buffers pointed to by the attributes
     // in order 0 to 99
     gl.drawArrays(gl.POINTS, offset, numVerts)
    

    实际上与相同

     // fill a buffer with numbers 0 to 99 (0 to numVerts)
     const numVerts = 100;
     const indexData = new Uint16Array(numVerts);
     for (let i = 0; i < numVerts; ++i) {
       indexData[i] = i;
     }
     const indexBuffer = gl.createBuffer();
     gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
     gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW);
    
     // process 100 vertices from the buffers pointed to by the attributes
     // in order 0 to 99
     const offset  = 0;
     gl.drawElements(gl.POINTS, numVerts, gl.UNSIGNED_SHORT, offset);
    

    我建议读一些其他的 webgl tutorials