UNPKG

pixelbutler

Version:

Low-res bitmap render engine for big screens

109 lines (108 loc) 4.45 kB
'use strict'; var vertexShaderSource = [ 'attribute vec2 a_position;', 'attribute vec2 a_texCoord;', 'varying vec2 v_texCoord;', 'void main() {', ' gl_Position = vec4(a_position, 0, 1);', ' v_texCoord = a_texCoord;', '}' ].join('\n'); var fragmentShaderSource = [ 'precision mediump float;', 'uniform sampler2D u_image;', 'varying vec2 v_texCoord;', 'void main() {', ' gl_FragColor = texture2D(u_image, v_texCoord);', '}' ].join('\n'); function loadShader(gl, shaderSource, shaderType) { var shader = gl.createShader(shaderType); gl.shaderSource(shader, shaderSource); gl.compileShader(shader); var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (!compiled) { throw new Error('error compiling shader "' + shader + '":' + gl.getShaderInfoLog(shader)); } return shader; } var WebGLRender = (function () { function WebGLRender(bitmap, canvas) { this.canvas = canvas; this.width = bitmap.width; this.height = bitmap.height; if (!bitmap.buffer || !Uint8Array) { throw new Error('bitmap doesn\'t support buffer operations'); } this.px = new Uint8Array(bitmap.buffer); if (!window.WebGLRenderingContext) { throw new Error('browser does not support WegGL'); } var glOpts = { alpha: false }; var gl = this.gl = this.canvas.getContext('webgl', glOpts) || this.canvas.getContext('experimental-webgl', glOpts); if (!gl) { throw new Error('could not create WebGL context'); } var program = gl.createProgram(); gl.attachShader(program, loadShader(gl, vertexShaderSource, gl.VERTEX_SHADER)); gl.attachShader(program, loadShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER)); gl.linkProgram(program); var linked = gl.getProgramParameter(program, gl.LINK_STATUS); if (!linked) { throw new Error(('error in program linking:' + gl.getProgramInfoLog(program))); } gl.useProgram(program); this.positionLocation = gl.getAttribLocation(program, 'a_position'); this.texCoordLocation = gl.getAttribLocation(program, 'a_texCoord'); this.positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer); gl.enableVertexAttribArray(this.positionLocation); gl.vertexAttribPointer(this.positionLocation, 2, gl.FLOAT, false, 0, 0); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0 ]), gl.STATIC_DRAW); this.texCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, this.texCoordBuffer); gl.enableVertexAttribArray(this.texCoordLocation); gl.vertexAttribPointer(this.texCoordLocation, 2, gl.FLOAT, false, 0, 0); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 ]), gl.STATIC_DRAW); this.texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.clearColor(0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); gl.colorMask(true, true, true, false); gl.viewport(0, 0, this.canvas.width, this.canvas.height); } WebGLRender.prototype.resize = function () { this.gl.viewport(0, 0, this.canvas.width, this.canvas.height); this.gl.clear(this.gl.COLOR_BUFFER_BIT); }; WebGLRender.prototype.update = function () { this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGB, this.width, this.height, 0, this.gl.RGB, this.gl.UNSIGNED_BYTE, this.px); this.gl.drawArrays(this.gl.TRIANGLES, 0, 6); }; WebGLRender.prototype.destruct = function () { this.gl.clear(this.gl.COLOR_BUFFER_BIT); this.gl = null; this.px = null; this.canvas = null; }; return WebGLRender; })(); module.exports = WebGLRender;