UNPKG

mapbox-gl

Version:
96 lines (76 loc) 3.44 kB
'use strict'; var assert = require('assert'); var util = require('../../util/util'); var shaders = require('mapbox-gl-shaders'); var utilSource = shaders.util; module.exports._createProgram = function(name, defines, vertexPragmas, fragmentPragmas) { var gl = this.gl; var program = gl.createProgram(); var definition = shaders[name]; var definesSource = '#define MAPBOX_GL_JS;\n'; for (var j = 0; j < defines.length; j++) { definesSource += '#define ' + defines[j] + ';\n'; } var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, applyPragmas(definesSource + definition.fragmentSource, fragmentPragmas)); gl.compileShader(fragmentShader); assert(gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS), gl.getShaderInfoLog(fragmentShader)); gl.attachShader(program, fragmentShader); var vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, applyPragmas(definesSource + utilSource + definition.vertexSource, vertexPragmas)); gl.compileShader(vertexShader); assert(gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS), gl.getShaderInfoLog(vertexShader)); gl.attachShader(program, vertexShader); gl.linkProgram(program); assert(gl.getProgramParameter(program, gl.LINK_STATUS), gl.getProgramInfoLog(program)); var attributes = {}; var numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); for (var i = 0; i < numAttributes; i++) { var attribute = gl.getActiveAttrib(program, i); attributes[attribute.name] = gl.getAttribLocation(program, attribute.name); } var uniforms = {}; var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (var ui = 0; ui < numUniforms; ui++) { var uniform = gl.getActiveUniform(program, ui); uniforms[uniform.name] = gl.getUniformLocation(program, uniform.name); } return util.extend({ program: program, definition: definition, attributes: attributes, numAttributes: numAttributes }, attributes, uniforms); }; module.exports._createProgramCached = function(name, defines, vertexPragmas, fragmentPragmas) { this.cache = this.cache || {}; var key = JSON.stringify({ name: name, defines: defines, vertexPragmas: vertexPragmas, fragmentPragmas: fragmentPragmas }); if (!this.cache[key]) { this.cache[key] = this._createProgram(name, defines, vertexPragmas, fragmentPragmas); } return this.cache[key]; }; module.exports.useProgram = function (nextProgramName, defines, vertexPragmas, fragmentPragmas) { var gl = this.gl; defines = defines || []; if (this._showOverdrawInspector) { defines = defines.concat('OVERDRAW_INSPECTOR'); } var nextProgram = this._createProgramCached(nextProgramName, defines, vertexPragmas, fragmentPragmas); var previousProgram = this.currentProgram; if (previousProgram !== nextProgram) { gl.useProgram(nextProgram.program); this.currentProgram = nextProgram; } return nextProgram; }; function applyPragmas(source, pragmas) { return source.replace(/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g, function(match, operation, precision, type, name) { return pragmas[operation][name].replace(/{type}/g, type).replace(/{precision}/g, precision); }); }