multiple webgl squares
uses webgl to paint multiple squares in one drawArrays() pass. Also, this demonstrates that the order of the rectangles put in the buffer matters.
by Lucas Thomas
HTML
<script src="http://greggman.github.com/webgl-fundamentals/webgl/resources/webgl-utils.js"></script>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
attribute vec4 a_color;
varying vec4 v_color;
uniform vec2 u_resolution;
void main() {
vec2 zeroToOne = a_position / u_resolution; // convert the rectangle from pixels to 0.0 to 1.0
vec2 zeroToTwo = zeroToOne * 2.0; // convert from 0->1 to 0->2
vec2 clipSpace = zeroToTwo - 1.0; // convert from 0->2 to -1->+1 (clipspace)
gl_Position = vec4(clipSpace, 0, 1);
v_color = a_color;
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
</script>
<canvas id="canvas" width="128" height="128"></canvas>
CSS
canvas {
border: 2px solid black;
width: 128px;
height: 128px;
}
JavaScript
function startGameLoop() {
//first draw 10 rectangles to show that the canvas does not clear each time.
var rectangleBufferBuilder = [];
var colorBufferBuilder = [];
for(var i =0; i < 10; i++) {
rectangleBufferBuilder.push({
x:i*10,//Math.round(Math.random()*100),
y:i*10,//Math.round(Math.random()*100),
width:20,
height:20
});
}
setRectangles(gl, rectangleBufferBuilder);
for(var i =0; i < 10; i++) {
colorBufferBuilder.push({
r:Math.random(),
g:Math.random(),
b:Math.random()
});
}
setColors(gl, colorBufferBuilder);
gl.drawArrays(gl.TRIANGLES, 0, rectangleBufferBuilder.length*6);
}
setRectangles = function(gl, rectangles){
gl.bindBuffer(gl.ARRAY_BUFFER, bufferRectangles);
var bufferBuilder = [];
for(var i = 0; i < rectangles.length; i++){
var rectangle = rectangles[i];
var x1 = rectangle.x;
var x2 = rectangle.x + rectangle.width;
var y1 = rectangle.y;
var y2 = rectangle.y + rectangle.height;
bufferBuilder.push(
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
);
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(bufferBuilder), gl.STATIC_DRAW);
}
setColors = function(gl, colors){
gl.bindBuffer(gl.ARRAY_BUFFER, bufferColors);
var bufferBuilder = [];
for(var i = 0; i < colors.length; i++){
var color = colors[i];
bufferBuilder.push(
color.r, color.g, color.b, 1,
color.r, color.g, color.b, 1,
color.r, color.g, color.b, 1,
color.r, color.g, color.b, 1,
color.r, color.g, color.b, 1,
color.r, color.g, color.b, 1
);
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(bufferBuilder), gl.STATIC_DRAW);
}
function initializeShaders() {
// Error Trapping
if (!gl) {
...