UNPKG

wggl

Version:

A friendly interface to shaders

107 lines (106 loc) 4.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var primitives_1 = require("./primitives"); var program_1 = require("./program"); var Wggl = /** @class */ (function () { function Wggl(canvas, vertShader, fragShader) { this.canvas = canvas; this.gl = canvas.getContext("webgl"); var programs; if (vertShader && fragShader) { programs = { default: [vertShader, fragShader] }; } else { programs = vertShader; } // do things with programs this.setupPrograms(programs); this.reset(); // If there is a default program, "hoist" its methods to the Wggl instance // wggl.default.draw() ==> wggl.draw(); // wggl.default.drawTo() ==> wggl.drawTo(); if (this.default) { var defaultProgram = this.default; this.draw = defaultProgram.draw.bind(this.default); this.drawTo = defaultProgram.drawTo.bind(this.default); } } Wggl.prototype.setupPrograms = function (programs) { var _this = this; Object.keys(programs).forEach(function (programName) { var _a = programs[programName], vShader = _a[0], fShader = _a[1]; var gl = _this.gl; if (_this[programName] != null) { console.warn("Skipping program " + programName + ". It is either a duplicate program or uses a reserved name"); } var bindPointers = {}; var vs = createShader(gl, gl.VERTEX_SHADER, vShader.src); var fs = createShader(gl, gl.FRAGMENT_SHADER, fShader.src); var program = createProgram(gl, vs, fs); mergeAttrs(gl, program, bindPointers, vShader.attrs); mergeAttrs(gl, program, bindPointers, fShader.attrs); Object.keys(bindPointers).forEach(function (key) { var value = bindPointers[key]; if (value.parameters.glType === primitives_1.GlType.attribute) { value.buffer = gl.createBuffer(); } }); _this[programName] = new program_1.WgglProgram(_this.canvas, bindPointers, program); }); }; Wggl.prototype.reset = function () { var _a = this, gl = _a.gl, canvas = _a.canvas; var scale = Math.min(window.devicePixelRatio, 2); canvas.width = Math.floor(canvas.clientWidth * scale); canvas.height = Math.floor(canvas.clientHeight * scale); gl.viewport(0, 0, canvas.width, canvas.height); gl.clearColor(0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); }; return Wggl; }()); exports.Wggl = Wggl; function mergeAttrs(gl, program, source, attrs) { Object.keys(attrs).forEach(function (attr) { if (source[attr] != null) { console.warn("Attribute " + attr + " is being bound multiple times. Variable names should be unique across shaders and primitives"); } source[attr] = { location: locationForAttr(gl, program, attr, attrs[attr]), parameters: attrs[attr] }; }); } function locationForAttr(gl, program, key, value) { switch (value.glType) { case primitives_1.GlType.attribute: return gl.getAttribLocation(program, key); case primitives_1.GlType.uniform: return gl.getUniformLocation(program, key); } } function createShader(gl, type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); var isCompiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (!isCompiled) { var err = gl.getShaderInfoLog(shader); gl.deleteShader(shader); throw new Error(err); } return shader; } function createProgram(gl, vertexShader, fragmentShader) { var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); var isLinked = gl.getProgramParameter(program, gl.LINK_STATUS); if (!isLinked) { var err = gl.getProgramInfoLog(program); gl.deleteProgram(program); throw new Error(err); } return program; }