Shader Coordinates - Fl-Matrix
Demo
by David Komer
HTML
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-type-identifiers/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-type-classes/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-def/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary/master/index.js"></script>
<script src="https://unpkg.com/fl-matrix/dist/fl-matrix.browser-production.js"></script>
<canvas id="canvas"></canvas>
CSS
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#canvas {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
JavaScript
//Globals
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
updateCanvasSize();
//Config
const QUAD_WIDTH = 200;
const QUAD_HEIGHT = 200;
const QUAD_COLOR = [1.0, 0, 0, 1.0];
const LIMIT_X = canvas.clientWidth - QUAD_WIDTH;
const LIMIT_Y = canvas.clientHeight - QUAD_HEIGHT;
const S = window.sanctuary.create({
checkTypes: false,
env: window.sanctuary.env
});
const velocity = FlMatrix.vectorFromElements([100,100]);
//Screen projection transform - using "setValueAtPosition" for illustrative purposes here
//There's several other approaches that are more efficient, but since this is just created once it's no biggie
const projectionMatrix = FlMatrix.identityMatrix (3) (3)
.setValueAtPosition (0) (0) (2/canvas.clientWidth)
.setValueAtPosition (1) (1) (2/canvas.clientHeight)
.setValueAtPosition (2) (0) (-1)
.setValueAtPosition (2) (1) (-1);
//The cool thing is that this drives the whole transformation pipeline.
//We could chain one matrix after another via compose() or S.compose :)
const getTransformMatrix = S.compose(projectionMatrix); //projectionMatrix.compose would also work
const status = S.chain(program => {
//set vertex data
const vertices = makeBuffer(program, "a_Vertex");
vertices.write(new Float32Array([
0, QUAD_HEIGHT, // top-left
0, 0, //bottom-left
QUAD_WIDTH, QUAD_HEIGHT, // top-right
QUAD_WIDTH, 0 // bottom-right
]));
//set uniforms - requires resetting the program pointer first
gl.useProgram(program);
//set color
const colorLocation = gl.getUniformLocation(program, "u_Color");
gl.uniform4fv(colorLocation, QUAD_COLOR);
//prepare object matrix for transformations
let objectMatrix = FlMatrix.identityMatrix (3) (3);
//deltaTime calculator
let lastNow;
const updatePosition = (m) => (deltaTime) =>
m.mapElements(el => {
if(el.column === 2) {
if(el.row === 0) {
const x =...