12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289 |
- /*
- * Copyright 2012, Gregg Tavares.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Gregg Tavares. nor the names of his
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- (function(root, factory) { // eslint-disable-line
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define([], function() {
- return factory.call(root);
- });
- } else {
- // Browser globals
- root.webglUtils = factory.call(root);
- }
- }(this, function() {
- "use strict";
- var topWindow = this;
- /** @module webgl-utils */
- function isInIFrame(w) {
- w = w || topWindow;
- return w !== w.top;
- }
- if (!isInIFrame()) {
- console.log("%c%s", 'color:blue;font-weight:bold;', 'for more about webgl-utils.js see:'); // eslint-disable-line
- console.log("%c%s", 'color:blue;font-weight:bold;', 'http://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html'); // eslint-disable-line
- }
- /**
- * Wrapped logging function.
- * @param {string} msg The message to log.
- */
- function error(msg) {
- if (topWindow.console) {
- if (topWindow.console.error) {
- topWindow.console.error(msg);
- } else if (topWindow.console.log) {
- topWindow.console.log(msg);
- }
- }
- }
- /**
- * Error Callback
- * @callback ErrorCallback
- * @param {string} msg error message.
- * @memberOf module:webgl-utils
- */
- /**
- * Loads a shader.
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.
- * @param {string} shaderSource The shader source.
- * @param {number} shaderType The type of shader.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors.
- * @return {WebGLShader} The created shader.
- */
- function loadShader(gl, shaderSource, shaderType, opt_errorCallback) {
- var errFn = opt_errorCallback || error;
- // Create the shader object
- var shader = gl.createShader(shaderType);
- // Load the shader source
- gl.shaderSource(shader, shaderSource);
- // Compile the shader
- gl.compileShader(shader);
- // Check the compile status
- var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
- if (!compiled) {
- // Something went wrong during compilation; get the error
- var lastError = gl.getShaderInfoLog(shader);
- errFn("*** Error compiling shader '" + shader + "':" + lastError);
- gl.deleteShader(shader);
- return null;
- }
- return shader;
- }
- /**
- * Creates a program, attaches shaders, binds attrib locations, links the
- * program and calls useProgram.
- * @param {WebGLShader[]} shaders The shaders to attach
- * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in
- * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console
- * on error. If you want something else pass an callback. It's passed an error message.
- * @memberOf module:webgl-utils
- */
- function createProgram(
- gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {
- var errFn = opt_errorCallback || error;
- var program = gl.createProgram();
- shaders.forEach(function(shader) {
- gl.attachShader(program, shader);
- });
- if (opt_attribs) {
- opt_attribs.forEach(function(attrib, ndx) {
- gl.bindAttribLocation(
- program,
- opt_locations ? opt_locations[ndx] : ndx,
- attrib);
- });
- }
- gl.linkProgram(program);
- // Check the link status
- var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
- if (!linked) {
- // something went wrong with the link
- var lastError = gl.getProgramInfoLog(program);
- errFn("Error in program linking:" + lastError);
- gl.deleteProgram(program);
- return null;
- }
- return program;
- }
- /**
- * Loads a shader from a script tag.
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.
- * @param {string} scriptId The id of the script tag.
- * @param {number} opt_shaderType The type of shader. If not passed in it will
- * be derived from the type of the script tag.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors.
- * @return {WebGLShader} The created shader.
- */
- function createShaderFromScript(
- gl, scriptId, opt_shaderType, opt_errorCallback) {
- var shaderSource = "";
- var shaderType;
- var shaderScript = document.getElementById(scriptId);
- if (!shaderScript) {
- throw ("*** Error: unknown script element" + scriptId);
- }
- shaderSource = shaderScript.text;
- if (!opt_shaderType) {
- if (shaderScript.type === "x-shader/x-vertex") {
- shaderType = gl.VERTEX_SHADER;
- } else if (shaderScript.type === "x-shader/x-fragment") {
- shaderType = gl.FRAGMENT_SHADER;
- } else if (shaderType !== gl.VERTEX_SHADER && shaderType !== gl.FRAGMENT_SHADER) {
- throw ("*** Error: unknown shader type");
- }
- }
- return loadShader(
- gl, shaderSource, opt_shaderType ? opt_shaderType : shaderType,
- opt_errorCallback);
- }
- var defaultShaderType = [
- "VERTEX_SHADER",
- "FRAGMENT_SHADER",
- ];
- /**
- * Creates a program from 2 script tags.
- *
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext
- * to use.
- * @param {string[]} shaderScriptIds Array of ids of the script
- * tags for the shaders. The first is assumed to be the
- * vertex shader, the second the fragment shader.
- * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in
- * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console
- * on error. If you want something else pass an callback. It's passed an error message.
- * @return {WebGLProgram} The created program.
- * @memberOf module:webgl-utils
- */
- function createProgramFromScripts(
- gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) {
- var shaders = [];
- for (var ii = 0; ii < shaderScriptIds.length; ++ii) {
- shaders.push(createShaderFromScript(
- gl, shaderScriptIds[ii], gl[defaultShaderType[ii]], opt_errorCallback));
- }
- return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback);
- }
- /**
- * Creates a program from 2 sources.
- *
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext
- * to use.
- * @param {string[]} shaderSourcess Array of sources for the
- * shaders. The first is assumed to be the vertex shader,
- * the second the fragment shader.
- * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in
- * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console
- * on error. If you want something else pass an callback. It's passed an error message.
- * @return {WebGLProgram} The created program.
- * @memberOf module:webgl-utils
- */
- function createProgramFromSources(
- gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {
- var shaders = [];
- for (var ii = 0; ii < shaderSources.length; ++ii) {
- shaders.push(loadShader(
- gl, shaderSources[ii], gl[defaultShaderType[ii]], opt_errorCallback));
- }
- return createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback);
- }
- /**
- * Returns the corresponding bind point for a given sampler type
- */
- function getBindPointForSamplerType(gl, type) {
- if (type === gl.SAMPLER_2D) return gl.TEXTURE_2D; // eslint-disable-line
- if (type === gl.SAMPLER_CUBE) return gl.TEXTURE_CUBE_MAP; // eslint-disable-line
- return undefined;
- }
- /**
- * @typedef {Object.<string, function>} Setters
- */
- /**
- * Creates setter functions for all uniforms of a shader
- * program.
- *
- * @see {@link module:webgl-utils.setUniforms}
- *
- * @param {WebGLProgram} program the program to create setters for.
- * @returns {Object.<string, function>} an object with a setter by name for each uniform
- * @memberOf module:webgl-utils
- */
- function createUniformSetters(gl, program) {
- var textureUnit = 0;
- /**
- * Creates a setter for a uniform of the given program with it's
- * location embedded in the setter.
- * @param {WebGLProgram} program
- * @param {WebGLUniformInfo} uniformInfo
- * @returns {function} the created setter.
- */
- function createUniformSetter(program, uniformInfo) {
- var location = gl.getUniformLocation(program, uniformInfo.name);
- var type = uniformInfo.type;
- // Check if this uniform is an array
- var isArray = (uniformInfo.size > 1 && uniformInfo.name.substr(-3) === "[0]");
- if (type === gl.FLOAT && isArray) {
- return function(v) {
- gl.uniform1fv(location, v);
- };
- }
- if (type === gl.FLOAT) {
- return function(v) {
- gl.uniform1f(location, v);
- };
- }
- if (type === gl.FLOAT_VEC2) {
- return function(v) {
- gl.uniform2fv(location, v);
- };
- }
- if (type === gl.FLOAT_VEC3) {
- return function(v) {
- gl.uniform3fv(location, v);
- };
- }
- if (type === gl.FLOAT_VEC4) {
- return function(v) {
- gl.uniform4fv(location, v);
- };
- }
- if (type === gl.INT && isArray) {
- return function(v) {
- gl.uniform1iv(location, v);
- };
- }
- if (type === gl.INT) {
- return function(v) {
- gl.uniform1i(location, v);
- };
- }
- if (type === gl.INT_VEC2) {
- return function(v) {
- gl.uniform2iv(location, v);
- };
- }
- if (type === gl.INT_VEC3) {
- return function(v) {
- gl.uniform3iv(location, v);
- };
- }
- if (type === gl.INT_VEC4) {
- return function(v) {
- gl.uniform4iv(location, v);
- };
- }
- if (type === gl.BOOL) {
- return function(v) {
- gl.uniform1iv(location, v);
- };
- }
- if (type === gl.BOOL_VEC2) {
- return function(v) {
- gl.uniform2iv(location, v);
- };
- }
- if (type === gl.BOOL_VEC3) {
- return function(v) {
- gl.uniform3iv(location, v);
- };
- }
- if (type === gl.BOOL_VEC4) {
- return function(v) {
- gl.uniform4iv(location, v);
- };
- }
- if (type === gl.FLOAT_MAT2) {
- return function(v) {
- gl.uniformMatrix2fv(location, false, v);
- };
- }
- if (type === gl.FLOAT_MAT3) {
- return function(v) {
- gl.uniformMatrix3fv(location, false, v);
- };
- }
- if (type === gl.FLOAT_MAT4) {
- return function(v) {
- gl.uniformMatrix4fv(location, false, v);
- };
- }
- if ((type === gl.SAMPLER_2D || type === gl.SAMPLER_CUBE) && isArray) {
- var units = [];
- for (var ii = 0; ii < info.size; ++ii) {
- units.push(textureUnit++);
- }
- return function(bindPoint, units) {
- return function(textures) {
- gl.uniform1iv(location, units);
- textures.forEach(function(texture, index) {
- gl.activeTexture(gl.TEXTURE0 + units[index]);
- gl.bindTexture(bindPoint, texture);
- });
- };
- }(getBindPointForSamplerType(gl, type), units);
- }
- if (type === gl.SAMPLER_2D || type === gl.SAMPLER_CUBE) {
- return function(bindPoint, unit) {
- return function(texture) {
- gl.uniform1i(location, unit);
- gl.activeTexture(gl.TEXTURE0 + unit);
- gl.bindTexture(bindPoint, texture);
- };
- }(getBindPointForSamplerType(gl, type), textureUnit++);
- }
- throw ("unknown type: 0x" + type.toString(16)); // we should never get here.
- }
- var uniformSetters = { };
- var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
- for (var ii = 0; ii < numUniforms; ++ii) {
- var uniformInfo = gl.getActiveUniform(program, ii);
- if (!uniformInfo) {
- break;
- }
- var name = uniformInfo.name;
- // remove the array suffix.
- if (name.substr(-3) === "[0]") {
- name = name.substr(0, name.length - 3);
- }
- var setter = createUniformSetter(program, uniformInfo);
- uniformSetters[name] = setter;
- }
- return uniformSetters;
- }
- /**
- * Set uniforms and binds related textures.
- *
- * example:
- *
- * var programInfo = createProgramInfo(
- * gl, ["some-vs", "some-fs");
- *
- * var tex1 = gl.createTexture();
- * var tex2 = gl.createTexture();
- *
- * ... assume we setup the textures with data ...
- *
- * var uniforms = {
- * u_someSampler: tex1,
- * u_someOtherSampler: tex2,
- * u_someColor: [1,0,0,1],
- * u_somePosition: [0,1,1],
- * u_someMatrix: [
- * 1,0,0,0,
- * 0,1,0,0,
- * 0,0,1,0,
- * 0,0,0,0,
- * ],
- * };
- *
- * gl.useProgram(program);
- *
- * This will automatically bind the textures AND set the
- * uniforms.
- *
- * setUniforms(programInfo.uniformSetters, uniforms);
- *
- * For the example above it is equivalent to
- *
- * var texUnit = 0;
- * gl.activeTexture(gl.TEXTURE0 + texUnit);
- * gl.bindTexture(gl.TEXTURE_2D, tex1);
- * gl.uniform1i(u_someSamplerLocation, texUnit++);
- * gl.activeTexture(gl.TEXTURE0 + texUnit);
- * gl.bindTexture(gl.TEXTURE_2D, tex2);
- * gl.uniform1i(u_someSamplerLocation, texUnit++);
- * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);
- * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);
- * gl.uniformMatrix4fv(u_someMatrix, false, [
- * 1,0,0,0,
- * 0,1,0,0,
- * 0,0,1,0,
- * 0,0,0,0,
- * ]);
- *
- * Note it is perfectly reasonable to call `setUniforms` multiple times. For example
- *
- * var uniforms = {
- * u_someSampler: tex1,
- * u_someOtherSampler: tex2,
- * };
- *
- * var moreUniforms {
- * u_someColor: [1,0,0,1],
- * u_somePosition: [0,1,1],
- * u_someMatrix: [
- * 1,0,0,0,
- * 0,1,0,0,
- * 0,0,1,0,
- * 0,0,0,0,
- * ],
- * };
- *
- * setUniforms(programInfo.uniformSetters, uniforms);
- * setUniforms(programInfo.uniformSetters, moreUniforms);
- *
- * @param {Object.<string, function>|module:webgl-utils.ProgramInfo} setters the setters returned from
- * `createUniformSetters` or a ProgramInfo from {@link module:webgl-utils.createProgramInfo}.
- * @param {Object.<string, value>} an object with values for the
- * uniforms.
- * @memberOf module:webgl-utils
- */
- function setUniforms(setters, values) {
- setters = setters.uniformSetters || setters;
- Object.keys(values).forEach(function(name) {
- var setter = setters[name];
- if (setter) {
- setter(values[name]);
- }
- });
- }
- /**
- * Creates setter functions for all attributes of a shader
- * program. You can pass this to {@link module:webgl-utils.setBuffersAndAttributes} to set all your buffers and attributes.
- *
- * @see {@link module:webgl-utils.setAttributes} for example
- * @param {WebGLProgram} program the program to create setters for.
- * @return {Object.<string, function>} an object with a setter for each attribute by name.
- * @memberOf module:webgl-utils
- */
- function createAttributeSetters(gl, program) {
- var attribSetters = {
- };
- function createAttribSetter(index) {
- return function(b) {
- gl.bindBuffer(gl.ARRAY_BUFFER, b.buffer);
- gl.enableVertexAttribArray(index);
- gl.vertexAttribPointer(
- index, b.numComponents || b.size, b.type || gl.FLOAT, b.normalize || false, b.stride || 0, b.offset || 0);
- };
- }
- var numAttribs = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
- for (var ii = 0; ii < numAttribs; ++ii) {
- var attribInfo = gl.getActiveAttrib(program, ii);
- if (!attribInfo) {
- break;
- }
- var index = gl.getAttribLocation(program, attribInfo.name);
- attribSetters[attribInfo.name] = createAttribSetter(index);
- }
- return attribSetters;
- }
- /**
- * Sets attributes and binds buffers (deprecated... use {@link module:webgl-utils.setBuffersAndAttributes})
- *
- * Example:
- *
- * var program = createProgramFromScripts(
- * gl, ["some-vs", "some-fs");
- *
- * var attribSetters = createAttributeSetters(program);
- *
- * var positionBuffer = gl.createBuffer();
- * var texcoordBuffer = gl.createBuffer();
- *
- * var attribs = {
- * a_position: {buffer: positionBuffer, numComponents: 3},
- * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},
- * };
- *
- * gl.useProgram(program);
- *
- * This will automatically bind the buffers AND set the
- * attributes.
- *
- * setAttributes(attribSetters, attribs);
- *
- * Properties of attribs. For each attrib you can add
- * properties:
- *
- * * type: the type of data in the buffer. Default = gl.FLOAT
- * * normalize: whether or not to normalize the data. Default = false
- * * stride: the stride. Default = 0
- * * offset: offset into the buffer. Default = 0
- *
- * For example if you had 3 value float positions, 2 value
- * float texcoord and 4 value uint8 colors you'd setup your
- * attribs like this
- *
- * var attribs = {
- * a_position: {buffer: positionBuffer, numComponents: 3},
- * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},
- * a_color: {
- * buffer: colorBuffer,
- * numComponents: 4,
- * type: gl.UNSIGNED_BYTE,
- * normalize: true,
- * },
- * };
- *
- * @param {Object.<string, function>|model:webgl-utils.ProgramInfo} setters Attribute setters as returned from createAttributeSetters or a ProgramInfo as returned {@link module:webgl-utils.createProgramInfo}
- * @param {Object.<string, module:webgl-utils.AttribInfo>} attribs AttribInfos mapped by attribute name.
- * @memberOf module:webgl-utils
- * @deprecated use {@link module:webgl-utils.setBuffersAndAttributes}
- */
- function setAttributes(setters, attribs) {
- setters = setters.attribSetters || setters;
- Object.keys(attribs).forEach(function(name) {
- var setter = setters[name];
- if (setter) {
- setter(attribs[name]);
- }
- });
- }
- /**
- * Creates a vertex array object and then sets the attributes
- * on it
- *
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext
- * to use.
- * @param {Object.<string, function>} setters Attribute setters as returned from createAttributeSetters
- * @param {Object.<string, module:webgl-utils.AttribInfo>} attribs AttribInfos mapped by attribute name.
- * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices
- */
- function createVAOAndSetAttributes(gl, setters, attribs, indices) {
- var vao = gl.createVertexArray();
- gl.bindVertexArray(vao);
- setAttributes(setters, attribs);
- if (indices) {
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices);
- }
- // We unbind this because otherwise any change to ELEMENT_ARRAY_BUFFER
- // like when creating buffers for other stuff will mess up this VAO's binding
- gl.bindVertexArray(null);
- return vao;
- }
- /**
- * Creates a vertex array object and then sets the attributes
- * on it
- *
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext
- * to use.
- * @param {Object.<string, function>| module:webgl-utils.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters
- * @param {module:webgl-utils:BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...
- * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices
- */
- function createVAOFromBufferInfo(gl, programInfo, bufferInfo) {
- return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices);
- }
- /**
- * @typedef {Object} ProgramInfo
- * @property {WebGLProgram} program A shader program
- * @property {Object<string, function>} uniformSetters: object of setters as returned from createUniformSetters,
- * @property {Object<string, function>} attribSetters: object of setters as returned from createAttribSetters,
- * @memberOf module:webgl-utils
- */
- /**
- * Creates a ProgramInfo from 2 sources.
- *
- * A ProgramInfo contains
- *
- * programInfo = {
- * program: WebGLProgram,
- * uniformSetters: object of setters as returned from createUniformSetters,
- * attribSetters: object of setters as returned from createAttribSetters,
- * }
- *
- * @param {WebGLRenderingContext} gl The WebGLRenderingContext
- * to use.
- * @param {string[]} shaderSourcess Array of sources for the
- * shaders or ids. The first is assumed to be the vertex shader,
- * the second the fragment shader.
- * @param {string[]} [opt_attribs] An array of attribs names. Locations will be assigned by index if not passed in
- * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.
- * @param {module:webgl-utils.ErrorCallback} opt_errorCallback callback for errors. By default it just prints an error to the console
- * on error. If you want something else pass an callback. It's passed an error message.
- * @return {module:webgl-utils.ProgramInfo} The created program.
- * @memberOf module:webgl-utils
- */
- function createProgramInfo(
- gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {
- shaderSources = shaderSources.map(function(source) {
- var script = document.getElementById(source);
- return script ? script.text : source;
- });
- var program = webglUtils.createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback);
- if (!program) {
- return null;
- }
- var uniformSetters = createUniformSetters(gl, program);
- var attribSetters = createAttributeSetters(gl, program);
- return {
- program: program,
- uniformSetters: uniformSetters,
- attribSetters: attribSetters,
- };
- }
- /**
- * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate
- *
- * Example:
- *
- * var programInfo = createProgramInfo(
- * gl, ["some-vs", "some-fs");
- *
- * var arrays = {
- * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },
- * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },
- * };
- *
- * var bufferInfo = createBufferInfoFromArrays(gl, arrays);
- *
- * gl.useProgram(programInfo.program);
- *
- * This will automatically bind the buffers AND set the
- * attributes.
- *
- * setBuffersAndAttributes(programInfo.attribSetters, bufferInfo);
- *
- * For the example above it is equivilent to
- *
- * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
- * gl.enableVertexAttribArray(a_positionLocation);
- * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0);
- * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
- * gl.enableVertexAttribArray(a_texcoordLocation);
- * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0);
- *
- * @param {WebGLRenderingContext} gl A WebGLRenderingContext.
- * @param {Object.<string, function>} setters Attribute setters as returned from `createAttributeSetters`
- * @param {module:webgl-utils.BufferInfo} buffers a BufferInfo as returned from `createBufferInfoFromArrays`.
- * @memberOf module:webgl-utils
- */
- function setBuffersAndAttributes(gl, setters, buffers) {
- setAttributes(setters, buffers.attribs);
- if (buffers.indices) {
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);
- }
- }
- // Add your prefix here.
- var browserPrefixes = [
- "",
- "MOZ_",
- "OP_",
- "WEBKIT_",
- ];
- /**
- * Given an extension name like WEBGL_compressed_texture_s3tc
- * returns the supported version extension, like
- * WEBKIT_WEBGL_compressed_teture_s3tc
- * @param {string} name Name of extension to look for
- * @return {WebGLExtension} The extension or undefined if not
- * found.
- * @memberOf module:webgl-utils
- */
- function getExtensionWithKnownPrefixes(gl, name) {
- for (var ii = 0; ii < browserPrefixes.length; ++ii) {
- var prefixedName = browserPrefixes[ii] + name;
- var ext = gl.getExtension(prefixedName);
- if (ext) {
- return ext;
- }
- }
- return undefined;
- }
- /**
- * Resize a canvas to match the size its displayed.
- * @param {HTMLCanvasElement} canvas The canvas to resize.
- * @param {number} [multiplier] amount to multiply by.
- * Pass in window.devicePixelRatio for native pixels.
- * @return {boolean} true if the canvas was resized.
- * @memberOf module:webgl-utils
- */
- function resizeCanvasToDisplaySize(canvas, multiplier) {
- multiplier = multiplier || 1;
- var width = canvas.clientWidth * multiplier | 0;
- var height = canvas.clientHeight * multiplier | 0;
- if (canvas.width !== width || canvas.height !== height) {
- canvas.width = width;
- canvas.height = height;
- return true;
- }
- return false;
- }
- // Add `push` to a typed array. It just keeps a 'cursor'
- // and allows use to `push` values into the array so we
- // don't have to manually compute offsets
- function augmentTypedArray(typedArray, numComponents) {
- var cursor = 0;
- typedArray.push = function() {
- for (var ii = 0; ii < arguments.length; ++ii) {
- var value = arguments[ii];
- if (value instanceof Array || (value.buffer && value.buffer instanceof ArrayBuffer)) {
- for (var jj = 0; jj < value.length; ++jj) {
- typedArray[cursor++] = value[jj];
- }
- } else {
- typedArray[cursor++] = value;
- }
- }
- };
- typedArray.reset = function(opt_index) {
- cursor = opt_index || 0;
- };
- typedArray.numComponents = numComponents;
- Object.defineProperty(typedArray, 'numElements', {
- get: function() {
- return this.length / this.numComponents | 0;
- },
- });
- return typedArray;
- }
- /**
- * creates a typed array with a `push` function attached
- * so that you can easily *push* values.
- *
- * `push` can take multiple arguments. If an argument is an array each element
- * of the array will be added to the typed array.
- *
- * Example:
- *
- * var array = createAugmentedTypedArray(3, 2); // creates a Float32Array with 6 values
- * array.push(1, 2, 3);
- * array.push([4, 5, 6]);
- * // array now contains [1, 2, 3, 4, 5, 6]
- *
- * Also has `numComponents` and `numElements` properties.
- *
- * @param {number} numComponents number of components
- * @param {number} numElements number of elements. The total size of the array will be `numComponents * numElements`.
- * @param {constructor} opt_type A constructor for the type. Default = `Float32Array`.
- * @return {ArrayBuffer} A typed array.
- * @memberOf module:webgl-utils
- */
- function createAugmentedTypedArray(numComponents, numElements, opt_type) {
- var Type = opt_type || Float32Array;
- return augmentTypedArray(new Type(numComponents * numElements), numComponents);
- }
- function createBufferFromTypedArray(gl, array, type, drawType) {
- type = type || gl.ARRAY_BUFFER;
- var buffer = gl.createBuffer();
- gl.bindBuffer(type, buffer);
- gl.bufferData(type, array, drawType || gl.STATIC_DRAW);
- return buffer;
- }
- function allButIndices(name) {
- return name !== "indices";
- }
- function createMapping(obj) {
- var mapping = {};
- Object.keys(obj).filter(allButIndices).forEach(function(key) {
- mapping["a_" + key] = key;
- });
- return mapping;
- }
- function getGLTypeForTypedArray(gl, typedArray) {
- if (typedArray instanceof Int8Array) { return gl.BYTE; } // eslint-disable-line
- if (typedArray instanceof Uint8Array) { return gl.UNSIGNED_BYTE; } // eslint-disable-line
- if (typedArray instanceof Int16Array) { return gl.SHORT; } // eslint-disable-line
- if (typedArray instanceof Uint16Array) { return gl.UNSIGNED_SHORT; } // eslint-disable-line
- if (typedArray instanceof Int32Array) { return gl.INT; } // eslint-disable-line
- if (typedArray instanceof Uint32Array) { return gl.UNSIGNED_INT; } // eslint-disable-line
- if (typedArray instanceof Float32Array) { return gl.FLOAT; } // eslint-disable-line
- throw "unsupported typed array type";
- }
- // This is really just a guess. Though I can't really imagine using
- // anything else? Maybe for some compression?
- function getNormalizationForTypedArray(typedArray) {
- if (typedArray instanceof Int8Array) { return true; } // eslint-disable-line
- if (typedArray instanceof Uint8Array) { return true; } // eslint-disable-line
- return false;
- }
- function isArrayBuffer(a) {
- return a.buffer && a.buffer instanceof ArrayBuffer;
- }
- function guessNumComponentsFromName(name, length) {
- var numComponents;
- if (name.indexOf("coord") >= 0) {
- numComponents = 2;
- } else if (name.indexOf("color") >= 0) {
- numComponents = 4;
- } else {
- numComponents = 3; // position, normals, indices ...
- }
- if (length % numComponents > 0) {
- throw "can not guess numComponents. You should specify it.";
- }
- return numComponents;
- }
- function makeTypedArray(array, name) {
- if (isArrayBuffer(array)) {
- return array;
- }
- if (Array.isArray(array)) {
- array = {
- data: array,
- };
- }
- if (!array.numComponents) {
- array.numComponents = guessNumComponentsFromName(name, array.length);
- }
- var type = array.type;
- if (!type) {
- if (name === "indices") {
- type = Uint16Array;
- }
- }
- var typedArray = createAugmentedTypedArray(array.numComponents, array.data.length / array.numComponents | 0, type);
- typedArray.push(array.data);
- return typedArray;
- }
- /**
- * @typedef {Object} AttribInfo
- * @property {number} [numComponents] the number of components for this attribute.
- * @property {number} [size] the number of components for this attribute.
- * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT`
- * @property {boolean} [normalized] whether or not to normalize the data. Default = false
- * @property {number} [offset] offset into buffer in bytes. Default = 0
- * @property {number} [stride] the stride in bytes per element. Default = 0
- * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute
- * @memberOf module:webgl-utils
- */
- /**
- * Creates a set of attribute data and WebGLBuffers from set of arrays
- *
- * Given
- *
- * var arrays = {
- * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },
- * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },
- * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },
- * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, },
- * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },
- * };
- *
- * returns something like
- *
- * var attribs = {
- * a_position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },
- * a_texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },
- * a_normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },
- * a_color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, },
- * };
- *
- * @param {WebGLRenderingContext} gl The webgl rendering context.
- * @param {Object.<string, array|typedarray>} arrays The arrays
- * @param {Object.<string, string>} [opt_mapping] mapping from attribute name to array name.
- * if not specified defaults to "a_name" -> "name".
- * @return {Object.<string, module:webgl-utils.AttribInfo>} the attribs
- * @memberOf module:webgl-utils
- */
- function createAttribsFromArrays(gl, arrays, opt_mapping) {
- var mapping = opt_mapping || createMapping(arrays);
- var attribs = {};
- Object.keys(mapping).forEach(function(attribName) {
- var bufferName = mapping[attribName];
- var array = makeTypedArray(arrays[bufferName], bufferName);
- attribs[attribName] = {
- buffer: createBufferFromTypedArray(gl, array),
- numComponents: array.numComponents || guessNumComponentsFromName(bufferName),
- type: getGLTypeForTypedArray(gl, array),
- normalize: getNormalizationForTypedArray(array),
- };
- });
- return attribs;
- }
- /**
- * tries to get the number of elements from a set of arrays.
- */
- function getNumElementsFromNonIndexedArrays(arrays) {
- var key = Object.keys(arrays)[0];
- var array = arrays[key];
- if (isArrayBuffer(array)) {
- return array.numElements;
- } else {
- return array.data.length / array.numComponents;
- }
- }
- /**
- * @typedef {Object} BufferInfo
- * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.
- * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist.
- * @property {Object.<string, module:webgl-utils.AttribInfo>} attribs The attribs approriate to call `setAttributes`
- * @memberOf module:webgl-utils
- */
- /**
- * Creates a BufferInfo from an object of arrays.
- *
- * This can be passed to {@link module:webgl-utils.setBuffersAndAttributes} and to
- * {@link module:webgl-utils:drawBufferInfo}.
- *
- * Given an object like
- *
- * var arrays = {
- * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },
- * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },
- * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },
- * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },
- * };
- *
- * Creates an BufferInfo like this
- *
- * bufferInfo = {
- * numElements: 4, // or whatever the number of elements is
- * indices: WebGLBuffer, // this property will not exist if there are no indices
- * attribs: {
- * a_position: { buffer: WebGLBuffer, numComponents: 3, },
- * a_normal: { buffer: WebGLBuffer, numComponents: 3, },
- * a_texcoord: { buffer: WebGLBuffer, numComponents: 2, },
- * },
- * };
- *
- * The properties of arrays can be JavaScript arrays in which case the number of components
- * will be guessed.
- *
- * var arrays = {
- * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0],
- * texcoord: [0, 0, 0, 1, 1, 0, 1, 1],
- * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
- * indices: [0, 1, 2, 1, 2, 3],
- * };
- *
- * They can also by TypedArrays
- *
- * var arrays = {
- * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),
- * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),
- * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),
- * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),
- * };
- *
- * Or augmentedTypedArrays
- *
- * var positions = createAugmentedTypedArray(3, 4);
- * var texcoords = createAugmentedTypedArray(2, 4);
- * var normals = createAugmentedTypedArray(3, 4);
- * var indices = createAugmentedTypedArray(3, 2, Uint16Array);
- *
- * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]);
- * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]);
- * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
- * indices.push([0, 1, 2, 1, 2, 3]);
- *
- * var arrays = {
- * position: positions,
- * texcoord: texcoords,
- * normal: normals,
- * indices: indices,
- * };
- *
- * For the last example it is equivalent to
- *
- * var bufferInfo = {
- * attribs: {
- * a_position: { numComponents: 3, buffer: gl.createBuffer(), },
- * a_texcoods: { numComponents: 2, buffer: gl.createBuffer(), },
- * a_normals: { numComponents: 3, buffer: gl.createBuffer(), },
- * },
- * indices: gl.createBuffer(),
- * numElements: 6,
- * };
- *
- * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_position.buffer);
- * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW);
- * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_texcoord.buffer);
- * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW);
- * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.a_normal.buffer);
- * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW);
- * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices);
- * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW);
- *
- * @param {WebGLRenderingContext} gl A WebGLRenderingContext
- * @param {Object.<string, array|object|typedarray>} arrays Your data
- * @param {Object.<string, string>} [opt_mapping] an optional mapping of attribute to array name.
- * If not passed in it's assumed the array names will be mapped to an attibute
- * of the same name with "a_" prefixed to it. An other words.
- *
- * var arrays = {
- * position: ...,
- * texcoord: ...,
- * normal: ...,
- * indices: ...,
- * };
- *
- * bufferInfo = createBufferInfoFromArrays(gl, arrays);
- *
- * Is the same as
- *
- * var arrays = {
- * position: ...,
- * texcoord: ...,
- * normal: ...,
- * indices: ...,
- * };
- *
- * var mapping = {
- * a_position: "position",
- * a_texcoord: "texcoord",
- * a_normal: "normal",
- * };
- *
- * bufferInfo = createBufferInfoFromArrays(gl, arrays, mapping);
- *
- * @return {module:webgl-utils.BufferInfo} A BufferInfo
- * @memberOf module:webgl-utils
- */
- function createBufferInfoFromArrays(gl, arrays, opt_mapping) {
- var bufferInfo = {
- attribs: createAttribsFromArrays(gl, arrays, opt_mapping),
- };
- var indices = arrays.indices;
- if (indices) {
- indices = makeTypedArray(indices, "indices");
- bufferInfo.indices = createBufferFromTypedArray(gl, indices, gl.ELEMENT_ARRAY_BUFFER);
- bufferInfo.numElements = indices.length;
- } else {
- bufferInfo.numElements = getNumElementsFromNonIndexedArrays(arrays);
- }
- return bufferInfo;
- }
- /**
- * Creates buffers from typed arrays
- *
- * Given something like this
- *
- * var arrays = {
- * positions: [1, 2, 3],
- * normals: [0, 0, 1],
- * }
- *
- * returns something like
- *
- * buffers = {
- * positions: WebGLBuffer,
- * normals: WebGLBuffer,
- * }
- *
- * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER.
- *
- * @param {WebGLRenderingContext} gl A WebGLRenderingContext.
- * @param {Object<string, array|typedarray>} arrays
- * @return {Object<string, WebGLBuffer>} returns an object with one WebGLBuffer per array
- * @memberOf module:webgl-utils
- */
- function createBuffersFromArrays(gl, arrays) {
- var buffers = { };
- Object.keys(arrays).forEach(function(key) {
- var type = key === "indices" ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
- var array = makeTypedArray(arrays[key], name);
- buffers[key] = createBufferFromTypedArray(gl, array, type);
- });
- // hrm
- if (arrays.indices) {
- buffers.numElements = arrays.indices.length;
- } else if (arrays.position) {
- buffers.numElements = arrays.position.length / 3;
- }
- return buffers;
- }
- /**
- * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate
- *
- * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself
- * but calling this means if you switch from indexed data to non-indexed
- * data you don't have to remember to update your draw call.
- *
- * @param {WebGLRenderingContext} gl A WebGLRenderingContext
- * @param {module:webgl-utils.BufferInfo} bufferInfo as returned from createBufferInfoFromArrays
- * @param {enum} [primitiveType] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...)
- * @param {number} [count] An optional count. Defaults to bufferInfo.numElements
- * @param {number} [offset] An optional offset. Defaults to 0.
- * @memberOf module:webgl-utils
- */
- function drawBufferInfo(gl, bufferInfo, primitiveType, count, offset) {
- var indices = bufferInfo.indices;
- primitiveType = primitiveType === undefined ? gl.TRIANGLES : primitiveType;
- var numElements = count === undefined ? bufferInfo.numElements : count;
- offset = offset === undefined ? offset : 0;
- if (indices) {
- gl.drawElements(primitiveType, numElements, gl.UNSIGNED_SHORT, offset);
- } else {
- gl.drawArrays(primitiveType, offset, numElements);
- }
- }
- /**
- * @typedef {Object} DrawObject
- * @property {module:webgl-utils.ProgramInfo} programInfo A ProgramInfo as returned from createProgramInfo
- * @property {module:webgl-utils.BufferInfo} bufferInfo A BufferInfo as returned from createBufferInfoFromArrays
- * @property {Object<string, ?>} uniforms The values for the uniforms
- * @memberOf module:webgl-utils
- */
- /**
- * Draws a list of objects
- * @param {WebGLRenderingContext} gl A WebGLRenderingContext
- * @param {DrawObject[]} objectsToDraw an array of objects to draw.
- * @memberOf module:webgl-utils
- */
- function drawObjectList(gl, objectsToDraw) {
- var lastUsedProgramInfo = null;
- var lastUsedBufferInfo = null;
- objectsToDraw.forEach(function(object) {
- var programInfo = object.programInfo;
- var bufferInfo = object.bufferInfo;
- var bindBuffers = false;
- if (programInfo !== lastUsedProgramInfo) {
- lastUsedProgramInfo = programInfo;
- gl.useProgram(programInfo.program);
- bindBuffers = true;
- }
- // Setup all the needed attributes.
- if (bindBuffers || bufferInfo !== lastUsedBufferInfo) {
- lastUsedBufferInfo = bufferInfo;
- setBuffersAndAttributes(gl, programInfo.attribSetters, bufferInfo);
- }
- // Set the uniforms.
- setUniforms(programInfo.uniformSetters, object.uniforms);
- // Draw
- drawBufferInfo(gl, bufferInfo);
- });
- }
- var isIE = /*@cc_on!@*/false || !!document.documentMode;
- // Edge 20+
- var isEdge = !isIE && !!window.StyleMedia;
- if (isEdge) {
- // Hack for Edge. Edge's WebGL implmentation is crap still and so they
- // only respond to "experimental-webgl". I don't want to clutter the
- // examples with that so his hack works around it
- HTMLCanvasElement.prototype.getContext = function(origFn) {
- return function() {
- var args = arguments;
- var type = args[0];
- if (type === "webgl") {
- args = [].slice.call(arguments);
- args[0] = "experimental-webgl";
- }
- return origFn.apply(this, args);
- };
- }(HTMLCanvasElement.prototype.getContext);
- }
- return {
- createAugmentedTypedArray: createAugmentedTypedArray,
- createAttribsFromArrays: createAttribsFromArrays,
- createBuffersFromArrays: createBuffersFromArrays,
- createBufferInfoFromArrays: createBufferInfoFromArrays,
- createAttributeSetters: createAttributeSetters,
- createProgram: createProgram,
- createProgramFromScripts: createProgramFromScripts,
- createProgramFromSources: createProgramFromSources,
- createProgramInfo: createProgramInfo,
- createUniformSetters: createUniformSetters,
- createVAOAndSetAttributes: createVAOAndSetAttributes,
- createVAOFromBufferInfo: createVAOFromBufferInfo,
- drawBufferInfo: drawBufferInfo,
- drawObjectList: drawObjectList,
- getExtensionWithKnownPrefixes: getExtensionWithKnownPrefixes,
- resizeCanvasToDisplaySize: resizeCanvasToDisplaySize,
- setAttributes: setAttributes,
- setBuffersAndAttributes: setBuffersAndAttributes,
- setUniforms: setUniforms,
- };
- }));
|