User:DiamondIceNS/global.js

(function ($, mw) {   'use strict';

// Code snippets from https://webglfundamentals.org/webgl/lessons/webgl-fundamentals.html

if (mw.config.get('wgPageName') !== 'Aura_Node') { return; }   console.log('Custom JS!');

var vertexShaderSource = 'attribute vec4 aPosition;' + 'uniform mat4 uMatrix;' + 'uniform mat4 uTextureMatrix;' + 'varying vec2 vTexcoord;' + 'void main {' + '   gl_Position = uMatrix * aPosition;' + '   vTexcoord = (uTextureMatrix * aPosition).xy;' + '}';

var fragmentShaderSource = 'precision mediump float;' + 'varying vec2 vTexcoord;' + 'uniform sampler2D uTexture;' + 'uniform vec4 uAspectColor;' + 'void main {' + '   if (vTexcoord.x < 0.0 || vTexcoord.x > 1.0 || vTexcoord.y < 0.0 || vTexcoord.y > 1.0) {' + '       discard;' + '   }'        + '    gl_FragColor = texture2D(uTexture, vTexcoord) * uAspectColor;' + '   if (gl_FragColor.a < 0.003921569) {' + '       /* discard; */' + '   }'        + '}';

var m4 = { identity: function { return [ 1, 0, 0, 0,               0, 1, 0, 0,                0, 0, 1, 0,                0, 0, 0, 1            ];        },        ortho: function(left, right, bottom, top, near, far) { return [ 2 / (right - left), 0, 0, 0, 0, 2 / (top - bottom), 0, 0, 0, 0, 2 / (near - far), 0, (left + right) / (left - right), (bottom + top) / (bottom - top), (near + far) / (near - far), 1           ];        },        multiply: function(a, b) { var b00 = b[0 * 4 + 0]; var b01 = b[0 * 4 + 1]; var b02 = b[0 * 4 + 2]; var b03 = b[0 * 4 + 3]; var b10 = b[1 * 4 + 0]; var b11 = b[1 * 4 + 1]; var b12 = b[1 * 4 + 2]; var b13 = b[1 * 4 + 3]; var b20 = b[2 * 4 + 0]; var b21 = b[2 * 4 + 1]; var b22 = b[2 * 4 + 2]; var b23 = b[2 * 4 + 3]; var b30 = b[3 * 4 + 0]; var b31 = b[3 * 4 + 1]; var b32 = b[3 * 4 + 2]; var b33 = b[3 * 4 + 3]; var a00 = a[0 * 4 + 0]; var a01 = a[0 * 4 + 1]; var a02 = a[0 * 4 + 2]; var a03 = a[0 * 4 + 3]; var a10 = a[1 * 4 + 0]; var a11 = a[1 * 4 + 1]; var a12 = a[1 * 4 + 2]; var a13 = a[1 * 4 + 3]; var a20 = a[2 * 4 + 0]; var a21 = a[2 * 4 + 1]; var a22 = a[2 * 4 + 2]; var a23 = a[2 * 4 + 3]; var a30 = a[3 * 4 + 0]; var a31 = a[3 * 4 + 1]; var a32 = a[3 * 4 + 2]; var a33 = a[3 * 4 + 3];

return [ b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31, b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32, b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33, b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33, ];       },        translation: function(tx, ty, tz) { return [ 1, 0,  0,  0,                0,  1,  0,  0,                0,  0,  1,  0,                tx, ty, tz, 1, ];       },        scaling: function(sx, sy, sz) { return [ sx, 0, 0,  0, 0, sy, 0,  0, 0, 0, sz,  0, 0, 0,  0,  1,            ];        },        translate: function(m, tx, ty, tz) { return this.multiply(m, this.translation(tx, ty, tz)); },       scale: function(m, sx, sy, sz) { return this.multiply(m, this.scaling(sx, sy, sz)); },

};

/**    * @param {WebGLRenderingContext} gl     * @param {number} type * @param {string} source * @returns {WebGlShader} */   function createShader(gl, type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (success) { return shader; }       console.log(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); }

/**    * @param {WebGLRenderingContext} gl     * @param {WebGLShader} vertexShader * @param {WebGLShader} fragmentShader * @returns {WebGLProgram} */   function createProgram(gl, vertexShader, fragmentShader) { var program = gl.createProgram; gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); var success = gl.getProgramParameter(program, gl.LINK_STATUS); if (success) { return program; }       console.log(gl.getProgramInfoLog(program)); gl.deleteProgram(program); }

/**    * @param {WebGLRenderingContext} gl     * @returns {ProgramInfo} */   function createProgramInfo(gl) { var vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource); var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource); var program = createProgram(gl, vertexShader, fragmentShader);

return { program: program, attrib: { position: gl.getAttribLocation(program, 'aPosition') },           uniform: { matrix: gl.getUniformLocation(program, 'uMatrix'), textureMatrix: gl.getUniformLocation(program, 'uTextureMatrix'), texture: gl.getUniformLocation(program, 'uTexture'), aspectColor: gl.getUniformLocation(program, 'uAspectColor') }       };    }

/**    * @param {WebGLRenderingContext} gl     */ function initBuffers(gl) { return { pos: initPositionBuffer(gl), texCoord: initTexCoordBuffer(gl) };   }

/**    * @param {WebGLRenderingContext} gl     * @returns {WebGlBuffer} */   function initPositionBuffer(gl) { const buffer = gl.createBuffer; gl.bindBuffer(gl.ARRAY_BUFFER, buffer); var positions = [ -0.5, -0.5,           -0.5, 0.5,            0.5, 0.5,

-0.5, -0.5,           0.5, 0.5,            0.5, -0.5        ];        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); return buffer; }

/**    * @param {WebGLRenderingContext} gl     * @returns {WebGlBuffer} */   function initTexCoordBuffer(gl) { const buffer = gl.createBuffer; gl.bindBuffer(gl.ARRAY_BUFFER, buffer); var positions = [ 0, 0,           1, 0,            1, 1,            0, 1        ];        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); return buffer; }

/**    * @param {WebGLRenderingContext} gl     * @param {string} src * @returns {WebGLTexture} */   function loadTexture(gl, src) { var texture = gl.createTexture; gl.bindTexture(gl.TEXTURE_2D, texture);

var level = 0; var internalFormat = gl.RGBA; var srcFormat = gl.RGBA; var srcType = gl.UNSIGNED_BYTE;

// Init to fallback var color = new Uint8Array([0, 0, 0, 255]); gl.texImage2D(           gl.TEXTURE_2D, level, internalFormat, 1, 1, 0, srcFormat, srcType, color        );

var image = new Image; image.addEventListener('load', function {           gl.bindTexture(gl.TEXTURE_2D, texture);            gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image);            gl.generateMipmap(gl.TEXTURE_2D);        }); image.crossOrigin = 'anonymous'; image.src = src; return texture; }

/**    * @param {WebGLRenderingContext} gl     * @param {ProgramInfo} programInfo * @param {*} buffers */   function setPositionBuffer(gl, programInfo, buffers) { gl.bindBuffer(gl.ARRAY_BUFFER, buffers.pos); gl.vertexAttribPointer(programInfo.attrib.position, 2, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(programInfo.attrib.position); }

/**    * @param {WebGLRenderingContext} gl     * @param {ProgramInfo} programInfo * @param {*} uniforms */   function setUniforms(gl, programInfo, uniforms) { gl.uniformMatrix4fv(programInfo.uniform.matrix, false, uniforms.matrix); gl.uniformMatrix4fv(programInfo.uniform.textureMatrix, false, uniforms.textureMatrix); gl.uniform1i(programInfo.uniform.texture, uniforms.texture); gl.uniform4fv(programInfo.uniform.aspectColor, uniforms.aspectColor); }

$.when( $.ready ).then(function {       $('.thumb, .tright').each(function (index) { var height = $(this).height; var width = $(this).width; $(this).html(' '); });       /** @type {HTMLCanvasElement} */        var canvas = $('#test-canvas-0')[0];        var gl = canvas.getContext('webgl');        if (!gl) {            return;        }

var programInfo = createProgramInfo(gl); var buffers = initBuffers(gl);

var nodeTexture = loadTexture(           gl,            'https://static.wikia.nocookie.net/thaumcraft-4/images/b/b9/Node_texture.png/revision/latest?cb=20221231231339&format=original'        ); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

function render(time) { var frame = Math.floor(time / 48) % 32; var timeTicks = time / 5;

gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); gl.clearColor(0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); gl.useProgram(programInfo.program); setPositionBuffer(gl, programInfo, buffers);

var mat = m4.ortho(0, gl.canvas.clientWidth, 0, gl.canvas.clientHeight, -1, 1); mat = m4.translate(mat, gl.canvas.clientWidth / 2, gl.canvas.clientHeight / 2, 0); mat = m4.scale(mat, 128, 128, 1);

var tmat = m4.identity; tmat = m4.scale(tmat, 0.03125, 0.125, 1); tmat = m4.translate(tmat, frame + 0.5, 2.5, 0);

setUniforms(gl, programInfo, {               matrix: mat,                textureMatrix: tmat,                texture: nodeTexture,                aspectColor: [1, 1, 1, 1]            }); gl.drawArrays(gl.TRIANGLES, 0, 6); requestAnimationFrame(render); }       requestAnimationFrame(render); }); })(jQuery, mw);

/** * @typedef ProgramInfo * @property {WebGLProgram} program * @property attrib * @property uniform */