var w, h, cw, ch, canvas, ctx, globalTime,webGL;
const NOISE_ALPHA = 0.5;
const NOISE_POWER = 1.2;
const shadersSource = {
VertexShader : {
type : "VERTEX_SHADER",
source : `
attribute vec2 position;
uniform vec2 resolution;
varying vec2 texPos;
void main() {
gl_Position = vec4((position / resolution) * 2.0 - 1.0, 0.0, 1.0);
texPos = gl_Position.xy;
}`
},
FragmentShader : {
type : "FRAGMENT_SHADER",
source : `
precision mediump float;
uniform float time;
varying vec2 texPos;
const float randC1 = 43758.5453;
const vec3 randC2 = vec3(12.9898, 78.233, 151.7182);
float randomF(float seed) {
return pow(fract(sin(dot(gl_FragCoord.xyz + seed, randC2)) * randC1 + seed), ${NOISE_POWER.toFixed(4)});
}
void main() {
gl_FragColor = vec4(vec3(randomF((texPos.x + 1.01) * (texPos.y + 1.01) * time)), ${NOISE_ALPHA});
}`
}
};
var globalTime = performance.now();
resizeCanvas();
startWebGL(ctx);
ctx.font = "64px arial black";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
function webGLRender(){
var gl = webGL.gl;
gl.uniform1f(webGL.locs.timer, globalTime / 100 + 100);
gl.drawArrays(gl.TRIANGLES, 0, 6);
ctx.drawImage(webGL, 0, 0, canvas.width, canvas.height);
}
function display(){
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset transform
ctx.globalAlpha = 1; // reset alpha
ctx.clearRect(0, 0, w, h);
ctx.fillStyle = "red";
ctx.fillText("Hello world "+ (globalTime / 1000).toFixed(1), cw, ch);
webGL && webGLRender();
}
function update(timer){ // Main update loop
globalTime = timer;
display(); // call demo code
requestAnimationFrame(update);
}
requestAnimationFrame(update);
// creates vertex and fragment shaders
function createProgramFromScripts( gl, ids) {
var shaders = [];
for (var i = 0; i < ids.length; i += 1) {
var script = shadersSource[ids[i]];
if (script !== undefined) {
var shader = gl.createShader(gl[script.type]);
gl.shaderSource(shader, script.source);
gl.compileShader(shader);
shaders.push(shader);
}else{
throw new ReferenceError("*** Error: unknown script ID : " + ids[i]);
}
}
var program = gl.createProgram();
shaders.forEach((shader) => { gl.attachShader(program, shader); });
gl.linkProgram(program);
return program;
}
function createCanvas() {
var c,cs;
cs = (c = document.createElement("canvas")).style;
cs.position = "absolute";
cs.top = cs.left = "0px";
cs.zIndex = 1000;
document.body.appendChild(c);
return c;
}
function resizeCanvas() {
if (canvas === undefined) { canvas = createCanvas() }
canvas.width = innerWidth;
canvas.height = innerHeight;
ctx = canvas.getContext("2d");
setGlobals && setGlobals();
}
function setGlobals(){
cw = (w = canvas.width) / 2;
ch = (h = canvas.height) / 2;
}
// setup simple 2D webGL
function startWebGL(ctx) {
webGL = document.createElement("canvas");
webGL.width = ctx.canvas.width;
webGL.height = ctx.canvas.height;
webGL.gl = webGL.getContext("webgl");
var gl = webGL.gl;
var program = createProgramFromScripts(gl, ["VertexShader", "FragmentShader"]);
gl.useProgram(program);
var positionLocation = gl.getAttribLocation(program, "position");
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer());
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0.0, 0.0,1.0, 0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0, 1.0]), gl.STATIC_DRAW);
var resolutionLocation = gl.getUniformLocation(program, "resolution");
webGL.locs = {
timer: gl.getUniformLocation(program, "time"),
};
gl.uniform2f(resolutionLocation, webGL.width, webGL.height);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
setRectangle(gl, 0, 0, ctx.canvas.width, ctx.canvas.height);
}
function setRectangle(gl, x, y, width, height) {
var x1 = x;
var x2 = x + width;
var y1 = y;
var y2 = y + height;
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]), gl.STATIC_DRAW);
}