function main() {
// Get A WebGL context
var canvas = document.getElementById("canvas");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
program = twgl.createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
gl.useProgram(program);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
// lookup uniforms
var colorLocation = gl.getUniformLocation(program, "u_color");
var matrixLocation = gl.getUniformLocation(program, "u_matrix");
// Create a buffer.
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
// Set Geometry.
setGeometry(gl);
// Set a random color.
gl.uniform4f(colorLocation, Math.random(), Math.random(), Math.random(), 1);
var translation = [100, 150];
var angleInRadians = 0;
var scale = [1, 1];
// Draw the scene.
function drawScene() {
angleInRadians += 0.01;
// Clear the canvas.
gl.clear(gl.COLOR_BUFFER_BIT);
// Compute the matrices
var projectionMatrix = make2DProjection(canvas.width, canvas.height);
var x2 = 130;
var x3 = 130;
var y2 = 30;
var y3 = 150;
var rotatePointX = (x2 + x3) / 2;
var rotatePointY = (y2 + y3) / 2;
var moveToRotationPointMatrix = makeTranslation(-rotatePointX, -rotatePointY);
var rotationMatrix = makeRotation(angleInRadians);
var moveBackMatrix = makeTranslation(rotatePointX, rotatePointY);
// Multiply the matrices.
var matrix = matrixMultiply(moveToRotationPointMatrix, rotationMatrix);
matrix = matrixMultiply(matrix, moveBackMatrix);
matrix = matrixMultiply(matrix, projectionMatrix);
// Set the matrix.
gl.uniformMatrix3fv(matrixLocation, false, matrix);
// Draw the geometry.
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(drawScene);
}
drawScene();
}
function make2DProjection(width, height) {
// Note: This matrix flips the Y axis so 0 is at the top.
return [
2 / width, 0, 0,
0, -2 / height, 0,
-1, 1, 1
];
}
function makeTranslation(tx, ty) {
return [
1, 0, 0,
0, 1, 0,
tx, ty, 1
];
}
function makeRotation(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c,-s, 0,
s, c, 0,
0, 0, 1
];
}
function makeScale(sx, sy) {
return [
sx, 0, 0,
0, sy, 0,
0, 0, 1
];
}
function matrixMultiply(a, b) {
var a00 = a[0*3+0];
var a01 = a[0*3+1];
var a02 = a[0*3+2];
var a10 = a[1*3+0];
var a11 = a[1*3+1];
var a12 = a[1*3+2];
var a20 = a[2*3+0];
var a21 = a[2*3+1];
var a22 = a[2*3+2];
var b00 = b[0*3+0];
var b01 = b[0*3+1];
var b02 = b[0*3+2];
var b10 = b[1*3+0];
var b11 = b[1*3+1];
var b12 = b[1*3+2];
var b20 = b[2*3+0];
var b21 = b[2*3+1];
var b22 = b[2*3+2];
return [a00 * b00 + a01 * b10 + a02 * b20,
a00 * b01 + a01 * b11 + a02 * b21,
a00 * b02 + a01 * b12 + a02 * b22,
a10 * b00 + a11 * b10 + a12 * b20,
a10 * b01 + a11 * b11 + a12 * b21,
a10 * b02 + a11 * b12 + a12 * b22,
a20 * b00 + a21 * b10 + a22 * b20,
a20 * b01 + a21 * b11 + a22 * b21,
a20 * b02 + a21 * b12 + a22 * b22];
}
// Fill the buffer with the values that make a rect.
function setGeometry(gl) {
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
10, 30,
130, 30,
10, 150,
10, 150,
130, 30,
130, 150]),
gl.STATIC_DRAW);
}
main();
canvas {
border: 1px solid black;
}
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
uniform mat3 u_matrix;
void main() {
// Multiply the position by the matrix.
gl_Position = vec4((u_matrix * vec3(a_position, 1)).xy, 0, 1);
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
</script>
<canvas id="canvas" width="400" height="300"></canvas>