var vsThatUses2Attributes = `
attribute vec4 position;
attribute vec2 texcoord;
varying vec2 v_texcoord;
void main() {
v_texcoord = texcoord;
gl_Position = position;
}
`;
var vsThatUses1Attribute = `
attribute vec4 position;
varying vec2 v_texcoord;
void main() {
v_texcoord = position.xy * 0.5 + 0.5;
gl_Position = position + vec4(1, 0, 0, 0);
}
`;
var fs = `
precision mediump float;
varying vec2 v_texcoord;
void main () {
gl_FragColor = vec4(v_texcoord, v_texcoord.x * v_texcoord.y, 1);
}
`;
var gl = document.querySelector("canvas").getContext("webgl");
document.body.appendChild(gl.canvas);
var programThatUses2Attributes = twgl.createProgramFromSources(gl, [vsThatUses2Attributes, fs]);
var programThatUses1Attribute = twgl.createProgramFromSources(gl, [vsThatUses1Attribute, fs]);
var positionLocation2AttribProg = gl.getAttribLocation(programThatUses2Attributes, "position");
var texcoordLocation2AttribProg = gl.getAttribLocation(programThatUses2Attributes, "texcoord");
var positionLocation1AttribProg = gl.getAttribLocation(programThatUses1Attribute, "position");
var positionBufferFor2AttribPrg = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBufferFor2AttribPrg);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1,
-.5, 1,
0, -1,
]), gl.STATIC_DRAW);
var texcoordBufferFor2AttribPrg = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBufferFor2AttribPrg);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0,
0.5, 1,
1, 0,
]), gl.STATIC_DRAW);
var positionBufferFor1AttribPrg = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBufferFor1AttribPrg);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1,
0, -1,
-1, 1,
-1, 1,
0, -1,
0, 1,
]), gl.STATIC_DRAW);
// turn on 2 attributes
gl.enableVertexAttribArray(positionLocation2AttribProg);
gl.enableVertexAttribArray(texcoordLocation2AttribProg);
gl.bindBuffer(gl.ARRAY_BUFFER, positionBufferFor2AttribPrg);
gl.vertexAttribPointer(positionLocation2AttribProg, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBufferFor2AttribPrg);
gl.vertexAttribPointer(texcoordLocation2AttribProg, 2, gl.FLOAT, false, 0, 0);
// draw with 2 attributes enabled
gl.useProgram(programThatUses2Attributes);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// setup for second program that uses only 1 attribute
gl.bindBuffer(gl.ARRAY_BUFFER, positionBufferFor1AttribPrg);
gl.vertexAttribPointer(positionLocation1AttribProg, 2, gl.FLOAT, false, 0, 0);
// NOTICE WE HAVE !NOT turned off other attribute
gl.useProgram(programThatUses1Attribute);
gl.drawArrays(gl.TRIANGLES, 0, 6);
log("glError:", gl.getError());
function log() {
var pre = document.createElement("pre");
pre.appendChild(document.createTextNode(Array.prototype.join.call(arguments, " ")));
document.body.appendChild(pre);
}
canvas { border: 1px solid black; }
<script src="https://twgljs.org/dist/twgl.min.js"></script>
<pre>
This example draws a triangle with 3 vertices using 2 attributes.
It then draws a quad using 6 vertices and 1 attribute
<b>WITHOUT TURNING OFF THE NOW 2nd UNUSED ATTRIBUTE</b>.
That means not only is that attribute left on but it only has 3 vertices even
though the draw will use 6 vertices. Because that attribute is not 'comsumed' by
the current program it's ok according to the spec.
</pre>
<canvas width="150" height="30"></canvas>