WebGL:一个程序的顶点属性影响另一个程序

WebGL: One program's vertex attribute influences other program

我对 WebGL 还是个新手,我正在尝试使用 2 个不同的程序制作一个简单的 WebGL 应用程序。在初始化步骤中,当我设置每个形状的顶点属性时,结果发现第二个程序(红色方块)的顶点属性也会影响第一个程序(紫色三角形)。

这是第一个对象(在称为“射手”的代码中)的样子。第二个节目还没有添加:

这是添加第二个程序(“球”)后的样子。

这是我在渲染阶段的代码。 programs 是程序字典,loc 是属性位置字典,buffers 是 WebGL 缓冲区字典。 createProgram 是 returns 来自 GLSL 代码的 WebGL 程序的辅助函数。

    // Shooter ============================
    programs.shooter = createProgram(gl,
        document.getElementById('shooter-vertex').textContent,
        document.getElementById('shooter-fragment').textContent);
    gl.useProgram(programs.shooter);

    loc.shooterVerts = gl.getAttribLocation(programs.shooter, 'aPosition');
    // (...color and uniform attribute stuff)

    buffers.shooterVerts = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffers.shooterVerts);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(geometry.shooter.shape), gl.STATIC_DRAW);
    gl.vertexAttribPointer(loc.shooterVerts, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(loc.shooterVerts);

    // Ball ================================
    programs.ball = createProgram(gl,
        document.getElementById('ball-vertex').textContent,
        document.getElementById('ball-fragment').textContent);
    gl.useProgram(programs.ball);

    loc.ballVerts = gl.getAttribLocation(programs.ball, 'aPosition');
    // (...uniform attributes)

    buffers.ballVerts = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffers.ballVerts);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(geometry.ball.shape), gl.STATIC_DRAW);
    gl.vertexAttribPointer(loc.ballVerts, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(loc.ballVerts);

在渲染阶段:

function render() {
    gl.clear(gl.COLOR_BUFFER_BIT);

    gl.useProgram(programs.shooter);
    // (...set some uniforms)

    gl.bindBuffer(gl.ARRAY_BUFFER, buffers.shooterVerts);
    gl.drawArrays(gl.TRIANGLES, 0, geometry.shooter.shape.length / 2);

    gl.useProgram(programs.ball);
    // (...set another uniforms)
    gl.bindBuffer(gl.ARRAY_BUFFER, buffers.ballVerts);
    gl.drawArrays(gl.TRIANGLE_FAN, 0, geometry.ball.shape.length / 2);

    requestAnimationFrame(render);
}

如果有人需要,这里是完整的代码:https://codepen.io/PseudoLW/pen/GRrwWeG

绘图调用 (drawArrays) 使用当前顶点规范来绘制对象。缓冲区对象仅存储顶点,但绑定缓冲区对 drawArrays 没有影响。当调用 vertexAttribPointer 时,当前绑定到目标 ARRAY_BUFFER 的缓冲区将关联到指定的顶点属性。因此,在绘制网格之前必须指定顶点属性:

// bind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.shooterVerts);
// specify the vertices and specify to use the current buffer (buffers.shooterVerts)
gl.vertexAttribPointer(loc.shooterVerts, 2, gl.FLOAT, false, 0, 0);
// draw the mesh
gl.drawArrays(gl.TRIANGLES, 0, geometry.shooter.shape.length / 2);
// bind the buffer
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.ballVerts);
// specify the vertices and specify to use the current buffer (buffers.ballVerts)
gl.vertexAttribPointer(loc.ballVerts, 2, gl.FLOAT, false, 0, 0);
// draw the mesh
gl.drawArrays(gl.TRIANGLE_FAN, 0, geometry.ball.shape.length / 2);

在 WebGL 2.0 中,顶点规范可以存储在顶点数组对象中,但在 WebGL 1.0 中,必须在 Draw 调用之前指定顶点。