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 调用之前指定顶点。
我对 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 调用之前指定顶点。