|
|
@ -0,0 +1,128 @@ |
|
|
|
'use strict'; |
|
|
|
|
|
|
|
let offsetX, offsetY, size; |
|
|
|
|
|
|
|
const canvas = document.getElementById('canvas'); |
|
|
|
const gl = canvas.getContext("experimental-webgl", {premultipliedAlpha: false}); |
|
|
|
|
|
|
|
gl.enable(gl.BLEND); |
|
|
|
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA); |
|
|
|
|
|
|
|
const quad = [ |
|
|
|
-2, -2, 0, |
|
|
|
-2, 2, 0, |
|
|
|
2, -2, 0, |
|
|
|
2, 2, 0, |
|
|
|
]; |
|
|
|
|
|
|
|
function shaderProgram(gl, vs, fs) { |
|
|
|
let prog = gl.createProgram(); |
|
|
|
let addshader = function(type, source) { |
|
|
|
let s = gl.createShader((type == 'vertex') ? |
|
|
|
gl.VERTEX_SHADER : gl.FRAGMENT_SHADER); |
|
|
|
gl.shaderSource(s, source); |
|
|
|
gl.compileShader(s); |
|
|
|
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) { |
|
|
|
throw "Could not compile "+type+ |
|
|
|
" shader:\n\n"+gl.getShaderInfoLog(s); |
|
|
|
} |
|
|
|
gl.attachShader(prog, s); |
|
|
|
}; |
|
|
|
addshader('vertex', vs); |
|
|
|
addshader('fragment', fs); |
|
|
|
gl.linkProgram(prog); |
|
|
|
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { |
|
|
|
throw "Could not link the shader program!"; |
|
|
|
} |
|
|
|
return prog; |
|
|
|
} |
|
|
|
|
|
|
|
function attributeSetFloats(gl, prog, attr_name, rsize, arr) { |
|
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer()); |
|
|
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(arr), |
|
|
|
gl.STATIC_DRAW); |
|
|
|
let attr = gl.getAttribLocation(prog, attr_name); |
|
|
|
gl.enableVertexAttribArray(attr); |
|
|
|
gl.vertexAttribPointer(attr, rsize, gl.FLOAT, false, 0, 0); |
|
|
|
} |
|
|
|
|
|
|
|
function clear(framebuffer) { |
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
|
|
|
gl.clearColor(0, 0, 0, 0); |
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT); |
|
|
|
} |
|
|
|
|
|
|
|
function render(prog, vertices, framebuffer, numTris, texture) { |
|
|
|
gl.bindTexture(gl.TEXTURE_2D, texture); |
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); |
|
|
|
gl.useProgram(prog); |
|
|
|
gl.uniform1f(gl.getUniformLocation(prog, "time"), [(Date.now() - start) / 1000]); |
|
|
|
gl.uniform2f(gl.getUniformLocation(prog, "resolution"), [canvas.width], [canvas.height]); |
|
|
|
attributeSetFloats(gl, prog, "pos", 3, vertices); |
|
|
|
gl.drawArrays(gl.TRIANGLE_STRIP, 0, numTris); |
|
|
|
} |
|
|
|
|
|
|
|
const progs = [ |
|
|
|
shaderProgram(gl, `
|
|
|
|
uniform mediump float time; |
|
|
|
varying mediump float color; |
|
|
|
attribute vec3 pos; |
|
|
|
void main() { |
|
|
|
gl_Position = vec4(sin(pos.x*(time/32.)), cos(pos.x*(time/32.)), 0.0, 1.2); |
|
|
|
color = pos.x; |
|
|
|
} |
|
|
|
`,` |
|
|
|
uniform mediump float time; |
|
|
|
uniform mediump vec2 resolution; |
|
|
|
varying mediump float color; |
|
|
|
void main() { |
|
|
|
mediump vec2 position = vec2(gl_FragCoord.x, gl_FragCoord.y) / resolution; |
|
|
|
gl_FragColor.r = sin(color); |
|
|
|
gl_FragColor.g = cos(color); |
|
|
|
gl_FragColor.b = 0.7; |
|
|
|
gl_FragColor.a = 0.1; |
|
|
|
} |
|
|
|
`)
|
|
|
|
]; |
|
|
|
|
|
|
|
const zeroes = []; |
|
|
|
for (let i = 0; i < 100; i++) { |
|
|
|
zeroes.push(i); |
|
|
|
} |
|
|
|
|
|
|
|
function draw() { |
|
|
|
requestAnimationFrame(draw); |
|
|
|
|
|
|
|
clear(null); |
|
|
|
//gl.viewport(0, 0, window.innerWidth, window.innerHeight); // background is fullscreen
|
|
|
|
render(progs[0], zeroes, null, 33); |
|
|
|
} |
|
|
|
|
|
|
|
const fbs = []; |
|
|
|
|
|
|
|
function resize() { |
|
|
|
canvas.height = window.innerHeight; |
|
|
|
canvas.width = window.innerWidth; |
|
|
|
for (let fb of fbs) { |
|
|
|
gl.bindTexture(gl.TEXTURE_2D, fb.texture); |
|
|
|
gl.texImage2D( |
|
|
|
gl.TEXTURE_2D, 0, gl.RGBA, canvas.width, canvas.height, 0, |
|
|
|
gl.RGBA, gl.UNSIGNED_BYTE, null); |
|
|
|
} |
|
|
|
if (window.innerHeight > window.innerWidth) { |
|
|
|
offsetX = 0; |
|
|
|
offsetY = (window.innerHeight - window.innerWidth) / 2; |
|
|
|
size = window.innerWidth; |
|
|
|
} else { |
|
|
|
offsetY = 0; |
|
|
|
offsetX = (window.innerWidth - window.innerHeight) / 2; |
|
|
|
size = window.innerHeight; |
|
|
|
} |
|
|
|
gl.viewport(offsetX, offsetY, size, size); // foreground
|
|
|
|
} |
|
|
|
|
|
|
|
window.onresize = resize; |
|
|
|
let start = Date.now(); |
|
|
|
|
|
|
|
resize(); |
|
|
|
draw(); |