From eaa4b13df880084380c1e4614985b8d4df132049 Mon Sep 17 00:00:00 2001 From: Gregg Tavares Date: Sat, 7 Sep 2024 10:32:54 -0700 Subject: [PATCH] build --- dist/6.x/twgl-full.d.ts | 4517 ++++++++++++ dist/6.x/twgl-full.js | 10682 +++++++++++++++++++++++++++++ dist/6.x/twgl-full.js.map | 1 + dist/6.x/twgl-full.min.js | 6 + dist/6.x/twgl-full.module.js | 10139 +++++++++++++++++++++++++++ dist/6.x/twgl.d.ts | 3172 +++++++++ dist/6.x/twgl.js | 7263 ++++++++++++++++++++ dist/6.x/twgl.js.map | 1 + dist/6.x/twgl.min.js | 6 + dist/6.x/twgl.module.js | 6233 +++++++++++++++++ index.html | 2 +- npm/base/dist/6.x/twgl.d.ts | 3172 +++++++++ npm/base/dist/6.x/twgl.js | 7263 ++++++++++++++++++++ npm/base/dist/6.x/twgl.js.map | 1 + npm/base/dist/6.x/twgl.module.js | 6233 +++++++++++++++++ npm/base/package.json | 2 +- 16 files changed, 58691 insertions(+), 2 deletions(-) create mode 100644 dist/6.x/twgl-full.d.ts create mode 100644 dist/6.x/twgl-full.js create mode 100644 dist/6.x/twgl-full.js.map create mode 100644 dist/6.x/twgl-full.min.js create mode 100644 dist/6.x/twgl-full.module.js create mode 100644 dist/6.x/twgl.d.ts create mode 100644 dist/6.x/twgl.js create mode 100644 dist/6.x/twgl.js.map create mode 100644 dist/6.x/twgl.min.js create mode 100644 dist/6.x/twgl.module.js create mode 100644 npm/base/dist/6.x/twgl.d.ts create mode 100644 npm/base/dist/6.x/twgl.js create mode 100644 npm/base/dist/6.x/twgl.js.map create mode 100644 npm/base/dist/6.x/twgl.module.js diff --git a/dist/6.x/twgl-full.d.ts b/dist/6.x/twgl-full.d.ts new file mode 100644 index 00000000..ed9f4dd7 --- /dev/null +++ b/dist/6.x/twgl-full.d.ts @@ -0,0 +1,4517 @@ + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ +export type Defaults = { + attribPrefix?: string; + textureColor?: number[]; + crossOrigin?: string; + addExtensionsToContext?: boolean; +}; +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +export function setDefaults(newDefaults: Defaults): void; +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +export function addExtensionsToContext(gl: WebGLRenderingContext): void; +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +export function createContext(canvas: HTMLCanvasElement): WebGLRenderingContext; +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +export function getContext(canvas: HTMLCanvasElement, opt_attribs?: WebGLContextAttributes): WebGLRenderingContext; +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +export function resizeCanvasToDisplaySize(canvas: HTMLCanvasElement, multiplier?: number): boolean; +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type AttribInfo = { + value?: number[] | ArrayBufferView; + numComponents?: number; + size?: number; + type?: number; + normalize?: boolean; + offset?: number; + stride?: number; + divisor?: number; + buffer: WebGLBuffer; + drawType?: number; +}; +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type FullArraySpec = { + value?: number[] | ArrayBufferView; + data?: number | number[] | ArrayBufferView; + numComponents?: number; + type?: number | TypedArrayConstructor; + size?: number; + normalize?: boolean; + stride?: number; + offset?: number; + divisor?: number; + attrib?: string; + name?: string; + attribName?: string; + buffer?: WebGLBuffer; + drawType?: number; +}; +/** + * An individual array in {@link Arrays} + * + * When passed to {@link createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ +export type ArraySpec = number | number[] | ArrayBufferView | FullArraySpec; +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ +export type Arrays = { + [key: string]: ArraySpec; +}; +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ +export type BufferInfo = { + numElements: number; + elementType?: number; + indices?: WebGLBuffer; + attribs?: { + [key: string]: AttribInfo; + }; +}; +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @property {BufferInfo} [bufferInfo] A BufferInfo as returned from {@link createBufferInfoFromArrays} + * @property {VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ +export type DrawObject = { + active?: boolean; + type?: number; + programInfo: ProgramInfo; + bufferInfo?: BufferInfo; + vertexArrayInfo?: VertexArrayInfo; + uniforms: { + [key: string]: any; + }; + offset?: number; + count?: number; + instanceCount?: number; +}; +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes TextureOptions + */ +export type AttachmentOptions = TextureOptions & { + attachmentPoint?: number; + format?: number; + type?: number; + target?: number; + samples?: number; + level?: number; + layer?: number; + attachment?: WebGLRenderbuffer | WebGLTexture; +}; +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ +export type FramebufferInfo = { + framebuffer: WebGLFramebuffer; + attachments: (WebGLRenderbuffer | WebGLTexture)[]; + width: number; + height: number; +}; +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ +export type ErrorCallback = (msg: string, lineOffset?: number) => void; +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type FullProgramSpec = { + shaders: string[]; + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {string[]|FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ +export type ProgramSpec = string[] | FullProgramSpec; +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type ProgramOptions = { + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ +export type TransformFeedbackInfo = { + index: number; + type: number; + size: number; +}; +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +export function createTransformFeedbackInfo(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: TransformFeedbackInfo; +}; +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +export function bindTransformFeedbackInfo(gl: WebGLRenderingContext, transformFeedbackInfo: ProgramInfo | { + [key: string]: TransformFeedbackInfo; +}, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): void; +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +export function createTransformFeedback(gl: WebGLRenderingContext, programInfo: ProgramInfo, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): WebGLTransformFeedback; +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ +export type UniformData = { + name: string; + type: number; + size: number; + blockNdx: number; + offset: number; +}; +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ +export type BlockSpec = { + index: number; + size: number; + uniformIndices: number[]; + usedByVertexShader: boolean; + usedByFragmentShader: boolean; + used: boolean; +}; +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ +export type UniformBlockSpec = { + blockSpecs: { + [key: string]: BlockSpec; + }; + uniformData: UniformData[]; +}; +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link setBlockUniforms} + * @memberOf module:twgl + */ +export type UniformBlockInfo = { + name: string; + array: ArrayBuffer; + asFloat: Float32Array; + asUint8t: Uint8Array; + buffer: WebGLBuffer; + offset?: number; + uniforms: { + [key: string]: ArrayBufferView; + }; + setters: { + [key: string]: (...params: any[]) => any; + }; +}; +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ +export type ProgramInfo = { + program: WebGLProgram; + uniformLocations: { + [key: string]: WebGLUniformLocation; + }; + attribLocations: { + [key: string]: number; + }; + uniformSetters: { + [key: string]: (...params: any[]) => any; + }; + attribSetters: { + [key: string]: (...params: any[]) => any; + }; + uniformBlockSpec?: UniformBlockSpec; + transformFeedbackInfo?: { + [key: string]: TransformFeedbackInfo; + }; +}; +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link TextureOptions}. + * @memberOf module:twgl + */ +export type TextureFunc = (gl: WebGLRenderingContext, options: TextureOptions) => any; +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link setDefaults}. + * + * @memberOf module:twgl + */ +export type TextureOptions = { + target?: number; + level?: number; + width?: number; + height?: number; + depth?: number; + min?: number; + mag?: number; + minMag?: number; + internalFormat?: number; + format?: number; + type?: number; + wrap?: number; + wrapS?: number; + wrapT?: number; + wrapR?: number; + minLod?: number; + maxLod?: number; + baseLevel?: number; + maxLevel?: number; + compareFunc?: number; + compareMode?: number; + unpackAlignment?: number; + color?: number[] | ArrayBufferView; + premultiplyAlpha?: number; + flipY?: number; + colorspaceConversion?: number; + auto?: boolean; + cubeFaceOrder?: number[]; + src?: number[] | ArrayBufferView | TexImageSource | TexImageSource[] | string | string[] | TextureFunc; + crossOrigin?: string; +}; +/** + * The src image(s) used to create a texture. + * + * When you call {@link createTexture} or {@link createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ +export type TextureSrc = HTMLImageElement | HTMLImageElement[]; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ +export type TextureReadyCallback = (err: any, texture: WebGLTexture, source: TextureSrc) => void; +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ +export type TexturesReadyCallback = (err: any, textures: { + [key: string]: WebGLTexture; +}, sources: { + [key: string]: TextureSrc; +}) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ +export type CubemapReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ +export type ThreeDReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +export function isWebGL2(gl: WebGLRenderingContext): boolean; +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +export function isWebGL1(gl: WebGLRenderingContext): boolean; +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +export function glEnumToString(gl: WebGLRenderingContext, value: number): string; +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ +export type VertexArrayInfo = { + numElements: number; + elementType?: number; + vertexArrayObject?: WebGLVertexArrayObject; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +export function setAttributePrefix(prefix: string): void; +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +export function createBufferFromTypedArray(gl: WebGLRenderingContext, typedArray: ArrayBuffer | SharedArrayBuffer | ArrayBufferView | WebGLBuffer, type?: number, drawType?: number): WebGLBuffer; +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ +export type TypedArrayConstructor = Int8ArrayConstructor | Uint8ArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor; +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {Arrays} arrays The arrays + * @param {BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +export function createAttribsFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): { + [key: string]: AttribInfo; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +export function createBufferFromArray(gl: WebGLRenderingContext, array: ArraySpec, arrayName: string): WebGLBuffer; +/** + * Creates buffers from arrays or 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 {Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +export function createBuffersFromArrays(gl: WebGLRenderingContext, arrays: Arrays): { + [key: string]: WebGLBuffer; +}; + + +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; + + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; + + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|ProgramInfo} [result] the program or programInfo + */ +export type ProgramCallback = (err?: string, result?: WebGLProgram | ProgramInfo) => void; +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgram(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created program + * @memberOf module:twgl/programs + */ +export function createProgramAsync(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +export function createProgramInfoAsync(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromScripts(gl: WebGLRenderingContext, shaderScriptIds: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromSources(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +export function createUniformSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +export function createUniformBlockSpecFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram): UniformBlockSpec; +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ +export type UniformBlockInfoOptions = { + array?: ArrayBuffer; + offset?: number; + buffer?: WebGLBuffer; + bufferOffset?: number; +}; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfoFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Alias for `setUniforms` + * @function + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +export function setUniformsAndBindTextures(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +export function createAttributeSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +export function createProgramInfoFromProgram(gl: WebGLRenderingContext, program: WebGLProgram): ProgramInfo; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createPrograms(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramInfos(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: ProgramInfo; +}; +/** + * Creates multiple programs asynchronously + * + * @see {@link createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramsAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos asynchronously + * + * @see {@link createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +export function createProgramInfosAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): Promise<{ + [key: string]: ProgramInfo; +}>; + + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +export function getBytesPerElementForInternalFormat(internalFormat: number, type: number): number; +/** + * Info related to a specific texture internalFormat as returned + * from {@link getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ +export type TextureFormatInfo = { + format: number; + type: number; +}; +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +export function getFormatAndTypeForInternalFormat(internalFormat: number): TextureFormatInfo; +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canGenerateMipmap(gl: WebGLRenderingContext, width: number, height: number, internalFormat: number): boolean; +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canFilter(internalFormat: number): boolean; +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +export function getNumComponentsForFormat(format: number): number; +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link setDefaults} + * @memberOf module:twgl/textures + */ +export function setDefaultTextureColor(color: number[]): void; +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureParameters(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setSamplerParameters(gl: WebGLRenderingContext, sampler: WebGLSampler, options: TextureOptions): void; +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +export function setTextureFilteringForSize(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, width?: number, height?: number, internalFormat?: number): void; +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +export function setTextureFromElement(gl: WebGLRenderingContext, tex: WebGLTexture, element: HTMLElement, options?: TextureOptions): void; +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +export function loadTextureFromUrl(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, callback?: TextureReadyCallback): HTMLImageElement; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setEmptyTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArray(typedArray: ArrayBufferView): number; +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArrayType(typedArrayType: ArrayBufferView): number; +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +export function getTypedArrayTypeForGLType(type: number): (...params: any[]) => any; + + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ProgramInfo|ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +export function createVertexArrayInfo(gl: WebGLRenderingContext, programInfo: ProgramInfo | ProgramInfo[], bufferInfo: BufferInfo): VertexArrayInfo; +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOAndSetAttributes(gl: WebGLRenderingContext, setters: { + [key: string]: (...params: any[]) => any; +}, attribs: { + [key: string]: AttribInfo; +}, indices?: WebGLBuffer): WebGLVertexArrayObject | null; +/** + * Creates a vertex array object and then sets the attributes + * on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {Object.| ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOFromBufferInfo(gl: WebGLRenderingContext, programInfo: { + [key: string]: (...params: any[]) => any; +} | ProgramInfo, bufferInfo: BufferInfo, indices?: WebGLBuffer): WebGLVertexArrayObject | null; + +declare module v3 { + /** + * A JavaScript array with 3 values or a Float32Array with 3 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link v3.setDefaultType}. + * @typedef {(number[]|Float32Array)} Vec3 + * @memberOf module:twgl/v3 + */ + export type Vec3 = number[] | Float32Array; + /** + * Sets the type this library creates for a Vec3 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Vec3 + * @memberOf module:twgl/v3 + */ + export function setDefaultType(ctor: Function): Function; + /** + * Creates a vec3; may be called with x, y, z to set initial values. + * @param {number} [x] Initial x value. + * @param {number} [y] Initial y value. + * @param {number} [z] Initial z value. + * @return {v3.Vec3} the created vector + * @memberOf module:twgl/v3 + */ + export function create(x?: number, y?: number, z?: number): v3.Vec3; + /** + * Adds two vectors; assumes a and b have the same dimension. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} A vector tha tis the sum of a and b. + * @memberOf module:twgl/v3 + */ + export function add(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Subtracts two vectors. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} A vector that is the difference of a and b. + * @memberOf module:twgl/v3 + */ + export function subtract(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient t, returns + * a + t * (b - a). + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {number} t Interpolation coefficient. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The linear interpolated result. + * @memberOf module:twgl/v3 + */ + export function lerp(a: v3.Vec3, b: v3.Vec3, t: number, dst?: v3.Vec3): v3.Vec3; + /** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient vector t, returns + * a + t * (b - a). + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} t Interpolation coefficients vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} the linear interpolated result. + * @memberOf module:twgl/v3 + */ + export function lerpV(a: v3.Vec3, b: v3.Vec3, t: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Return max values of two vectors. + * Given vectors a and b returns + * [max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2])]. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The max components vector. + * @memberOf module:twgl/v3 + */ + export function max(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Return min values of two vectors. + * Given vectors a and b returns + * [min(a[0], b[0]), min(a[1], b[1]), min(a[2], b[2])]. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The min components vector. + * @memberOf module:twgl/v3 + */ + export function min(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Multiplies a vector by a scalar. + * @param {v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ + export function mulScalar(v: v3.Vec3, k: number, dst?: v3.Vec3): v3.Vec3; + /** + * Divides a vector by a scalar. + * @param {v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ + export function divScalar(v: v3.Vec3, k: number, dst?: v3.Vec3): v3.Vec3; + /** + * Computes the cross product of two vectors; assumes both vectors have + * three entries. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The vector of a cross b. + * @memberOf module:twgl/v3 + */ + export function cross(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Computes the dot product of two vectors; assumes both vectors have + * three entries. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @return {number} dot product + * @memberOf module:twgl/v3 + */ + export function dot(a: v3.Vec3, b: v3.Vec3): number; + /** + * Computes the length of vector + * @param {v3.Vec3} v vector. + * @return {number} length of vector. + * @memberOf module:twgl/v3 + */ + export function length(v: v3.Vec3): number; + /** + * Computes the square of the length of vector + * @param {v3.Vec3} v vector. + * @return {number} square of the length of vector. + * @memberOf module:twgl/v3 + */ + export function lengthSq(v: v3.Vec3): number; + /** + * Computes the distance between 2 points + * @param {v3.Vec3} a vector. + * @param {v3.Vec3} b vector. + * @return {number} distance between a and b + * @memberOf module:twgl/v3 + */ + export function distance(a: v3.Vec3, b: v3.Vec3): number; + /** + * Computes the square of the distance between 2 points + * @param {v3.Vec3} a vector. + * @param {v3.Vec3} b vector. + * @return {number} square of the distance between a and b + * @memberOf module:twgl/v3 + */ + export function distanceSq(a: v3.Vec3, b: v3.Vec3): number; + /** + * Divides a vector by its Euclidean length and returns the quotient. + * @param {v3.Vec3} a The vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The normalized vector. + * @memberOf module:twgl/v3 + */ + export function normalize(a: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Negates a vector. + * @param {v3.Vec3} v The vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} -v. + * @memberOf module:twgl/v3 + */ + export function negate(v: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Copies a vector. + * @param {v3.Vec3} v The vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} A copy of v. + * @memberOf module:twgl/v3 + */ + export function copy(v: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Multiplies a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The vector of products of entries of a and + * b. + * @memberOf module:twgl/v3 + */ + export function multiply(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Divides a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {v3.Vec3} a Operand vector. + * @param {v3.Vec3} b Operand vector. + * @param {v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {v3.Vec3} The vector of quotients of entries of a and + * b. + * @memberOf module:twgl/v3 + */ + export function divide(a: v3.Vec3, b: v3.Vec3, dst?: v3.Vec3): v3.Vec3; +} +declare module m4 { + /** + * A JavaScript array with 16 values or a Float32Array with 16 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link m4.setDefaultType}. + * @typedef {(number[]|Float32Array)} Mat4 + * @memberOf module:twgl/m4 + */ + export type Mat4 = number[] | Float32Array; + /** + * Sets the type this library creates for a Mat4 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Mat4 + * @memberOf module:twgl/m4 + */ + export function setDefaultType(ctor: Function): Function; + /** + * Negates a matrix. + * @param {m4.Mat4} m The matrix. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} -m. + * @memberOf module:twgl/m4 + */ + export function negate(m: m4.Mat4, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a matrix. + * @return {m4.Mat4} A new matrix. + * @memberOf module:twgl/m4 + */ + export function create(): m4.Mat4; + /** + * Copies a matrix. + * @param {m4.Mat4} m The matrix. + * @param {m4.Mat4} [dst] The matrix. If not passed a new one is created. + * @return {m4.Mat4} A copy of m. + * @memberOf module:twgl/m4 + */ + export function copy(m: m4.Mat4, dst?: m4.Mat4): m4.Mat4; + /** + * Creates an n-by-n identity matrix. + * + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} An n-by-n identity matrix. + * @memberOf module:twgl/m4 + */ + export function identity(dst?: m4.Mat4): m4.Mat4; + /** + * Takes the transpose of a matrix. + * @param {m4.Mat4} m The matrix. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The transpose of m. + * @memberOf module:twgl/m4 + */ + export function transpose(m: m4.Mat4, dst?: m4.Mat4): m4.Mat4; + /** + * Computes the inverse of a 4-by-4 matrix. + * @param {m4.Mat4} m The matrix. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The inverse of m. + * @memberOf module:twgl/m4 + */ + export function inverse(m: m4.Mat4, dst?: m4.Mat4): m4.Mat4; + /** + * Multiplies two 4-by-4 matrices with a on the left and b on the right + * @param {m4.Mat4} a The matrix on the left. + * @param {m4.Mat4} b The matrix on the right. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The matrix product of a and b. + * @memberOf module:twgl/m4 + */ + export function multiply(a: m4.Mat4, b: m4.Mat4, dst?: m4.Mat4): m4.Mat4; + /** + * Sets the translation component of a 4-by-4 matrix to the given + * vector. + * @param {m4.Mat4} a The matrix. + * @param {v3.Vec3} v The vector. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The matrix with translation set. + * @memberOf module:twgl/m4 + */ + export function setTranslation(a: m4.Mat4, v: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Returns the translation component of a 4-by-4 matrix as a vector with 3 + * entries. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} [dst] vector to hold result. If not passed a new one is created. + * @return {v3.Vec3} The translation component of m. + * @memberOf module:twgl/m4 + */ + export function getTranslation(m: m4.Mat4, dst?: v3.Vec3): v3.Vec3; + /** + * Returns an axis of a 4x4 matrix as a vector with 3 entries + * @param {m4.Mat4} m The matrix. + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @return {v3.Vec3} [dst] vector. + * @return {v3.Vec3} The axis component of m. + * @memberOf module:twgl/m4 + */ + export function getAxis(m: m4.Mat4, axis: number): void; + /** + * Sets an axis of a 4x4 matrix as a vector with 3 entries + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} v the axis vector + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @param {m4.Mat4} [dst] The matrix to set. If not passed a new one is created. + * @return {m4.Mat4} The matrix with axis set. + * @memberOf module:twgl/m4 + */ + export function setAxis(m: m4.Mat4, v: v3.Vec3, axis: number, dst?: m4.Mat4): m4.Mat4; + /** + * Computes a 4-by-4 perspective transformation matrix given the angular height + * of the frustum, the aspect ratio, and the near and far clipping planes. The + * arguments define a frustum extending in the negative z direction. The given + * angle is the vertical angle of the frustum, and the horizontal angle is + * determined to produce the given aspect ratio. The arguments near and far are + * the distances to the near and far clipping planes. Note that near and far + * are not z coordinates, but rather they are distances along the negative + * z-axis. The matrix generated sends the viewing frustum to the unit box. + * We assume a unit box extending from -1 to 1 in the x and y dimensions and + * from 0 to 1 in the z dimension. + * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians). + * @param {number} aspect The aspect ratio width / height. + * @param {number} zNear The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} zFar The depth (negative z coordinate) + * of the far clipping plane. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ + export function perspective(fieldOfViewYInRadians: number, aspect: number, zNear: number, zFar: number, dst?: m4.Mat4): m4.Mat4; + /** + * Computes a 4-by-4 orthogonal transformation matrix given the left, right, + * bottom, and top dimensions of the near clipping plane as well as the + * near and far clipping plane distances. + * @param {number} left Left side of the near clipping plane viewport. + * @param {number} right Right side of the near clipping plane viewport. + * @param {number} bottom Bottom of the near clipping plane viewport. + * @param {number} top Top of the near clipping plane viewport. + * @param {number} near The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} far The depth (negative z coordinate) + * of the far clipping plane. + * @param {m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ + export function ortho(left: number, right: number, bottom: number, top: number, near: number, far: number, dst?: m4.Mat4): m4.Mat4; + /** + * Computes a 4-by-4 perspective transformation matrix given the left, right, + * top, bottom, near and far clipping planes. The arguments define a frustum + * extending in the negative z direction. The arguments near and far are the + * distances to the near and far clipping planes. Note that near and far are not + * z coordinates, but rather they are distances along the negative z-axis. The + * matrix generated sends the viewing frustum to the unit box. We assume a unit + * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z + * dimension. + * @param {number} left The x coordinate of the left plane of the box. + * @param {number} right The x coordinate of the right plane of the box. + * @param {number} bottom The y coordinate of the bottom plane of the box. + * @param {number} top The y coordinate of the right plane of the box. + * @param {number} near The negative z coordinate of the near plane of the box. + * @param {number} far The negative z coordinate of the far plane of the box. + * @param {m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {m4.Mat4} The perspective projection matrix. + * @memberOf module:twgl/m4 + */ + export function frustum(left: number, right: number, bottom: number, top: number, near: number, far: number, dst?: m4.Mat4): m4.Mat4; + /** + * Computes a 4-by-4 look-at transformation. + * + * This is a matrix which positions the camera itself. If you want + * a view matrix (a matrix which moves things in front of the camera) + * take the inverse of this. + * + * @param {v3.Vec3} eye The position of the eye. + * @param {v3.Vec3} target The position meant to be viewed. + * @param {v3.Vec3} up A vector pointing up. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The look-at matrix. + * @memberOf module:twgl/m4 + */ + export function lookAt(eye: v3.Vec3, target: v3.Vec3, up: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which translates by the given vector v. + * @param {v3.Vec3} v The vector by + * which to translate. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The translation matrix. + * @memberOf module:twgl/m4 + */ + export function translation(v: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Translates the given 4-by-4 matrix by the given vector v. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} v The vector by + * which to translate. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The translated matrix. + * @memberOf module:twgl/m4 + */ + export function translate(m: m4.Mat4, v: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ + export function rotationX(angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Rotates the given 4-by-4 matrix around the x-axis by the given + * angle. + * @param {m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ + export function rotateX(m: m4.Mat4, angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ + export function rotationY(angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Rotates the given 4-by-4 matrix around the y-axis by the given + * angle. + * @param {m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ + export function rotateY(m: m4.Mat4, angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ + export function rotationZ(angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Rotates the given 4-by-4 matrix around the z-axis by the given + * angle. + * @param {m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ + export function rotateZ(m: m4.Mat4, angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which rotates around the given axis by the given + * angle. + * @param {v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} A matrix which rotates angle radians + * around the axis. + * @memberOf module:twgl/m4 + */ + export function axisRotation(axis: v3.Vec3, angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Rotates the given 4-by-4 matrix around the given axis by the + * given angle. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ + export function axisRotate(m: m4.Mat4, axis: v3.Vec3, angleInRadians: number, dst?: m4.Mat4): m4.Mat4; + /** + * Creates a 4-by-4 matrix which scales in each dimension by an amount given by + * the corresponding entry in the given vector; assumes the vector has three + * entries. + * @param {v3.Vec3} v A vector of + * three entries specifying the factor by which to scale in each dimension. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The scaling matrix. + * @memberOf module:twgl/m4 + */ + export function scaling(v: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Scales the given 4-by-4 matrix in each dimension by an amount + * given by the corresponding entry in the given vector; assumes the vector has + * three entries. + * @param {m4.Mat4} m The matrix to be modified. + * @param {v3.Vec3} v A vector of three entries specifying the + * factor by which to scale in each dimension. + * @param {m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {m4.Mat4} The scaled matrix. + * @memberOf module:twgl/m4 + */ + export function scale(m: m4.Mat4, v: v3.Vec3, dst?: m4.Mat4): m4.Mat4; + /** + * Takes a 4-by-4 matrix and a vector with 3 entries, + * interprets the vector as a point, transforms that point by the matrix, and + * returns the result as a vector with 3 entries. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} v The point. + * @param {v3.Vec3} [dst] optional vec3 to store result. If not passed a new one is created. + * @return {v3.Vec3} The transformed point. + * @memberOf module:twgl/m4 + */ + export function transformPoint(m: m4.Mat4, v: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a + * direction, transforms that direction by the matrix, and returns the result; + * assumes the transformation of 3-dimensional space represented by the matrix + * is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} v The direction. + * @param {v3.Vec3} [dst] optional Vec3 to store result. If not passed a new one is created. + * @return {v3.Vec3} The transformed direction. + * @memberOf module:twgl/m4 + */ + export function transformDirection(m: m4.Mat4, v: v3.Vec3, dst?: v3.Vec3): v3.Vec3; + /** + * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector + * as a normal to a surface, and computes a vector which is normal upon + * transforming that surface by the matrix. The effect of this function is the + * same as transforming v (as a direction) by the inverse-transpose of m. This + * function assumes the transformation of 3-dimensional space represented by the + * matrix is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {m4.Mat4} m The matrix. + * @param {v3.Vec3} v The normal. + * @param {v3.Vec3} [dst] The direction. If not passed a new one is created. + * @return {v3.Vec3} The transformed normal. + * @memberOf module:twgl/m4 + */ + export function transformNormal(m: m4.Mat4, v: v3.Vec3, dst?: v3.Vec3): v3.Vec3; +} +declare module primitives { + /** + * @typedef {(Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array)} TypedArray + */ + + export type TypedArray = Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array; + + export type AugmentedTypedArrayHelper = { + numComponents: number; + readonly numElements: number; + /** + * Push elements into typed array + */ + push(...elements: (number | TypedArray | number[])[]): void; + /** + * Reset push cursor + */ + reset(index?: number): void; + }; + + export type AugmentedTypedArray = T & AugmentedTypedArrayHelper + + + /** + * 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: + * + * const 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 {ArrayBufferView} A typed array. + * @memberOf module:twgl/primitives + */ + export function createAugmentedTypedArray(numComponents: number, numElements: number, type: T): AugmentedTypedArray>; + export function createAugmentedTypedArray(numComponents: number, numElements: number): AugmentedTypedArray; + + /** + * Given indexed vertices creates a new set of vertices un-indexed by expanding the indexed vertices. + * @param {Object.} vertices The indexed vertices to deindex + * @return {Object.} The deindexed vertices + * @memberOf module:twgl/primitives + */ + export function deindexVertices(vertices: { + [key: string]: TypedArray; + }): { + [key: string]: TypedArray; + }; + /** + * flattens the normals of deindexed vertices in place. + * @param {Object.} vertices The deindexed vertices who's normals to flatten + * @return {Object.} The flattened vertices (same as was passed in) + * @memberOf module:twgl/primitives + */ + export function flattenNormals(vertices: { + [key: string]: TypedArray; + }): { + [key: string]: TypedArray; + }; + /** + * Reorients directions by the given matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ + export function reorientDirections(array: number[] | TypedArray, matrix: m4.Mat4): number[] | TypedArray; + /** + * Reorients normals by the inverse-transpose of the given + * matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ + export function reorientNormals(array: number[] | TypedArray, matrix: m4.Mat4): number[] | TypedArray; + /** + * Reorients positions by the given matrix. In other words, it + * multiplies each vertex by the given matrix. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ + export function reorientPositions(array: number[] | TypedArray, matrix: m4.Mat4): number[] | TypedArray; + /** + * @typedef {(number[]|TypedArray)} NativeArrayOrTypedArray + */ + export type NativeArrayOrTypedArray = number[] | TypedArray; + /** + * Reorients arrays by the given matrix. Assumes arrays have + * names that contains 'pos' could be reoriented as positions, + * 'binorm' or 'tan' as directions, and 'norm' as normals. + * + * @param {Object.} arrays The vertices to reorient + * @param {m4.Mat4} matrix matrix to reorient by. + * @return {Object.} same arrays that were passed in. + * @memberOf module:twgl/primitives + */ + export function reorientVertices(arrays: { + [key: string]: NativeArrayOrTypedArray; + }, matrix: m4.Mat4): { + [key: string]: NativeArrayOrTypedArray; + }; + /** + * Creates XY quad BufferInfo + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad BufferInfo + * @memberOf module:twgl/primitives + * @function createXYQuadBuffers + */ + export function createXYQuadBuffers(gl: WebGLRenderingContext, size?: number, xOffset?: number, yOffset?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates XY quad Buffers + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {BufferInfo} the created XY Quad buffers + * @memberOf module:twgl/primitives + * @function createXYQuadBufferInfo + */ + export function createXYQuadBufferInfo(gl: WebGLRenderingContext, size?: number, xOffset?: number, yOffset?: number): BufferInfo; + /** + * Creates XY quad vertices + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0, 0.5); + * + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad vertices + * @memberOf module:twgl/primitives + */ + export function createXYQuadVertices(size?: number, xOffset?: number, yOffset?: number): { + [key: string]: TypedArray; + }; + /** + * Creates XZ plane BufferInfo. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {BufferInfo} The created plane BufferInfo. + * @memberOf module:twgl/primitives + * @function createPlaneBufferInfo + */ + export function createPlaneBufferInfo(gl: WebGLRenderingContext, width?: number, depth?: number, subdivisionsWidth?: number, subdivisionsDepth?: number, matrix?: m4.Mat4): BufferInfo; + /** + * Creates XZ plane buffers. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane buffers. + * @memberOf module:twgl/primitives + * @function createPlaneBuffers + */ + export function createPlaneBuffers(gl: WebGLRenderingContext, width?: number, depth?: number, subdivisionsWidth?: number, subdivisionsDepth?: number, matrix?: m4.Mat4): { + [key: string]: WebGLBuffer; + }; + /** + * Creates XZ plane vertices. + * + * The created plane has position, normal, and texcoord data + * + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane vertices. + * @memberOf module:twgl/primitives + */ + export function createPlaneVertices(width?: number, depth?: number, subdivisionsWidth?: number, subdivisionsDepth?: number, matrix?: m4.Mat4): { + [key: string]: TypedArray; + }; + /** + * Creates sphere BufferInfo. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {BufferInfo} The created sphere BufferInfo. + * @memberOf module:twgl/primitives + * @function createSphereBufferInfo + */ + export function createSphereBufferInfo(gl: WebGLRenderingContext, radius: number, subdivisionsAxis: number, subdivisionsHeight: number, opt_startLatitudeInRadians?: number, opt_endLatitudeInRadians?: number, opt_startLongitudeInRadians?: number, opt_endLongitudeInRadians?: number): BufferInfo; + /** + * Creates sphere buffers. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere buffers. + * @memberOf module:twgl/primitives + * @function createSphereBuffers + */ + export function createSphereBuffers(gl: WebGLRenderingContext, radius: number, subdivisionsAxis: number, subdivisionsHeight: number, opt_startLatitudeInRadians?: number, opt_endLatitudeInRadians?: number, opt_startLongitudeInRadians?: number, opt_endLongitudeInRadians?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates sphere vertices. + * + * The created sphere has position, normal, and texcoord data + * + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere vertices. + * @memberOf module:twgl/primitives + */ + export function createSphereVertices(radius: number, subdivisionsAxis: number, subdivisionsHeight: number, opt_startLatitudeInRadians?: number, opt_endLatitudeInRadians?: number, opt_startLongitudeInRadians?: number, opt_endLongitudeInRadians?: number): { + [key: string]: TypedArray; + }; + /** + * Creates a BufferInfo for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCubeBufferInfo + */ + export function createCubeBufferInfo(gl: WebGLRenderingContext, size?: number): BufferInfo; + /** + * Creates the buffers and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCubeBuffers + */ + export function createCubeBuffers(gl: WebGLRenderingContext, size?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates the vertices and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function createCubeVertices(size?: number): { + [key: string]: TypedArray; + }; + /** + * Creates a BufferInfo for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {BufferInfo} The created cone BufferInfo. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBufferInfo + */ + export function createTruncatedConeBufferInfo(gl: WebGLRenderingContext, bottomRadius: number, topRadius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, opt_topCap?: boolean, opt_bottomCap?: boolean): BufferInfo; + /** + * Creates buffers for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone buffers. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBuffers + */ + export function createTruncatedConeBuffers(gl: WebGLRenderingContext, bottomRadius: number, topRadius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, opt_topCap?: boolean, opt_bottomCap?: boolean): { + [key: string]: WebGLBuffer; + }; + /** + * Creates vertices for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. . + * + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone vertices. + * @memberOf module:twgl/primitives + */ + export function createTruncatedConeVertices(bottomRadius: number, topRadius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, opt_topCap?: boolean, opt_bottomCap?: boolean): { + [key: string]: TypedArray; + }; + /** + * Creates 3D 'F' BufferInfo. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function create3DFBufferInfo + */ + export function create3DFBufferInfo(gl: WebGLRenderingContext): BufferInfo; + /** + * Creates 3D 'F' buffers. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function create3DFBuffers + */ + export function create3DFBuffers(gl: WebGLRenderingContext): { + [key: string]: WebGLBuffer; + }; + /** + * Creates 3D 'F' vertices. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color arrays. + * + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function create3DFVertices(): { + [key: string]: TypedArray; + }; + /** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCresentBufferInfo + */ + export function createCresentBufferInfo(gl: WebGLRenderingContext, verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): BufferInfo; + /** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + export function createCresentBuffers(gl: WebGLRenderingContext, verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + export function createCresentBuffers(gl: WebGLRenderingContext, verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCrescentBufferInfo + */ + export function createCrescentBufferInfo(gl: WebGLRenderingContext, verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): BufferInfo; + /** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCrescentBuffers + */ + export function createCrescentBuffers(gl: WebGLRenderingContext, verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function createCrescentVertices(verticalRadius: number, outerRadius: number, innerRadius: number, thickness: number, subdivisionsDown: number, startOffset?: number, endOffset?: number): { + [key: string]: TypedArray; + }; + /** + * Creates cylinder BufferInfo. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCylinderBufferInfo + */ + export function createCylinderBufferInfo(gl: WebGLRenderingContext, radius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, topCap?: boolean, bottomCap?: boolean): BufferInfo; + /** + * Creates cylinder buffers. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCylinderBuffers + */ + export function createCylinderBuffers(gl: WebGLRenderingContext, radius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, topCap?: boolean, bottomCap?: boolean): { + [key: string]: WebGLBuffer; + }; + /** + * Creates cylinder vertices. The cylinder will be created around the origin + * along the y-axis. + * + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function createCylinderVertices(radius: number, height: number, radialSubdivisions: number, verticalSubdivisions: number, topCap?: boolean, bottomCap?: boolean): { + [key: string]: TypedArray; + }; + /** + * Creates BufferInfo for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createTorusBufferInfo + */ + export function createTorusBufferInfo(gl: WebGLRenderingContext, radius: number, thickness: number, radialSubdivisions: number, bodySubdivisions: number, startAngle?: boolean, endAngle?: boolean): BufferInfo; + /** + * Creates buffers for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createTorusBuffers + */ + export function createTorusBuffers(gl: WebGLRenderingContext, radius: number, thickness: number, radialSubdivisions: number, bodySubdivisions: number, startAngle?: boolean, endAngle?: boolean): { + [key: string]: WebGLBuffer; + }; + /** + * Creates vertices for a torus + * + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function createTorusVertices(radius: number, thickness: number, radialSubdivisions: number, bodySubdivisions: number, startAngle?: boolean, endAngle?: boolean): { + [key: string]: TypedArray; + }; + /** + * Creates a disc BufferInfo. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createDiscBufferInfo + */ + export function createDiscBufferInfo(gl: WebGLRenderingContext, radius: number, divisions: number, stacks?: number, innerRadius?: number, stackPower?: number): BufferInfo; + /** + * Creates disc buffers. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createDiscBuffers + */ + export function createDiscBuffers(gl: WebGLRenderingContext, radius: number, divisions: number, stacks?: number, innerRadius?: number, stackPower?: number): { + [key: string]: WebGLBuffer; + }; + /** + * Creates disc vertices. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + export function createDiscVertices(radius: number, divisions: number, stacks?: number, innerRadius?: number, stackPower?: number): { + [key: string]: TypedArray; + }; + /** + * Used to supply random colors + * @callback RandomColorFunc + * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed + * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha + * @return {number} a number from 0 to 255 + * @memberOf module:twgl/primitives + */ + export type RandomColorFunc = (ndx: number, channel: number) => number; + /** + * @typedef {Object} RandomVerticesOptions + * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices + * @property {primitives.RandomColorFunc} [rand] A function to generate random numbers + * @memberOf module:twgl/primitives + */ + export type RandomVerticesOptions = { + vertsPerColor?: number; + rand?: primitives.RandomColorFunc; + }; + /** + * Creates an augmentedTypedArray of random vertex colors. + * If the vertices are indexed (have an indices array) then will + * just make random colors. Otherwise assumes they are triangles + * and makes one random color for every 3 vertices. + * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions. + * @param {primitives.RandomVerticesOptions} [options] options. + * @return {Object.} same vertices as passed in with `color` added. + * @memberOf module:twgl/primitives + */ + export function makeRandomVertexColors(vertices: { + [key: string]: ArrayBufferView; + }, options?: primitives.RandomVerticesOptions): { + [key: string]: ArrayBufferView; + }; + /** + * Concatenates sets of vertices + * + * Assumes the vertices match in composition. For example + * if one set of vertices has positions, normals, and indices + * all sets of vertices must have positions, normals, and indices + * and of the same type. + * + * Example: + * + * const cubeVertices = twgl.primitives.createCubeVertices(2); + * const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10); + * // move the sphere 2 units up + * twgl.primitives.reorientVertices( + * sphereVertices, twgl.m4.translation([0, 2, 0])); + * // merge the sphere with the cube + * const cubeSphereVertices = twgl.primitives.concatVertices( + * [cubeVertices, sphereVertices]); + * // turn them into WebGL buffers and attrib data + * const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices); + * + * @param {Arrays[]} arrays Array of arrays of vertices + * @return {Arrays} The concatenated vertices. + * @memberOf module:twgl/primitives + */ + export function concatVertices(arrays: Arrays[]): Arrays; + /** + * Creates a duplicate set of vertices + * + * This is useful for calling reorientVertices when you + * also want to keep the original available + * + * @param {Arrays} arrays of vertices + * @return {Arrays} The duplicated vertices. + * @memberOf module:twgl/primitives + */ + export function duplicateVertices(arrays: Arrays): Arrays; +} \ No newline at end of file diff --git a/dist/6.x/twgl-full.js b/dist/6.x/twgl-full.js new file mode 100644 index 00000000..aa0ef397 --- /dev/null +++ b/dist/6.x/twgl-full.js @@ -0,0 +1,10682 @@ +/*! + * @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. + * Available via the MIT license. + * see: http://github.com/greggman/twgl.js for details + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["twgl"] = factory(); + else + root["twgl"] = factory(); +})(typeof self !== 'undefined' ? self : this, () => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/attributes.js": +/*!***************************!*\ + !*** ./src/attributes.js ***! + \***************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createAttribsFromArrays = createAttribsFromArrays; +exports.createBufferFromArray = createBufferFromArray; +exports.createBufferFromTypedArray = createBufferFromTypedArray; +exports.createBufferInfoFromArrays = createBufferInfoFromArrays; +exports.createBuffersFromArrays = createBuffersFromArrays; +exports.getArray_ = getArray; +exports.getNumComponents_ = getNumComponents; +exports.setAttribInfoBufferFromArray = setAttribInfoBufferFromArray; +exports.setAttributeDefaults_ = setDefaults; +exports.setAttributePrefix = setAttributePrefix; +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var STATIC_DRAW = 0x88e4; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var BUFFER_SIZE = 0x8764; +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; + +/** + * Low level attribute and buffer related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/attributes + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + attribPrefix: "" +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults.attribPrefix = prefix; +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); +} +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (helper.isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER; + var buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return true; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return true; + } // eslint-disable-line + return false; +} +function getArray(array) { + return array.length ? array : array.data; +} +var texcoordRE = /coord|texture/i; +var colorRE = /color|colour/i; +function guessNumComponentsFromName(name, length) { + var numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + if (length % numComponents > 0) { + throw new Error("Can not guess numComponents for attribute '".concat(name, "'. Tried ").concat(numComponents, " but ").concat(length, " values is not evenly divisible by ").concat(numComponents, ". You should specify it.")); + } + return numComponents; +} +function getNumComponents(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length); +} +function makeTypedArray(array, name) { + if (typedArrays.isArrayBuffer(array)) { + return array; + } + if (typedArrays.isArrayBuffer(array.data)) { + return array.data; + } + if (Array.isArray(array)) { + array = { + data: array + }; + } + var Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? glTypeOrTypedArrayCtor : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT; +} +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) : glTypeOrTypedArrayCtor || Float32Array; +} +function attribBufferFromBuffer(gl, array /*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, + // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) + }; +} +function attribBufferFromSize(gl, array /*, arrayName*/) { + var numValues = array.data || array; + var arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + var numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + var buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER, buffer); + gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW); + return { + buffer: buffer, + numValues: numValues, + type: typedArrays.getGLTypeForTypedArrayType(arrayType), + arrayType: arrayType + }; +} +function attribBufferFromArrayLike(gl, array, arrayName) { + var typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: typedArrays.getGLTypeForTypedArray(typedArray), + numValues: 0 + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + var attribs = {}; + Object.keys(arrays).forEach(function (arrayName) { + if (!isIndices(arrayName)) { + var array = arrays[arrayName]; + var attribName = array.attrib || array.name || array.attribName || defaults.attribPrefix + arrayName; + if (array.value) { + if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value + }; + } else { + var fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + var _fn = fn(gl, array, arrayName), + buffer = _fn.buffer, + type = _fn.type, + numValues = _fn.numValues, + arrayType = _fn.arrayType; + var normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + var numComponents = getNumComponents(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType); + } +} +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line + if (type === SHORT) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line + if (type === INT) return 4; // eslint-disable-line + if (type === UNSIGNED_INT) return 4; // eslint-disable-line + if (type === FLOAT) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +var positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + var array = arrays[key]; + var length = getArray(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + var numComponents = getNumComponents(array, key); + var numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} +function getNumElementsFromAttributes(gl, attribs) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + var attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER, attrib.buffer); + var numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER, null); + var bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + var totalElements = numBytes / bytesPerValue; + var numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + var numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + var newAttribs = createAttribsFromArrays(gl, arrays); + var bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + var indices = arrays.indices; + if (indices) { + var newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + var type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER; + var typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + var buffers = {}; + Object.keys(arrays).forEach(function (key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices'); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + return buffers; +} + +/***/ }), + +/***/ "./src/draw.js": +/*!*********************!*\ + !*** ./src/draw.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.drawBufferInfo = drawBufferInfo; +exports.drawObjectList = drawObjectList; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var TRIANGLES = 0x0004; +var UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + var indices = bufferInfo.indices; + var elementType = bufferInfo.elementType; + var numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + var lastUsedProgramInfo = null; + var lastUsedBufferInfo = null; + objectsToDraw.forEach(function (object) { + if (object.active === false) { + return; + } + var programInfo = object.programInfo; + var bufferInfo = object.vertexArrayInfo || object.bufferInfo; + var bindBuffers = false; + var type = object.type === undefined ? TRIANGLES : object.type; + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + programs.setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +/***/ }), + +/***/ "./src/framebuffers.js": +/*!*****************************!*\ + !*** ./src/framebuffers.js ***! + \*****************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindFramebufferInfo = bindFramebufferInfo; +exports.createFramebufferInfo = createFramebufferInfo; +exports.resizeFramebufferInfo = resizeFramebufferInfo; +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Framebuffer related functions + * + * For backward compatibility they are available at both `twgl.framebuffer` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/framebuffers + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var FRAMEBUFFER = 0x8d40; +var RENDERBUFFER = 0x8d41; +var TEXTURE_2D = 0x0de1; +var UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +var DEPTH_COMPONENT = 0x1902; +var RGBA = 0x1908; +var DEPTH_COMPONENT24 = 0x81a6; +var DEPTH_COMPONENT32F = 0x8cac; +var DEPTH24_STENCIL8 = 0x88f0; +var DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +var RGBA4 = 0x8056; +var RGB5_A1 = 0x8057; +var RGB565 = 0x8D62; +var DEPTH_COMPONENT16 = 0x81A5; +var STENCIL_INDEX = 0x1901; +var STENCIL_INDEX8 = 0x8D48; +var DEPTH_STENCIL = 0x84F9; +var COLOR_ATTACHMENT0 = 0x8CE0; +var DEPTH_ATTACHMENT = 0x8D00; +var STENCIL_ATTACHMENT = 0x8D20; +var DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +var CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +var LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +var defaultAttachments = [{ + format: RGBA, + type: UNSIGNED_BYTE, + min: LINEAR, + wrap: CLAMP_TO_EDGE +}, { + format: DEPTH_STENCIL +}]; +var attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} +var renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} +var MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + var target = FRAMEBUFFER; + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + var usedColorAttachmentsPoints = []; + var framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height + }; + attachments.forEach(function (attachmentOptions, i) { + var attachment = attachmentOptions.attachment; + var samples = attachmentOptions.samples; + var format = attachmentOptions.format; + var attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + var textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = textures.createTexture(gl, textureOptions); + } + } + if (helper.isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (helper.isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer(target, attachmentPoint, attachment, attachmentOptions.level || 0, attachmentOptions.layer); + } else { + gl.framebufferTexture2D(target, attachmentPoint, attachmentOptions.target || TEXTURE_2D, attachment, attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function (attachmentOptions, ndx) { + var attachment = framebufferInfo.attachments[ndx]; + var format = attachmentOptions.format; + var samples = attachmentOptions.samples; + if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (helper.isTexture(gl, attachment)) { + textures.resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +/***/ }), + +/***/ "./src/helper.js": +/*!***********************!*\ + !*** ./src/helper.js ***! + \***********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.copyExistingProperties = copyExistingProperties; +exports.copyNamedProperties = copyNamedProperties; +exports.error = error; +exports.isBuffer = isBuffer; +exports.isRenderbuffer = isRenderbuffer; +exports.isSampler = isSampler; +exports.isShader = isShader; +exports.isTexture = isTexture; +exports.warn = warn; +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* eslint no-console: "off" */ + +/** + * Copy named properties + * + * @param {string[]} names names of properties to copy + * @param {object} src object to copy properties from + * @param {object} dst object to copy properties to + * @private + */ +function copyNamedProperties(names, src, dst) { + names.forEach(function (name) { + var value = src[name]; + if (value !== undefined) { + dst[name] = value; + } + }); +} + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function (key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { + /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} +function error() { + var _console; + (_console = console).error.apply(_console, arguments); +} +function warn() { + var _console2; + (_console2 = console).warn.apply(_console2, arguments); +} +var isTypeWeakMaps = new Map(); +function isType(object, type) { + if (!object || _typeof(object) !== 'object') { + return false; + } + var weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + var isOfType = weakMap.get(object); + if (isOfType === undefined) { + var s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} +function isShader(gl, t) { + return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader'); +} +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/***/ }), + +/***/ "./src/m4.js": +/*!*******************!*\ + !*** ./src/m4.js ***! + \*******************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.axisRotate = axisRotate; +exports.axisRotation = axisRotation; +exports.copy = copy; +exports.create = create; +exports.frustum = frustum; +exports.getAxis = getAxis; +exports.getTranslation = getTranslation; +exports.identity = identity; +exports.inverse = inverse; +exports.lookAt = lookAt; +exports.multiply = multiply; +exports.negate = negate; +exports.ortho = ortho; +exports.perspective = perspective; +exports.rotateX = rotateX; +exports.rotateY = rotateY; +exports.rotateZ = rotateZ; +exports.rotationX = rotationX; +exports.rotationY = rotationY; +exports.rotationZ = rotationZ; +exports.scale = scale; +exports.scaling = scaling; +exports.setAxis = setAxis; +exports.setDefaultType = setDefaultType; +exports.setTranslation = setTranslation; +exports.transformDirection = transformDirection; +exports.transformNormal = transformNormal; +exports.transformPoint = transformPoint; +exports.translate = translate; +exports.translation = translation; +exports.transpose = transpose; +var v3 = _interopRequireWildcard(__webpack_require__(/*! ./v3.js */ "./src/v3.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * 4x4 Matrix math math functions. + * + * Almost all functions take an optional `dst` argument. If it is not passed in the + * functions will create a new matrix. In other words you can do this + * + * const mat = m4.translation([1, 2, 3]); // Creates a new translation matrix + * + * or + * + * const mat = m4.create(); + * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat. + * + * The first style is often easier but depending on where it's used it generates garbage where + * as there is almost never allocation with the second style. + * + * It is always save to pass any matrix as the destination. So for example + * + * const mat = m4.identity(); + * const trans = m4.translation([1, 2, 3]); + * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat. + * + * @module twgl/m4 + */ +var MatType = Float32Array; + +/** + * A JavaScript array with 16 values or a Float32Array with 16 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link module:twgl/m4.setDefaultType}. + * @typedef {(number[]|Float32Array)} Mat4 + * @memberOf module:twgl/m4 + */ + +/** + * Sets the type this library creates for a Mat4 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Mat4 + * @memberOf module:twgl/m4 + */ +function setDefaultType(ctor) { + var oldType = MatType; + MatType = ctor; + return oldType; +} + +/** + * Negates a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} -m. + * @memberOf module:twgl/m4 + */ +function negate(m, dst) { + dst = dst || new MatType(16); + dst[0] = -m[0]; + dst[1] = -m[1]; + dst[2] = -m[2]; + dst[3] = -m[3]; + dst[4] = -m[4]; + dst[5] = -m[5]; + dst[6] = -m[6]; + dst[7] = -m[7]; + dst[8] = -m[8]; + dst[9] = -m[9]; + dst[10] = -m[10]; + dst[11] = -m[11]; + dst[12] = -m[12]; + dst[13] = -m[13]; + dst[14] = -m[14]; + dst[15] = -m[15]; + return dst; +} + +/** + * Creates a matrix. + * @return {module:twgl/m4.Mat4} A new matrix. + * @memberOf module:twgl/m4 + */ +function create() { + return new MatType(16).fill(0); +} + +/** + * Copies a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] The matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A copy of m. + * @memberOf module:twgl/m4 + */ +function copy(m, dst) { + dst = dst || new MatType(16); + dst[0] = m[0]; + dst[1] = m[1]; + dst[2] = m[2]; + dst[3] = m[3]; + dst[4] = m[4]; + dst[5] = m[5]; + dst[6] = m[6]; + dst[7] = m[7]; + dst[8] = m[8]; + dst[9] = m[9]; + dst[10] = m[10]; + dst[11] = m[11]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + return dst; +} + +/** + * Creates an n-by-n identity matrix. + * + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} An n-by-n identity matrix. + * @memberOf module:twgl/m4 + */ +function identity(dst) { + dst = dst || new MatType(16); + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 1; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Takes the transpose of a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The transpose of m. + * @memberOf module:twgl/m4 + */ +function transpose(m, dst) { + dst = dst || new MatType(16); + if (dst === m) { + var t; + t = m[1]; + m[1] = m[4]; + m[4] = t; + t = m[2]; + m[2] = m[8]; + m[8] = t; + t = m[3]; + m[3] = m[12]; + m[12] = t; + t = m[6]; + m[6] = m[9]; + m[9] = t; + t = m[7]; + m[7] = m[13]; + m[13] = t; + t = m[11]; + m[11] = m[14]; + m[14] = t; + return dst; + } + var m00 = m[0 * 4 + 0]; + var m01 = m[0 * 4 + 1]; + var m02 = m[0 * 4 + 2]; + var m03 = m[0 * 4 + 3]; + var m10 = m[1 * 4 + 0]; + var m11 = m[1 * 4 + 1]; + var m12 = m[1 * 4 + 2]; + var m13 = m[1 * 4 + 3]; + var m20 = m[2 * 4 + 0]; + var m21 = m[2 * 4 + 1]; + var m22 = m[2 * 4 + 2]; + var m23 = m[2 * 4 + 3]; + var m30 = m[3 * 4 + 0]; + var m31 = m[3 * 4 + 1]; + var m32 = m[3 * 4 + 2]; + var m33 = m[3 * 4 + 3]; + dst[0] = m00; + dst[1] = m10; + dst[2] = m20; + dst[3] = m30; + dst[4] = m01; + dst[5] = m11; + dst[6] = m21; + dst[7] = m31; + dst[8] = m02; + dst[9] = m12; + dst[10] = m22; + dst[11] = m32; + dst[12] = m03; + dst[13] = m13; + dst[14] = m23; + dst[15] = m33; + return dst; +} + +/** + * Computes the inverse of a 4-by-4 matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The inverse of m. + * @memberOf module:twgl/m4 + */ +function inverse(m, dst) { + dst = dst || new MatType(16); + var m00 = m[0 * 4 + 0]; + var m01 = m[0 * 4 + 1]; + var m02 = m[0 * 4 + 2]; + var m03 = m[0 * 4 + 3]; + var m10 = m[1 * 4 + 0]; + var m11 = m[1 * 4 + 1]; + var m12 = m[1 * 4 + 2]; + var m13 = m[1 * 4 + 3]; + var m20 = m[2 * 4 + 0]; + var m21 = m[2 * 4 + 1]; + var m22 = m[2 * 4 + 2]; + var m23 = m[2 * 4 + 3]; + var m30 = m[3 * 4 + 0]; + var m31 = m[3 * 4 + 1]; + var m32 = m[3 * 4 + 2]; + var m33 = m[3 * 4 + 3]; + var tmp_0 = m22 * m33; + var tmp_1 = m32 * m23; + var tmp_2 = m12 * m33; + var tmp_3 = m32 * m13; + var tmp_4 = m12 * m23; + var tmp_5 = m22 * m13; + var tmp_6 = m02 * m33; + var tmp_7 = m32 * m03; + var tmp_8 = m02 * m23; + var tmp_9 = m22 * m03; + var tmp_10 = m02 * m13; + var tmp_11 = m12 * m03; + var tmp_12 = m20 * m31; + var tmp_13 = m30 * m21; + var tmp_14 = m10 * m31; + var tmp_15 = m30 * m11; + var tmp_16 = m10 * m21; + var tmp_17 = m20 * m11; + var tmp_18 = m00 * m31; + var tmp_19 = m30 * m01; + var tmp_20 = m00 * m21; + var tmp_21 = m20 * m01; + var tmp_22 = m00 * m11; + var tmp_23 = m10 * m01; + var t0 = tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31 - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); + var t1 = tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31 - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); + var t2 = tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31 - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); + var t3 = tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21 - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); + var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); + dst[0] = d * t0; + dst[1] = d * t1; + dst[2] = d * t2; + dst[3] = d * t3; + dst[4] = d * (tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30 - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); + dst[5] = d * (tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30 - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); + dst[6] = d * (tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30 - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); + dst[7] = d * (tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20 - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); + dst[8] = d * (tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33 - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); + dst[9] = d * (tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33 - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); + dst[10] = d * (tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33 - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); + dst[11] = d * (tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23 - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); + dst[12] = d * (tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12 - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); + dst[13] = d * (tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22 - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); + dst[14] = d * (tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02 - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); + dst[15] = d * (tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12 - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); + return dst; +} + +/** + * Multiplies two 4-by-4 matrices with a on the left and b on the right + * @param {module:twgl/m4.Mat4} a The matrix on the left. + * @param {module:twgl/m4.Mat4} b The matrix on the right. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix product of a and b. + * @memberOf module:twgl/m4 + */ +function multiply(a, b, dst) { + dst = dst || new MatType(16); + var a00 = a[0]; + var a01 = a[1]; + var a02 = a[2]; + var a03 = a[3]; + var a10 = a[4 + 0]; + var a11 = a[4 + 1]; + var a12 = a[4 + 2]; + var a13 = a[4 + 3]; + var a20 = a[8 + 0]; + var a21 = a[8 + 1]; + var a22 = a[8 + 2]; + var a23 = a[8 + 3]; + var a30 = a[12 + 0]; + var a31 = a[12 + 1]; + var a32 = a[12 + 2]; + var a33 = a[12 + 3]; + var b00 = b[0]; + var b01 = b[1]; + var b02 = b[2]; + var b03 = b[3]; + var b10 = b[4 + 0]; + var b11 = b[4 + 1]; + var b12 = b[4 + 2]; + var b13 = b[4 + 3]; + var b20 = b[8 + 0]; + var b21 = b[8 + 1]; + var b22 = b[8 + 2]; + var b23 = b[8 + 3]; + var b30 = b[12 + 0]; + var b31 = b[12 + 1]; + var b32 = b[12 + 2]; + var b33 = b[12 + 3]; + dst[0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03; + dst[1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03; + dst[2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03; + dst[3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03; + dst[4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13; + dst[5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13; + dst[6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13; + dst[7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13; + dst[8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23; + dst[9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23; + dst[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23; + dst[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23; + dst[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33; + dst[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33; + dst[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33; + dst[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33; + return dst; +} + +/** + * Sets the translation component of a 4-by-4 matrix to the given + * vector. + * @param {module:twgl/m4.Mat4} a The matrix. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with translation set. + * @memberOf module:twgl/m4 + */ +function setTranslation(a, v, dst) { + dst = dst || identity(); + if (a !== dst) { + dst[0] = a[0]; + dst[1] = a[1]; + dst[2] = a[2]; + dst[3] = a[3]; + dst[4] = a[4]; + dst[5] = a[5]; + dst[6] = a[6]; + dst[7] = a[7]; + dst[8] = a[8]; + dst[9] = a[9]; + dst[10] = a[10]; + dst[11] = a[11]; + } + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; + return dst; +} + +/** + * Returns the translation component of a 4-by-4 matrix as a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The translation component of m. + * @memberOf module:twgl/m4 + */ +function getTranslation(m, dst) { + dst = dst || v3.create(); + dst[0] = m[12]; + dst[1] = m[13]; + dst[2] = m[14]; + return dst; +} + +/** + * Returns an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @return {module:twgl/v3.Vec3} [dst] vector. + * @return {module:twgl/v3.Vec3} The axis component of m. + * @memberOf module:twgl/m4 + */ +function getAxis(m, axis, dst) { + dst = dst || v3.create(); + var off = axis * 4; + dst[0] = m[off + 0]; + dst[1] = m[off + 1]; + dst[2] = m[off + 2]; + return dst; +} + +/** + * Sets an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v the axis vector + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with axis set. + * @memberOf module:twgl/m4 + */ +function setAxis(a, v, axis, dst) { + if (dst !== a) { + dst = copy(a, dst); + } + var off = axis * 4; + dst[off + 0] = v[0]; + dst[off + 1] = v[1]; + dst[off + 2] = v[2]; + return dst; +} + +/** + * Computes a 4-by-4 perspective transformation matrix given the angular height + * of the frustum, the aspect ratio, and the near and far clipping planes. The + * arguments define a frustum extending in the negative z direction. The given + * angle is the vertical angle of the frustum, and the horizontal angle is + * determined to produce the given aspect ratio. The arguments near and far are + * the distances to the near and far clipping planes. Note that near and far + * are not z coordinates, but rather they are distances along the negative + * z-axis. The matrix generated sends the viewing frustum to the unit box. + * We assume a unit box extending from -1 to 1 in the x and y dimensions and + * from 0 to 1 in the z dimension. + * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians). + * @param {number} aspect The aspect ratio width / height. + * @param {number} zNear The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} zFar The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ +function perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) { + dst = dst || new MatType(16); + var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians); + var rangeInv = 1.0 / (zNear - zFar); + dst[0] = f / aspect; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = f; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = (zNear + zFar) * rangeInv; + dst[11] = -1; + dst[12] = 0; + dst[13] = 0; + dst[14] = zNear * zFar * rangeInv * 2; + dst[15] = 0; + return dst; +} + +/** + * Computes a 4-by-4 orthogonal transformation matrix given the left, right, + * bottom, and top dimensions of the near clipping plane as well as the + * near and far clipping plane distances. + * @param {number} left Left side of the near clipping plane viewport. + * @param {number} right Right side of the near clipping plane viewport. + * @param {number} bottom Bottom of the near clipping plane viewport. + * @param {number} top Top of the near clipping plane viewport. + * @param {number} near The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} far The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ +function ortho(left, right, bottom, top, near, far, dst) { + dst = dst || new MatType(16); + dst[0] = 2 / (right - left); + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 2 / (top - bottom); + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 2 / (near - far); + dst[11] = 0; + dst[12] = (right + left) / (left - right); + dst[13] = (top + bottom) / (bottom - top); + dst[14] = (far + near) / (near - far); + dst[15] = 1; + return dst; +} + +/** + * Computes a 4-by-4 perspective transformation matrix given the left, right, + * top, bottom, near and far clipping planes. The arguments define a frustum + * extending in the negative z direction. The arguments near and far are the + * distances to the near and far clipping planes. Note that near and far are not + * z coordinates, but rather they are distances along the negative z-axis. The + * matrix generated sends the viewing frustum to the unit box. We assume a unit + * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z + * dimension. + * @param {number} left The x coordinate of the left plane of the box. + * @param {number} right The x coordinate of the right plane of the box. + * @param {number} bottom The y coordinate of the bottom plane of the box. + * @param {number} top The y coordinate of the right plane of the box. + * @param {number} near The negative z coordinate of the near plane of the box. + * @param {number} far The negative z coordinate of the far plane of the box. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective projection matrix. + * @memberOf module:twgl/m4 + */ +function frustum(left, right, bottom, top, near, far, dst) { + dst = dst || new MatType(16); + var dx = right - left; + var dy = top - bottom; + var dz = near - far; + dst[0] = 2 * near / dx; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 2 * near / dy; + dst[6] = 0; + dst[7] = 0; + dst[8] = (left + right) / dx; + dst[9] = (top + bottom) / dy; + dst[10] = far / dz; + dst[11] = -1; + dst[12] = 0; + dst[13] = 0; + dst[14] = near * far / dz; + dst[15] = 0; + return dst; +} +var xAxis; +var yAxis; +var zAxis; + +/** + * Computes a 4-by-4 look-at transformation. + * + * This is a matrix which positions the camera itself. If you want + * a view matrix (a matrix which moves things in front of the camera) + * take the inverse of this. + * + * @param {module:twgl/v3.Vec3} eye The position of the eye. + * @param {module:twgl/v3.Vec3} target The position meant to be viewed. + * @param {module:twgl/v3.Vec3} up A vector pointing up. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The look-at matrix. + * @memberOf module:twgl/m4 + */ +function lookAt(eye, target, up, dst) { + dst = dst || new MatType(16); + xAxis = xAxis || v3.create(); + yAxis = yAxis || v3.create(); + zAxis = zAxis || v3.create(); + v3.normalize(v3.subtract(eye, target, zAxis), zAxis); + v3.normalize(v3.cross(up, zAxis, xAxis), xAxis); + v3.normalize(v3.cross(zAxis, xAxis, yAxis), yAxis); + dst[0] = xAxis[0]; + dst[1] = xAxis[1]; + dst[2] = xAxis[2]; + dst[3] = 0; + dst[4] = yAxis[0]; + dst[5] = yAxis[1]; + dst[6] = yAxis[2]; + dst[7] = 0; + dst[8] = zAxis[0]; + dst[9] = zAxis[1]; + dst[10] = zAxis[2]; + dst[11] = 0; + dst[12] = eye[0]; + dst[13] = eye[1]; + dst[14] = eye[2]; + dst[15] = 1; + return dst; +} + +/** + * Creates a 4-by-4 matrix which translates by the given vector v. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translation matrix. + * @memberOf module:twgl/m4 + */ +function translation(v, dst) { + dst = dst || new MatType(16); + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = 1; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; + return dst; +} + +/** + * Translates the given 4-by-4 matrix by the given vector v. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translated matrix. + * @memberOf module:twgl/m4 + */ +function translate(m, v, dst) { + dst = dst || new MatType(16); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + var m00 = m[0]; + var m01 = m[1]; + var m02 = m[2]; + var m03 = m[3]; + var m10 = m[1 * 4 + 0]; + var m11 = m[1 * 4 + 1]; + var m12 = m[1 * 4 + 2]; + var m13 = m[1 * 4 + 3]; + var m20 = m[2 * 4 + 0]; + var m21 = m[2 * 4 + 1]; + var m22 = m[2 * 4 + 2]; + var m23 = m[2 * 4 + 3]; + var m30 = m[3 * 4 + 0]; + var m31 = m[3 * 4 + 1]; + var m32 = m[3 * 4 + 2]; + var m33 = m[3 * 4 + 3]; + if (m !== dst) { + dst[0] = m00; + dst[1] = m01; + dst[2] = m02; + dst[3] = m03; + dst[4] = m10; + dst[5] = m11; + dst[6] = m12; + dst[7] = m13; + dst[8] = m20; + dst[9] = m21; + dst[10] = m22; + dst[11] = m23; + } + dst[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; + dst[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; + dst[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; + dst[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationX(angleInRadians, dst) { + dst = dst || new MatType(16); + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[0] = 1; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = c; + dst[6] = s; + dst[7] = 0; + dst[8] = 0; + dst[9] = -s; + dst[10] = c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the x-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateX(m, angleInRadians, dst) { + dst = dst || new MatType(16); + var m10 = m[4]; + var m11 = m[5]; + var m12 = m[6]; + var m13 = m[7]; + var m20 = m[8]; + var m21 = m[9]; + var m22 = m[10]; + var m23 = m[11]; + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[4] = c * m10 + s * m20; + dst[5] = c * m11 + s * m21; + dst[6] = c * m12 + s * m22; + dst[7] = c * m13 + s * m23; + dst[8] = c * m20 - s * m10; + dst[9] = c * m21 - s * m11; + dst[10] = c * m22 - s * m12; + dst[11] = c * m23 - s * m13; + if (m !== dst) { + dst[0] = m[0]; + dst[1] = m[1]; + dst[2] = m[2]; + dst[3] = m[3]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationY(angleInRadians, dst) { + dst = dst || new MatType(16); + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[0] = c; + dst[1] = 0; + dst[2] = -s; + dst[3] = 0; + dst[4] = 0; + dst[5] = 1; + dst[6] = 0; + dst[7] = 0; + dst[8] = s; + dst[9] = 0; + dst[10] = c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the y-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateY(m, angleInRadians, dst) { + dst = dst || new MatType(16); + var m00 = m[0 * 4 + 0]; + var m01 = m[0 * 4 + 1]; + var m02 = m[0 * 4 + 2]; + var m03 = m[0 * 4 + 3]; + var m20 = m[2 * 4 + 0]; + var m21 = m[2 * 4 + 1]; + var m22 = m[2 * 4 + 2]; + var m23 = m[2 * 4 + 3]; + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[0] = c * m00 - s * m20; + dst[1] = c * m01 - s * m21; + dst[2] = c * m02 - s * m22; + dst[3] = c * m03 - s * m23; + dst[8] = c * m20 + s * m00; + dst[9] = c * m21 + s * m01; + dst[10] = c * m22 + s * m02; + dst[11] = c * m23 + s * m03; + if (m !== dst) { + dst[4] = m[4]; + dst[5] = m[5]; + dst[6] = m[6]; + dst[7] = m[7]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationZ(angleInRadians, dst) { + dst = dst || new MatType(16); + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[0] = c; + dst[1] = s; + dst[2] = 0; + dst[3] = 0; + dst[4] = -s; + dst[5] = c; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the z-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateZ(m, angleInRadians, dst) { + dst = dst || new MatType(16); + var m00 = m[0 * 4 + 0]; + var m01 = m[0 * 4 + 1]; + var m02 = m[0 * 4 + 2]; + var m03 = m[0 * 4 + 3]; + var m10 = m[1 * 4 + 0]; + var m11 = m[1 * 4 + 1]; + var m12 = m[1 * 4 + 2]; + var m13 = m[1 * 4 + 3]; + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + dst[0] = c * m00 + s * m10; + dst[1] = c * m01 + s * m11; + dst[2] = c * m02 + s * m12; + dst[3] = c * m03 + s * m13; + dst[4] = c * m10 - s * m00; + dst[5] = c * m11 - s * m01; + dst[6] = c * m12 - s * m02; + dst[7] = c * m13 - s * m03; + if (m !== dst) { + dst[8] = m[8]; + dst[9] = m[9]; + dst[10] = m[10]; + dst[11] = m[11]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the given axis by the given + * angle. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians + * around the axis. + * @memberOf module:twgl/m4 + */ +function axisRotation(axis, angleInRadians, dst) { + dst = dst || new MatType(16); + var x = axis[0]; + var y = axis[1]; + var z = axis[2]; + var n = Math.sqrt(x * x + y * y + z * z); + x /= n; + y /= n; + z /= n; + var xx = x * x; + var yy = y * y; + var zz = z * z; + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + var oneMinusCosine = 1 - c; + dst[0] = xx + (1 - xx) * c; + dst[1] = x * y * oneMinusCosine + z * s; + dst[2] = x * z * oneMinusCosine - y * s; + dst[3] = 0; + dst[4] = x * y * oneMinusCosine - z * s; + dst[5] = yy + (1 - yy) * c; + dst[6] = y * z * oneMinusCosine + x * s; + dst[7] = 0; + dst[8] = x * z * oneMinusCosine + y * s; + dst[9] = y * z * oneMinusCosine - x * s; + dst[10] = zz + (1 - zz) * c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the given axis by the + * given angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function axisRotate(m, axis, angleInRadians, dst) { + dst = dst || new MatType(16); + var x = axis[0]; + var y = axis[1]; + var z = axis[2]; + var n = Math.sqrt(x * x + y * y + z * z); + x /= n; + y /= n; + z /= n; + var xx = x * x; + var yy = y * y; + var zz = z * z; + var c = Math.cos(angleInRadians); + var s = Math.sin(angleInRadians); + var oneMinusCosine = 1 - c; + var r00 = xx + (1 - xx) * c; + var r01 = x * y * oneMinusCosine + z * s; + var r02 = x * z * oneMinusCosine - y * s; + var r10 = x * y * oneMinusCosine - z * s; + var r11 = yy + (1 - yy) * c; + var r12 = y * z * oneMinusCosine + x * s; + var r20 = x * z * oneMinusCosine + y * s; + var r21 = y * z * oneMinusCosine - x * s; + var r22 = zz + (1 - zz) * c; + var m00 = m[0]; + var m01 = m[1]; + var m02 = m[2]; + var m03 = m[3]; + var m10 = m[4]; + var m11 = m[5]; + var m12 = m[6]; + var m13 = m[7]; + var m20 = m[8]; + var m21 = m[9]; + var m22 = m[10]; + var m23 = m[11]; + dst[0] = r00 * m00 + r01 * m10 + r02 * m20; + dst[1] = r00 * m01 + r01 * m11 + r02 * m21; + dst[2] = r00 * m02 + r01 * m12 + r02 * m22; + dst[3] = r00 * m03 + r01 * m13 + r02 * m23; + dst[4] = r10 * m00 + r11 * m10 + r12 * m20; + dst[5] = r10 * m01 + r11 * m11 + r12 * m21; + dst[6] = r10 * m02 + r11 * m12 + r12 * m22; + dst[7] = r10 * m03 + r11 * m13 + r12 * m23; + dst[8] = r20 * m00 + r21 * m10 + r22 * m20; + dst[9] = r20 * m01 + r21 * m11 + r22 * m21; + dst[10] = r20 * m02 + r21 * m12 + r22 * m22; + dst[11] = r20 * m03 + r21 * m13 + r22 * m23; + if (m !== dst) { + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + return dst; +} + +/** + * Creates a 4-by-4 matrix which scales in each dimension by an amount given by + * the corresponding entry in the given vector; assumes the vector has three + * entries. + * @param {module:twgl/v3.Vec3} v A vector of + * three entries specifying the factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaling matrix. + * @memberOf module:twgl/m4 + */ +function scaling(v, dst) { + dst = dst || new MatType(16); + dst[0] = v[0]; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + dst[4] = 0; + dst[5] = v[1]; + dst[6] = 0; + dst[7] = 0; + dst[8] = 0; + dst[9] = 0; + dst[10] = v[2]; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + return dst; +} + +/** + * Scales the given 4-by-4 matrix in each dimension by an amount + * given by the corresponding entry in the given vector; assumes the vector has + * three entries. + * @param {module:twgl/m4.Mat4} m The matrix to be modified. + * @param {module:twgl/v3.Vec3} v A vector of three entries specifying the + * factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaled matrix. + * @memberOf module:twgl/m4 + */ +function scale(m, v, dst) { + dst = dst || new MatType(16); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + dst[0] = v0 * m[0 * 4 + 0]; + dst[1] = v0 * m[0 * 4 + 1]; + dst[2] = v0 * m[0 * 4 + 2]; + dst[3] = v0 * m[0 * 4 + 3]; + dst[4] = v1 * m[1 * 4 + 0]; + dst[5] = v1 * m[1 * 4 + 1]; + dst[6] = v1 * m[1 * 4 + 2]; + dst[7] = v1 * m[1 * 4 + 3]; + dst[8] = v2 * m[2 * 4 + 0]; + dst[9] = v2 * m[2 * 4 + 1]; + dst[10] = v2 * m[2 * 4 + 2]; + dst[11] = v2 * m[2 * 4 + 3]; + if (m !== dst) { + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + return dst; +} + +/** + * Takes a 4-by-4 matrix and a vector with 3 entries, + * interprets the vector as a point, transforms that point by the matrix, and + * returns the result as a vector with 3 entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The point. + * @param {module:twgl/v3.Vec3} [dst] optional vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed point. + * @memberOf module:twgl/m4 + */ +function transformPoint(m, v, dst) { + dst = dst || v3.create(); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + var d = v0 * m[0 * 4 + 3] + v1 * m[1 * 4 + 3] + v2 * m[2 * 4 + 3] + m[3 * 4 + 3]; + dst[0] = (v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0] + m[3 * 4 + 0]) / d; + dst[1] = (v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1] + m[3 * 4 + 1]) / d; + dst[2] = (v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2] + m[3 * 4 + 2]) / d; + return dst; +} + +/** + * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a + * direction, transforms that direction by the matrix, and returns the result; + * assumes the transformation of 3-dimensional space represented by the matrix + * is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The direction. + * @param {module:twgl/v3.Vec3} [dst] optional Vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed direction. + * @memberOf module:twgl/m4 + */ +function transformDirection(m, v, dst) { + dst = dst || v3.create(); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + dst[0] = v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0]; + dst[1] = v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1]; + dst[2] = v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2]; + return dst; +} + +/** + * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector + * as a normal to a surface, and computes a vector which is normal upon + * transforming that surface by the matrix. The effect of this function is the + * same as transforming v (as a direction) by the inverse-transpose of m. This + * function assumes the transformation of 3-dimensional space represented by the + * matrix is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The normal. + * @param {module:twgl/v3.Vec3} [dst] The direction. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed normal. + * @memberOf module:twgl/m4 + */ +function transformNormal(m, v, dst) { + dst = dst || v3.create(); + var mi = inverse(m); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; + dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; + dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; + return dst; +} + +/***/ }), + +/***/ "./src/primitives.js": +/*!***************************!*\ + !*** ./src/primitives.js ***! + \***************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.concatVertices = concatVertices; +exports.create3DFBuffers = exports.create3DFBufferInfo = void 0; +exports.create3DFVertices = create3DFVertices; +exports.createAugmentedTypedArray = createAugmentedTypedArray; +exports.createCrescentBuffers = exports.createCrescentBufferInfo = void 0; +exports.createCrescentVertices = createCrescentVertices; +exports.createCubeBuffers = exports.createCubeBufferInfo = exports.createCresentVertices = exports.createCresentBuffers = exports.createCresentBufferInfo = void 0; +exports.createCubeVertices = createCubeVertices; +exports.createCylinderBuffers = exports.createCylinderBufferInfo = void 0; +exports.createCylinderVertices = createCylinderVertices; +exports.createDiscBuffers = exports.createDiscBufferInfo = void 0; +exports.createDiscVertices = createDiscVertices; +exports.createPlaneBuffers = exports.createPlaneBufferInfo = void 0; +exports.createPlaneVertices = createPlaneVertices; +exports.createSphereBuffers = exports.createSphereBufferInfo = void 0; +exports.createSphereVertices = createSphereVertices; +exports.createTorusBuffers = exports.createTorusBufferInfo = void 0; +exports.createTorusVertices = createTorusVertices; +exports.createTruncatedConeBuffers = exports.createTruncatedConeBufferInfo = void 0; +exports.createTruncatedConeVertices = createTruncatedConeVertices; +exports.createXYQuadBuffers = exports.createXYQuadBufferInfo = void 0; +exports.createXYQuadVertices = createXYQuadVertices; +exports.deindexVertices = deindexVertices; +exports.duplicateVertices = duplicateVertices; +exports.flattenNormals = flattenNormals; +exports.makeRandomVertexColors = makeRandomVertexColors; +exports.reorientDirections = reorientDirections; +exports.reorientNormals = reorientNormals; +exports.reorientPositions = reorientPositions; +exports.reorientVertices = reorientVertices; +var attributes = _interopRequireWildcard(__webpack_require__(/*! ./attributes.js */ "./src/attributes.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var m4 = _interopRequireWildcard(__webpack_require__(/*! ./m4.js */ "./src/m4.js")); +var v3 = _interopRequireWildcard(__webpack_require__(/*! ./v3.js */ "./src/v3.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Various functions to make simple primitives + * + * note: Most primitive functions come in 3 styles + * + * * `createSomeShapeBufferInfo` + * + * These functions are almost always the functions you want to call. They + * create vertices then make WebGLBuffers and create {@link module:twgl.AttribInfo}s + * returning a {@link module:twgl.BufferInfo} you can pass to {@link module:twgl.setBuffersAndAttributes} + * and {@link module:twgl.drawBufferInfo} etc... + * + * * `createSomeShapeBuffers` + * + * These create WebGLBuffers and put your data in them but nothing else. + * It's a shortcut to doing it yourself if you don't want to use + * the higher level functions. + * + * * `createSomeShapeVertices` + * + * These just create vertices, no buffers. This allows you to manipulate the vertices + * or add more data before generating a {@link module:twgl.BufferInfo}. Once you're finished + * manipulating the vertices call {@link module:twgl.createBufferInfoFromArrays}. + * + * example: + * + * const arrays = twgl.primitives.createPlaneVertices(1); + * twgl.primitives.reorientVertices(arrays, m4.rotationX(Math.PI * 0.5)); + * const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * @module twgl/primitives + */ + +var getArray = attributes.getArray_; // eslint-disable-line +var getNumComponents = attributes.getNumComponents_; // eslint-disable-line + +/** + * @typedef {(Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array)} TypedArray + */ + +/** + * 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 + * @param {TypedArray} typedArray TypedArray to augment + * @param {number} numComponents number of components. + * @private + */ +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 || typedArrays.isArrayBuffer(value)) { + 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 get() { + 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: + * + * const 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 {ArrayBufferView} A typed array. + * @memberOf module:twgl/primitives + */ +function createAugmentedTypedArray(numComponents, numElements, opt_type) { + var Type = opt_type || Float32Array; + return augmentTypedArray(new Type(numComponents * numElements), numComponents); +} +function allButIndices(name) { + return name !== "indices"; +} + +/** + * Given indexed vertices creates a new set of vertices un-indexed by expanding the indexed vertices. + * @param {Object.} vertices The indexed vertices to deindex + * @return {Object.} The deindexed vertices + * @memberOf module:twgl/primitives + */ +function deindexVertices(vertices) { + var indices = vertices.indices; + var newVertices = {}; + var numElements = indices.length; + function expandToUnindexed(channel) { + var srcBuffer = vertices[channel]; + var numComponents = srcBuffer.numComponents; + var dstBuffer = createAugmentedTypedArray(numComponents, numElements, srcBuffer.constructor); + for (var ii = 0; ii < numElements; ++ii) { + var ndx = indices[ii]; + var offset = ndx * numComponents; + for (var jj = 0; jj < numComponents; ++jj) { + dstBuffer.push(srcBuffer[offset + jj]); + } + } + newVertices[channel] = dstBuffer; + } + Object.keys(vertices).filter(allButIndices).forEach(expandToUnindexed); + return newVertices; +} + +/** + * flattens the normals of deindexed vertices in place. + * @param {Object.} vertices The deindexed vertices who's normals to flatten + * @return {Object.} The flattened vertices (same as was passed in) + * @memberOf module:twgl/primitives + */ +function flattenNormals(vertices) { + if (vertices.indices) { + throw new Error('can not flatten normals of indexed vertices. deindex them first'); + } + var normals = vertices.normal; + var numNormals = normals.length; + for (var ii = 0; ii < numNormals; ii += 9) { + // pull out the 3 normals for this triangle + var nax = normals[ii + 0]; + var nay = normals[ii + 1]; + var naz = normals[ii + 2]; + var nbx = normals[ii + 3]; + var nby = normals[ii + 4]; + var nbz = normals[ii + 5]; + var ncx = normals[ii + 6]; + var ncy = normals[ii + 7]; + var ncz = normals[ii + 8]; + + // add them + var nx = nax + nbx + ncx; + var ny = nay + nby + ncy; + var nz = naz + nbz + ncz; + + // normalize them + var length = Math.sqrt(nx * nx + ny * ny + nz * nz); + nx /= length; + ny /= length; + nz /= length; + + // copy them back in + normals[ii + 0] = nx; + normals[ii + 1] = ny; + normals[ii + 2] = nz; + normals[ii + 3] = nx; + normals[ii + 4] = ny; + normals[ii + 5] = nz; + normals[ii + 6] = nx; + normals[ii + 7] = ny; + normals[ii + 8] = nz; + } + return vertices; +} +function applyFuncToV3Array(array, matrix, fn) { + var len = array.length; + var tmp = new Float32Array(3); + for (var ii = 0; ii < len; ii += 3) { + fn(matrix, [array[ii], array[ii + 1], array[ii + 2]], tmp); + array[ii] = tmp[0]; + array[ii + 1] = tmp[1]; + array[ii + 2] = tmp[2]; + } +} +function transformNormal(mi, v, dst) { + dst = dst || v3.create(); + var v0 = v[0]; + var v1 = v[1]; + var v2 = v[2]; + dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; + dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; + dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; + return dst; +} + +/** + * Reorients directions by the given matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientDirections(array, matrix) { + applyFuncToV3Array(array, matrix, m4.transformDirection); + return array; +} + +/** + * Reorients normals by the inverse-transpose of the given + * matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientNormals(array, matrix) { + applyFuncToV3Array(array, m4.inverse(matrix), transformNormal); + return array; +} + +/** + * Reorients positions by the given matrix. In other words, it + * multiplies each vertex by the given matrix. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientPositions(array, matrix) { + applyFuncToV3Array(array, matrix, m4.transformPoint); + return array; +} + +/** + * @typedef {(number[]|TypedArray)} NativeArrayOrTypedArray + */ + +/** + * Reorients arrays by the given matrix. Assumes arrays have + * names that contains 'pos' could be reoriented as positions, + * 'binorm' or 'tan' as directions, and 'norm' as normals. + * + * @param {Object.} arrays The vertices to reorient + * @param {module:twgl/m4.Mat4} matrix matrix to reorient by. + * @return {Object.} same arrays that were passed in. + * @memberOf module:twgl/primitives + */ +function reorientVertices(arrays, matrix) { + Object.keys(arrays).forEach(function (name) { + var array = arrays[name]; + if (name.indexOf("pos") >= 0) { + reorientPositions(array, matrix); + } else if (name.indexOf("tan") >= 0 || name.indexOf("binorm") >= 0) { + reorientDirections(array, matrix); + } else if (name.indexOf("norm") >= 0) { + reorientNormals(array, matrix); + } + }); + return arrays; +} + +/** + * Creates XY quad BufferInfo + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad BufferInfo + * @memberOf module:twgl/primitives + * @function createXYQuadBuffers + */ + +/** + * Creates XY quad Buffers + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {module:twgl.BufferInfo} the created XY Quad buffers + * @memberOf module:twgl/primitives + * @function createXYQuadBufferInfo + */ + +/** + * Creates XY quad vertices + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0, 0.5); + * + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad vertices + * @memberOf module:twgl/primitives + */ +function createXYQuadVertices(size, xOffset, yOffset) { + size = size || 2; + xOffset = xOffset || 0; + yOffset = yOffset || 0; + size *= 0.5; + return { + position: { + numComponents: 2, + data: [xOffset + -1 * size, yOffset + -1 * size, xOffset + 1 * size, yOffset + -1 * size, xOffset + -1 * size, yOffset + 1 * size, xOffset + 1 * size, yOffset + 1 * size] + }, + normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], + texcoord: [0, 0, 1, 0, 0, 1, 1, 1], + indices: [0, 1, 2, 2, 1, 3] + }; +} + +/** + * Creates XZ plane BufferInfo. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {module:twgl.BufferInfo} The created plane BufferInfo. + * @memberOf module:twgl/primitives + * @function createPlaneBufferInfo + */ + +/** + * Creates XZ plane buffers. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane buffers. + * @memberOf module:twgl/primitives + * @function createPlaneBuffers + */ + +/** + * Creates XZ plane vertices. + * + * The created plane has position, normal, and texcoord data + * + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane vertices. + * @memberOf module:twgl/primitives + */ +function createPlaneVertices(width, depth, subdivisionsWidth, subdivisionsDepth, matrix) { + width = width || 1; + depth = depth || 1; + subdivisionsWidth = subdivisionsWidth || 1; + subdivisionsDepth = subdivisionsDepth || 1; + matrix = matrix || m4.identity(); + var numVertices = (subdivisionsWidth + 1) * (subdivisionsDepth + 1); + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + for (var z = 0; z <= subdivisionsDepth; z++) { + for (var x = 0; x <= subdivisionsWidth; x++) { + var u = x / subdivisionsWidth; + var v = z / subdivisionsDepth; + positions.push(width * u - width * 0.5, 0, depth * v - depth * 0.5); + normals.push(0, 1, 0); + texcoords.push(u, v); + } + } + var numVertsAcross = subdivisionsWidth + 1; + var indices = createAugmentedTypedArray(3, subdivisionsWidth * subdivisionsDepth * 2, Uint16Array); + for (var _z = 0; _z < subdivisionsDepth; _z++) { + // eslint-disable-line + for (var _x = 0; _x < subdivisionsWidth; _x++) { + // eslint-disable-line + // Make triangle 1 of quad. + indices.push((_z + 0) * numVertsAcross + _x, (_z + 1) * numVertsAcross + _x, (_z + 0) * numVertsAcross + _x + 1); + + // Make triangle 2 of quad. + indices.push((_z + 1) * numVertsAcross + _x, (_z + 1) * numVertsAcross + _x + 1, (_z + 0) * numVertsAcross + _x + 1); + } + } + var arrays = reorientVertices({ + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }, matrix); + return arrays; +} + +/** + * Creates sphere BufferInfo. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {module:twgl.BufferInfo} The created sphere BufferInfo. + * @memberOf module:twgl/primitives + * @function createSphereBufferInfo + */ + +/** + * Creates sphere buffers. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere buffers. + * @memberOf module:twgl/primitives + * @function createSphereBuffers + */ + +/** + * Creates sphere vertices. + * + * The created sphere has position, normal, and texcoord data + * + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere vertices. + * @memberOf module:twgl/primitives + */ +function createSphereVertices(radius, subdivisionsAxis, subdivisionsHeight, opt_startLatitudeInRadians, opt_endLatitudeInRadians, opt_startLongitudeInRadians, opt_endLongitudeInRadians) { + if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { + throw new Error('subdivisionAxis and subdivisionHeight must be > 0'); + } + opt_startLatitudeInRadians = opt_startLatitudeInRadians || 0; + opt_endLatitudeInRadians = opt_endLatitudeInRadians || Math.PI; + opt_startLongitudeInRadians = opt_startLongitudeInRadians || 0; + opt_endLongitudeInRadians = opt_endLongitudeInRadians || Math.PI * 2; + var latRange = opt_endLatitudeInRadians - opt_startLatitudeInRadians; + var longRange = opt_endLongitudeInRadians - opt_startLongitudeInRadians; + + // We are going to generate our sphere by iterating through its + // spherical coordinates and generating 2 triangles for each quad on a + // ring of the sphere. + var numVertices = (subdivisionsAxis + 1) * (subdivisionsHeight + 1); + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + + // Generate the individual vertices in our vertex buffer. + for (var y = 0; y <= subdivisionsHeight; y++) { + for (var x = 0; x <= subdivisionsAxis; x++) { + // Generate a vertex based on its spherical coordinates + var u = x / subdivisionsAxis; + var v = y / subdivisionsHeight; + var theta = longRange * u + opt_startLongitudeInRadians; + var phi = latRange * v + opt_startLatitudeInRadians; + var sinTheta = Math.sin(theta); + var cosTheta = Math.cos(theta); + var sinPhi = Math.sin(phi); + var cosPhi = Math.cos(phi); + var ux = cosTheta * sinPhi; + var uy = cosPhi; + var uz = sinTheta * sinPhi; + positions.push(radius * ux, radius * uy, radius * uz); + normals.push(ux, uy, uz); + texcoords.push(1 - u, v); + } + } + var numVertsAround = subdivisionsAxis + 1; + var indices = createAugmentedTypedArray(3, subdivisionsAxis * subdivisionsHeight * 2, Uint16Array); + for (var _x2 = 0; _x2 < subdivisionsAxis; _x2++) { + // eslint-disable-line + for (var _y = 0; _y < subdivisionsHeight; _y++) { + // eslint-disable-line + // Make triangle 1 of quad. + indices.push((_y + 0) * numVertsAround + _x2, (_y + 0) * numVertsAround + _x2 + 1, (_y + 1) * numVertsAround + _x2); + + // Make triangle 2 of quad. + indices.push((_y + 1) * numVertsAround + _x2, (_y + 0) * numVertsAround + _x2 + 1, (_y + 1) * numVertsAround + _x2 + 1); + } + } + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * Array of the indices of corners of each face of a cube. + * @type {Array.} + * @private + */ +var CUBE_FACE_INDICES = [[3, 7, 5, 1], +// right +[6, 2, 0, 4], +// left +[6, 7, 3, 2], +// ?? +[0, 1, 5, 4], +// ?? +[7, 6, 4, 5], +// front +[2, 3, 1, 0] // back +]; + +/** + * Creates a BufferInfo for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCubeBufferInfo + */ + +/** + * Creates the buffers and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCubeBuffers + */ + +/** + * Creates the vertices and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createCubeVertices(size) { + size = size || 1; + var k = size / 2; + var cornerVertices = [[-k, -k, -k], [+k, -k, -k], [-k, +k, -k], [+k, +k, -k], [-k, -k, +k], [+k, -k, +k], [-k, +k, +k], [+k, +k, +k]]; + var faceNormals = [[+1, +0, +0], [-1, +0, +0], [+0, +1, +0], [+0, -1, +0], [+0, +0, +1], [+0, +0, -1]]; + var uvCoords = [[1, 0], [0, 0], [0, 1], [1, 1]]; + var numVertices = 6 * 4; + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + var indices = createAugmentedTypedArray(3, 6 * 2, Uint16Array); + for (var f = 0; f < 6; ++f) { + var faceIndices = CUBE_FACE_INDICES[f]; + for (var v = 0; v < 4; ++v) { + var position = cornerVertices[faceIndices[v]]; + var normal = faceNormals[f]; + var uv = uvCoords[v]; + + // Each face needs all four vertices because the normals and texture + // coordinates are not all the same. + positions.push(position); + normals.push(normal); + texcoords.push(uv); + } + // Two triangles make a square face. + var offset = 4 * f; + indices.push(offset + 0, offset + 1, offset + 2); + indices.push(offset + 0, offset + 2, offset + 3); + } + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * Creates a BufferInfo for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {module:twgl.BufferInfo} The created cone BufferInfo. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBufferInfo + */ + +/** + * Creates buffers for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone buffers. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBuffers + */ + +/** + * Creates vertices for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. . + * + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone vertices. + * @memberOf module:twgl/primitives + */ +function createTruncatedConeVertices(bottomRadius, topRadius, height, radialSubdivisions, verticalSubdivisions, opt_topCap, opt_bottomCap) { + if (radialSubdivisions < 3) { + throw new Error('radialSubdivisions must be 3 or greater'); + } + if (verticalSubdivisions < 1) { + throw new Error('verticalSubdivisions must be 1 or greater'); + } + var topCap = opt_topCap === undefined ? true : opt_topCap; + var bottomCap = opt_bottomCap === undefined ? true : opt_bottomCap; + var extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0); + var numVertices = (radialSubdivisions + 1) * (verticalSubdivisions + 1 + extra); + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + var indices = createAugmentedTypedArray(3, radialSubdivisions * (verticalSubdivisions + extra / 2) * 2, Uint16Array); + var vertsAroundEdge = radialSubdivisions + 1; + + // The slant of the cone is constant across its surface + var slant = Math.atan2(bottomRadius - topRadius, height); + var cosSlant = Math.cos(slant); + var sinSlant = Math.sin(slant); + var start = topCap ? -2 : 0; + var end = verticalSubdivisions + (bottomCap ? 2 : 0); + for (var yy = start; yy <= end; ++yy) { + var v = yy / verticalSubdivisions; + var y = height * v; + var ringRadius = void 0; + if (yy < 0) { + y = 0; + v = 1; + ringRadius = bottomRadius; + } else if (yy > verticalSubdivisions) { + y = height; + v = 1; + ringRadius = topRadius; + } else { + ringRadius = bottomRadius + (topRadius - bottomRadius) * (yy / verticalSubdivisions); + } + if (yy === -2 || yy === verticalSubdivisions + 2) { + ringRadius = 0; + v = 0; + } + y -= height / 2; + for (var ii = 0; ii < vertsAroundEdge; ++ii) { + var sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions); + var cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions); + positions.push(sin * ringRadius, y, cos * ringRadius); + if (yy < 0) { + normals.push(0, -1, 0); + } else if (yy > verticalSubdivisions) { + normals.push(0, 1, 0); + } else if (ringRadius === 0.0) { + normals.push(0, 0, 0); + } else { + normals.push(sin * cosSlant, sinSlant, cos * cosSlant); + } + texcoords.push(ii / radialSubdivisions, 1 - v); + } + } + for (var _yy = 0; _yy < verticalSubdivisions + extra; ++_yy) { + // eslint-disable-line + if (_yy === 1 && topCap || _yy === verticalSubdivisions + extra - 2 && bottomCap) { + continue; + } + for (var _ii = 0; _ii < radialSubdivisions; ++_ii) { + // eslint-disable-line + indices.push(vertsAroundEdge * (_yy + 0) + 0 + _ii, vertsAroundEdge * (_yy + 0) + 1 + _ii, vertsAroundEdge * (_yy + 1) + 1 + _ii); + indices.push(vertsAroundEdge * (_yy + 0) + 0 + _ii, vertsAroundEdge * (_yy + 1) + 1 + _ii, vertsAroundEdge * (_yy + 1) + 0 + _ii); + } + } + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * Expands RLE data + * @param {number[]} rleData data in format of run-length, x, y, z, run-length, x, y, z + * @param {number[]} [padding] value to add each entry with. + * @return {number[]} the expanded rleData + * @private + */ +function expandRLEData(rleData, padding) { + padding = padding || []; + var data = []; + for (var ii = 0; ii < rleData.length; ii += 4) { + var runLength = rleData[ii]; + var element = rleData.slice(ii + 1, ii + 4); + element.push.apply(element, padding); + for (var jj = 0; jj < runLength; ++jj) { + data.push.apply(data, element); + } + } + return data; +} + +/** + * Creates 3D 'F' BufferInfo. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function create3DFBufferInfo + */ + +/** + * Creates 3D 'F' buffers. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function create3DFBuffers + */ + +/** + * Creates 3D 'F' vertices. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color arrays. + * + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function create3DFVertices() { + var positions = [ + // left column front + 0, 0, 0, 0, 150, 0, 30, 0, 0, 0, 150, 0, 30, 150, 0, 30, 0, 0, + // top rung front + 30, 0, 0, 30, 30, 0, 100, 0, 0, 30, 30, 0, 100, 30, 0, 100, 0, 0, + // middle rung front + 30, 60, 0, 30, 90, 0, 67, 60, 0, 30, 90, 0, 67, 90, 0, 67, 60, 0, + // left column back + 0, 0, 30, 30, 0, 30, 0, 150, 30, 0, 150, 30, 30, 0, 30, 30, 150, 30, + // top rung back + 30, 0, 30, 100, 0, 30, 30, 30, 30, 30, 30, 30, 100, 0, 30, 100, 30, 30, + // middle rung back + 30, 60, 30, 67, 60, 30, 30, 90, 30, 30, 90, 30, 67, 60, 30, 67, 90, 30, + // top + 0, 0, 0, 100, 0, 0, 100, 0, 30, 0, 0, 0, 100, 0, 30, 0, 0, 30, + // top rung front + 100, 0, 0, 100, 30, 0, 100, 30, 30, 100, 0, 0, 100, 30, 30, 100, 0, 30, + // under top rung + 30, 30, 0, 30, 30, 30, 100, 30, 30, 30, 30, 0, 100, 30, 30, 100, 30, 0, + // between top rung and middle + 30, 30, 0, 30, 60, 30, 30, 30, 30, 30, 30, 0, 30, 60, 0, 30, 60, 30, + // top of middle rung + 30, 60, 0, 67, 60, 30, 30, 60, 30, 30, 60, 0, 67, 60, 0, 67, 60, 30, + // front of middle rung + 67, 60, 0, 67, 90, 30, 67, 60, 30, 67, 60, 0, 67, 90, 0, 67, 90, 30, + // bottom of middle rung. + 30, 90, 0, 30, 90, 30, 67, 90, 30, 30, 90, 0, 67, 90, 30, 67, 90, 0, + // front of bottom + 30, 90, 0, 30, 150, 30, 30, 90, 30, 30, 90, 0, 30, 150, 0, 30, 150, 30, + // bottom + 0, 150, 0, 0, 150, 30, 30, 150, 30, 0, 150, 0, 30, 150, 30, 30, 150, 0, + // left side + 0, 0, 0, 0, 0, 30, 0, 150, 30, 0, 0, 0, 0, 150, 30, 0, 150, 0]; + var texcoords = [ + // left column front + 0.22, 0.19, 0.22, 0.79, 0.34, 0.19, 0.22, 0.79, 0.34, 0.79, 0.34, 0.19, + // top rung front + 0.34, 0.19, 0.34, 0.31, 0.62, 0.19, 0.34, 0.31, 0.62, 0.31, 0.62, 0.19, + // middle rung front + 0.34, 0.43, 0.34, 0.55, 0.49, 0.43, 0.34, 0.55, 0.49, 0.55, 0.49, 0.43, + // left column back + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // top rung back + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // middle rung back + 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, + // top + 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, + // top rung front + 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, + // under top rung + 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, + // between top rung and middle + 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, + // top of middle rung + 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, + // front of middle rung + 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, + // bottom of middle rung. + 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, + // front of bottom + 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, + // bottom + 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, + // left side + 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0]; + var normals = expandRLEData([ + // left column front + // top rung front + // middle rung front + 18, 0, 0, 1, + // left column back + // top rung back + // middle rung back + 18, 0, 0, -1, + // top + 6, 0, 1, 0, + // top rung front + 6, 1, 0, 0, + // under top rung + 6, 0, -1, 0, + // between top rung and middle + 6, 1, 0, 0, + // top of middle rung + 6, 0, 1, 0, + // front of middle rung + 6, 1, 0, 0, + // bottom of middle rung. + 6, 0, -1, 0, + // front of bottom + 6, 1, 0, 0, + // bottom + 6, 0, -1, 0, + // left side + 6, -1, 0, 0]); + var colors = expandRLEData([ + // left column front + // top rung front + // middle rung front + 18, 200, 70, 120, + // left column back + // top rung back + // middle rung back + 18, 80, 70, 200, + // top + 6, 70, 200, 210, + // top rung front + 6, 200, 200, 70, + // under top rung + 6, 210, 100, 70, + // between top rung and middle + 6, 210, 160, 70, + // top of middle rung + 6, 70, 180, 210, + // front of middle rung + 6, 100, 70, 210, + // bottom of middle rung. + 6, 76, 210, 100, + // front of bottom + 6, 140, 210, 80, + // bottom + 6, 90, 130, 110, + // left side + 6, 160, 160, 220], [255]); + var numVerts = positions.length / 3; + var arrays = { + position: createAugmentedTypedArray(3, numVerts), + texcoord: createAugmentedTypedArray(2, numVerts), + normal: createAugmentedTypedArray(3, numVerts), + color: createAugmentedTypedArray(4, numVerts, Uint8Array), + indices: createAugmentedTypedArray(3, numVerts / 3, Uint16Array) + }; + arrays.position.push(positions); + arrays.texcoord.push(texcoords); + arrays.normal.push(normals); + arrays.color.push(colors); + for (var ii = 0; ii < numVerts; ++ii) { + arrays.indices.push(ii); + } + return arrays; +} + +/** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCresentBufferInfo + */ + +/** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + +/** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + +/** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCrescentBufferInfo + */ + +/** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCrescentBuffers + */ + +/** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createCrescentVertices(verticalRadius, outerRadius, innerRadius, thickness, subdivisionsDown, startOffset, endOffset) { + if (subdivisionsDown <= 0) { + throw new Error('subdivisionDown must be > 0'); + } + startOffset = startOffset || 0; + endOffset = endOffset || 1; + var subdivisionsThick = 2; + var offsetRange = endOffset - startOffset; + var numVertices = (subdivisionsDown + 1) * 2 * (2 + subdivisionsThick); + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + function lerp(a, b, s) { + return a + (b - a) * s; + } + function createArc(arcRadius, x, normalMult, normalAdd, uMult, uAdd) { + for (var z = 0; z <= subdivisionsDown; z++) { + var uBack = x / (subdivisionsThick - 1); + var v = z / subdivisionsDown; + var xBack = (uBack - 0.5) * 2; + var angle = (startOffset + v * offsetRange) * Math.PI; + var s = Math.sin(angle); + var c = Math.cos(angle); + var radius = lerp(verticalRadius, arcRadius, s); + var px = xBack * thickness; + var py = c * verticalRadius; + var pz = s * radius; + positions.push(px, py, pz); + var n = v3.add(v3.multiply([0, s, c], normalMult), normalAdd); + normals.push(n); + texcoords.push(uBack * uMult + uAdd, v); + } + } + + // Generate the individual vertices in our vertex buffer. + for (var x = 0; x < subdivisionsThick; x++) { + var uBack = (x / (subdivisionsThick - 1) - 0.5) * 2; + createArc(outerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); + createArc(outerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 0); + createArc(innerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); + createArc(innerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 1); + } + + // Do outer surface. + var indices = createAugmentedTypedArray(3, subdivisionsDown * 2 * (2 + subdivisionsThick), Uint16Array); + function createSurface(leftArcOffset, rightArcOffset) { + for (var z = 0; z < subdivisionsDown; ++z) { + // Make triangle 1 of quad. + indices.push(leftArcOffset + z + 0, leftArcOffset + z + 1, rightArcOffset + z + 0); + + // Make triangle 2 of quad. + indices.push(leftArcOffset + z + 1, rightArcOffset + z + 1, rightArcOffset + z + 0); + } + } + var numVerticesDown = subdivisionsDown + 1; + // front + createSurface(numVerticesDown * 0, numVerticesDown * 4); + // right + createSurface(numVerticesDown * 5, numVerticesDown * 7); + // back + createSurface(numVerticesDown * 6, numVerticesDown * 2); + // left + createSurface(numVerticesDown * 3, numVerticesDown * 1); + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * Creates cylinder BufferInfo. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCylinderBufferInfo + */ + +/** + * Creates cylinder buffers. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCylinderBuffers + */ + +/** + * Creates cylinder vertices. The cylinder will be created around the origin + * along the y-axis. + * + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createCylinderVertices(radius, height, radialSubdivisions, verticalSubdivisions, topCap, bottomCap) { + return createTruncatedConeVertices(radius, radius, height, radialSubdivisions, verticalSubdivisions, topCap, bottomCap); +} + +/** + * Creates BufferInfo for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createTorusBufferInfo + */ + +/** + * Creates buffers for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createTorusBuffers + */ + +/** + * Creates vertices for a torus + * + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createTorusVertices(radius, thickness, radialSubdivisions, bodySubdivisions, startAngle, endAngle) { + if (radialSubdivisions < 3) { + throw new Error('radialSubdivisions must be 3 or greater'); + } + if (bodySubdivisions < 3) { + throw new Error('verticalSubdivisions must be 3 or greater'); + } + startAngle = startAngle || 0; + endAngle = endAngle || Math.PI * 2; + var range = endAngle - startAngle; + var radialParts = radialSubdivisions + 1; + var bodyParts = bodySubdivisions + 1; + var numVertices = radialParts * bodyParts; + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + var indices = createAugmentedTypedArray(3, radialSubdivisions * bodySubdivisions * 2, Uint16Array); + for (var slice = 0; slice < bodyParts; ++slice) { + var v = slice / bodySubdivisions; + var sliceAngle = v * Math.PI * 2; + var sliceSin = Math.sin(sliceAngle); + var ringRadius = radius + sliceSin * thickness; + var ny = Math.cos(sliceAngle); + var y = ny * thickness; + for (var ring = 0; ring < radialParts; ++ring) { + var u = ring / radialSubdivisions; + var ringAngle = startAngle + u * range; + var xSin = Math.sin(ringAngle); + var zCos = Math.cos(ringAngle); + var x = xSin * ringRadius; + var z = zCos * ringRadius; + var nx = xSin * sliceSin; + var nz = zCos * sliceSin; + positions.push(x, y, z); + normals.push(nx, ny, nz); + texcoords.push(u, 1 - v); + } + } + for (var _slice = 0; _slice < bodySubdivisions; ++_slice) { + // eslint-disable-line + for (var _ring = 0; _ring < radialSubdivisions; ++_ring) { + // eslint-disable-line + var nextRingIndex = 1 + _ring; + var nextSliceIndex = 1 + _slice; + indices.push(radialParts * _slice + _ring, radialParts * nextSliceIndex + _ring, radialParts * _slice + nextRingIndex); + indices.push(radialParts * nextSliceIndex + _ring, radialParts * nextSliceIndex + nextRingIndex, radialParts * _slice + nextRingIndex); + } + } + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * Creates a disc BufferInfo. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createDiscBufferInfo + */ + +/** + * Creates disc buffers. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createDiscBuffers + */ + +/** + * Creates disc vertices. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createDiscVertices(radius, divisions, stacks, innerRadius, stackPower) { + if (divisions < 3) { + throw new Error('divisions must be at least 3'); + } + stacks = stacks ? stacks : 1; + stackPower = stackPower ? stackPower : 1; + innerRadius = innerRadius ? innerRadius : 0; + + // Note: We don't share the center vertex because that would + // mess up texture coordinates. + var numVertices = (divisions + 1) * (stacks + 1); + var positions = createAugmentedTypedArray(3, numVertices); + var normals = createAugmentedTypedArray(3, numVertices); + var texcoords = createAugmentedTypedArray(2, numVertices); + var indices = createAugmentedTypedArray(3, stacks * divisions * 2, Uint16Array); + var firstIndex = 0; + var radiusSpan = radius - innerRadius; + var pointsPerStack = divisions + 1; + + // Build the disk one stack at a time. + for (var stack = 0; stack <= stacks; ++stack) { + var stackRadius = innerRadius + radiusSpan * Math.pow(stack / stacks, stackPower); + for (var i = 0; i <= divisions; ++i) { + var theta = 2.0 * Math.PI * i / divisions; + var x = stackRadius * Math.cos(theta); + var z = stackRadius * Math.sin(theta); + positions.push(x, 0, z); + normals.push(0, 1, 0); + texcoords.push(1 - i / divisions, stack / stacks); + if (stack > 0 && i !== divisions) { + // a, b, c and d are the indices of the vertices of a quad. unless + // the current stack is the one closest to the center, in which case + // the vertices a and b connect to the center vertex. + var a = firstIndex + (i + 1); + var b = firstIndex + i; + var c = firstIndex + i - pointsPerStack; + var d = firstIndex + (i + 1) - pointsPerStack; + + // Make a quad of the vertices a, b, c, d. + indices.push(a, b, c); + indices.push(a, c, d); + } + } + firstIndex += divisions + 1; + } + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices + }; +} + +/** + * creates a random integer between 0 and range - 1 inclusive. + * @param {number} range + * @return {number} random value between 0 and range - 1 inclusive. + * @private + */ +function randInt(range) { + return Math.random() * range | 0; +} + +/** + * Used to supply random colors + * @callback RandomColorFunc + * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed + * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha + * @return {number} a number from 0 to 255 + * @memberOf module:twgl/primitives + */ + +/** + * @typedef {Object} RandomVerticesOptions + * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices + * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers + * @memberOf module:twgl/primitives + */ + +/** + * Creates an augmentedTypedArray of random vertex colors. + * If the vertices are indexed (have an indices array) then will + * just make random colors. Otherwise assumes they are triangles + * and makes one random color for every 3 vertices. + * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions. + * @param {module:twgl/primitives.RandomVerticesOptions} [options] options. + * @return {Object.} same vertices as passed in with `color` added. + * @memberOf module:twgl/primitives + */ +function makeRandomVertexColors(vertices, options) { + options = options || {}; + var numElements = vertices.position.numElements; + var vColors = createAugmentedTypedArray(4, numElements, Uint8Array); + var rand = options.rand || function (ndx, channel) { + return channel < 3 ? randInt(256) : 255; + }; + vertices.color = vColors; + if (vertices.indices) { + // just make random colors if index + for (var ii = 0; ii < numElements; ++ii) { + vColors.push(rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)); + } + } else { + // make random colors per triangle + var numVertsPerColor = options.vertsPerColor || 3; + var numSets = numElements / numVertsPerColor; + for (var _ii2 = 0; _ii2 < numSets; ++_ii2) { + // eslint-disable-line + var color = [rand(_ii2, 0), rand(_ii2, 1), rand(_ii2, 2), rand(_ii2, 3)]; + for (var jj = 0; jj < numVertsPerColor; ++jj) { + vColors.push(color); + } + } + } + return vertices; +} + +/** + * creates a function that calls fn to create vertices and then + * creates a buffers for them + * @private + */ +function createBufferFunc(fn) { + return function (gl) { + var arrays = fn.apply(this, Array.prototype.slice.call(arguments, 1)); + return attributes.createBuffersFromArrays(gl, arrays); + }; +} + +/** + * creates a function that calls fn to create vertices and then + * creates a bufferInfo object for them + * @private + */ +function createBufferInfoFunc(fn) { + return function (gl) { + var arrays = fn.apply(null, Array.prototype.slice.call(arguments, 1)); + return attributes.createBufferInfoFromArrays(gl, arrays); + }; +} +var arraySpecPropertyNames = ["numComponents", "size", "type", "normalize", "stride", "offset", "attrib", "name", "attribName"]; + +/** + * Copy elements from one array to another + * + * @param {Array|TypedArray} src source array + * @param {Array|TypedArray} dst dest array + * @param {number} dstNdx index in dest to copy src + * @param {number} [offset] offset to add to copied values + * @private + */ +function copyElements(src, dst, dstNdx, offset) { + offset = offset || 0; + var length = src.length; + for (var ii = 0; ii < length; ++ii) { + dst[dstNdx + ii] = src[ii] + offset; + } +} + +/** + * Creates an array of the same time + * + * @param {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} srcArray array who's type to copy + * @param {number} length size of new array + * @return {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} array with same type as srcArray + * @private + */ +function createArrayOfSameType(srcArray, length) { + var arraySrc = getArray(srcArray); + var newArray = new arraySrc.constructor(length); + var newArraySpec = newArray; + // If it appears to have been augmented make new one augmented + if (arraySrc.numComponents && arraySrc.numElements) { + augmentTypedArray(newArray, arraySrc.numComponents); + } + // If it was a full spec make new one a full spec + if (srcArray.data) { + newArraySpec = { + data: newArray + }; + helper.copyNamedProperties(arraySpecPropertyNames, srcArray, newArraySpec); + } + return newArraySpec; +} + +/** + * Concatenates sets of vertices + * + * Assumes the vertices match in composition. For example + * if one set of vertices has positions, normals, and indices + * all sets of vertices must have positions, normals, and indices + * and of the same type. + * + * Example: + * + * const cubeVertices = twgl.primitives.createCubeVertices(2); + * const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10); + * // move the sphere 2 units up + * twgl.primitives.reorientVertices( + * sphereVertices, twgl.m4.translation([0, 2, 0])); + * // merge the sphere with the cube + * const cubeSphereVertices = twgl.primitives.concatVertices( + * [cubeVertices, sphereVertices]); + * // turn them into WebGL buffers and attrib data + * const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices); + * + * @param {module:twgl.Arrays[]} arrays Array of arrays of vertices + * @return {module:twgl.Arrays} The concatenated vertices. + * @memberOf module:twgl/primitives + */ +function concatVertices(arrayOfArrays) { + var names = {}; + var baseName; + // get names of all arrays. + // and numElements for each set of vertices + var _loop = function _loop() { + var arrays = arrayOfArrays[ii]; + Object.keys(arrays).forEach(function (name) { + // eslint-disable-line + if (!names[name]) { + names[name] = []; + } + if (!baseName && name !== 'indices') { + baseName = name; + } + var arrayInfo = arrays[name]; + var numComponents = getNumComponents(arrayInfo, name); + var array = getArray(arrayInfo); + var numElements = array.length / numComponents; + names[name].push(numElements); + }); + }; + for (var ii = 0; ii < arrayOfArrays.length; ++ii) { + _loop(); + } + + // compute length of combined array + // and return one for reference + function getLengthOfCombinedArrays(name) { + var length = 0; + var arraySpec; + for (var _ii3 = 0; _ii3 < arrayOfArrays.length; ++_ii3) { + var arrays = arrayOfArrays[_ii3]; + var arrayInfo = arrays[name]; + var array = getArray(arrayInfo); + length += array.length; + if (!arraySpec || arrayInfo.data) { + arraySpec = arrayInfo; + } + } + return { + length: length, + spec: arraySpec + }; + } + function copyArraysToNewArray(name, base, newArray) { + var baseIndex = 0; + var offset = 0; + for (var _ii4 = 0; _ii4 < arrayOfArrays.length; ++_ii4) { + var arrays = arrayOfArrays[_ii4]; + var arrayInfo = arrays[name]; + var array = getArray(arrayInfo); + if (name === 'indices') { + copyElements(array, newArray, offset, baseIndex); + baseIndex += base[_ii4]; + } else { + copyElements(array, newArray, offset); + } + offset += array.length; + } + } + var base = names[baseName]; + var newArrays = {}; + Object.keys(names).forEach(function (name) { + var info = getLengthOfCombinedArrays(name); + var newArraySpec = createArrayOfSameType(info.spec, info.length); + copyArraysToNewArray(name, base, getArray(newArraySpec)); + newArrays[name] = newArraySpec; + }); + return newArrays; +} + +/** + * Creates a duplicate set of vertices + * + * This is useful for calling reorientVertices when you + * also want to keep the original available + * + * @param {module:twgl.Arrays} arrays of vertices + * @return {module:twgl.Arrays} The duplicated vertices. + * @memberOf module:twgl/primitives + */ +function duplicateVertices(arrays) { + var newArrays = {}; + Object.keys(arrays).forEach(function (name) { + var arraySpec = arrays[name]; + var srcArray = getArray(arraySpec); + var newArraySpec = createArrayOfSameType(arraySpec, srcArray.length); + copyElements(srcArray, getArray(newArraySpec), 0); + newArrays[name] = newArraySpec; + }); + return newArrays; +} +var create3DFBufferInfo = exports.create3DFBufferInfo = createBufferInfoFunc(create3DFVertices); +var create3DFBuffers = exports.create3DFBuffers = createBufferFunc(create3DFVertices); +var createCubeBufferInfo = exports.createCubeBufferInfo = createBufferInfoFunc(createCubeVertices); +var createCubeBuffers = exports.createCubeBuffers = createBufferFunc(createCubeVertices); +var createPlaneBufferInfo = exports.createPlaneBufferInfo = createBufferInfoFunc(createPlaneVertices); +var createPlaneBuffers = exports.createPlaneBuffers = createBufferFunc(createPlaneVertices); +var createSphereBufferInfo = exports.createSphereBufferInfo = createBufferInfoFunc(createSphereVertices); +var createSphereBuffers = exports.createSphereBuffers = createBufferFunc(createSphereVertices); +var createTruncatedConeBufferInfo = exports.createTruncatedConeBufferInfo = createBufferInfoFunc(createTruncatedConeVertices); +var createTruncatedConeBuffers = exports.createTruncatedConeBuffers = createBufferFunc(createTruncatedConeVertices); +var createXYQuadBufferInfo = exports.createXYQuadBufferInfo = createBufferInfoFunc(createXYQuadVertices); +var createXYQuadBuffers = exports.createXYQuadBuffers = createBufferFunc(createXYQuadVertices); +var createCrescentBufferInfo = exports.createCrescentBufferInfo = createBufferInfoFunc(createCrescentVertices); +var createCrescentBuffers = exports.createCrescentBuffers = createBufferFunc(createCrescentVertices); +var createCylinderBufferInfo = exports.createCylinderBufferInfo = createBufferInfoFunc(createCylinderVertices); +var createCylinderBuffers = exports.createCylinderBuffers = createBufferFunc(createCylinderVertices); +var createTorusBufferInfo = exports.createTorusBufferInfo = createBufferInfoFunc(createTorusVertices); +var createTorusBuffers = exports.createTorusBuffers = createBufferFunc(createTorusVertices); +var createDiscBufferInfo = exports.createDiscBufferInfo = createBufferInfoFunc(createDiscVertices); +var createDiscBuffers = exports.createDiscBuffers = createBufferFunc(createDiscVertices); + +// these were mis-spelled until 4.12 +var createCresentBufferInfo = exports.createCresentBufferInfo = createCrescentBufferInfo; +var createCresentBuffers = exports.createCresentBuffers = createCrescentBuffers; +var createCresentVertices = exports.createCresentVertices = createCrescentVertices; + +/***/ }), + +/***/ "./src/programs.js": +/*!*************************!*\ + !*** ./src/programs.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindTransformFeedbackInfo = bindTransformFeedbackInfo; +exports.bindUniformBlock = bindUniformBlock; +exports.createAttributeSetters = createAttributeSetters; +exports.createProgram = createProgram; +exports.createProgramAsync = void 0; +exports.createProgramFromScripts = createProgramFromScripts; +exports.createProgramFromSources = createProgramFromSources; +exports.createProgramInfo = createProgramInfo; +exports.createProgramInfoAsync = void 0; +exports.createProgramInfoFromProgram = createProgramInfoFromProgram; +exports.createProgramInfos = createProgramInfos; +exports.createProgramInfosAsync = void 0; +exports.createPrograms = createPrograms; +exports.createProgramsAsync = void 0; +exports.createTransformFeedback = createTransformFeedback; +exports.createTransformFeedbackInfo = createTransformFeedbackInfo; +exports.createUniformBlockInfo = createUniformBlockInfo; +exports.createUniformBlockInfoFromProgram = createUniformBlockInfoFromProgram; +exports.createUniformBlockSpecFromProgram = createUniformBlockSpecFromProgram; +exports.createUniformSetters = createUniformSetters; +exports.setAttributes = setAttributes; +exports.setBlockUniforms = setBlockUniforms; +exports.setBuffersAndAttributes = setBuffersAndAttributes; +exports.setUniformBlock = setUniformBlock; +exports.setUniforms = setUniforms; +exports.setUniformsAndBindTextures = void 0; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } +function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } /* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +var error = helper.error; +var warn = helper.warn; +function getElementById(id) { + return typeof document !== 'undefined' && document.getElementById ? document.getElementById(id) : null; +} +var TEXTURE0 = 0x84c0; +var DYNAMIC_DRAW = 0x88e8; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var UNIFORM_BUFFER = 0x8a11; +var TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; +var TRANSFORM_FEEDBACK = 0x8e22; +var COMPILE_STATUS = 0x8b81; +var LINK_STATUS = 0x8b82; +var FRAGMENT_SHADER = 0x8b30; +var VERTEX_SHADER = 0x8b31; +var SEPARATE_ATTRIBS = 0x8c8d; +var ACTIVE_UNIFORMS = 0x8b86; +var ACTIVE_ATTRIBUTES = 0x8b89; +var TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +var ACTIVE_UNIFORM_BLOCKS = 0x8a36; +var UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +var UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +var UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +var UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; +var FLOAT = 0x1406; +var FLOAT_VEC2 = 0x8B50; +var FLOAT_VEC3 = 0x8B51; +var FLOAT_VEC4 = 0x8B52; +var INT = 0x1404; +var INT_VEC2 = 0x8B53; +var INT_VEC3 = 0x8B54; +var INT_VEC4 = 0x8B55; +var BOOL = 0x8B56; +var BOOL_VEC2 = 0x8B57; +var BOOL_VEC3 = 0x8B58; +var BOOL_VEC4 = 0x8B59; +var FLOAT_MAT2 = 0x8B5A; +var FLOAT_MAT3 = 0x8B5B; +var FLOAT_MAT4 = 0x8B5C; +var SAMPLER_2D = 0x8B5E; +var SAMPLER_CUBE = 0x8B60; +var SAMPLER_3D = 0x8B5F; +var SAMPLER_2D_SHADOW = 0x8B62; +var FLOAT_MAT2x3 = 0x8B65; +var FLOAT_MAT2x4 = 0x8B66; +var FLOAT_MAT3x2 = 0x8B67; +var FLOAT_MAT3x4 = 0x8B68; +var FLOAT_MAT4x2 = 0x8B69; +var FLOAT_MAT4x3 = 0x8B6A; +var SAMPLER_2D_ARRAY = 0x8DC1; +var SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +var SAMPLER_CUBE_SHADOW = 0x8DC5; +var UNSIGNED_INT = 0x1405; +var UNSIGNED_INT_VEC2 = 0x8DC6; +var UNSIGNED_INT_VEC3 = 0x8DC7; +var UNSIGNED_INT_VEC4 = 0x8DC8; +var INT_SAMPLER_2D = 0x8DCA; +var INT_SAMPLER_3D = 0x8DCB; +var INT_SAMPLER_CUBE = 0x8DCC; +var INT_SAMPLER_2D_ARRAY = 0x8DCF; +var UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +var UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +var UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +var UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; +var TEXTURE_2D = 0x0DE1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806F; +var TEXTURE_2D_ARRAY = 0x8C1A; +var typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function (v) { + gl.uniform1f(location, v); + }; +} +function floatArraySetter(gl, location) { + return function (v) { + gl.uniform1fv(location, v); + }; +} +function floatVec2Setter(gl, location) { + return function (v) { + gl.uniform2fv(location, v); + }; +} +function floatVec3Setter(gl, location) { + return function (v) { + gl.uniform3fv(location, v); + }; +} +function floatVec4Setter(gl, location) { + return function (v) { + gl.uniform4fv(location, v); + }; +} +function intSetter(gl, location) { + return function (v) { + gl.uniform1i(location, v); + }; +} +function intArraySetter(gl, location) { + return function (v) { + gl.uniform1iv(location, v); + }; +} +function intVec2Setter(gl, location) { + return function (v) { + gl.uniform2iv(location, v); + }; +} +function intVec3Setter(gl, location) { + return function (v) { + gl.uniform3iv(location, v); + }; +} +function intVec4Setter(gl, location) { + return function (v) { + gl.uniform4iv(location, v); + }; +} +function uintSetter(gl, location) { + return function (v) { + gl.uniform1ui(location, v); + }; +} +function uintArraySetter(gl, location) { + return function (v) { + gl.uniform1uiv(location, v); + }; +} +function uintVec2Setter(gl, location) { + return function (v) { + gl.uniform2uiv(location, v); + }; +} +function uintVec3Setter(gl, location) { + return function (v) { + gl.uniform3uiv(location, v); + }; +} +function uintVec4Setter(gl, location) { + return function (v) { + gl.uniform4uiv(location, v); + }; +} +function floatMat2Setter(gl, location) { + return function (v) { + gl.uniformMatrix2fv(location, false, v); + }; +} +function floatMat3Setter(gl, location) { + return function (v) { + gl.uniformMatrix3fv(location, false, v); + }; +} +function floatMat4Setter(gl, location) { + return function (v) { + gl.uniformMatrix4fv(location, false, v); + }; +} +function floatMat23Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} +function floatMat32Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} +function floatMat24Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} +function floatMat42Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} +function floatMat34Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} +function floatMat43Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} +function samplerSetter(gl, type, unit, location) { + var bindPoint = getBindPointForSamplerType(gl, type); + return utils.isWebGL2(gl) ? function (textureOrPair) { + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function (texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} +function samplerArraySetter(gl, type, unit, location, size) { + var bindPoint = getBindPointForSamplerType(gl, type); + var units = new Int32Array(size); + for (var ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + return utils.isWebGL2(gl) ? function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} +typeMap[FLOAT] = { + Type: Float32Array, + size: 4, + setter: floatSetter, + arraySetter: floatArraySetter +}; +typeMap[FLOAT_VEC2] = { + Type: Float32Array, + size: 8, + setter: floatVec2Setter, + cols: 2 +}; +typeMap[FLOAT_VEC3] = { + Type: Float32Array, + size: 12, + setter: floatVec3Setter, + cols: 3 +}; +typeMap[FLOAT_VEC4] = { + Type: Float32Array, + size: 16, + setter: floatVec4Setter, + cols: 4 +}; +typeMap[INT] = { + Type: Int32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[INT_VEC2] = { + Type: Int32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[INT_VEC3] = { + Type: Int32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[INT_VEC4] = { + Type: Int32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[UNSIGNED_INT] = { + Type: Uint32Array, + size: 4, + setter: uintSetter, + arraySetter: uintArraySetter +}; +typeMap[UNSIGNED_INT_VEC2] = { + Type: Uint32Array, + size: 8, + setter: uintVec2Setter, + cols: 2 +}; +typeMap[UNSIGNED_INT_VEC3] = { + Type: Uint32Array, + size: 12, + setter: uintVec3Setter, + cols: 3 +}; +typeMap[UNSIGNED_INT_VEC4] = { + Type: Uint32Array, + size: 16, + setter: uintVec4Setter, + cols: 4 +}; +typeMap[BOOL] = { + Type: Uint32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[BOOL_VEC2] = { + Type: Uint32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[BOOL_VEC3] = { + Type: Uint32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[BOOL_VEC4] = { + Type: Uint32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[FLOAT_MAT2] = { + Type: Float32Array, + size: 32, + setter: floatMat2Setter, + rows: 2, + cols: 2 +}; +typeMap[FLOAT_MAT3] = { + Type: Float32Array, + size: 48, + setter: floatMat3Setter, + rows: 3, + cols: 3 +}; +typeMap[FLOAT_MAT4] = { + Type: Float32Array, + size: 64, + setter: floatMat4Setter, + rows: 4, + cols: 4 +}; +typeMap[FLOAT_MAT2x3] = { + Type: Float32Array, + size: 32, + setter: floatMat23Setter, + rows: 2, + cols: 3 +}; +typeMap[FLOAT_MAT2x4] = { + Type: Float32Array, + size: 32, + setter: floatMat24Setter, + rows: 2, + cols: 4 +}; +typeMap[FLOAT_MAT3x2] = { + Type: Float32Array, + size: 48, + setter: floatMat32Setter, + rows: 3, + cols: 2 +}; +typeMap[FLOAT_MAT3x4] = { + Type: Float32Array, + size: 48, + setter: floatMat34Setter, + rows: 3, + cols: 4 +}; +typeMap[FLOAT_MAT4x2] = { + Type: Float32Array, + size: 64, + setter: floatMat42Setter, + rows: 4, + cols: 2 +}; +typeMap[FLOAT_MAT4x3] = { + Type: Float32Array, + size: 64, + setter: floatMat43Setter, + rows: 4, + cols: 3 +}; +typeMap[SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[SAMPLER_2D_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_CUBE_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +function floatAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer(index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function intAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function uintAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function matAttribSetter(gl, index, typeInfo) { + var defaultSize = typeInfo.size; + var count = typeInfo.count; + return function (b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + var numComponents = b.size || b.numComponents || defaultSize; + var size = numComponents / count; + var type = b.type || FLOAT; + var typeInfo = typeMap[type]; + var stride = typeInfo.size * numComponents; + var normalize = b.normalize || false; + var offset = b.offset || 0; + var rowOffset = stride / count; + for (var i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer(index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} +var attrTypeMap = {}; +attrTypeMap[FLOAT] = { + size: 4, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC2] = { + size: 8, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC3] = { + size: 12, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC4] = { + size: 16, + setter: floatAttribSetter +}; +attrTypeMap[INT] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[UNSIGNED_INT] = { + size: 4, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC2] = { + size: 8, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC3] = { + size: 12, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC4] = { + size: 16, + setter: uintAttribSetter +}; +attrTypeMap[BOOL] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[FLOAT_MAT2] = { + size: 4, + setter: matAttribSetter, + count: 2 +}; +attrTypeMap[FLOAT_MAT3] = { + size: 9, + setter: matAttribSetter, + count: 3 +}; +attrTypeMap[FLOAT_MAT4] = { + size: 16, + setter: matAttribSetter, + count: 4 +}; + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src) { + var log = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var lineOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + // Note: Error message formats are not defined by any spec so this may or may not work. + var matches = _toConsumableArray(log.matchAll(errorRE)); + var lineNoToErrorMap = new Map(matches.map(function (m, ndx) { + var lineNo = parseInt(m[1]); + var next = matches[ndx + 1]; + var end = next ? next.index : log.length; + var msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map(function (line, lineNo) { + var err = lineNoToErrorMap.get(lineNo); + return "".concat(lineNo + 1 + lineOffset, ": ").concat(line).concat(err ? "\n\n^^^ ".concat(err) : ''); + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +var spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + var lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return { + lineOffset: lineOffset, + shaderSource: shaderSource + }; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(function () { + progOptions.callback("".concat(msg, "\n").concat(progOptions.errors.join('\n'))); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + var compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var lastError = gl.getShaderInfoLog(shader); + var _prepShaderSource = prepShaderSource(gl.getShaderSource(shader)), + lineOffset = _prepShaderSource.lineOffset, + shaderSource = _prepShaderSource.shaderSource; + var _error = "".concat(addLineNumbersWithError(shaderSource, lastError, lineOffset), "\nError compiling ").concat(utils.glEnumToString(gl, shaderType), ": ").concat(lastError); + errFn(_error); + return _error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + var transformFeedbackVaryings; + var transformFeedbackMode; + var callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + var opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + var _errorCallback = opt_errorCallback || error; + var errors = []; + var options = { + errorCallback: function errorCallback(msg) { + errors.push(msg); + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + _errorCallback.apply(void 0, [msg].concat(args)); + }, + transformFeedbackVaryings: transformFeedbackVaryings, + transformFeedbackMode: transformFeedbackMode, + callback: callback, + errors: errors + }; + { + var attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function (attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + return options; +} +var defaultShaderType = ["VERTEX_SHADER", "FRAGMENT_SHADER"]; +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} +function deleteProgramAndShaders(gl, program, notThese) { + var shaders = gl.getAttachedShaders(program); + var _iterator = _createForOfIteratorHelper(shaders), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var shader = _step.value; + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + gl.deleteProgram(program); +} +var wait = function wait() { + var ms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + return new Promise(function (resolve) { + return setTimeout(resolve, ms); + }); +}; +function createProgramNoCheck(gl, shaders, programOptions) { + var program = gl.createProgram(); + var _getProgramOptions = getProgramOptions(programOptions), + attribLocations = _getProgramOptions.attribLocations, + transformFeedbackVaryings = _getProgramOptions.transformFeedbackVaryings, + transformFeedbackMode = _getProgramOptions.transformFeedbackMode; + for (var ndx = 0; ndx < shaders.length; ++ndx) { + var shader = shaders[ndx]; + if (typeof shader === 'string') { + var elem = getElementById(shader); + var src = elem ? elem.text : shader; + var type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + Object.entries(attribLocations).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + attrib = _ref2[0], + loc = _ref2[1]; + return gl.bindAttribLocation(program, loc, attrib); + }); + { + var varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaderSet = new Set(shaders); + var program = createProgramNoCheck(gl, shaders, progOptions); + function hasErrors(gl, program) { + var errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(function () { + var errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function (gl, arg1) { + for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + return new Promise(function (resolve, reject) { + var programOptions = getProgramOptions.apply(void 0, args); + programOptions.callback = function (err, program) { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +var createProgramAsync = exports.createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +var createProgramInfoAsync = exports.createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); +function waitForProgramLinkCompletionAsync(_x, _x2) { + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function _waitForProgramLinkCompletionAsync() { + _waitForProgramLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(gl, program) { + var ext, checkFn, waitTime; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + ext = gl.getExtension('KHR_parallel_shader_compile'); + checkFn = ext ? function (gl, program) { + return gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR); + } : function () { + return true; + }; + waitTime = 0; + case 3: + _context.next = 5; + return wait(waitTime); + case 5: + // must wait at least once + waitTime = 1000 / 60; + case 6: + if (!checkFn(gl, program)) { + _context.next = 3; + break; + } + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function waitForAllProgramsLinkCompletionAsync(_x3, _x4) { + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function _waitForAllProgramsLinkCompletionAsync() { + _waitForAllProgramsLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(gl, programs) { + var _i3, _Object$values2, program; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + _i3 = 0, _Object$values2 = Object.values(programs); + case 1: + if (!(_i3 < _Object$values2.length)) { + _context2.next = 8; + break; + } + program = _Object$values2[_i3]; + _context2.next = 5; + return waitForProgramLinkCompletionAsync(gl, program); + case 5: + _i3++; + _context2.next = 1; + break; + case 8: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + var linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + var lastError = gl.getProgramInfoLog(program); + errFn("Error in program linking: ".concat(lastError)); + // print any errors from these shaders + var shaders = gl.getAttachedShaders(program); + var errors = shaders.map(function (shader) { + return checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn); + }); + return "".concat(lastError, "\n").concat(errors.filter(function (_) { + return _; + }).join('\n')); + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts(gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaders = []; + var _iterator2 = _createForOfIteratorHelper(shaderScriptIds), + _step2; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var scriptId = _step2.value; + var shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, "unknown script element: ".concat(scriptId)); + } + shaders.push(shaderScript.text); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + var name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} +var tokenRE = /(\.|\[|]|\w+)/g; +var isDigit = function isDigit(s) { + return s >= '0' && s <= '9'; +}; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + var tokens = fullPath.split(tokenRE).filter(function (s) { + return s !== ''; + }); + var tokenNdx = 0; + var path = ''; + for (;;) { + var token = tokens[tokenNdx++]; // has to be name or number + path += token; + var isArrayIndex = isDigit(token[0]); + var accessor = isArrayIndex ? parseInt(token) : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + var isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + var _token = tokens[tokenNdx++]; // has to be . or [ + var isArray = _token === '['; + var child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function (node) { + return function (value) { + setUniformTree(node, value); + }; + }(child); + path += _token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +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, location) { + var isArray = uniformInfo.name.endsWith("[0]"); + var type = uniformInfo.type; + var typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error("unknown type: 0x".concat(type.toString(16))); // we should never get here. + } + var setter; + if (typeInfo.bindPoint) { + // it's a sampler + var unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + var uniformSetters = {}; + var uniformTree = {}; + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + for (var ii = 0; ii < numUniforms; ++ii) { + var uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + var name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + var location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + var setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + var info = {}; + var numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (var ii = 0; ii < numVaryings; ++ii) { + var varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (var name in bufferInfo) { + var varying = transformFeedbackInfo[name]; + if (varying) { + var buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + var tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + var uniformData = []; + var uniformIndices = []; + for (var ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + var uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + [["UNIFORM_TYPE", "type"], ["UNIFORM_SIZE", "size"], + // num elements + ["UNIFORM_BLOCK_INDEX", "blockNdx"], ["UNIFORM_OFFSET", "offset"]].forEach(function (pair) { + var pname = pair[0]; + var key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function (value, ndx) { + uniformData[ndx][key] = value; + }); + }); + var blockSpecs = {}; + var numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (var _ii = 0; _ii < numUniformBlocks; ++_ii) { + var name = gl.getActiveUniformBlockName(program, _ii); + var blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + return { + blockSpecs: blockSpecs, + uniformData: uniformData + }; +} +var arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +var pad = function pad(v, padding) { + return ((v + (padding - 1)) / padding | 0) * padding; +}; +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + var numElements = view.length; + var totalRows = numElements / 4; + return function (value) { + var dst = 0; + var src = 0; + for (var row = 0; row < totalRows; ++row) { + for (var col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function (value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName) { + var _options$offset, _options$array, _options$buffer, _options$bufferOffset; + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + var blockSpecs = uniformBlockSpec.blockSpecs; + var uniformData = uniformBlockSpec.uniformData; + var blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {} + }; + } + var offset = (_options$offset = options.offset) !== null && _options$offset !== void 0 ? _options$offset : 0; + var array = (_options$array = options.array) !== null && _options$array !== void 0 ? _options$array : new ArrayBuffer(blockSpec.size); + var buffer = (_options$buffer = options.buffer) !== null && _options$buffer !== void 0 ? _options$buffer : gl.createBuffer(); + var uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + var prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + var uniforms = {}; + var setters = {}; + var setterTree = {}; + blockSpec.uniformIndices.forEach(function (uniformNdx) { + var data = uniformData[uniformNdx]; + var name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + var isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + var typeInfo = typeMap[data.type]; + var Type = typeInfo.Type; + var byteLength = isArray ? pad(typeInfo.size, 16) * data.size : typeInfo.size * data.size; + var uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + var setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array: array, + asFloat: new Float32Array(array), + // for debugging + asUint8: new Uint8Array(array), + // needed for gl.bufferSubData because it doesn't take an array buffer + buffer: buffer, + uniforms: uniforms, + setters: setters, + offset: (_options$bufferOffset = options.bufferOffset) !== null && _options$bufferOffset !== void 0 ? _options$bufferOffset : offset, + size: blockSpec.size + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + var uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + var blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + var _uniformBlockInfo$siz; + var bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, (_uniformBlockInfo$siz = uniformBlockInfo.size) !== null && _uniformBlockInfo$siz !== void 0 ? _uniformBlockInfo$siz : uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + var setters = uniformBlockInfo.setters; + for (var name in values) { + var setter = setters[name]; + if (setter) { + var value = values[name]; + setter(value); + } + } +} +function setUniformTree(tree, values) { + for (var name in values) { + var prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters) { + // eslint-disable-line + var actualSetters = setters.uniformSetters || setters; + var numArgs = arguments.length <= 1 ? 0 : arguments.length - 1; + for (var aNdx = 0; aNdx < numArgs; ++aNdx) { + var values = aNdx + 1 < 1 || arguments.length <= aNdx + 1 ? undefined : arguments[aNdx + 1]; + if (Array.isArray(values)) { + var numValues = values.length; + for (var ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (var name in values) { + var setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +var setUniformsAndBindTextures = exports.setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + var attribSetters = {}; + var numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (var ii = 0; ii < numAttribs; ++ii) { + var attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + var index = gl.getAttribLocation(program, attribInfo.name); + var typeInfo = attrTypeMap[attribInfo.type]; + var setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (var name in buffers) { + var setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + var uniformSetters = createUniformSetters(gl, program); + var attribSetters = createAttributeSetters(gl, program); + var programInfo = { + program: program, + uniformSetters: uniformSetters, + attribSetters: attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + k = _ref4[0], + v = _ref4[1]; + return [k, v.location]; + })), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + k = _ref6[0], + v = _ref6[1]; + return [k, v.location]; + })) + }; + if (utils.isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + return programInfo; +} +var notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var errors = []; + shaderSources = shaderSources.map(function (source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + var script = getElementById(source); + if (!script) { + var err = "no element with id: ".concat(source); + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + if (errors.length) { + return reportError(progOptions, ''); + } + var origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = function (err, program) { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + var program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + return createProgramInfoFromProgram(gl, program); +} +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (var _i = 0, _Object$entries = Object.entries(programs); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), + name = _Object$entries$_i[0], + program = _Object$entries$_i[1]; + var options = _objectSpread({}, programOptions); + var spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + var errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (var _i2 = 0, _Object$values = Object.values(programs); _i2 < _Object$values.length; _i2++) { + var _program = _Object$values[_i2]; + var shaders = gl.getAttachedShaders(_program); + gl.deleteProgram(_program); + var _iterator3 = _createForOfIteratorHelper(shaders), + _step3; + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var shader = _step3.value; + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + } + return errors; + } + } + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs) { + var programOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // Remember existing shaders so that if there is an error we don't delete them + var noDeleteShadersSet = new Set(); + + // compile and link everything + var programs = Object.fromEntries(Object.entries(programSpecs).map(function (_ref7) { + var _ref8 = _slicedToArray(_ref7, 2), + name = _ref8[0], + spec = _ref8[1]; + var options = _objectSpread({}, programOptions); + var shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(function () { + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + name = _ref10[0], + program = _ref10[1]; + return [name, createProgramInfoFromProgram(gl, program)]; + })); + } + var origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = function (err, programs) { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + var programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +var createProgramsAsync = exports.createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +var createProgramInfosAsync = exports.createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +/***/ }), + +/***/ "./src/textures.js": +/*!*************************!*\ + !*** ./src/textures.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.canFilter = canFilter; +exports.canGenerateMipmap = canGenerateMipmap; +exports.createSampler = createSampler; +exports.createSamplers = createSamplers; +exports.createTexture = createTexture; +exports.createTextures = createTextures; +exports.getBytesPerElementForInternalFormat = getBytesPerElementForInternalFormat; +exports.getFormatAndTypeForInternalFormat = getFormatAndTypeForInternalFormat; +exports.getNumComponentsForFormat = getNumComponentsForFormat; +exports.loadTextureFromUrl = loadTextureFromUrl; +exports.resizeTexture = resizeTexture; +exports.setDefaultTextureColor = setDefaultTextureColor; +exports.setEmptyTexture = setEmptyTexture; +exports.setSamplerParameters = setSamplerParameters; +exports.setTextureDefaults_ = setDefaults; +exports.setTextureFilteringForSize = setTextureFilteringForSize; +exports.setTextureFromArray = setTextureFromArray; +exports.setTextureFromElement = setTextureFromElement; +exports.setTextureParameters = setTextureParameters; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level texture related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.textures` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/textures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined +}; +var isArrayBuffer = typedArrays.isArrayBuffer; + +// Should we make this on demand? +var getShared2DContext = function () { + var s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || (typeof document !== 'undefined' && document.createElement ? document.createElement("canvas").getContext("2d") : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +var ALPHA = 0x1906; +var RGB = 0x1907; +var RGBA = 0x1908; +var LUMINANCE = 0x1909; +var LUMINANCE_ALPHA = 0x190A; +var DEPTH_COMPONENT = 0x1902; +var DEPTH_STENCIL = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +var CLAMP_TO_EDGE = 0x812f; + +/* TextureMagFilter */ +var NEAREST = 0x2600; +var LINEAR = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +var TEXTURE_2D = 0x0de1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806f; +var TEXTURE_2D_ARRAY = 0x8c1a; + +/* Cubemap Targets */ +var TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +var TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +var TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +var TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +var TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +var TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +var TEXTURE_MIN_FILTER = 0x2801; +var TEXTURE_MAG_FILTER = 0x2800; +var TEXTURE_WRAP_S = 0x2802; +var TEXTURE_WRAP_T = 0x2803; +var TEXTURE_WRAP_R = 0x8072; +var TEXTURE_MIN_LOD = 0x813a; +var TEXTURE_MAX_LOD = 0x813b; +var TEXTURE_BASE_LEVEL = 0x813c; +var TEXTURE_MAX_LEVEL = 0x813d; +var TEXTURE_COMPARE_MODE = 0x884C; +var TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +var UNPACK_ALIGNMENT = 0x0cf5; +var UNPACK_ROW_LENGTH = 0x0cf2; +var UNPACK_IMAGE_HEIGHT = 0x806e; +var UNPACK_SKIP_PIXELS = 0x0cf4; +var UNPACK_SKIP_ROWS = 0x0cf3; +var UNPACK_SKIP_IMAGES = 0x806d; +var UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +var UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +var UNPACK_FLIP_Y_WEBGL = 0x9240; +var R8 = 0x8229; +var R8_SNORM = 0x8F94; +var R16F = 0x822D; +var R32F = 0x822E; +var R8UI = 0x8232; +var R8I = 0x8231; +var RG16UI = 0x823A; +var RG16I = 0x8239; +var RG32UI = 0x823C; +var RG32I = 0x823B; +var RG8 = 0x822B; +var RG8_SNORM = 0x8F95; +var RG16F = 0x822F; +var RG32F = 0x8230; +var RG8UI = 0x8238; +var RG8I = 0x8237; +var R16UI = 0x8234; +var R16I = 0x8233; +var R32UI = 0x8236; +var R32I = 0x8235; +var RGB8 = 0x8051; +var SRGB8 = 0x8C41; +var RGB565 = 0x8D62; +var RGB8_SNORM = 0x8F96; +var R11F_G11F_B10F = 0x8C3A; +var RGB9_E5 = 0x8C3D; +var RGB16F = 0x881B; +var RGB32F = 0x8815; +var RGB8UI = 0x8D7D; +var RGB8I = 0x8D8F; +var RGB16UI = 0x8D77; +var RGB16I = 0x8D89; +var RGB32UI = 0x8D71; +var RGB32I = 0x8D83; +var RGBA8 = 0x8058; +var SRGB8_ALPHA8 = 0x8C43; +var RGBA8_SNORM = 0x8F97; +var RGB5_A1 = 0x8057; +var RGBA4 = 0x8056; +var RGB10_A2 = 0x8059; +var RGBA16F = 0x881A; +var RGBA32F = 0x8814; +var RGBA8UI = 0x8D7C; +var RGBA8I = 0x8D8E; +var RGB10_A2UI = 0x906F; +var RGBA16UI = 0x8D76; +var RGBA16I = 0x8D88; +var RGBA32I = 0x8D82; +var RGBA32UI = 0x8D70; +var DEPTH_COMPONENT16 = 0x81A5; +var DEPTH_COMPONENT24 = 0x81A6; +var DEPTH_COMPONENT32F = 0x8CAC; +var DEPTH32F_STENCIL8 = 0x8CAD; +var DEPTH24_STENCIL8 = 0x88F0; + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var RG = 0x8227; +var RG_INTEGER = 0x8228; +var RED = 0x1903; +var RED_INTEGER = 0x8D94; +var RGB_INTEGER = 0x8D98; +var RGBA_INTEGER = 0x8D99; +var formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + var f = formatInfo; + f[ALPHA] = { + numColorComponents: 1 + }; + f[LUMINANCE] = { + numColorComponents: 1 + }; + f[LUMINANCE_ALPHA] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RED] = { + numColorComponents: 1 + }; + f[RED_INTEGER] = { + numColorComponents: 1 + }; + f[RG] = { + numColorComponents: 2 + }; + f[RG_INTEGER] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGB_INTEGER] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RGBA_INTEGER] = { + numColorComponents: 4 + }; + f[DEPTH_COMPONENT] = { + numColorComponents: 1 + }; + f[DEPTH_STENCIL] = { + numColorComponents: 2 + }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +var s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + var t = {}; + // unsized formats + t[ALPHA] = { + textureFormat: ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE] = { + textureFormat: LUMINANCE, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE_ALPHA] = { + textureFormat: LUMINANCE_ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2, 4, 4, 8], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[RGB] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 6, 6, 12, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5] + }; + t[RGBA] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 8, 8, 16, 2, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1] + }; + t[DEPTH_COMPONENT] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_INT, UNSIGNED_SHORT] + }; + + // sized formats + t[R8] = { + textureFormat: RED, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8_SNORM] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [FLOAT, HALF_FLOAT] + }; + t[R32F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[R8UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_SHORT] + }; + t[R16I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [SHORT] + }; + t[R32UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[R32I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [INT] + }; + t[RG8] = { + textureFormat: RG, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8_SNORM] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [8, 4], + type: [FLOAT, HALF_FLOAT] + }; + t[RG32F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [8], + type: [FLOAT] + }; + t[RG8UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_SHORT] + }; + t[RG16I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [SHORT] + }; + t[RG32UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_INT] + }; + t[RG32I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [INT] + }; + t[RGB8] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[SRGB8] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB565] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5] + }; + t[RGB8_SNORM] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [BYTE] + }; + t[R11F_G11F_B10F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV] + }; + t[RGB9_E5] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV] + }; + t[RGB16F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6], + type: [FLOAT, HALF_FLOAT] + }; + t[RGB32F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [FLOAT] + }; + t[RGB8UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB8I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [BYTE] + }; + t[RGB16UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [UNSIGNED_SHORT] + }; + t[RGB16I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [SHORT] + }; + t[RGB32UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [UNSIGNED_INT] + }; + t[RGB32I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [INT] + }; + t[RGBA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[SRGB8_ALPHA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8_SNORM] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB5_A1] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2, 4], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA4] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4] + }; + t[RGB10_A2] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [16, 8], + type: [FLOAT, HALF_FLOAT] + }; + t[RGBA32F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [16], + type: [FLOAT] + }; + t[RGBA8UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB10_A2UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_SHORT] + }; + t[RGBA16I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [SHORT] + }; + t[RGBA32I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [INT] + }; + t[RGBA32UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [UNSIGNED_INT] + }; + // Sized Internal + t[DEPTH_COMPONENT16] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_SHORT, UNSIGNED_INT] + }; + t[DEPTH_COMPONENT24] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[DEPTH_COMPONENT32F] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[DEPTH24_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_24_8] + }; + t[DEPTH32F_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT_32_UNSIGNED_INT_24_8_REV] + }; + Object.keys(t).forEach(function (internalFormat) { + var info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function (bytesPerElement, ndx) { + var type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + var bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0] + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & value - 1) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!utils.isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + var info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return typedArrays.getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE; +} +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + var size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + var colorspaceConversion; + var premultiplyAlpha; + var flipY; + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + fn(); + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (utils.isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D || helper.isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + var sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + var samplers = {}; + Object.keys(samplerOptions).forEach(function (name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults.textureOptions; + internalFormat = internalFormat || RGBA; + var target = options.target || TEXTURE_2D; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + var filtering = canFilter(internalFormat) ? LINEAR : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } +} +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || options.auto === undefined && options.level === undefined; +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_Z]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + var faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + var facesWithNdx = faces.map(function (face, ndx) { + return { + face: face, + ndx: ndx + }; + }); + facesWithNdx.sort(function (a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + var level = options.level || 0; + var width = element.width; + var height = element.height; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // guess the parts + var imgWidth = element.width; + var imgHeight = element.height; + var size; + var slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + var ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, function () { + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }).then(function (imageBitmap) { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + scopedSetPackState(gl, options, function () { + var smallest = Math.min(element.width, element.height); + var largest = Math.max(element.width, element.height); + var depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + var xMult = element.width === largest ? 1 : 0; + var yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (var d = 0; d < depth; ++d) { + var srcX = d * smallest * xMult; + var srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, function () { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} +function noop() {} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + var a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && a.port === location.port && a.protocol === location.protocol; + } else { + var localOrigin = new URL(location.href).origin; + var urlOrigin = new URL(url, location.href).origin; + return urlOrigin === localOrigin; + } +} +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) ? 'anonymous' : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + var img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + var clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + var onError = function onError() { + var msg = "couldn't load image: " + url; + helper.error(msg); + callback(msg, img); + clearEventHandlers(); + }; + var onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + var err; + var bm; + var cb = function cb() { + callback(err, bm); + }; + var options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function (response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function (blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }); + }).then(function (bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + })["catch"](function (e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap || typeof ImageData !== 'undefined' && obj instanceof ImageData || typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement; +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function () { + callback(null, obj); + }); + return obj; + } + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + var color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } else { + gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var img = loadAndUseImage(options.src, options.crossOrigin, function (err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D; + if (target !== TEXTURE_CUBE_MAP) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = 6; + var errors = []; + var faces = getCubeFaceOrder(gl, options); + var imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder(gl).forEach(function (otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D_ARRAY; + if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = urls.length; + var errors = []; + var imgs; // eslint-disable-line + var level = options.level || 0; + var width = options.width; + var height = options.height; + var depth = urls.length; + var firstImage = true; + function uploadImg(slice) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (var s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + var src = img; + var ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var width = options.width; + var height = options.height; + var depth = options.depth; + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + var Type = typedArrays.getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + var bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + var numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + utils.glEnumToString(gl, format); + } + var dimensions; + if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + if (!width && !height && !depth) { + var size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + var elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + var faceSize = numElements / 6 * elementsPerElement; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var offset = faceSize * f.ndx; + var data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + var tex = gl.createTexture(); + var target = options.target || TEXTURE_2D; + var width = options.width || 1; + var height = options.height || 1; + var internalFormat = options.internalFormat || RGBA; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } + var src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof src === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || Array.isArray(src) && (typeof src[0] === 'number' || Array.isArray(src[0]) || isArrayBuffer(src[0]))) { + var dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof src[0] === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { + // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type; + var src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || Array.isArray(src) && typeof src[0] === 'number') { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || Array.isArray(src) && typeof src[0] === 'string'; +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + var numDownloading = 0; + var errors = []; + var textures = {}; + var images = {}; + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function () { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + Object.keys(textureOptions).forEach(function (name) { + var options = textureOptions[name]; + var onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function onLoadFn(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + return textures; +} + +/***/ }), + +/***/ "./src/twgl-full.js": +/*!**************************!*\ + !*** ./src/twgl-full.js ***! + \**************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +var _exportNames = { + m4: true, + v3: true, + primitives: true +}; +exports.v3 = exports.primitives = exports.m4 = void 0; +var m4 = _interopRequireWildcard(__webpack_require__(/*! ./m4.js */ "./src/m4.js")); +exports.m4 = m4; +var v3 = _interopRequireWildcard(__webpack_require__(/*! ./v3.js */ "./src/v3.js")); +exports.v3 = v3; +var primitives = _interopRequireWildcard(__webpack_require__(/*! ./primitives.js */ "./src/primitives.js")); +exports.primitives = primitives; +var _twgl = __webpack_require__(/*! ./twgl.js */ "./src/twgl.js"); +Object.keys(_twgl).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === _twgl[key]) return; + exports[key] = _twgl[key]; +}); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } + +/***/ }), + +/***/ "./src/twgl.js": +/*!*********************!*\ + !*** ./src/twgl.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +var _exportNames = { + addExtensionsToContext: true, + getContext: true, + getWebGLContext: true, + resizeCanvasToDisplaySize: true, + setDefaults: true, + attributes: true, + textures: true, + utils: true, + draw: true, + framebuffers: true, + programs: true, + typedarrays: true, + vertexArrays: true +}; +exports.addExtensionsToContext = addExtensionsToContext; +exports.framebuffers = exports.draw = exports.attributes = void 0; +exports.getContext = getContext; +exports.getWebGLContext = getWebGLContext; +exports.programs = void 0; +exports.resizeCanvasToDisplaySize = resizeCanvasToDisplaySize; +exports.setDefaults = setDefaults; +exports.vertexArrays = exports.utils = exports.typedarrays = exports.textures = void 0; +var attributes = _interopRequireWildcard(__webpack_require__(/*! ./attributes.js */ "./src/attributes.js")); +exports.attributes = attributes; +Object.keys(attributes).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === attributes[key]) return; + exports[key] = attributes[key]; +}); +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +exports.textures = textures; +Object.keys(textures).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === textures[key]) return; + exports[key] = textures[key]; +}); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +exports.utils = utils; +Object.keys(utils).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === utils[key]) return; + exports[key] = utils[key]; +}); +var draw = _interopRequireWildcard(__webpack_require__(/*! ./draw.js */ "./src/draw.js")); +exports.draw = draw; +Object.keys(draw).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === draw[key]) return; + exports[key] = draw[key]; +}); +var framebuffers = _interopRequireWildcard(__webpack_require__(/*! ./framebuffers.js */ "./src/framebuffers.js")); +exports.framebuffers = framebuffers; +Object.keys(framebuffers).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === framebuffers[key]) return; + exports[key] = framebuffers[key]; +}); +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +exports.programs = programs; +Object.keys(programs).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === programs[key]) return; + exports[key] = programs[key]; +}); +var typedarrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +exports.typedarrays = typedarrays; +Object.keys(typedarrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === typedarrays[key]) return; + exports[key] = typedarrays[key]; +}); +var vertexArrays = _interopRequireWildcard(__webpack_require__(/*! ./vertex-arrays.js */ "./src/vertex-arrays.js")); +exports.vertexArrays = vertexArrays; +Object.keys(vertexArrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === vertexArrays[key]) return; + exports[key] = vertexArrays[key]; +}); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * The main TWGL module. + * + * For most use cases you shouldn't need anything outside this module. + * Exceptions between the stuff added to twgl-full (v3, m4, primitives) + * + * @module twgl + * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray + * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays + * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo + * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo + * @borrows module:twgl/draw.drawObjectList as drawObjectList + * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo + * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo + * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo + * @borrows module:twgl/programs.createProgramInfo as createProgramInfo + * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo + * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock + * @borrows module:twgl/programs.setUniformBlock as setUniformBlock + * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms + * @borrows module:twgl/programs.setUniforms as setUniforms + * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes + * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray + * @borrows module:twgl/textures.createTexture as createTexture + * @borrows module:twgl/textures.resizeTexture as resizeTexture + * @borrows module:twgl/textures.createTextures as createTextures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + addExtensionsToContext: true +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line + textures.setTextureDefaults_(newDefaults); // eslint-disable-line +} +var prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + utils.glEnumToString(gl, 0); + var ext = gl.getExtension(extensionName); + if (ext) { + var enums = {}; + var fnSuffix = prefixRE.exec(extensionName)[1]; + var enumSuffix = '_' + fnSuffix; + for (var key in ext) { + var value = ext[key]; + var isFunc = typeof value === 'function'; + var suffix = isFunc ? fnSuffix : enumSuffix; + var name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + helper.warn(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function (origFn) { + return function () { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name + }; + utils.glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +var supportedExtensions = ['ANGLE_instanced_arrays', 'EXT_blend_minmax', 'EXT_color_buffer_float', 'EXT_color_buffer_half_float', 'EXT_disjoint_timer_query', 'EXT_disjoint_timer_query_webgl2', 'EXT_frag_depth', 'EXT_sRGB', 'EXT_shader_texture_lod', 'EXT_texture_filter_anisotropic', 'OES_element_index_uint', 'OES_standard_derivatives', 'OES_texture_float', 'OES_texture_float_linear', 'OES_texture_half_float', 'OES_texture_half_float_linear', 'OES_vertex_array_object', 'WEBGL_color_buffer_float', 'WEBGL_compressed_texture_atc', 'WEBGL_compressed_texture_etc1', 'WEBGL_compressed_texture_pvrtc', 'WEBGL_compressed_texture_s3tc', 'WEBGL_compressed_texture_s3tc_srgb', 'WEBGL_depth_texture', 'WEBGL_draw_buffers']; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (var ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + var gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + var names = ["webgl2", "webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + var gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + 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; +} + +// function notPrivate(name) { +// return name[name.length - 1] !== '_'; +// } +// +// function copyPublicProperties(src, dst) { +// Object.keys(src).filter(notPrivate).forEach(function(key) { +// dst[key] = src[key]; +// }); +// return dst; +// } + +/***/ }), + +/***/ "./src/typedarrays.js": +/*!****************************!*\ + !*** ./src/typedarrays.js ***! + \****************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.getGLTypeForTypedArray = getGLTypeForTypedArray; +exports.getGLTypeForTypedArrayType = getGLTypeForTypedArrayType; +exports.getTypedArrayTypeForGLType = getTypedArrayTypeForGLType; +exports.isArrayBuffer = void 0; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader typed array related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.typedArray` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/typedArray + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var glTypeToTypedArray = {}; +{ + var tt = glTypeToTypedArray; + tt[BYTE] = Int8Array; + tt[UNSIGNED_BYTE] = Uint8Array; + tt[SHORT] = Int16Array; + tt[UNSIGNED_SHORT] = Uint16Array; + tt[INT] = Int32Array; + tt[UNSIGNED_INT] = Uint32Array; + tt[FLOAT] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5] = Uint16Array; + tt[HALF_FLOAT] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array; + tt[UNSIGNED_INT_24_8] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArray instanceof Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArray instanceof Int32Array) { + return INT; + } // eslint-disable-line + if (typedArray instanceof Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArray instanceof Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArrayType === Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArrayType === Int32Array) { + return INT; + } // eslint-disable-line + if (typedArrayType === Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArrayType === Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + var CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} +var isArrayBuffer = exports.isArrayBuffer = typeof SharedArrayBuffer !== 'undefined' ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); +} : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; +}; + +/***/ }), + +/***/ "./src/utils.js": +/*!**********************!*\ + !*** ./src/utils.js ***! + \**********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.glEnumToString = void 0; +exports.isWebGL1 = isWebGL1; +exports.isWebGL2 = isWebGL2; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +var glEnumToString = exports.glEnumToString = function () { + var haveEnumsForType = {}; + var enums = {}; + function addEnums(gl) { + var type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (var key in gl) { + if (typeof gl[key] === 'number') { + var existing = enums[gl[key]]; + enums[gl[key]] = existing ? "".concat(existing, " | ").concat(key) : key; + } + } + haveEnumsForType[type] = true; + } + } + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? "0x".concat(value.toString(16)) : value); + }; +}(); + +/***/ }), + +/***/ "./src/v3.js": +/*!*******************!*\ + !*** ./src/v3.js ***! + \*******************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.add = add; +exports.copy = copy; +exports.create = create; +exports.cross = cross; +exports.distance = distance; +exports.distanceSq = distanceSq; +exports.divScalar = divScalar; +exports.divide = divide; +exports.dot = dot; +exports.length = length; +exports.lengthSq = lengthSq; +exports.lerp = lerp; +exports.lerpV = lerpV; +exports.max = max; +exports.min = min; +exports.mulScalar = mulScalar; +exports.multiply = multiply; +exports.negate = negate; +exports.normalize = normalize; +exports.setDefaultType = setDefaultType; +exports.subtract = subtract; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * + * Vec3 math math functions. + * + * Almost all functions take an optional `dst` argument. If it is not passed in the + * functions will create a new Vec3. In other words you can do this + * + * var v = v3.cross(v1, v2); // Creates a new Vec3 with the cross product of v1 x v2. + * + * or + * + * var v = v3.create(); + * v3.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v + * + * The first style is often easier but depending on where it's used it generates garbage where + * as there is almost never allocation with the second style. + * + * It is always save to pass any vector as the destination. So for example + * + * v3.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1 + * + * @module twgl/v3 + */ + +var VecType = Float32Array; + +/** + * A JavaScript array with 3 values or a Float32Array with 3 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link module:twgl/v3.setDefaultType}. + * @typedef {(number[]|Float32Array)} Vec3 + * @memberOf module:twgl/v3 + */ + +/** + * Sets the type this library creates for a Vec3 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Vec3 + * @memberOf module:twgl/v3 + */ +function setDefaultType(ctor) { + var oldType = VecType; + VecType = ctor; + return oldType; +} + +/** + * Creates a vec3; may be called with x, y, z to set initial values. + * @param {number} [x] Initial x value. + * @param {number} [y] Initial y value. + * @param {number} [z] Initial z value. + * @return {module:twgl/v3.Vec3} the created vector + * @memberOf module:twgl/v3 + */ +function create(x, y, z) { + var dst = new VecType(3); + if (x) { + dst[0] = x; + } + if (y) { + dst[1] = y; + } + if (z) { + dst[2] = z; + } + return dst; +} + +/** + * Adds two vectors; assumes a and b have the same dimension. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A vector tha tis the sum of a and b. + * @memberOf module:twgl/v3 + */ +function add(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] + b[0]; + dst[1] = a[1] + b[1]; + dst[2] = a[2] + b[2]; + return dst; +} + +/** + * Subtracts two vectors. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A vector that is the difference of a and b. + * @memberOf module:twgl/v3 + */ +function subtract(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] - b[0]; + dst[1] = a[1] - b[1]; + dst[2] = a[2] - b[2]; + return dst; +} + +/** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient t, returns + * a + t * (b - a). + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {number} t Interpolation coefficient. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The linear interpolated result. + * @memberOf module:twgl/v3 + */ +function lerp(a, b, t, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] + t * (b[0] - a[0]); + dst[1] = a[1] + t * (b[1] - a[1]); + dst[2] = a[2] + t * (b[2] - a[2]); + return dst; +} + +/** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient vector t, returns + * a + t * (b - a). + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} t Interpolation coefficients vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} the linear interpolated result. + * @memberOf module:twgl/v3 + */ +function lerpV(a, b, t, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] + t[0] * (b[0] - a[0]); + dst[1] = a[1] + t[1] * (b[1] - a[1]); + dst[2] = a[2] + t[2] * (b[2] - a[2]); + return dst; +} + +/** + * Return max values of two vectors. + * Given vectors a and b returns + * [max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2])]. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The max components vector. + * @memberOf module:twgl/v3 + */ +function max(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = Math.max(a[0], b[0]); + dst[1] = Math.max(a[1], b[1]); + dst[2] = Math.max(a[2], b[2]); + return dst; +} + +/** + * Return min values of two vectors. + * Given vectors a and b returns + * [min(a[0], b[0]), min(a[1], b[1]), min(a[2], b[2])]. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The min components vector. + * @memberOf module:twgl/v3 + */ +function min(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = Math.min(a[0], b[0]); + dst[1] = Math.min(a[1], b[1]); + dst[2] = Math.min(a[2], b[2]); + return dst; +} + +/** + * Multiplies a vector by a scalar. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ +function mulScalar(v, k, dst) { + dst = dst || new VecType(3); + dst[0] = v[0] * k; + dst[1] = v[1] * k; + dst[2] = v[2] * k; + return dst; +} + +/** + * Divides a vector by a scalar. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ +function divScalar(v, k, dst) { + dst = dst || new VecType(3); + dst[0] = v[0] / k; + dst[1] = v[1] / k; + dst[2] = v[2] / k; + return dst; +} + +/** + * Computes the cross product of two vectors; assumes both vectors have + * three entries. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of a cross b. + * @memberOf module:twgl/v3 + */ +function cross(a, b, dst) { + dst = dst || new VecType(3); + var t1 = a[2] * b[0] - a[0] * b[2]; + var t2 = a[0] * b[1] - a[1] * b[0]; + dst[0] = a[1] * b[2] - a[2] * b[1]; + dst[1] = t1; + dst[2] = t2; + return dst; +} + +/** + * Computes the dot product of two vectors; assumes both vectors have + * three entries. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @return {number} dot product + * @memberOf module:twgl/v3 + */ +function dot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +/** + * Computes the length of vector + * @param {module:twgl/v3.Vec3} v vector. + * @return {number} length of vector. + * @memberOf module:twgl/v3 + */ +function length(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +/** + * Computes the square of the length of vector + * @param {module:twgl/v3.Vec3} v vector. + * @return {number} square of the length of vector. + * @memberOf module:twgl/v3 + */ +function lengthSq(v) { + return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; +} + +/** + * Computes the distance between 2 points + * @param {module:twgl/v3.Vec3} a vector. + * @param {module:twgl/v3.Vec3} b vector. + * @return {number} distance between a and b + * @memberOf module:twgl/v3 + */ +function distance(a, b) { + var dx = a[0] - b[0]; + var dy = a[1] - b[1]; + var dz = a[2] - b[2]; + return Math.sqrt(dx * dx + dy * dy + dz * dz); +} + +/** + * Computes the square of the distance between 2 points + * @param {module:twgl/v3.Vec3} a vector. + * @param {module:twgl/v3.Vec3} b vector. + * @return {number} square of the distance between a and b + * @memberOf module:twgl/v3 + */ +function distanceSq(a, b) { + var dx = a[0] - b[0]; + var dy = a[1] - b[1]; + var dz = a[2] - b[2]; + return dx * dx + dy * dy + dz * dz; +} + +/** + * Divides a vector by its Euclidean length and returns the quotient. + * @param {module:twgl/v3.Vec3} a The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The normalized vector. + * @memberOf module:twgl/v3 + */ +function normalize(a, dst) { + dst = dst || new VecType(3); + var lenSq = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; + var len = Math.sqrt(lenSq); + if (len > 0.00001) { + dst[0] = a[0] / len; + dst[1] = a[1] / len; + dst[2] = a[2] / len; + } else { + dst[0] = 0; + dst[1] = 0; + dst[2] = 0; + } + return dst; +} + +/** + * Negates a vector. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} -v. + * @memberOf module:twgl/v3 + */ +function negate(v, dst) { + dst = dst || new VecType(3); + dst[0] = -v[0]; + dst[1] = -v[1]; + dst[2] = -v[2]; + return dst; +} + +/** + * Copies a vector. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A copy of v. + * @memberOf module:twgl/v3 + */ +function copy(v, dst) { + dst = dst || new VecType(3); + dst[0] = v[0]; + dst[1] = v[1]; + dst[2] = v[2]; + return dst; +} + +/** + * Multiplies a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of products of entries of a and + * b. + * @memberOf module:twgl/v3 + */ +function multiply(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] * b[0]; + dst[1] = a[1] * b[1]; + dst[2] = a[2] * b[2]; + return dst; +} + +/** + * Divides a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of quotients of entries of a and + * b. + * @memberOf module:twgl/v3 + */ +function divide(a, b, dst) { + dst = dst || new VecType(3); + dst[0] = a[0] / b[0]; + dst[1] = a[1] / b[1]; + dst[2] = a[2] / b[2]; + return dst; +} + +/***/ }), + +/***/ "./src/vertex-arrays.js": +/*!******************************!*\ + !*** ./src/vertex-arrays.js ***! + \******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createVAOAndSetAttributes = createVAOAndSetAttributes; +exports.createVAOFromBufferInfo = createVAOFromBufferInfo; +exports.createVertexArrayInfo = createVertexArrayInfo; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +var ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function (programInfo) { + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + programs.setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__("./src/twgl-full.js"); +/******/ +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=twgl-full.js.map \ No newline at end of file diff --git a/dist/6.x/twgl-full.js.map b/dist/6.x/twgl-full.js.map new file mode 100644 index 00000000..afd7452e --- /dev/null +++ b/dist/6.x/twgl-full.js.map @@ -0,0 +1 @@ +{"version":3,"file":"twgl-full.js","mappings":"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AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASsB,uBAAuBA,CAAC5D,EAAE,EAAE6D,MAAM,EAAE;EAC3C,IAAMC,OAAO,GAAG,CAAC,CAAC;EAClBlF,MAAM,CAACmF,IAAI,CAACF,MAAM,CAAC,CAACG,OAAO,CAAC,UAAS3B,SAAS,EAAE;IAC9C,IAAI,CAACjB,SAAS,CAACiB,SAAS,CAAC,EAAE;MACzB,IAAMzB,KAAK,GAAGiD,MAAM,CAACxB,SAAS,CAAC;MAC/B,IAAM4B,UAAU,GAAGrD,KAAK,CAACsD,MAAM,IAAItD,KAAK,CAACS,IAAI,IAAIT,KAAK,CAACqD,UAAU,IAAK/D,QAAQ,CAACC,YAAY,GAAGkC,SAAU;MACxG,IAAIzB,KAAK,CAACuD,KAAK,EAAE;QACf,IAAI,CAACzB,KAAK,CAACC,OAAO,CAAC/B,KAAK,CAACuD,KAAK,CAAC,IAAI,CAACvG,WAAW,CAAC6E,aAAa,CAAC7B,KAAK,CAACuD,KAAK,CAAC,EAAE;UAC1E,MAAM,IAAIjC,KAAK,CAAC,wCAAwC,CAAC;QAC3D;QACA4B,OAAO,CAACG,UAAU,CAAC,GAAG;UACpBE,KAAK,EAAEvD,KAAK,CAACuD;QACf,CAAC;MACH,CAAC,MAAM;QACL,IAAIC,EAAE;QA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,IAAM4C,QAAQ,GAAGvD,EAAE,CAACsF,kBAAkB,CAAChG,YAAY,EAAEE,WAAW,CAAC;EACjEQ,EAAE,CAACc,UAAU,CAACxB,YAAY,EAAE,IAAI,CAAC;EAEjC,IAAMiG,aAAa,GAAGR,yBAAyB,CAAC/E,EAAE,EAAEkE,MAAM,CAACxD,IAAI,CAAC;EAChE,IAAM8E,aAAa,GAAGjC,QAAQ,GAAGgC,aAAa;EAC9C,IAAMvD,aAAa,GAAGkC,MAAM,CAAClC,aAAa,IAAIkC,MAAM,CAAC3B,IAAI;EACzD;EACA,IAAM6C,WAAW,GAAGI,aAAa,GAAGxD,aAAa;EACjD,IAAIoD,WAAW,GAAG,CAAC,KAAK,CAAC,EAAE;IACzB,MAAM,IAAIlD,KAAK,kBAAAC,MAAA,CAAkBH,aAAa,8BAAAG,MAAA,CAA2BR,MAAM,CAAE,CAAC;EACpF;EACA,OAAOyD,WAAW;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASK,0BAA0BA,CAACzF,EAAE,EAAE6D,MAAM,EAAE6B,aAAa,EAAE;EAC7D,IAAMC,UAAU,GAAG/B,uBAAuB,CAAC5D,EAAE,EAAE6D,MAAM,CAAC;EACtD,IAAM+B,UAAU,GAAGhH,MAAM,CAACiH,MAAM,CAAC,CAAC,CAAC,EAAEH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OAAO,CAACiL,MAAM,CAAC,EAAEvC,eAAe,CAAC;EAC9D,OAAO5X,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASwa,iBAAiBA,CAACxa,KAAK,EAAEma,MAAM,EAAE;EACxCD,kBAAkB,CAACla,KAAK,EAAEma,MAAM,EAAEpC,EAAE,CAACL,cAAc,CAAC;EACpD,OAAO1X,KAAK;AACd;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASya,gBAAgBA,CAACxX,MAAM,EAAEkX,MAAM,EAAE;EACxCnc,MAAM,CAACmF,IAAI,CAACF,MAAM,CAAC,CAACG,OAAO,CAAC,UAAS3C,IAAI,EAAE;IACzC,IAAMT,KAAK,GAAGiD,MAAM,CAACxC,IAAI,CAAC;IAC1B,IAAIA,IAAI,CAACia,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;MAC5BF,iBAAiB,CAACxa,KAAK,EAAEma,MAAM,CAAC;IAClC,CAAC,MAAM,IAAI1Z,IAAI,CAACia,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAIja,IAAI,CAACia,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;MAClEJ,kBAAkB,CAACta,KAAK,EAAEma,MAAM,CAAC;IACnC,CAAC,MAAM,IAAI1Z,IAAI,CAACia,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;MACpCH,eAAe,CAACva,KAAK,EAAEma,MAAM,CAAC;IAChC;EACF,CAAC,CAAC;EACF,OAAOlX,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS0X,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ACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC;EAEJ;EACA,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,CAAC,EACJ,CAAC,EAAE,C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H,aAAa,CAACG,eAAe,GAAG,CAAC,EAAEA,eAAe,GAAG,CAAC,CAAC;EACvD;EACAH,aAAa,CAACG,eAAe,GAAG,CAAC,EAAEA,eAAe,GAAG,CAAC,CAAC;EACvD;EACAH,aAAa,CAACG,eAAe,GAAG,CAAC,EAAEA,eAAe,GAAG,CAAC,CAAC;EAEvD,OAAO;IACL7F,QAAQ,EAAEO,SAAS;IACnBjC,MAAM,EAAID,OAAO;IACjB4B,QAAQ,EAAEO,SAAS;IACnBpW,OAAO,EAAGA;EACZ,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS0b,sBAAsBA,CAC3BnF,MAAM,EACNlS,MAAM,EACNgU,kBAAkB,EAClBC,oBAAoB,EACpBG,MAAM,EACNC,SAAS,EAAE;EACb,OAAOR,2BAA2B,CAC9B3B,MAAM,EACNA,MAAM,EACNlS,MAAM,EACNgU,kBAAkB,EAClBC,oBAAoB,EACpBG,MAAM,EACNC,SAAS,CAAC;AAChB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASiD,mBAAmBA,CACxBpF,MAAM,EACN2D,SAAS,EACT7B,kBAAkB,EAClBuD,gBAAgB,EAChBC,UAAU,EACVC,QAAQ,EAAE;EACZ,IAAIzD,kBAAkB,GAAG,CAAC,EAAE;IAC1B,MAAM,IAAIjc,KAAK,CAAC,yCAAyC,CAAC;EAC5D;EAEA,IAAIwf,gBAAgB,GAAG,CAAC,EAAE;IACxB,MAAM,IAAIxf,KAAK,CAAC,2CAA2C,CAAC;EAC9D;EA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ASugB,gBAAgBA,CAAC5jC,EAAE,EAAEmH,WAAW,EAAE08B,gBAAgB,EAAE;EAC3D,IAAMnB,gBAAgB,GAAGv7B,WAAW,CAACu7B,gBAAgB,IAAIv7B,WAAW;EACpE,IAAMy6B,SAAS,GAAGc,gBAAgB,CAACjB,UAAU,CAACoC,gBAAgB,CAACxiC,IAAI,CAAC;EACpE,IAAIugC,SAAS,EAAE;IAAA,IAAAkC,qBAAA;IACb,IAAMC,eAAe,GAAGnC,SAAS,CAAChM,KAAK;IACvC51B,EAAE,CAAC8gC,eAAe,CAAC1S,cAAc,EAAE2V,eAAe,EAAEF,gBAAgB,CAACljC,MAAM,EAAEkjC,gBAAgB,CAACn/B,MAAM,IAAI,CAAC,GAAAo/B,qBAAA,GAAED,gBAAgB,CAACthC,IAAI,cAAAuhC,qBAAA,cAAAA,qBAAA,GAAID,gBAAgB,CAACjjC,KAAK,CAACsiC,UAAU,CAAC;IACtK,OAAO,IAAI;EACb;EACA,OAAO,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASc,eAAeA,CAAChkC,EAAE,EAAEmH,WAAW,EAAE08B,gBAAgB,EAAE;EAC1D,IAAID,gBAAgB,CAAC5jC,EAAE,EAAEmH,WAAW,EAAE08B,gBAAgB,CAAC,EAAE;IACvD7jC,EAAE,CAAC8E,aAAa,CAACspB,cAAc,EAAE,CAAC,EAAEyV,gBAAgB,CAACJ,OAAO,EAAEI,gBAAgB,CAACn/B,MAAM,IAAI,CAAC,EAAEm/B,gBAAgB,CAACthC,IAAI,IAAI,CAAC,CAAC;EACzH;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS0hC,gBAAgBA,CAACJ,gBAAgB,EAAE5b,MAAM,EAAE;EAClD,IAAMmb,OAAO,GAAGS,gBAAgB,CAACT,OAAO;EACxC,KAAK,IAAM/hC,IAAI,IAAI4mB,MAAM,EAAE;IACzB,IAAM4N,MAAM,GAAGuN,OAAO,CAAC/hC,IAAI,CAAC;IAC5B,IAAIw0B,MAAM,EAAE;MACV,IAAM1xB,KAAK,GAAG8jB,MAAM,CAAC5mB,IAAI,CAAC;MAC1Bw0B,MAAM,CAAC1xB,KAAK,CAAC;IACf;EACF;AACF;AAEA,SAASy7B,cAAcA,CAACsE,IAAI,EAAEjc,MAAM,EAAE;EACpC,KAAK,IAAM5mB,IAAI,IAAI4mB,MAAM,EAAE;IACzB,IAAMkc,IAAI,GAAGD,IAAI,CAAC7iC,IAAI,CAAC;IACvB,IAAI,OAAO8iC,IAAI,KAAK,UAAU,EAAE;MAC9BA,IAAI,CAAClc,MAAM,CAAC5mB,IAAI,CAAC,CAAC;IACpB,CAAC,MAAM;MACLu+B,cAAc,CAACsE,IAAI,CAAC7iC,IAAI,CAAC,EAAE4mB,MAAM,CAAC5mB,IAAI,CAAC,CAAC;IAC1C;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASsG,WAAWA,CAACy7B,OAAO,EAAW;EAAG;EACxC,IAAMgB,aAAa,GAAGhB,OAAO,CAACjE,cAAc,IAAIiE,OAAO;EACvD,IAAMiB,OAAO,GAAAp3B,SAAA,CAAAtL,MAAA,YAAAsL,SAAA,CAAAtL,MAAA,IAAc;EAC3B,KAAK,IAAI2iC,IAAI,GAAG,CAAC,EAAEA,IAAI,GAAGD,OAAO,EAAE,EAAEC,IAAI,EAAE;IACzC,IAAMrc,MAAM,GAAQqc,IAAI,YAAAr3B,SAAA,CAAAtL,MAAA,IAAJ2iC,IAAI,OAAArkC,SAAA,GAAAgN,SAAA,CAAJq3B,IAAI,KAAC;IACzB,IAAI5hC,KAAK,CAACC,OAAO,CAACslB,MAAM,CAAC,EAAE;MACzB,IAAM3lB,SAAS,GAAG2lB,MAAM,CAACtmB,MAAM;MAC/B,KAAK,IAAIwD,EAAE,GAAG,CAAC,EAAEA,EAAE,GAAG7C,SAAS,EAAE,EAAE6C,EAAE,EAAE;QACrCwC,WAAW,CAACy8B,aAAa,EAAEnc,MAAM,CAAC9iB,EAAE,CAAC,CAAC;MACxC;IACF,CAAC,MAAM;MACL,KAAK,IAAM9D,IAAI,IAAI4mB,MAAM,EAAE;QACzB,IAAM4N,MAAM,GAAGuO,aAAa,CAAC/iC,IAAI,CAAC;QAClC,IAAIw0B,MAAM,EAAE;UACVA,MAAM,CAAC5N,MAAM,CAAC5mB,IAAI,CAAC,CAAC;QACtB;MACF;IACF;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMkjC,0BAA0B,GAAAnf,kCAAA,GAAGzd,WAAW;;AAE9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS68B,sBAAsBA,CAACxkC,EAAE,EAAEuH,OAAO,EAAE;EAC3C,IAAMk9B,aAAa,GAAG,CACtB,CAAC;EAED,IAAMC,UAAU,GAAG1kC,EAAE,CAACq9B,mBAAmB,CAAC91B,OAAO,EAAEsnB,iBAAiB,CAAC;EACrE,KAAK,IAAI1pB,EAAE,GAAG,CAAC,EAAEA,EAAE,GAAGu/B,UAAU,EAAE,EAAEv/B,EAAE,EAAE;IACtC,IAAMN,UAAU,GAAG7E,EAAE,CAAC2kC,eAAe,CAACp9B,OAAO,EAAEpC,EAAE,CAAC;IAClD,IAAIy5B,SAAS,CAAC/5B,UAAU,CAAC,EAAE;MACzB;IACF;IACA,IAAM+wB,KAAK,GAAG51B,EAAE,CAAC4kC,iBAAiB,CAACr9B,OAAO,EAAE1C,UAAU,CAACxD,IAAI,CAAC;IAC5D,IAAM41B,QAAQ,GAAGG,WAAW,CAACvyB,UAAU,CAACnE,IAAI,CAAC;IAC7C,IAAMm1B,MAAM,GAAGoB,QAAQ,CAACpB,MAAM,CAAC71B,EAAE,EAAE41B,KAAK,EAAEqB,QAAQ,CAAC;IACnDpB,MAAM,CAAC7D,QAAQ,GAAG4D,KAAK;IACvB6O,aAAa,CAAC5/B,UAAU,CAACxD,IAAI,CAAC,GAAGw0B,MAAM;EACzC;EAEA,OAAO4O,aAAa;AACtB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASI,aAAaA,CAACzB,OAAO,EAAEj9B,OAAO,EAAE;EACvC,KAAK,IAAM9E,IAAI,IAAI8E,OAAO,EAAE;IAC1B,IAAM0vB,MAAM,GAAGuN,OAAO,CAAC/hC,IAAI,CAAC;IAC5B,IAAIw0B,MAAM,EAAE;MACVA,MAAM,CAAC1vB,OAAO,CAAC9E,IAAI,CAAC,CAAC;IACvB;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASqG,uBAAuBA,CAAC1H,EAAE,EAAEmH,WAAW,EAAEhB,OAAO,EAAE;EACzD,IAAIA,OAAO,CAACqB,iBAAiB,EAAE;IAC7BxH,EAAE,CAACyH,eAAe,CAACtB,OAAO,CAACqB,iBAAiB,CAAC;EAC/C,CAAC,MAAM;IACLq9B,aAAa,CAAC19B,WAAW,CAACs9B,aAAa,IAAIt9B,WAAW,EAAEhB,OAAO,CAACrC,OAAO,CAAC;IACxE,IAAIqC,OAAO,CAACL,OAAO,EAAE;MACnB9F,EAAE,CAACc,UAAU,CAACvB,oBAAoB,EAAE4G,OAAO,CAACL,OAAO,CAAC;IACtD;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASg/B,4BAA4BA,CAAC9kC,EAAE,EAAEuH,OAAO,EAAE;EACjD,IAAM43B,cAAc,GAAGU,oBAAoB,CAAC7/B,EAAE,EAAEuH,OAAO,CAAC;EACxD,IAAMk9B,aAAa,GAAGD,sBAAsB,CAACxkC,EAAE,EAAEuH,OAAO,CAAC;EACzD,IAAMJ,WAAW,GAAG;IAClBI,OAAO,EAAPA,OAAO;IACP43B,cAAc,EAAdA,cAAc;IACdsF,aAAa,EAAbA,aAAa;IACbM,gBAAgB,EAAEnmC,MAAM,CAAComC,WAAW,CAACpmC,MAAM,CAAC48B,OAAO,CAAC2D,cAAc,CAAC,CAACvH,GAAG,CAAC,UAAAqN,KAAA;MAAA,IAAAC,KAAA,GAAA3Y,cAAA,CAAA0Y,KAAA;QAAEvnB,CAAC,GAAAwnB,KAAA;QAAEnxB,CAAC,GAAAmxB,KAAA;MAAA,OAAM,CAACxnB,CAAC,EAAE3J,CAAC,CAACie,QAAQ,CAAC;IAAA,EAAC,CAAC;IACrG+H,eAAe,EAAEn7B,MAAM,CAAComC,WAAW,CAACpmC,MAAM,CAAC48B,OAAO,CAACiJ,aAAa,CAAC,CAAC7M,GAAG,CAAC,UAAAuN,KAAA;MAAA,IAAAC,KAAA,GAAA7Y,cAAA,CAAA4Y,KAAA;QAAEznB,CAAC,GAAA0nB,KAAA;QAAErxB,CAAC,GAAAqxB,KAAA;MAAA,OAAM,CAAC1nB,CAAC,EAAE3J,CAAC,CAACie,QAAQ,CAAC;IAAA,EAAC;EACpG,CAAC;EAED,IAAIrL,KAAK,CAACuO,QAAQ,CAACl1B,EAAE,CAAC,EAAE;IACtBmH,WAAW,CAACu7B,gBAAgB,GAAGvB,iCAAiC,CAACnhC,EAAE,EAAEuH,OAAO,CAAC;IAC7EJ,WAAW,CAACy5B,qBAAqB,GAAGL,2BAA2B,CAACvgC,EAAE,EAAEuH,OAAO,CAAC;EAC9E;EAEA,OAAOJ,WAAW;AACpB;AAEA,IAAMk+B,OAAO,GAAG,UAAU;;AAE1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS3I,iBAAiBA,CACtB18B,EAAE,EAAE2+B,aAAa,EAAElF,WAAW,EAAEC,aAAa,EAAEC,iBAAiB,EAAE;EACpE,IAAMnB,WAAW,GAAGgB,iBAAiB,CAACC,WAAW,EAAEC,aAAa,EAAEC,iBAAiB,CAAC;EACpF,IAAMf,MAAM,GAAG,EAAE;EACjB+F,aAAa,GAAGA,aAAa,CAAC/G,GAAG,CAAC,UAAS0N,MAAM,EAAE;IACjD;IACA,IAAI,CAACD,OAAO,CAACpjC,IAAI,CAACqjC,MAAM,CAAC,EAAE;MACzB,IAAMC,MAAM,GAAGxX,cAAc,CAACuX,MAAM,CAAC;MACrC,IAAI,CAACC,MAAM,EAAE;QACX,IAAMjZ,GAAG,0BAAAnqB,MAAA,CAA0BmjC,MAAM,CAAE;QAC3C9M,WAAW,CAACC,aAAa,CAACnM,GAAG,CAAC;QAC9BsM,MAAM,CAAC5tB,IAAI,CAACshB,GAAG,CAAC;MAClB,CAAC,MAAM;QACLgZ,MAAM,GAAGC,MAAM,CAACnK,IAAI;MACtB;IACF;IACA,OAAOkK,MAAM;EACf,CAAC,CAAC;EAEF,IAAI1M,MAAM,CAACj3B,MAAM,EAAE;IACjB,OAAO42B,WAAW,CAACC,WAAW,EAAE,EAAE,CAAC;EACrC;EAEA,IAAMgN,YAAY,GAAGhN,WAAW,CAACE,QAAQ;EACzC,IAAI8M,YAAY,EAAE;IAChBhN,WAAW,CAACE,QAAQ,GAAG,UAACpM,GAAG,EAAE/kB,OAAO,EAAK;MACvCi+B,YAAY,CAAClZ,GAAG,EAAEA,GAAG,GAAGrsB,SAAS,GAAG6kC,4BAA4B,CAAC9kC,EAAE,EAAEuH,OAAO,CAAC,CAAC;IAChF,CAAC;EACH;EAEA,IAAMA,OAAO,GAAGm3B,wBAAwB,CAAC1+B,EAAE,EAAE2+B,aAAa,EAAEnG,WAAW,CAAC;EACxE,IAAI,CAACjxB,OAAO,EAAE;IACZ,OAAO,IAAI;EACb;EAEA,OAAOu9B,4BAA4B,CAAC9kC,EAAE,EAAEuH,OAAO,CAAC;AAClD;AAEA,SAASk+B,gBAAgBA,CAACzlC,EAAE,EAAEoG,QAAQ,EAAEs/B,YAAY,EAAEC,kBAAkB,EAAE3K,cAAc,EAAE;EACxF;EACA,SAAA4K,EAAA,MAAAC,eAAA,GAA8BjnC,MAAM,CAAC48B,OAAO,CAACp1B,QAAQ,CAAC,EAAAw/B,EAAA,GAAAC,eAAA,CAAAlkC,MAAA,EAAAikC,EAAA,IAAE;IAAnD,IAAAE,kBAAA,GAAAvZ,cAAA,CAAAsZ,eAAA,CAAAD,EAAA;MAAOvkC,IAAI,GAAAykC,kBAAA;MAAEv+B,OAAO,GAAAu+B,kBAAA;IACvB,IAAMziB,OAAO,GAAA+H,aAAA,KAAO4P,cAAc,CAAC;IACnC,IAAMpW,IAAI,GAAG8gB,YAAY,CAACrkC,IAAI,CAAC;IAC/B,IAAI,CAACqB,KAAK,CAACC,OAAO,CAACiiB,IAAI,CAAC,EAAE;MACxBhmB,MAAM,CAACiH,MAAM,CAACwd,OAAO,EAAEuB,IAAI,CAAC;IAC9B;IACA,IAAMgU,MAAM,GAAGsD,gBAAgB,CAACl8B,EAAE,EAAEuH,OAAO,EAAE8b,OAAO,CAACoV,aAAa,CAAC;IACnE,IAAIG,MAAM,EAAE;MACV;MACA,SAAAmN,GAAA,MAAAC,cAAA,GAAsBpnC,MAAM,CAACqpB,MAAM,CAAC7hB,QAAQ,CAAC,EAAA2/B,GAAA,GAAAC,cAAA,CAAArkC,MAAA,EAAAokC,GAAA,IAAE;QAA1C,IAAMx+B,QAAO,GAAAy+B,cAAA,CAAAD,GAAA;QAChB,IAAMxL,OAAO,GAAGv6B,EAAE,CAACw6B,kBAAkB,CAACjzB,QAAO,CAAC;QAC9CvH,EAAE,CAAC46B,aAAa,CAACrzB,QAAO,CAAC;QAAC,IAAA0+B,UAAA,GAAApZ,0BAAA,CACL0N,OAAO;UAAA2L,MAAA;QAAA;UAA5B,KAAAD,UAAA,CAAAx4B,CAAA,MAAAy4B,MAAA,GAAAD,UAAA,CAAAxnC,CAAA,IAAAkqB,IAAA,GAA8B;YAAA,IAAnBoQ,MAAM,GAAAmN,MAAA,CAAA/hC,KAAA;YACf;YACA,IAAI,CAACwhC,kBAAkB,CAACpnC,GAAG,CAACw6B,MAAM,CAAC,EAAE;cACnC/4B,EAAE,CAAC26B,YAAY,CAAC5B,MAAM,CAAC;YACzB;UACF;QAAC,SAAAzM,GAAA;UAAA2Z,UAAA,CAAAhoC,CAAA,CAAAquB,GAAA;QAAA;UAAA2Z,UAAA,CAAAvxB,CAAA;QAAA;MACH;MACA,OAAOkkB,MAAM;IACf;EACF;EAEA,OAAO34B,SAAS;AAClB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASkmC,cAAcA,CAACnmC,EAAE,EAAE0lC,YAAY,EAAuB;EAAA,IAArB1K,cAAc,GAAA/tB,SAAA,CAAAtL,MAAA,QAAAsL,SAAA,QAAAhN,SAAA,GAAAgN,SAAA,MAAG,CAAC,CAAC;EAC3D;EACA,IAAM04B,kBAAkB,GAAG,IAAI3J,GAAG,CAAC,CAAC;;EAEpC;EACA,IAAM51B,QAAQ,GAAGxH,MAAM,CAAComC,WAAW,CAACpmC,MAAM,CAAC48B,OAAO,CAACkK,YAAY,CAAC,CAAC9N,GAAG,CAAC,UAAAwO,KAAA,EAAkB;IAAA,IAAAC,KAAA,GAAA9Z,cAAA,CAAA6Z,KAAA;MAAhB/kC,IAAI,GAAAglC,KAAA;MAAEzhB,IAAI,GAAAyhB,KAAA;IAC/E,IAAMhjB,OAAO,GAAA+H,aAAA,KAAO4P,cAAc,CAAC;IACnC,IAAMT,OAAO,GAAG73B,KAAK,CAACC,OAAO,CAACiiB,IAAI,CAAC,GAAGA,IAAI,GAAGA,IAAI,CAAC2V,OAAO;IACzD,IAAI,CAAC73B,KAAK,CAACC,OAAO,CAACiiB,IAAI,CAAC,EAAE;MACxBhmB,MAAM,CAACiH,MAAM,CAACwd,OAAO,EAAEuB,IAAI,CAAC;IAC9B;IACA2V,OAAO,CAACv2B,OAAO,CAAC2hC,kBAAkB,CAACxkB,GAAG,EAAEwkB,kBAAkB,CAAC;IAC3D,OAAO,CAACtkC,IAAI,EAAE05B,oBAAoB,CAAC/6B,EAAE,EAAEu6B,OAAO,EAAElX,OAAO,CAAC,CAAC;EAC3D,CAAC,CAAC,CAAC;EAEH,IAAI2X,cAAc,CAACtC,QAAQ,EAAE;IAC3B6E,qCAAqC,CAACv9B,EAAE,EAAEoG,QAAQ,CAAC,CAACqiB,IAAI,CAAC,YAAM;MAC7D,IAAMmQ,MAAM,GAAG6M,gBAAgB,CAACzlC,EAAE,EAAEoG,QAAQ,EAAEs/B,YAAY,EAAEC,kBAAkB,EAAE3K,cAAc,CAAC;MAC/FA,cAAc,CAACtC,QAAQ,CAACE,MAAM,EAAEA,MAAM,GAAG34B,SAAS,GAAGmG,QAAQ,CAAC;IAChE,CAAC,CAAC;IACF,OAAOnG,SAAS;EAClB;EAEA,IAAM24B,MAAM,GAAG6M,gBAAgB,CAACzlC,EAAE,EAAEoG,QAAQ,EAAEs/B,YAAY,EAAEC,kBAAkB,EAAE3K,cAAc,CAAC;EAC/F,OAAOpC,MAAM,GAAG34B,SAAS,GAAGmG,QAAQ;AACtC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASkgC,kBAAkBA,CAACtmC,EAAE,EAAE0lC,YAAY,EAAE1K,cAAc,EAAE;EAC5DA,cAAc,GAAGxB,iBAAiB,CAACwB,cAAc,CAAC;EAElD,SAASuL,6BAA6BA,CAACvmC,EAAE,EAAEoG,QAAQ,EAAE;IACnD,OAAOxH,MAAM,CAAComC,WAAW,CAACpmC,MAAM,CAAC48B,OAAO,CAACp1B,QAAQ,CAAC,CAACwxB,GAAG,CAAC,UAAA4O,KAAA;MAAA,IAAAC,MAAA,GAAAla,cAAA,CAAAia,KAAA;QAAEnlC,IAAI,GAAAolC,MAAA;QAAEl/B,OAAO,GAAAk/B,MAAA;MAAA,OACpE,CAACplC,IAAI,EAAEyjC,4BAA4B,CAAC9kC,EAAE,EAAEuH,OAAO,CAAC,CAAC;IAAA,CACnD,CAAC,CAAC;EACJ;EAEA,IAAMi+B,YAAY,GAAGxK,cAAc,CAACtC,QAAQ;EAC5C,IAAI8M,YAAY,EAAE;IAChBxK,cAAc,CAACtC,QAAQ,GAAG,UAACpM,GAAG,EAAElmB,QAAQ,EAAK;MAC3Co/B,YAAY,CAAClZ,GAAG,EAAEA,GAAG,GAAGrsB,SAAS,GAAGsmC,6BAA6B,CAACvmC,EAAE,EAAEoG,QAAQ,CAAC,CAAC;IAClF,CAAC;EACH;EAEA,IAAMA,QAAQ,GAAG+/B,cAAc,CAACnmC,EAAE,EAAE0lC,YAAY,EAAE1K,cAAc,CAAC;EACjE,IAAIwK,YAAY,IAAI,CAACp/B,QAAQ,EAAE;IAC7B,OAAOnG,SAAS;EAClB;EAEA,OAAOsmC,6BAA6B,CAACvmC,EAAE,EAAEoG,QAAQ,CAAC;AACpD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMsgC,mBAAmB,GAAAthB,2BAAA,GAAGgX,uBAAuB,CAAC+J,cAAc,CAAC;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMQ,uBAAuB,GAAAvhB,+BAAA,GAAGgX,uBAAuB,CAACkK,kBAAkB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrrE3E,IAAA3f,KAAA,GAAA9oB,uBAAA,CAAAC,mBAAA;AACA,IAAAF,WAAA,GAAAC,uBAAA,CAAAC,mBAAA;AACA,IAAAC,MAAA,GAAAF,uBAAA,CAAAC,mBAAA;AAAsC,SAAAE,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,yBAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAJ,wBAAAI,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,gBAAAK,OAAA,CAAAL,CAAA,0BAAAA,CAAA,sBAAAA,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAjB,CAAA,EAAAc,CAAA,SAAAI,CAAA,GAAAR,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAI,CAAA,KAAAA,CAAA,CAAAX,GAAA,IAAAW,CAAA,CAAAC,GAAA,IAAAR,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAI,CAAA,IAAAV,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,cAAAR,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAgB,GAAA,CAAAnB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAxBtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAMuB,EAAE,GAAGC,SAAS,CAAC,CAAE;AACvB,IAAMC,QAAQ,GAAG;EACf0mC,YAAY,EAAE,IAAInlC,UAAU,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;EAClD4J,cAAc,EAAE,CAAC,CAAC;EAClBw7B,WAAW,EAAE5mC;AACf,CAAC;AACD,IAAMwC,aAAa,GAAG7E,WAAW,CAAC6E,aAAa;;AAE/C;AACA,IAAMqkC,kBAAkB,GAAG,YAAW;EACpC,IAAIC,KAAK;EACT,OAAO,SAASD,kBAAkBA,CAAA,EAAG;IACnCC,KAAK,GAAGA,KAAK,KACP,OAAO9Y,QAAQ,KAAK,WAAW,IAAIA,QAAQ,CAAC+Y,aAAa,GACvD/Y,QAAQ,CAAC+Y,aAAa,CAAC,QAAQ,CAAC,CAACC,UAAU,CAAC,IAAI,CAAC,GACjD,IAAI,CAAC;IACb,OAAOF,KAAK;EACd,CAAC;AACH,CAAC,CAAC,CAAC;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAMG,KAAK,GAA4B,MAAM;AAC7C,IAAMC,GAAG,GAA8B,MAAM;AAC7C,IAAMj/B,IAAI,GAA6B,MAAM;AAC7C,IAAMk/B,SAAS,GAAwB,MAAM;AAC7C,IAAMC,eAAe,GAAkB,MAAM;AAC7C,IAAMp/B,eAAe,GAAkB,MAAM;AAC7C,IAAMY,aAAa,GAAoB,MAAM;;AAE7C;AACA;AACA;AACA,IAAMK,aAAa,GAAoB,MAAM;;AAE7C;AACA,IAAMo+B,OAAO,GAA0B,MAAM;AAC7C,IAAMn+B,MAAM,GAA2B,MAAM;;AAE7C;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAMnB,UAAU,GAAuB,MAAM;AAC7C,IAAMypB,gBAAgB,GAAiB,MAAM;AAC7C,IAAMC,UAAU,GAAuB,MAAM;AAC7C,IAAMC,gBAAgB,GAAiB,MAAM;;AAE7C;AACA,IAAM4V,2BAA2B,GAAM,MAAM;AAC7C,IAAMC,2BAA2B,GAAM,MAAM;AAC7C,IAAMC,2BAA2B,GAAM,MAAM;AAC7C,IAAMC,2BAA2B,GAAM,MAAM;AAC7C,IAAMC,2BAA2B,GAAM,MAAM;AAC7C,IAAMC,2BAA2B,GAAM,MAAM;;AAE7C;AACA,IAAMC,kBAAkB,GAAe,MAAM;AAC7C,IAAMC,kBAAkB,GAAe,MAAM;AAC7C,IAAMC,cAAc,GAAmB,MAAM;AAC7C,IAAMC,cAAc,GAAmB,MAAM;AAC7C,IAAMC,cAAc,GAAmB,MAAM;AAC7C,IAAMC,eAAe,GAAkB,MAAM;AAC7C,IAAMC,eAAe,GAAkB,MAAM;AAC7C,IAAMC,kBAAkB,GAAe,MAAM;AAC7C,IAAMC,iBAAiB,GAAgB,MAAM;AAC7C,IAAMC,oBAAoB,GAAa,MAAM;AAC7C,IAAMC,oBAAoB,GAAa,MAAM;;AAE7C;AACA,IAAMC,gBAAgB,GAAqB,MAAM;AACjD,IAAMC,iBAAiB,GAAoB,MAAM;AACjD,IAAMC,mBAAmB,GAAkB,MAAM;AACjD,IAAMC,kBAAkB,GAAmB,MAAM;AACjD,IAAMC,gBAAgB,GAAqB,MAAM;AACjD,IAAMC,kBAAkB,GAAmB,MAAM;AACjD,IAAMC,kCAAkC,GAAG,MAAM;AACjD,IAAMC,8BAA8B,GAAO,MAAM;AACjD,IAAMC,mBAAmB,GAAkB,MAAM;AAEjD,IAAMC,EAAE,GAA6B,MAAM;AAC3C,IAAMC,QAAQ,GAAuB,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,GAAG,GAA4B,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,GAAG,GAA4B,MAAM;AAC3C,IAAMC,SAAS,GAAsB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,IAAI,GAA2B,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAM7hC,MAAM,GAAyB,MAAM;AAC3C,IAAM8hC,UAAU,GAAqB,MAAM;AAC3C,IAAMC,cAAc,GAAiB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,YAAY,GAAmB,MAAM;AAC3C,IAAMC,WAAW,GAAoB,MAAM;AAC3C,IAAM5iC,OAAO,GAAwB,MAAM;AAC3C,IAAMD,KAAK,GAA0B,MAAM;AAC3C,IAAM8iC,QAAQ,GAAuB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,MAAM,GAAyB,MAAM;AAC3C,IAAMC,UAAU,GAAqB,MAAM;AAC3C,IAAMC,QAAQ,GAAuB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,OAAO,GAAwB,MAAM;AAC3C,IAAMC,QAAQ,GAAuB,MAAM;AAE3C,IAAMpjC,iBAAiB,GAAc,MAAM;AAC3C,IAAMP,iBAAiB,GAAc,MAAM;AAC3C,IAAMC,kBAAkB,GAAa,MAAM;AAC3C,IAAME,iBAAiB,GAAc,MAAM;AAC3C,IAAMD,gBAAgB,GAAe,MAAM;;AAE3C;AACA,IAAM5I,IAAI,GAA2B,MAAM;AAC3C,IAAMC,aAAa,GAAkB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMC,cAAc,GAAiB,MAAM;AAC3C,IAAMC,GAAG,GAA4B,MAAM;AAC3C,IAAMC,YAAY,GAAmB,MAAM;AAC3C,IAAMC,KAAK,GAA0B,MAAM;AAC3C,IAAMgsC,sBAAsB,GAAS,MAAM;AAC3C,IAAMC,sBAAsB,GAAS,MAAM;AAC3C,IAAMC,oBAAoB,GAAW,MAAM;AAC3C,IAAMC,UAAU,GAAqB,MAAM;AAC3C,IAAMC,cAAc,GAAiB,MAAM,CAAC,CAAE;AAC9C,IAAMC,2BAA2B,GAAI,MAAM;AAC3C,IAAMC,4BAA4B,GAAG,MAAM;AAC3C,IAAMC,wBAAwB,GAAO,MAAM;AAC3C,IAAMC,8BAA8B,GAAG,MAAM;AAC7C,IAAMC,iBAAiB,GAAc,MAAM;AAE3C,IAAMC,EAAE,GAA6B,MAAM;AAC3C,IAAMC,UAAU,GAAqB,MAAM;AAC3C,IAAMC,GAAG,GAA4B,MAAM;AAC3C,IAAMC,WAAW,GAAoB,MAAM;AAC3C,IAAMC,WAAW,GAAoB,MAAM;AAC3C,IAAMC,YAAY,GAAmB,MAAM;AAE3C,IAAMC,UAAU,GAAG,CAAC,CAAC;AACrB;EACE;EACA;EACA,IAAMr4B,CAAC,GAAGq4B,UAAU;EACpBr4B,CAAC,CAACwyB,KAAK,CAAC,GAAa;IAAE8F,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAAC0yB,SAAS,CAAC,GAAS;IAAE4F,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAAC2yB,eAAe,CAAC,GAAG;IAAE2F,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACyyB,GAAG,CAAC,GAAe;IAAE6F,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACxM,IAAI,CAAC,GAAc;IAAE8kC,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACi4B,GAAG,CAAC,GAAe;IAAEK,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACk4B,WAAW,CAAC,GAAO;IAAEI,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAAC+3B,EAAE,CAAC,GAAgB;IAAEO,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACg4B,UAAU,CAAC,GAAQ;IAAEM,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACyyB,GAAG,CAAC,GAAe;IAAE6F,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACm4B,WAAW,CAAC,GAAO;IAAEG,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACxM,IAAI,CAAC,GAAc;IAAE8kC,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACo4B,YAAY,CAAC,GAAM;IAAEE,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAACzM,eAAe,CAAC,GAAG;IAAE+kC,kBAAkB,EAAE;EAAG,CAAC;EAC/Ct4B,CAAC,CAAC7L,aAAa,CAAC,GAAK;IAAEmkC,kBAAkB,EAAE;EAAG,CAAC;AACjD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,IAAIC,2BAA2B;AAC/B,SAASC,4BAA4BA,CAACxjC,cAAc,EAAE;EACpD,IAAI,CAACujC,2BAA2B,EAAE;IAChC;IACA,IAAM7uC,CAAC,GAAG,CAAC,CAAC;IACZ;IACAA,CAAC,CAAC8oC,KAAK,CAAC,GAAgB;MAAEiG,aAAa,EAAEjG,KAAK;MAAYkG,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa,EAAEwsC,UAAU,EAAEC,cAAc,EAAEpsC,KAAK;IAAG,CAAC;IAC7M3B,CAAC,CAACgpC,SAAS,CAAC,GAAY;MAAE+F,aAAa,EAAE/F,SAAS;MAAQgG,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa,EAAEwsC,UAAU,EAAEC,cAAc,EAAEpsC,KAAK;IAAG,CAAC;IAC7M3B,CAAC,CAACipC,eAAe,CAAC,GAAM;MAAE8F,aAAa,EAAE9F,eAAe;MAAE+F,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa,EAAEwsC,UAAU,EAAEC,cAAc,EAAEpsC,KAAK;IAAG,CAAC;IAC7M3B,CAAC,CAAC+oC,GAAG,CAAC,GAAkB;MAAEgG,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;MAAK5sC,IAAI,EAAE,CAAChB,aAAa,EAAEwsC,UAAU,EAAEC,cAAc,EAAEpsC,KAAK,EAAEksC,oBAAoB;IAAG,CAAC;IACnO7tC,CAAC,CAAC8J,IAAI,CAAC,GAAiB;MAAEilC,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;MAAE5sC,IAAI,EAAE,CAAChB,aAAa,EAAEwsC,UAAU,EAAEC,cAAc,EAAEpsC,KAAK,EAAEgsC,sBAAsB,EAAEC,sBAAsB;IAAG,CAAC;IAC7P5tC,CAAC,CAAC6J,eAAe,CAAC,GAAM;MAAEklC,aAAa,EAAEllC,eAAe;MAAEmlC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAe5sC,IAAI,EAAE,CAACZ,YAAY,EAAEF,cAAc;IAAG,CAAC;;IAEzL;IACAxB,CAAC,CAAC6qC,EAAE,CAAC,GAAmB;MAAEkE,aAAa,EAAER,GAAG;MAAcS,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAAC8qC,QAAQ,CAAC,GAAa;MAAEiE,aAAa,EAAER,GAAG;MAAcS,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAAC+qC,IAAI,CAAC,GAAiB;MAAEgE,aAAa,EAAER,GAAG;MAAcS,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAM5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU;IAAG,CAAC;IACrK9tC,CAAC,CAACgrC,IAAI,CAAC,GAAiB;MAAE+D,aAAa,EAAER,GAAG;MAAcS,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACX,KAAK;IAAG,CAAC;IACzJ3B,CAAC,CAACirC,IAAI,CAAC,GAAiB;MAAE8D,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACkrC,GAAG,CAAC,GAAkB;MAAE6D,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAAC6rC,KAAK,CAAC,GAAgB;MAAEkD,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACd,cAAc;IAAG,CAAC;IAClKxB,CAAC,CAAC8rC,IAAI,CAAC,GAAiB;MAAEiD,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACf,KAAK;IAAG,CAAC;IACzJvB,CAAC,CAAC+rC,KAAK,CAAC,GAAgB;MAAEgD,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACZ,YAAY;IAAG,CAAC;IAChK1B,CAAC,CAACgsC,IAAI,CAAC,GAAiB;MAAE+C,aAAa,EAAEP,WAAW;MAAMQ,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACb,GAAG;IAAG,CAAC;IACvJzB,CAAC,CAACurC,GAAG,CAAC,GAAkB;MAAEwD,aAAa,EAAEV,EAAE;MAAeW,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACwrC,SAAS,CAAC,GAAY;MAAEuD,aAAa,EAAEV,EAAE;MAAeW,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAACyrC,KAAK,CAAC,GAAgB;MAAEsD,aAAa,EAAEV,EAAE;MAAeW,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAM5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU;IAAG,CAAC;IACrK9tC,CAAC,CAAC0rC,KAAK,CAAC,GAAgB;MAAEqD,aAAa,EAAEV,EAAE;MAAeW,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACX,KAAK;IAAG,CAAC;IACzJ3B,CAAC,CAAC2rC,KAAK,CAAC,GAAgB;MAAEoD,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAAC4rC,IAAI,CAAC,GAAiB;MAAEmD,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAACmrC,MAAM,CAAC,GAAe;MAAE4D,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACd,cAAc;IAAG,CAAC;IAClKxB,CAAC,CAACorC,KAAK,CAAC,GAAgB;MAAE2D,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACf,KAAK;IAAG,CAAC;IACzJvB,CAAC,CAACqrC,MAAM,CAAC,GAAe;MAAE0D,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACZ,YAAY;IAAG,CAAC;IAChK1B,CAAC,CAACsrC,KAAK,CAAC,GAAgB;MAAEyD,aAAa,EAAET,UAAU;MAAOU,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACb,GAAG;IAAG,CAAC;IACvJzB,CAAC,CAACisC,IAAI,CAAC,GAAiB;MAAE8C,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACksC,KAAK,CAAC,GAAgB;MAAE6C,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACqK,MAAM,CAAC,GAAe;MAAE0kC,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAM5sC,IAAI,EAAE,CAAChB,aAAa,EAAEusC,oBAAoB;IAAG,CAAC;IACvL7tC,CAAC,CAACmsC,UAAU,CAAC,GAAW;MAAE4C,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAACosC,cAAc,CAAC,GAAO;MAAE2C,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;MAAE5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU,EAAEG,4BAA4B;IAAG,CAAC;IACnMjuC,CAAC,CAACqsC,OAAO,CAAC,GAAc;MAAE0C,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;MAAE5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU,EAAEI,wBAAwB;IAAG,CAAC;IAC/LluC,CAAC,CAACssC,MAAM,CAAC,GAAe;MAAEyC,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;MAAK5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU;IAAG,CAAC;IACrK9tC,CAAC,CAACusC,MAAM,CAAC,GAAe;MAAEwC,aAAa,EAAEhG,GAAG;MAAciG,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACX,KAAK;IAAG,CAAC;IACzJ3B,CAAC,CAACwsC,MAAM,CAAC,GAAe;MAAEuC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACysC,KAAK,CAAC,GAAgB;MAAEsC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAAC0sC,OAAO,CAAC,GAAc;MAAEqC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACd,cAAc;IAAG,CAAC;IAClKxB,CAAC,CAAC2sC,MAAM,CAAC,GAAe;MAAEoC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACf,KAAK;IAAG,CAAC;IACzJvB,CAAC,CAAC4sC,OAAO,CAAC,GAAc;MAAEmC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACZ,YAAY;IAAG,CAAC;IAChK1B,CAAC,CAAC6sC,MAAM,CAAC,GAAe;MAAEkC,aAAa,EAAEN,WAAW;MAAMO,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACb,GAAG;IAAG,CAAC;IACvJzB,CAAC,CAAC8sC,KAAK,CAAC,GAAgB;MAAEiC,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAAC+sC,YAAY,CAAC,GAAS;MAAEgC,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACgtC,WAAW,CAAC,GAAU;MAAE+B,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAACoK,OAAO,CAAC,GAAc;MAAE2kC,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;MAAG5sC,IAAI,EAAE,CAAChB,aAAa,EAAEssC,sBAAsB,EAAEI,2BAA2B;IAAG,CAAC;IACtNhuC,CAAC,CAACmK,KAAK,CAAC,GAAgB;MAAE4kC,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAM5sC,IAAI,EAAE,CAAChB,aAAa,EAAEqsC,sBAAsB;IAAG,CAAC;IACzL3tC,CAAC,CAACitC,QAAQ,CAAC,GAAa;MAAE8B,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAC0rC,2BAA2B;IAAG,CAAC;IAC/KhuC,CAAC,CAACktC,OAAO,CAAC,GAAc;MAAE6B,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,IAAI;MAAGC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;MAAK5sC,IAAI,EAAE,CAACX,KAAK,EAAEmsC,UAAU;IAAG,CAAC;IACrK9tC,CAAC,CAACmtC,OAAO,CAAC,GAAc;MAAE4B,aAAa,EAAEjlC,IAAI;MAAaklC,eAAe,EAAE,KAAK;MAAEC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACX,KAAK;IAAG,CAAC;IACzJ3B,CAAC,CAACotC,OAAO,CAAC,GAAc;MAAE2B,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAChB,aAAa;IAAG,CAAC;IACjKtB,CAAC,CAACqtC,MAAM,CAAC,GAAe;MAAE0B,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACjB,IAAI;IAAG,CAAC;IACxJrB,CAAC,CAACstC,UAAU,CAAC,GAAW;MAAEyB,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAC0rC,2BAA2B;IAAG,CAAC;IAC/KhuC,CAAC,CAACutC,QAAQ,CAAC,GAAa;MAAEwB,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACd,cAAc;IAAG,CAAC;IAClKxB,CAAC,CAACwtC,OAAO,CAAC,GAAc;MAAEuB,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACf,KAAK;IAAG,CAAC;IACzJvB,CAAC,CAACytC,OAAO,CAAC,GAAc;MAAEsB,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACb,GAAG;IAAG,CAAC;IACvJzB,CAAC,CAAC0tC,QAAQ,CAAC,GAAa;MAAEqB,aAAa,EAAEL,YAAY;MAAKM,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,EAAE,CAAC;MAAQ5sC,IAAI,EAAE,CAACZ,YAAY;IAAG,CAAC;IAChK;IACA1B,CAAC,CAACsK,iBAAiB,CAAC,GAAI;MAAEykC,aAAa,EAAEllC,eAAe;MAAEmlC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;MAAM5sC,IAAI,EAAE,CAACd,cAAc,EAAEE,YAAY;IAAG,CAAC;IAChL1B,CAAC,CAAC+J,iBAAiB,CAAC,GAAI;MAAEglC,aAAa,EAAEllC,eAAe;MAAEmlC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACZ,YAAY;IAAG,CAAC;IAChK1B,CAAC,CAACgK,kBAAkB,CAAC,GAAG;MAAE+kC,aAAa,EAAEllC,eAAe;MAAEmlC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAACX,KAAK;IAAG,CAAC;IACzJ3B,CAAC,CAACiK,gBAAgB,CAAC,GAAK;MAAE8kC,aAAa,EAAEtkC,aAAa;MAAIukC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAC8rC,iBAAiB;IAAG,CAAC;IACrKpuC,CAAC,CAACkK,iBAAiB,CAAC,GAAI;MAAE6kC,aAAa,EAAEtkC,aAAa;MAAIukC,eAAe,EAAE,IAAI;MAAGC,iBAAiB,EAAE,KAAK;MAAEC,eAAe,EAAE,CAAC,CAAC,CAAC;MAAS5sC,IAAI,EAAE,CAAC6rC,8BAA8B;IAAG,CAAC;IAElL3tC,MAAM,CAACmF,IAAI,CAAC3F,CAAC,CAAC,CAAC4F,OAAO,CAAC,UAAS0F,cAAc,EAAE;MAC9C,IAAMub,IAAI,GAAG7mB,CAAC,CAACsL,cAAc,CAAC;MAC9Bub,IAAI,CAACsoB,kBAAkB,GAAG,CAAC,CAAC;MAC5BtoB,IAAI,CAACqoB,eAAe,CAACtpC,OAAO,CAAC,UAASspC,eAAe,EAAEjhC,GAAG,EAAE;QAC1D,IAAM3L,IAAI,GAAGukB,IAAI,CAACvkB,IAAI,CAAC2L,GAAG,CAAC;QAC3B4Y,IAAI,CAACsoB,kBAAkB,CAAC7sC,IAAI,CAAC,GAAG4sC,eAAe;MACjD,CAAC,CAAC;IACJ,CAAC,CAAC;IACFL,2BAA2B,GAAG7uC,CAAC;EACjC;EACA,OAAO6uC,2BAA2B,CAACvjC,cAAc,CAAC;AACpD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS8jC,mCAAmCA,CAAC9jC,cAAc,EAAEhJ,IAAI,EAAE;EACjE,IAAMukB,IAAI,GAAGioB,4BAA4B,CAACxjC,cAAc,CAAC;EACzD,IAAI,CAACub,IAAI,EAAE;IACT,MAAM,yBAAyB;EACjC;EACA,IAAMqoB,eAAe,GAAGroB,IAAI,CAACsoB,kBAAkB,CAAC7sC,IAAI,CAAC;EACrD,IAAI4sC,eAAe,KAAKrtC,SAAS,EAAE;IACjC,MAAM,yBAAyB;EACjC;EACA,OAAOqtC,eAAe;AACxB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASG,iCAAiCA,CAAC/jC,cAAc,EAAE;EACzD,IAAMub,IAAI,GAAGioB,4BAA4B,CAACxjC,cAAc,CAAC;EACzD,IAAI,CAACub,IAAI,EAAE;IACT,MAAM,yBAAyB;EACjC;EACA,OAAO;IACL5b,MAAM,EAAE4b,IAAI,CAACkoB,aAAa;IAC1BzsC,IAAI,EAAEukB,IAAI,CAACvkB,IAAI,CAAC,CAAC;EACnB,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASgtC,UAAUA,CAACvpC,KAAK,EAAE;EACzB,OAAO,CAACA,KAAK,GAAIA,KAAK,GAAG,CAAE,MAAM,CAAC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASwpC,iBAAiBA,CAAC3tC,EAAE,EAAEkK,KAAK,EAAEC,MAAM,EAAET,cAAc,EAAE;EAC5D,IAAI,CAACid,KAAK,CAACuO,QAAQ,CAACl1B,EAAE,CAAC,EAAE;IACvB,OAAO0tC,UAAU,CAACxjC,KAAK,CAAC,IAAIwjC,UAAU,CAACvjC,MAAM,CAAC;EAChD;EACA,IAAM8a,IAAI,GAAGioB,4BAA4B,CAACxjC,cAAc,CAAC;EACzD,IAAI,CAACub,IAAI,EAAE;IACT,MAAM,yBAAyB;EACjC;EACA,OAAOA,IAAI,CAACmoB,eAAe,IAAInoB,IAAI,CAACooB,iBAAiB;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASO,SAASA,CAAClkC,cAAc,EAAE;EACjC,IAAMub,IAAI,GAAGioB,4BAA4B,CAACxjC,cAAc,CAAC;EACzD,IAAI,CAACub,IAAI,EAAE;IACT,MAAM,yBAAyB;EACjC;EACA,OAAOA,IAAI,CAACooB,iBAAiB;AAC/B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASQ,yBAAyBA,CAACxkC,MAAM,EAAE;EACzC,IAAM4b,IAAI,GAAG8nB,UAAU,CAAC1jC,MAAM,CAAC;EAC/B,IAAI,CAAC4b,IAAI,EAAE;IACT,MAAM,kBAAkB,GAAG5b,MAAM;EACnC;EACA,OAAO4b,IAAI,CAAC+nB,kBAAkB;AAChC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASc,0BAA0BA,CAAC9tC,EAAE,EAAE2M,GAAG,EAAEohC,WAAW,EAAE;EACxD,IAAItrC,aAAa,CAACkK,GAAG,CAAC,EAAE;IACtB,OAAO/O,WAAW,CAAC+F,sBAAsB,CAACgJ,GAAG,CAAC;EAChD;EACA,OAAOohC,WAAW,IAAIruC,aAAa;AACrC;AAEA,SAASsuC,eAAeA,CAAChuC,EAAE,EAAEoK,MAAM,EAAEF,KAAK,EAAEC,MAAM,EAAE/E,WAAW,EAAE;EAC/D,IAAIA,WAAW,GAAG,CAAC,KAAK,CAAC,EAAE;IACzB,MAAM,wBAAwB;EAChC;EACA,IAAI,CAAC8E,KAAK,IAAI,CAACC,MAAM,EAAE;IACrB,IAAM5H,IAAI,GAAGoS,IAAI,CAAC0C,IAAI,CAACjS,WAAW,IAAIgF,MAAM,KAAKqnB,gBAAgB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3E,IAAIlvB,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE;MAClB2H,KAAK,GAAG3H,IAAI;MACZ4H,MAAM,GAAG5H,IAAI;IACf,CAAC,MAAM;MACL2H,KAAK,GAAG9E,WAAW;MACnB+E,MAAM,GAAG,CAAC;IACZ;EACF,CAAC,MAAM,IAAI,CAACA,MAAM,EAAE;IAClBA,MAAM,GAAG/E,WAAW,GAAG8E,KAAK;IAC5B,IAAIC,MAAM,GAAG,CAAC,EAAE;MACd,MAAM,wBAAwB;IAChC;EACF,CAAC,MAAM,IAAI,CAACD,KAAK,EAAE;IACjBA,KAAK,GAAG9E,WAAW,GAAG+E,MAAM;IAC5B,IAAID,KAAK,GAAG,CAAC,EAAE;MACb,MAAM,wBAAwB;IAChC;EACF;EACA,OAAO;IACLA,KAAK,EAAEA,KAAK;IACZC,MAAM,EAAEA;EACV,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS8jC,sBAAsBA,CAACtuB,KAAK,EAAE;EACrCzf,QAAQ,CAAC0mC,YAAY,GAAG,IAAInlC,UAAU,CAAC,CAACke,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,EAAEA,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,EAAEA,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,EAAEA,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AAC1G;AAEA,SAASrf,WAAWA,CAACC,WAAW,EAAE;EAChCxC,MAAM,CAACyC,sBAAsB,CAACD,WAAW,EAAEL,QAAQ,CAAC;EACpD,IAAIK,WAAW,CAACqmC,YAAY,EAAE;IAC5BqH,sBAAsB,CAAC1tC,WAAW,CAACqmC,YAAY,CAAC;EAClD;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASsH,kBAAkBA,CAACluC,EAAE,EAAEqjB,OAAO,EAAEjf,EAAE,EAAE;EAC3C,IAAI+pC,oBAAoB;EACxB,IAAIC,gBAAgB;EACpB,IAAIC,KAAK;EAET,IAAIhrB,OAAO,CAAC8qB,oBAAoB,KAAKluC,SAAS,EAAE;IAC9CkuC,oBAAoB,GAAGnuC,EAAE,CAACsuC,YAAY,CAACxF,kCAAkC,CAAC;IAC1E9oC,EAAE,CAACuuC,WAAW,CAACzF,kCAAkC,EAAEzlB,OAAO,CAAC8qB,oBAAoB,CAAC;EAClF;EACA,IAAI9qB,OAAO,CAAC+qB,gBAAgB,KAAKnuC,SAAS,EAAE;IAC1CmuC,gBAAgB,GAAGpuC,EAAE,CAACsuC,YAAY,CAACvF,8BAA8B,CAAC;IAClE/oC,EAAE,CAACuuC,WAAW,CAACxF,8BAA8B,EAAE1lB,OAAO,CAAC+qB,gBAAgB,CAAC;EAC1E;EACA,IAAI/qB,OAAO,CAACgrB,KAAK,KAAKpuC,SAAS,EAAE;IAC/BouC,KAAK,GAAGruC,EAAE,C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CA;;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,IAAMuB,EAAE,GAAGC,SAAS,CAAC,CAAE;AACvB,IAAMC,QAAQ,GAAG;EACf61C,sBAAsB,EAAE;AAC1B,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASz1C,WAAWA,CAACC,WAAW,EAAE;EAChCxC,MAAM,CAACyC,sBAAsB,CAACD,WAAW,EAAEL,QAAQ,CAAC;EACpDwY,UAAU,CAACs9B,qBAAqB,CAACz1C,WAAW,CAAC,CAAC,CAAE;EAChDsH,QAAQ,CAACouC,mBAAmB,CAAC11C,WAAW,CAAC,CAAC,CAAE;AAC9C;AAEA,IAAM21C,QAAQ,GAAG,SAAS;AAC1B,SAASC,qBAAqBA,CAACn2C,EAAE,EAAEo2C,aAAa,EAAE;EAChDzvB,KAAK,CAAC4S,cAAc,CAACv5B,EAAE,EAAE,CAAC,CAAC;EAC3B,IAAM+8B,GAAG,GAAG/8B,EAAE,CAACo9B,YAAY,CAACgZ,aAAa,CAAC;EAC1C,IAAIrZ,GAAG,EAAE;IACP,IAAMsZ,KAAK,GAAG,CAAC,CAAC;IAChB,IAAMC,QAAQ,GAAGJ,QAAQ,CAACK,IAAI,CAACH,aAAa,CAAC,CAAC,CAAC,CAAC;IAChD,IAAMI,UAAU,GAAG,GAAG,GAAGF,QAAQ;IACjC,KAAK,IAAMpxC,GAAG,IAAI63B,GAAG,EAAE;MACrB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C,EAAE;EAC1B,OAAOA,CAAC,IAAIA,CAAC,CAACgC,MAAM,IAAIhC,CAAC,CAACgC,MAAM,YAAYqiC,WAAW;AACzD,CAAC;;;;;;;;;;;;;;;;ACzIH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS9N,QAAQA,CAACl1B,EAAE,EAAE;EACpB;EACA;EACA;EACA;EACA,OAAO,CAAC,CAACA,EAAE,CAAC23C,YAAY;AAC1B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,QAAQA,CAAC53C,EAAE,EAAE;EACpB;EACA;EACA;EACA;EACA;EACA,OAAO,CAACA,EAAE,CAAC23C,YAAY;AACzB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAMpe,cAAc,GAAAnU,sBAAA,GAAI,YAAW;EACjC,IAAMyyB,gBAAgB,GAAG,CAAC,CAAC;EAC3B,IAAMxB,KAAK,GAAG,CAAC,CAAC;EAEhB,SAASyB,QAAQA,CAAC93C,EAAE,EAAE;IACpB,IAAMU,IAAI,GAAGV,EAAE,CAAC0D,WAAW,CAACrC,IAAI;IAChC,IAAI,CAACw2C,gBAAgB,CAACn3C,IAAI,CAAC,EAAE;MAC3B,KAAK,IAAMwE,GAAG,IAAIlF,EAAE,EAAE;QACpB,IAAI,OAAOA,EAAE,CAACkF,GAAG,CAAC,KAAK,QAAQ,EAAE;UAC/B,IAAM6yC,QAAQ,GAAG1B,KAAK,CAACr2C,EAAE,CAACkF,GAAG,CAAC,CAAC;UAC/BmxC,KAAK,CAACr2C,EAA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","sources":["webpack://twgl/webpack/universalModuleDefinition","webpack://twgl/./src/attributes.js","webpack://twgl/./src/draw.js","webpack://twgl/./src/framebuffers.js","webpack://twgl/./src/helper.js","webpack://twgl/./src/m4.js","webpack://twgl/./src/primitives.js","webpack://twgl/./src/programs.js","webpack://twgl/./src/textures.js","webpack://twgl/./src/twgl-full.js","webpack://twgl/./src/twgl.js","webpack://twgl/./src/typedarrays.js","webpack://twgl/./src/utils.js","webpack://twgl/./src/v3.js","webpack://twgl/./src/vertex-arrays.js","webpack://twgl/webpack/bootstrap","webpack://twgl/webpack/before-startup","webpack://twgl/webpack/startup","webpack://twgl/webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"twgl\"] = factory();\n\telse\n\t\troot[\"twgl\"] = factory();\n})(typeof self !== 'undefined' ? self : this, () => {\nreturn ","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\nconst STATIC_DRAW = 0x88e4;\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst BUFFER_SIZE = 0x8764;\n\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\n\n/**\n * Low level attribute and buffer related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/attributes\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n attribPrefix: \"\",\n};\n\n/**\n * Sets the default attrib prefix\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * var arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * @deprecated see {@link module:twgl.setDefaults}\n * @param {string} prefix prefix for attribs\n * @memberOf module:twgl/attributes\n */\nfunction setAttributePrefix(prefix) {\n defaults.attribPrefix = prefix;\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n}\n\nfunction setBufferFromTypedArray(gl, type, buffer, array, drawType) {\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, array, drawType || STATIC_DRAW);\n}\n\n/**\n * Given typed array creates a WebGLBuffer and copies the typed array\n * into it.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken\n * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`.\n * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`.\n * @return {WebGLBuffer} the created WebGLBuffer\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromTypedArray(gl, typedArray, type, drawType) {\n if (helper.isBuffer(gl, typedArray)) {\n return typedArray;\n }\n type = type || ARRAY_BUFFER;\n const buffer = gl.createBuffer();\n setBufferFromTypedArray(gl, type, buffer, typedArray, drawType);\n return buffer;\n}\n\nfunction isIndices(name) {\n return name === \"indices\";\n}\n\n// This is really just a guess. Though I can't really imagine using\n// anything else? Maybe for some compression?\nfunction getNormalizationForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return true; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line\n return false;\n}\n\nfunction getArray(array) {\n return array.length ? array : array.data;\n}\n\nconst texcoordRE = /coord|texture/i;\nconst colorRE = /color|colour/i;\n\nfunction guessNumComponentsFromName(name, length) {\n let numComponents;\n if (texcoordRE.test(name)) {\n numComponents = 2;\n } else if (colorRE.test(name)) {\n numComponents = 4;\n } else {\n numComponents = 3; // position, normals, indices ...\n }\n\n if (length % numComponents > 0) {\n throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`);\n }\n\n return numComponents;\n}\n\nfunction getNumComponents(array, arrayName, numValues) {\n return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length);\n}\n\nfunction makeTypedArray(array, name) {\n if (typedArrays.isArrayBuffer(array)) {\n return array;\n }\n\n if (typedArrays.isArrayBuffer(array.data)) {\n return array.data;\n }\n\n if (Array.isArray(array)) {\n array = {\n data: array,\n };\n }\n\n let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined;\n if (!Type) {\n if (isIndices(name)) {\n Type = Uint16Array;\n } else {\n Type = Float32Array;\n }\n }\n return new Type(array.data);\n}\n\nfunction glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? glTypeOrTypedArrayCtor\n : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT;\n}\n\nfunction typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor)\n : glTypeOrTypedArrayCtor || Float32Array;\n}\n\nfunction attribBufferFromBuffer(gl, array/*, arrayName */) {\n return {\n buffer: array.buffer,\n numValues: 2 * 3 * 4, // safely divided by 2, 3, 4\n type: glTypeFromGLTypeOrTypedArrayType(array.type),\n arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type),\n };\n}\n\nfunction attribBufferFromSize(gl, array/*, arrayName*/) {\n const numValues = array.data || array;\n const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type);\n const numBytes = numValues * arrayType.BYTES_PER_ELEMENT;\n const buffer = gl.createBuffer();\n gl.bindBuffer(ARRAY_BUFFER, buffer);\n gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW);\n return {\n buffer,\n numValues,\n type: typedArrays.getGLTypeForTypedArrayType(arrayType),\n arrayType,\n };\n}\n\nfunction attribBufferFromArrayLike(gl, array, arrayName) {\n const typedArray = makeTypedArray(array, arrayName);\n return {\n arrayType: typedArray.constructor,\n buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType),\n type: typedArrays.getGLTypeForTypedArray(typedArray),\n numValues: 0,\n };\n}\n\n/**\n * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer\n * for the attribute.\n *\n * @typedef {Object} AttribInfo\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {number} [numComponents] the number of components for this attribute.\n * @property {number} [size] synonym for `numComponents`.\n * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT`\n * @property {boolean} [normalize] whether or not to normalize the data. Default = false\n * @property {number} [offset] offset into buffer in bytes. Default = 0\n * @property {number} [stride] the stride in bytes per element. Default = 0\n * @property {number} [divisor] the divisor in instances. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor\n */\n\n/**\n * Use this type of array spec when TWGL can't guess the type or number of components of an array\n * @typedef {Object} FullArraySpec\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type.\n * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array.\n * If `coord` is in the name assumes `numComponents = 2`.\n * If `color` is in the name assumes `numComponents = 4`.\n * otherwise assumes `numComponents = 3`\n * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number.\n * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`).\n * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`.\n * @property {number} [size] synonym for `numComponents`.\n * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false.\n * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0\n * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0\n * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix.\n * @property {string} [name] synonym for `attrib`.\n * @property {string} [attribName] synonym for `attrib`.\n * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer\n * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo`\n * to provide this. Example:\n *\n * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, {\n * position: [1, 2, 3, ... ],\n * });\n * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, {\n * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1\n * });\n *\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * An individual array in {@link module:twgl.Arrays}\n *\n * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView`\n * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will\n * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer.\n *\n * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec\n * @memberOf module:twgl\n */\n\n/**\n * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your\n * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}.\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * Objects with various fields. See {@link module:twgl.FullArraySpec}.\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * @typedef {Object.} Arrays\n * @memberOf module:twgl\n */\n\n\n/**\n * Creates a set of attribute data and WebGLBuffers from set of arrays\n *\n * Given\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * returns something like\n *\n * var attribs = {\n * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, },\n * };\n *\n * notes:\n *\n * * Arrays can take various forms\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * @param {WebGLRenderingContext} gl The webgl rendering context.\n * @param {module:twgl.Arrays} arrays The arrays\n * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from\n * This lets you share buffers. Any arrays you supply will override\n * the buffers from srcBufferInfo.\n * @return {Object.} the attribs\n * @memberOf module:twgl/attributes\n */\nfunction createAttribsFromArrays(gl, arrays) {\n const attribs = {};\n Object.keys(arrays).forEach(function(arrayName) {\n if (!isIndices(arrayName)) {\n const array = arrays[arrayName];\n const attribName = array.attrib || array.name || array.attribName || (defaults.attribPrefix + arrayName);\n if (array.value) {\n if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) {\n throw new Error('array.value is not array or typedarray');\n }\n attribs[attribName] = {\n value: array.value,\n };\n } else {\n let fn;\n if (array.buffer && array.buffer instanceof WebGLBuffer) {\n fn = attribBufferFromBuffer;\n } else if (typeof array === \"number\" || typeof array.data === \"number\") {\n fn = attribBufferFromSize;\n } else {\n fn = attribBufferFromArrayLike;\n }\n const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName);\n const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType);\n const numComponents = getNumComponents(array, arrayName, numValues);\n attribs[attribName] = {\n buffer: buffer,\n numComponents: numComponents,\n type: type,\n normalize: normalization,\n stride: array.stride || 0,\n offset: array.offset || 0,\n divisor: array.divisor === undefined ? undefined : array.divisor,\n drawType: array.drawType,\n };\n }\n }\n });\n gl.bindBuffer(ARRAY_BUFFER, null);\n return attribs;\n}\n\n/**\n * Sets the contents of a buffer attached to an attribInfo\n *\n * This is helper function to dynamically update a buffer.\n *\n * Let's say you make a bufferInfo\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * And you want to dynamically update the positions. You could do this\n *\n * // assuming arrays.position has already been updated with new data.\n * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position);\n *\n * @param {WebGLRenderingContext} gl\n * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix\n * the name of the attribute will include the prefix.\n * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything\n * else will have to be converted to a typed array before it can be used by WebGL. During init time that\n * inefficiency is usually not important but if you're updating data dynamically best to be efficient.\n * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer\n * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView`\n * for the portion of the array you want to use.\n *\n * var someArray = new Float32Array(1000); // an array with 1000 floats\n * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray\n *\n * Now you can pass `someSubArray` into setAttribInfoBufferFromArray`\n * @memberOf module:twgl/attributes\n */\nfunction setAttribInfoBufferFromArray(gl, attribInfo, array, offset) {\n array = makeTypedArray(array);\n if (offset !== undefined) {\n gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer);\n gl.bufferSubData(ARRAY_BUFFER, offset, array);\n } else {\n setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType);\n }\n}\n\nfunction getBytesPerValueForGLType(gl, type) {\n if (type === BYTE) return 1; // eslint-disable-line\n if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line\n if (type === SHORT) return 2; // eslint-disable-line\n if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line\n if (type === INT) return 4; // eslint-disable-line\n if (type === UNSIGNED_INT) return 4; // eslint-disable-line\n if (type === FLOAT) return 4; // eslint-disable-line\n return 0;\n}\n\n// Tries to get the number of elements from a set of arrays.\nconst positionKeys = ['position', 'positions', 'a_position'];\nfunction getNumElementsFromNonIndexedArrays(arrays) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in arrays) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(arrays)[0];\n }\n const array = arrays[key];\n const length = getArray(array).length;\n if (length === undefined) {\n return 1; // There's no arrays\n }\n const numComponents = getNumComponents(array, key);\n const numElements = length / numComponents;\n if (length % numComponents > 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\nfunction getNumElementsFromAttributes(gl, attribs) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in attribs) {\n break;\n }\n key = defaults.attribPrefix + key;\n if (key in attribs) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(attribs)[0];\n }\n const attrib = attribs[key];\n if (!attrib.buffer) {\n return 1; // There's no buffer\n }\n gl.bindBuffer(ARRAY_BUFFER, attrib.buffer);\n const numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE);\n gl.bindBuffer(ARRAY_BUFFER, null);\n\n const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type);\n const totalElements = numBytes / bytesPerValue;\n const numComponents = attrib.numComponents || attrib.size;\n // TODO: check stride\n const numElements = totalElements / numComponents;\n if (numElements % 1 !== 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\n/**\n * @typedef {Object} BufferInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist.\n * @property {Object.} [attribs] The attribs appropriate to call `setAttributes`\n * @memberOf module:twgl\n */\n\n/**\n * Creates a BufferInfo from an object of arrays.\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * Given an object like\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * Creates an BufferInfo like this\n *\n * bufferInfo = {\n * numElements: 4, // or whatever the number of elements is\n * indices: WebGLBuffer, // this property will not exist if there are no indices\n * attribs: {\n * position: { buffer: WebGLBuffer, numComponents: 3, },\n * normal: { buffer: WebGLBuffer, numComponents: 3, },\n * texcoord: { buffer: WebGLBuffer, numComponents: 2, },\n * },\n * };\n *\n * The properties of arrays can be JavaScript arrays in which case the number of components\n * will be guessed.\n *\n * var arrays = {\n * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0],\n * texcoord: [0, 0, 0, 1, 1, 0, 1, 1],\n * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],\n * indices: [0, 1, 2, 1, 2, 3],\n * };\n *\n * They can also be TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n *\n * Or AugmentedTypedArrays\n *\n * var positions = createAugmentedTypedArray(3, 4);\n * var texcoords = createAugmentedTypedArray(2, 4);\n * var normals = createAugmentedTypedArray(3, 4);\n * var indices = createAugmentedTypedArray(3, 2, Uint16Array);\n *\n * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]);\n * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]);\n * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\n * indices.push([0, 1, 2, 1, 2, 3]);\n *\n * var arrays = {\n * position: positions,\n * texcoord: texcoords,\n * normal: normals,\n * indices: indices,\n * };\n *\n * For the last example it is equivalent to\n *\n * var bufferInfo = {\n * attribs: {\n * position: { numComponents: 3, buffer: gl.createBuffer(), },\n * texcoord: { numComponents: 2, buffer: gl.createBuffer(), },\n * normal: { numComponents: 3, buffer: gl.createBuffer(), },\n * },\n * indices: gl.createBuffer(),\n * numElements: 6,\n * };\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.normal.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices);\n * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.Arrays} arrays Your data\n * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing\n * buffer info to start from. WebGLBuffers etc specified\n * in the srcBufferInfo will be used in a new BufferInfo\n * with any arrays specified overriding the ones in\n * srcBufferInfo.\n * @return {module:twgl.BufferInfo} A BufferInfo\n * @memberOf module:twgl/attributes\n */\nfunction createBufferInfoFromArrays(gl, arrays, srcBufferInfo) {\n const newAttribs = createAttribsFromArrays(gl, arrays);\n const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {});\n bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs);\n const indices = arrays.indices;\n if (indices) {\n const newIndices = makeTypedArray(indices, \"indices\");\n bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER);\n bufferInfo.numElements = newIndices.length;\n bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices);\n } else if (!bufferInfo.numElements) {\n bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs);\n }\n\n return bufferInfo;\n}\n\n/**\n * Creates a buffer from an array, typed array, or array spec\n *\n * Given something like this\n *\n * [1, 2, 3],\n *\n * or\n *\n * new Uint16Array([1,2,3]);\n *\n * or\n *\n * {\n * data: [1, 2, 3],\n * type: Uint8Array,\n * }\n *\n * returns a WebGLBuffer that contains the given data.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.ArraySpec} array an array, typed array, or array spec.\n * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise.\n * @return {WebGLBuffer} a WebGLBuffer containing the data in array.\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromArray(gl, array, arrayName) {\n const type = arrayName === \"indices\" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER;\n const typedArray = makeTypedArray(array, arrayName);\n return createBufferFromTypedArray(gl, typedArray, type);\n}\n\n/**\n * Creates buffers from arrays or typed arrays\n *\n * Given something like this\n *\n * var arrays = {\n * positions: [1, 2, 3],\n * normals: [0, 0, 1],\n * }\n *\n * returns something like\n *\n * buffers = {\n * positions: WebGLBuffer,\n * normals: WebGLBuffer,\n * }\n *\n * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.Arrays} arrays\n * @return {Object} returns an object with one WebGLBuffer per array\n * @memberOf module:twgl/attributes\n */\nfunction createBuffersFromArrays(gl, arrays) {\n const buffers = { };\n Object.keys(arrays).forEach(function(key) {\n buffers[key] = createBufferFromArray(gl, arrays[key], key);\n });\n\n // Ugh!\n if (arrays.indices) {\n buffers.numElements = arrays.indices.length;\n buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices');\n } else {\n buffers.numElements = getNumElementsFromNonIndexedArrays(arrays);\n }\n\n return buffers;\n}\n\nexport {\n createAttribsFromArrays,\n createBuffersFromArrays,\n createBufferFromArray,\n createBufferFromTypedArray,\n createBufferInfoFromArrays,\n setAttribInfoBufferFromArray,\n\n setAttributePrefix,\n\n setDefaults as setAttributeDefaults_,\n getNumComponents as getNumComponents_,\n getArray as getArray_,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\nconst TRIANGLES = 0x0004;\nconst UNSIGNED_SHORT = 0x1403;\n\n/**\n * Drawing related functions\n *\n * For backward compatibility they are available at both `twgl.draw` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/draw\n */\n\n/**\n * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate\n *\n * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself\n * but calling this means if you switch from indexed data to non-indexed\n * data you don't have to remember to update your draw call.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or\n * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES`\n * @param {number} [count] An optional count. Defaults to bufferInfo.numElements\n * @param {number} [offset] An optional offset. Defaults to 0.\n * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called\n * @memberOf module:twgl/draw\n */\nfunction drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) {\n type = type === undefined ? TRIANGLES : type;\n const indices = bufferInfo.indices;\n const elementType = bufferInfo.elementType;\n const numElements = count === undefined ? bufferInfo.numElements : count;\n offset = offset === undefined ? 0 : offset;\n if (elementType || indices) {\n if (instanceCount !== undefined) {\n gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount);\n } else {\n gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset);\n }\n } else {\n if (instanceCount !== undefined) {\n gl.drawArraysInstanced(type, offset, numElements, instanceCount);\n } else {\n gl.drawArrays(type, offset, numElements);\n }\n }\n}\n\n/**\n * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}.\n *\n * You need either a `BufferInfo` or a `VertexArrayInfo`.\n *\n * @typedef {Object} DrawObject\n * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true`\n * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc...\n * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays}\n * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @property {Object} uniforms The values for the uniforms.\n * You can pass multiple objects by putting them in an array. For example\n *\n * var sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * var localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * var drawObj = {\n * ...\n * uniforms: [sharedUniforms, localUniforms],\n * };\n *\n * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0.\n * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements.\n * @property {number} [instanceCount] the number of instances. Defaults to undefined.\n * @memberOf module:twgl\n */\n\n/**\n * Draws a list of objects\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {DrawObject[]} objectsToDraw an array of objects to draw.\n * @memberOf module:twgl/draw\n */\nfunction drawObjectList(gl, objectsToDraw) {\n let lastUsedProgramInfo = null;\n let lastUsedBufferInfo = null;\n\n objectsToDraw.forEach(function(object) {\n if (object.active === false) {\n return;\n }\n\n const programInfo = object.programInfo;\n const bufferInfo = object.vertexArrayInfo || object.bufferInfo;\n let bindBuffers = false;\n const type = object.type === undefined ? TRIANGLES : object.type;\n\n if (programInfo !== lastUsedProgramInfo) {\n lastUsedProgramInfo = programInfo;\n gl.useProgram(programInfo.program);\n\n // We have to rebind buffers when changing programs because we\n // only bind buffers the program uses. So if 2 programs use the same\n // bufferInfo but the 1st one uses only positions the when the\n // we switch to the 2nd one some of the attributes will not be on.\n bindBuffers = true;\n }\n\n // Setup all the needed attributes.\n if (bindBuffers || bufferInfo !== lastUsedBufferInfo) {\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n lastUsedBufferInfo = bufferInfo;\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n }\n\n // Set the uniforms.\n programs.setUniforms(programInfo, object.uniforms);\n\n // Draw\n drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount);\n });\n\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n}\n\nexport {\n drawBufferInfo,\n drawObjectList,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\n\n/**\n * Framebuffer related functions\n *\n * For backward compatibility they are available at both `twgl.framebuffer` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/framebuffers\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst FRAMEBUFFER = 0x8d40;\nconst RENDERBUFFER = 0x8d41;\nconst TEXTURE_2D = 0x0de1;\n\nconst UNSIGNED_BYTE = 0x1401;\n\n/* PixelFormat */\nconst DEPTH_COMPONENT = 0x1902;\nconst RGBA = 0x1908;\nconst DEPTH_COMPONENT24 = 0x81a6;\nconst DEPTH_COMPONENT32F = 0x8cac;\nconst DEPTH24_STENCIL8 = 0x88f0;\nconst DEPTH32F_STENCIL8 = 0x8cad;\n\n/* Framebuffer Object. */\nconst RGBA4 = 0x8056;\nconst RGB5_A1 = 0x8057;\nconst RGB565 = 0x8D62;\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst STENCIL_INDEX = 0x1901;\nconst STENCIL_INDEX8 = 0x8D48;\nconst DEPTH_STENCIL = 0x84F9;\nconst COLOR_ATTACHMENT0 = 0x8CE0;\nconst DEPTH_ATTACHMENT = 0x8D00;\nconst STENCIL_ATTACHMENT = 0x8D20;\nconst DEPTH_STENCIL_ATTACHMENT = 0x821A;\n\n/* TextureWrapMode */\nconst CLAMP_TO_EDGE = 0x812F;\n\n/* TextureMagFilter */\nconst LINEAR = 0x2601;\n\n/**\n * The options for a framebuffer attachment.\n *\n * Note: For a `format` that is a texture include all the texture\n * options from {@link module:twgl.TextureOptions} for example\n * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions}\n * `auto` defaults to `false` for attachment textures but `min` and `mag` default\n * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE`\n *\n * @typedef {Object} AttachmentOptions\n * @property {number} [attachmentPoint] The attachment point. Defaults\n * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type\n * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending\n * on the format or attachment type.\n * @property {number} [format] The format. If one of `gl.RGBA4`,\n * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`,\n * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a\n * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA`\n * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`.\n * @property {number} [target] The texture target for `gl.framebufferTexture2D`.\n * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps.\n * @property {number} [samples] The number of samples. Default = 1\n * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0.\n * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined.\n * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D`\n * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture.\n * If provided will attach this Object. This allows you to share\n * attachments across framebuffers.\n * @memberOf module:twgl\n * @mixes module:twgl.TextureOptions\n */\n\nconst defaultAttachments = [\n { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, },\n { format: DEPTH_STENCIL, },\n];\n\nconst attachmentsByFormat = {};\nattachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\n\nfunction getAttachmentPointForFormat(format, internalFormat) {\n return attachmentsByFormat[format] || attachmentsByFormat[internalFormat];\n}\n\nconst renderbufferFormats = {};\nrenderbufferFormats[RGBA4] = true;\nrenderbufferFormats[RGB5_A1] = true;\nrenderbufferFormats[RGB565] = true;\nrenderbufferFormats[DEPTH_STENCIL] = true;\nrenderbufferFormats[DEPTH_COMPONENT16] = true;\nrenderbufferFormats[STENCIL_INDEX] = true;\nrenderbufferFormats[STENCIL_INDEX8] = true;\n\nfunction isRenderbufferFormat(format) {\n return renderbufferFormats[format];\n}\n\nconst MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32\n\nfunction isColorAttachmentPoint(attachmentPoint) {\n return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS;\n}\n\n/**\n * @typedef {Object} FramebufferInfo\n * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo\n * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}.\n * @property {number} width The width of the framebuffer and its attachments\n * @property {number} height The width of the framebuffer and its attachments\n * @memberOf module:twgl\n */\n\n/**\n * Creates a framebuffer and attachments.\n *\n * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer.\n * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`.\n * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers\n * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * Passing in a specific size\n *\n * const width = 256;\n * const height = 256;\n * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height);\n *\n * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`.\n * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6).\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an\n * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @return {module:twgl.FramebufferInfo} the framebuffer and attachments.\n * @memberOf module:twgl/framebuffers\n */\nfunction createFramebufferInfo(gl, attachments, width, height) {\n const target = FRAMEBUFFER;\n const fb = gl.createFramebuffer();\n gl.bindFramebuffer(target, fb);\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n attachments = attachments || defaultAttachments;\n const usedColorAttachmentsPoints = [];\n const framebufferInfo = {\n framebuffer: fb,\n attachments: [],\n width: width,\n height: height,\n };\n\n attachments.forEach(function(attachmentOptions, i) {\n let attachment = attachmentOptions.attachment;\n const samples = attachmentOptions.samples;\n const format = attachmentOptions.format;\n let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat);\n if (!attachmentPoint) {\n attachmentPoint = COLOR_ATTACHMENT0 + i;\n }\n if (isColorAttachmentPoint(attachmentPoint)) {\n usedColorAttachmentsPoints.push(attachmentPoint);\n }\n if (!attachment) {\n if (samples !== undefined || isRenderbufferFormat(format)) {\n attachment = gl.createRenderbuffer();\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else {\n const textureOptions = Object.assign({}, attachmentOptions);\n textureOptions.width = width;\n textureOptions.height = height;\n if (textureOptions.auto === undefined) {\n textureOptions.auto = false;\n textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR;\n textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR;\n textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE;\n textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE;\n }\n attachment = textures.createTexture(gl, textureOptions);\n }\n }\n if (helper.isRenderbuffer(gl, attachment)) {\n gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment);\n } else if (helper.isTexture(gl, attachment)) {\n if (attachmentOptions.layer !== undefined) {\n gl.framebufferTextureLayer(\n target,\n attachmentPoint,\n attachment,\n attachmentOptions.level || 0,\n attachmentOptions.layer);\n } else {\n gl.framebufferTexture2D(\n target,\n attachmentPoint,\n attachmentOptions.target || TEXTURE_2D,\n attachment,\n attachmentOptions.level || 0);\n }\n } else {\n throw new Error('unknown attachment type');\n }\n framebufferInfo.attachments.push(attachment);\n });\n if (gl.drawBuffers) {\n gl.drawBuffers(usedColorAttachmentsPoints);\n }\n return framebufferInfo;\n}\n\n/**\n * Resizes the attachments of a framebuffer.\n *\n * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo}\n * because TWGL has no idea the format/type of each attachment.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments\n * twgl.resizeFramebufferInfo(gl, fbi);\n * }\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments to match\n * twgl.resizeFramebufferInfo(gl, fbi, attachments);\n * }\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @memberOf module:twgl/framebuffers\n */\nfunction resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) {\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n framebufferInfo.width = width;\n framebufferInfo.height = height;\n attachments = attachments || defaultAttachments;\n attachments.forEach(function(attachmentOptions, ndx) {\n const attachment = framebufferInfo.attachments[ndx];\n const format = attachmentOptions.format;\n const samples = attachmentOptions.samples;\n if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) {\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else if (helper.isTexture(gl, attachment)) {\n textures.resizeTexture(gl, attachment, attachmentOptions, width, height);\n } else {\n throw new Error('unknown attachment type');\n }\n });\n}\n\n/**\n * Binds a framebuffer\n *\n * This function pretty much solely exists because I spent hours\n * trying to figure out why something I wrote wasn't working only\n * to realize I forget to set the viewport dimensions.\n * My hope is this function will fix that.\n *\n * It is effectively the same as\n *\n * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer);\n * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height);\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * If falsy will bind the canvas.\n * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used.\n * @memberOf module:twgl/framebuffers\n */\n\nfunction bindFramebufferInfo(gl, framebufferInfo, target) {\n target = target || FRAMEBUFFER;\n if (framebufferInfo) {\n gl.bindFramebuffer(target, framebufferInfo.framebuffer);\n gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height);\n } else {\n gl.bindFramebuffer(target, null);\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n}\n\nexport {\n bindFramebufferInfo,\n createFramebufferInfo,\n resizeFramebufferInfo,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/* eslint no-console: \"off\" */\n\n/**\n * Copy named properties\n *\n * @param {string[]} names names of properties to copy\n * @param {object} src object to copy properties from\n * @param {object} dst object to copy properties to\n * @private\n */\nfunction copyNamedProperties(names, src, dst) {\n names.forEach(function(name) {\n const value = src[name];\n if (value !== undefined) {\n dst[name] = value;\n }\n });\n}\n\n/**\n * Copies properties from source to dest only if a matching key is in dest\n *\n * @param {Object.} src the source\n * @param {Object.} dst the dest\n * @private\n */\nfunction copyExistingProperties(src, dst) {\n Object.keys(dst).forEach(function(key) {\n if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */\n dst[key] = src[key];\n }\n });\n}\n\nfunction error(...args) {\n console.error(...args);\n}\n\nfunction warn(...args) {\n console.warn(...args);\n}\n\nconst isTypeWeakMaps = new Map();\n\nfunction isType(object, type) {\n if (!object || typeof object !== 'object') {\n return false;\n }\n let weakMap = isTypeWeakMaps.get(type);\n if (!weakMap) {\n weakMap = new WeakMap();\n isTypeWeakMaps.set(type, weakMap);\n }\n let isOfType = weakMap.get(object);\n if (isOfType === undefined) {\n const s = Object.prototype.toString.call(object);\n isOfType = s.substring(8, s.length - 1) === type;\n weakMap.set(object, isOfType);\n }\n return isOfType;\n}\n\nfunction isBuffer(gl, t) {\n return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer');\n}\n\nfunction isRenderbuffer(gl, t) {\n return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer');\n}\n\nfunction isShader(gl, t) {\n return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader');\n}\n\nfunction isTexture(gl, t) {\n return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture');\n}\n\nfunction isSampler(gl, t) {\n return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler');\n}\n\nexport {\n copyExistingProperties,\n copyNamedProperties,\n error,\n warn,\n isBuffer,\n isRenderbuffer,\n isShader,\n isTexture,\n isSampler,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as v3 from './v3.js';\n\n/**\n * 4x4 Matrix math math functions.\n *\n * Almost all functions take an optional `dst` argument. If it is not passed in the\n * functions will create a new matrix. In other words you can do this\n *\n * const mat = m4.translation([1, 2, 3]); // Creates a new translation matrix\n *\n * or\n *\n * const mat = m4.create();\n * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat.\n *\n * The first style is often easier but depending on where it's used it generates garbage where\n * as there is almost never allocation with the second style.\n *\n * It is always save to pass any matrix as the destination. So for example\n *\n * const mat = m4.identity();\n * const trans = m4.translation([1, 2, 3]);\n * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat.\n *\n * @module twgl/m4\n */\nlet MatType = Float32Array;\n\n/**\n * A JavaScript array with 16 values or a Float32Array with 16 values.\n * When created by the library will create the default type which is `Float32Array`\n * but can be set by calling {@link module:twgl/m4.setDefaultType}.\n * @typedef {(number[]|Float32Array)} Mat4\n * @memberOf module:twgl/m4\n */\n\n/**\n * Sets the type this library creates for a Mat4\n * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array`\n * @return {constructor} previous constructor for Mat4\n * @memberOf module:twgl/m4\n */\nfunction setDefaultType(ctor) {\n const oldType = MatType;\n MatType = ctor;\n return oldType;\n}\n\n/**\n * Negates a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} -m.\n * @memberOf module:twgl/m4\n */\nfunction negate(m, dst) {\n dst = dst || new MatType(16);\n\n dst[ 0] = -m[ 0];\n dst[ 1] = -m[ 1];\n dst[ 2] = -m[ 2];\n dst[ 3] = -m[ 3];\n dst[ 4] = -m[ 4];\n dst[ 5] = -m[ 5];\n dst[ 6] = -m[ 6];\n dst[ 7] = -m[ 7];\n dst[ 8] = -m[ 8];\n dst[ 9] = -m[ 9];\n dst[10] = -m[10];\n dst[11] = -m[11];\n dst[12] = -m[12];\n dst[13] = -m[13];\n dst[14] = -m[14];\n dst[15] = -m[15];\n\n return dst;\n}\n\n/**\n * Creates a matrix.\n * @return {module:twgl/m4.Mat4} A new matrix.\n * @memberOf module:twgl/m4\n */\nfunction create() {\n return new MatType(16).fill(0);\n}\n\n/**\n * Copies a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] The matrix. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} A copy of m.\n * @memberOf module:twgl/m4\n */\nfunction copy(m, dst) {\n dst = dst || new MatType(16);\n\n dst[ 0] = m[ 0];\n dst[ 1] = m[ 1];\n dst[ 2] = m[ 2];\n dst[ 3] = m[ 3];\n dst[ 4] = m[ 4];\n dst[ 5] = m[ 5];\n dst[ 6] = m[ 6];\n dst[ 7] = m[ 7];\n dst[ 8] = m[ 8];\n dst[ 9] = m[ 9];\n dst[10] = m[10];\n dst[11] = m[11];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n\n return dst;\n}\n\n/**\n * Creates an n-by-n identity matrix.\n *\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} An n-by-n identity matrix.\n * @memberOf module:twgl/m4\n */\nfunction identity(dst) {\n dst = dst || new MatType(16);\n\n dst[ 0] = 1;\n dst[ 1] = 0;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = 1;\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = 0;\n dst[ 9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Takes the transpose of a matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The transpose of m.\n * @memberOf module:twgl/m4\n */\n function transpose(m, dst) {\n dst = dst || new MatType(16);\n if (dst === m) {\n let t;\n\n t = m[1];\n m[1] = m[4];\n m[4] = t;\n\n t = m[2];\n m[2] = m[8];\n m[8] = t;\n\n t = m[3];\n m[3] = m[12];\n m[12] = t;\n\n t = m[6];\n m[6] = m[9];\n m[9] = t;\n\n t = m[7];\n m[7] = m[13];\n m[13] = t;\n\n t = m[11];\n m[11] = m[14];\n m[14] = t;\n return dst;\n }\n\n const m00 = m[0 * 4 + 0];\n const m01 = m[0 * 4 + 1];\n const m02 = m[0 * 4 + 2];\n const m03 = m[0 * 4 + 3];\n const m10 = m[1 * 4 + 0];\n const m11 = m[1 * 4 + 1];\n const m12 = m[1 * 4 + 2];\n const m13 = m[1 * 4 + 3];\n const m20 = m[2 * 4 + 0];\n const m21 = m[2 * 4 + 1];\n const m22 = m[2 * 4 + 2];\n const m23 = m[2 * 4 + 3];\n const m30 = m[3 * 4 + 0];\n const m31 = m[3 * 4 + 1];\n const m32 = m[3 * 4 + 2];\n const m33 = m[3 * 4 + 3];\n\n dst[ 0] = m00;\n dst[ 1] = m10;\n dst[ 2] = m20;\n dst[ 3] = m30;\n dst[ 4] = m01;\n dst[ 5] = m11;\n dst[ 6] = m21;\n dst[ 7] = m31;\n dst[ 8] = m02;\n dst[ 9] = m12;\n dst[10] = m22;\n dst[11] = m32;\n dst[12] = m03;\n dst[13] = m13;\n dst[14] = m23;\n dst[15] = m33;\n\n return dst;\n}\n\n/**\n * Computes the inverse of a 4-by-4 matrix.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The inverse of m.\n * @memberOf module:twgl/m4\n */\nfunction inverse(m, dst) {\n dst = dst || new MatType(16);\n\n const m00 = m[0 * 4 + 0];\n const m01 = m[0 * 4 + 1];\n const m02 = m[0 * 4 + 2];\n const m03 = m[0 * 4 + 3];\n const m10 = m[1 * 4 + 0];\n const m11 = m[1 * 4 + 1];\n const m12 = m[1 * 4 + 2];\n const m13 = m[1 * 4 + 3];\n const m20 = m[2 * 4 + 0];\n const m21 = m[2 * 4 + 1];\n const m22 = m[2 * 4 + 2];\n const m23 = m[2 * 4 + 3];\n const m30 = m[3 * 4 + 0];\n const m31 = m[3 * 4 + 1];\n const m32 = m[3 * 4 + 2];\n const m33 = m[3 * 4 + 3];\n const tmp_0 = m22 * m33;\n const tmp_1 = m32 * m23;\n const tmp_2 = m12 * m33;\n const tmp_3 = m32 * m13;\n const tmp_4 = m12 * m23;\n const tmp_5 = m22 * m13;\n const tmp_6 = m02 * m33;\n const tmp_7 = m32 * m03;\n const tmp_8 = m02 * m23;\n const tmp_9 = m22 * m03;\n const tmp_10 = m02 * m13;\n const tmp_11 = m12 * m03;\n const tmp_12 = m20 * m31;\n const tmp_13 = m30 * m21;\n const tmp_14 = m10 * m31;\n const tmp_15 = m30 * m11;\n const tmp_16 = m10 * m21;\n const tmp_17 = m20 * m11;\n const tmp_18 = m00 * m31;\n const tmp_19 = m30 * m01;\n const tmp_20 = m00 * m21;\n const tmp_21 = m20 * m01;\n const tmp_22 = m00 * m11;\n const tmp_23 = m10 * m01;\n\n const t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) -\n (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);\n const t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) -\n (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);\n const t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) -\n (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);\n const t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) -\n (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);\n\n const d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);\n\n dst[ 0] = d * t0;\n dst[ 1] = d * t1;\n dst[ 2] = d * t2;\n dst[ 3] = d * t3;\n dst[ 4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) -\n (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30));\n dst[ 5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) -\n (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30));\n dst[ 6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) -\n (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30));\n dst[ 7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) -\n (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20));\n dst[ 8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) -\n (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33));\n dst[ 9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) -\n (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33));\n dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) -\n (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33));\n dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) -\n (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23));\n dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) -\n (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22));\n dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) -\n (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02));\n dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) -\n (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12));\n dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) -\n (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02));\n\n return dst;\n}\n\n/**\n * Multiplies two 4-by-4 matrices with a on the left and b on the right\n * @param {module:twgl/m4.Mat4} a The matrix on the left.\n * @param {module:twgl/m4.Mat4} b The matrix on the right.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The matrix product of a and b.\n * @memberOf module:twgl/m4\n */\nfunction multiply(a, b, dst) {\n dst = dst || new MatType(16);\n\n const a00 = a[0];\n const a01 = a[1];\n const a02 = a[2];\n const a03 = a[3];\n const a10 = a[ 4 + 0];\n const a11 = a[ 4 + 1];\n const a12 = a[ 4 + 2];\n const a13 = a[ 4 + 3];\n const a20 = a[ 8 + 0];\n const a21 = a[ 8 + 1];\n const a22 = a[ 8 + 2];\n const a23 = a[ 8 + 3];\n const a30 = a[12 + 0];\n const a31 = a[12 + 1];\n const a32 = a[12 + 2];\n const a33 = a[12 + 3];\n const b00 = b[0];\n const b01 = b[1];\n const b02 = b[2];\n const b03 = b[3];\n const b10 = b[ 4 + 0];\n const b11 = b[ 4 + 1];\n const b12 = b[ 4 + 2];\n const b13 = b[ 4 + 3];\n const b20 = b[ 8 + 0];\n const b21 = b[ 8 + 1];\n const b22 = b[ 8 + 2];\n const b23 = b[ 8 + 3];\n const b30 = b[12 + 0];\n const b31 = b[12 + 1];\n const b32 = b[12 + 2];\n const b33 = b[12 + 3];\n\n dst[ 0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03;\n dst[ 1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03;\n dst[ 2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03;\n dst[ 3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03;\n dst[ 4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13;\n dst[ 5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13;\n dst[ 6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13;\n dst[ 7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13;\n dst[ 8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23;\n dst[ 9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23;\n dst[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23;\n dst[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23;\n dst[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33;\n dst[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33;\n dst[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33;\n dst[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33;\n\n return dst;\n}\n\n/**\n * Sets the translation component of a 4-by-4 matrix to the given\n * vector.\n * @param {module:twgl/m4.Mat4} a The matrix.\n * @param {module:twgl/v3.Vec3} v The vector.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The matrix with translation set.\n * @memberOf module:twgl/m4\n */\nfunction setTranslation(a, v, dst) {\n dst = dst || identity();\n if (a !== dst) {\n dst[ 0] = a[ 0];\n dst[ 1] = a[ 1];\n dst[ 2] = a[ 2];\n dst[ 3] = a[ 3];\n dst[ 4] = a[ 4];\n dst[ 5] = a[ 5];\n dst[ 6] = a[ 6];\n dst[ 7] = a[ 7];\n dst[ 8] = a[ 8];\n dst[ 9] = a[ 9];\n dst[10] = a[10];\n dst[11] = a[11];\n }\n dst[12] = v[0];\n dst[13] = v[1];\n dst[14] = v[2];\n dst[15] = 1;\n return dst;\n}\n\n/**\n * Returns the translation component of a 4-by-4 matrix as a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not passed a new one is created.\n * @return {module:twgl/v3.Vec3} The translation component of m.\n * @memberOf module:twgl/m4\n */\nfunction getTranslation(m, dst) {\n dst = dst || v3.create();\n dst[0] = m[12];\n dst[1] = m[13];\n dst[2] = m[14];\n return dst;\n}\n\n/**\n * Returns an axis of a 4x4 matrix as a vector with 3 entries\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} axis The axis 0 = x, 1 = y, 2 = z;\n * @return {module:twgl/v3.Vec3} [dst] vector.\n * @return {module:twgl/v3.Vec3} The axis component of m.\n * @memberOf module:twgl/m4\n */\nfunction getAxis(m, axis, dst) {\n dst = dst || v3.create();\n const off = axis * 4;\n dst[0] = m[off + 0];\n dst[1] = m[off + 1];\n dst[2] = m[off + 2];\n return dst;\n}\n\n/**\n * Sets an axis of a 4x4 matrix as a vector with 3 entries\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} v the axis vector\n * @param {number} axis The axis 0 = x, 1 = y, 2 = z;\n * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The matrix with axis set.\n * @memberOf module:twgl/m4\n */\nfunction setAxis(a, v, axis, dst) {\n if (dst !== a) {\n dst = copy(a, dst);\n }\n const off = axis * 4;\n dst[off + 0] = v[0];\n dst[off + 1] = v[1];\n dst[off + 2] = v[2];\n return dst;\n}\n\n/**\n * Computes a 4-by-4 perspective transformation matrix given the angular height\n * of the frustum, the aspect ratio, and the near and far clipping planes. The\n * arguments define a frustum extending in the negative z direction. The given\n * angle is the vertical angle of the frustum, and the horizontal angle is\n * determined to produce the given aspect ratio. The arguments near and far are\n * the distances to the near and far clipping planes. Note that near and far\n * are not z coordinates, but rather they are distances along the negative\n * z-axis. The matrix generated sends the viewing frustum to the unit box.\n * We assume a unit box extending from -1 to 1 in the x and y dimensions and\n * from 0 to 1 in the z dimension.\n * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians).\n * @param {number} aspect The aspect ratio width / height.\n * @param {number} zNear The depth (negative z coordinate)\n * of the near clipping plane.\n * @param {number} zFar The depth (negative z coordinate)\n * of the far clipping plane.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The perspective matrix.\n * @memberOf module:twgl/m4\n */\nfunction perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) {\n dst = dst || new MatType(16);\n\n const f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians);\n const rangeInv = 1.0 / (zNear - zFar);\n\n dst[0] = f / aspect;\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n\n dst[4] = 0;\n dst[5] = f;\n dst[6] = 0;\n dst[7] = 0;\n\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = (zNear + zFar) * rangeInv;\n dst[11] = -1;\n\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = zNear * zFar * rangeInv * 2;\n dst[15] = 0;\n\n return dst;\n}\n\n/**\n * Computes a 4-by-4 orthogonal transformation matrix given the left, right,\n * bottom, and top dimensions of the near clipping plane as well as the\n * near and far clipping plane distances.\n * @param {number} left Left side of the near clipping plane viewport.\n * @param {number} right Right side of the near clipping plane viewport.\n * @param {number} bottom Bottom of the near clipping plane viewport.\n * @param {number} top Top of the near clipping plane viewport.\n * @param {number} near The depth (negative z coordinate)\n * of the near clipping plane.\n * @param {number} far The depth (negative z coordinate)\n * of the far clipping plane.\n * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The perspective matrix.\n * @memberOf module:twgl/m4\n */\nfunction ortho(left, right, bottom, top, near, far, dst) {\n dst = dst || new MatType(16);\n\n dst[0] = 2 / (right - left);\n dst[1] = 0;\n dst[2] = 0;\n dst[3] = 0;\n\n dst[4] = 0;\n dst[5] = 2 / (top - bottom);\n dst[6] = 0;\n dst[7] = 0;\n\n dst[8] = 0;\n dst[9] = 0;\n dst[10] = 2 / (near - far);\n dst[11] = 0;\n\n dst[12] = (right + left) / (left - right);\n dst[13] = (top + bottom) / (bottom - top);\n dst[14] = (far + near) / (near - far);\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Computes a 4-by-4 perspective transformation matrix given the left, right,\n * top, bottom, near and far clipping planes. The arguments define a frustum\n * extending in the negative z direction. The arguments near and far are the\n * distances to the near and far clipping planes. Note that near and far are not\n * z coordinates, but rather they are distances along the negative z-axis. The\n * matrix generated sends the viewing frustum to the unit box. We assume a unit\n * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z\n * dimension.\n * @param {number} left The x coordinate of the left plane of the box.\n * @param {number} right The x coordinate of the right plane of the box.\n * @param {number} bottom The y coordinate of the bottom plane of the box.\n * @param {number} top The y coordinate of the right plane of the box.\n * @param {number} near The negative z coordinate of the near plane of the box.\n * @param {number} far The negative z coordinate of the far plane of the box.\n * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The perspective projection matrix.\n * @memberOf module:twgl/m4\n */\nfunction frustum(left, right, bottom, top, near, far, dst) {\n dst = dst || new MatType(16);\n\n const dx = (right - left);\n const dy = (top - bottom);\n const dz = (near - far);\n\n dst[ 0] = 2 * near / dx;\n dst[ 1] = 0;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = 2 * near / dy;\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = (left + right) / dx;\n dst[ 9] = (top + bottom) / dy;\n dst[10] = far / dz;\n dst[11] = -1;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = near * far / dz;\n dst[15] = 0;\n\n return dst;\n}\n\nlet xAxis;\nlet yAxis;\nlet zAxis;\n\n/**\n * Computes a 4-by-4 look-at transformation.\n *\n * This is a matrix which positions the camera itself. If you want\n * a view matrix (a matrix which moves things in front of the camera)\n * take the inverse of this.\n *\n * @param {module:twgl/v3.Vec3} eye The position of the eye.\n * @param {module:twgl/v3.Vec3} target The position meant to be viewed.\n * @param {module:twgl/v3.Vec3} up A vector pointing up.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The look-at matrix.\n * @memberOf module:twgl/m4\n */\nfunction lookAt(eye, target, up, dst) {\n dst = dst || new MatType(16);\n\n xAxis = xAxis || v3.create();\n yAxis = yAxis || v3.create();\n zAxis = zAxis || v3.create();\n\n v3.normalize(\n v3.subtract(eye, target, zAxis), zAxis);\n v3.normalize(v3.cross(up, zAxis, xAxis), xAxis);\n v3.normalize(v3.cross(zAxis, xAxis, yAxis), yAxis);\n\n dst[ 0] = xAxis[0];\n dst[ 1] = xAxis[1];\n dst[ 2] = xAxis[2];\n dst[ 3] = 0;\n dst[ 4] = yAxis[0];\n dst[ 5] = yAxis[1];\n dst[ 6] = yAxis[2];\n dst[ 7] = 0;\n dst[ 8] = zAxis[0];\n dst[ 9] = zAxis[1];\n dst[10] = zAxis[2];\n dst[11] = 0;\n dst[12] = eye[0];\n dst[13] = eye[1];\n dst[14] = eye[2];\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which translates by the given vector v.\n * @param {module:twgl/v3.Vec3} v The vector by\n * which to translate.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The translation matrix.\n * @memberOf module:twgl/m4\n */\nfunction translation(v, dst) {\n dst = dst || new MatType(16);\n\n dst[ 0] = 1;\n dst[ 1] = 0;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = 1;\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = 0;\n dst[ 9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = v[0];\n dst[13] = v[1];\n dst[14] = v[2];\n dst[15] = 1;\n return dst;\n}\n\n/**\n * Translates the given 4-by-4 matrix by the given vector v.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} v The vector by\n * which to translate.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The translated matrix.\n * @memberOf module:twgl/m4\n */\nfunction translate(m, v, dst) {\n dst = dst || new MatType(16);\n\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const m00 = m[0];\n const m01 = m[1];\n const m02 = m[2];\n const m03 = m[3];\n const m10 = m[1 * 4 + 0];\n const m11 = m[1 * 4 + 1];\n const m12 = m[1 * 4 + 2];\n const m13 = m[1 * 4 + 3];\n const m20 = m[2 * 4 + 0];\n const m21 = m[2 * 4 + 1];\n const m22 = m[2 * 4 + 2];\n const m23 = m[2 * 4 + 3];\n const m30 = m[3 * 4 + 0];\n const m31 = m[3 * 4 + 1];\n const m32 = m[3 * 4 + 2];\n const m33 = m[3 * 4 + 3];\n\n if (m !== dst) {\n dst[ 0] = m00;\n dst[ 1] = m01;\n dst[ 2] = m02;\n dst[ 3] = m03;\n dst[ 4] = m10;\n dst[ 5] = m11;\n dst[ 6] = m12;\n dst[ 7] = m13;\n dst[ 8] = m20;\n dst[ 9] = m21;\n dst[10] = m22;\n dst[11] = m23;\n }\n\n dst[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30;\n dst[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31;\n dst[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32;\n dst[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33;\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotationX(angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[ 0] = 1;\n dst[ 1] = 0;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = c;\n dst[ 6] = s;\n dst[ 7] = 0;\n dst[ 8] = 0;\n dst[ 9] = -s;\n dst[10] = c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Rotates the given 4-by-4 matrix around the x-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotated matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotateX(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const m10 = m[4];\n const m11 = m[5];\n const m12 = m[6];\n const m13 = m[7];\n const m20 = m[8];\n const m21 = m[9];\n const m22 = m[10];\n const m23 = m[11];\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[4] = c * m10 + s * m20;\n dst[5] = c * m11 + s * m21;\n dst[6] = c * m12 + s * m22;\n dst[7] = c * m13 + s * m23;\n dst[8] = c * m20 - s * m10;\n dst[9] = c * m21 - s * m11;\n dst[10] = c * m22 - s * m12;\n dst[11] = c * m23 - s * m13;\n\n if (m !== dst) {\n dst[ 0] = m[ 0];\n dst[ 1] = m[ 1];\n dst[ 2] = m[ 2];\n dst[ 3] = m[ 3];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotationY(angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[ 0] = c;\n dst[ 1] = 0;\n dst[ 2] = -s;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = 1;\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = s;\n dst[ 9] = 0;\n dst[10] = c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Rotates the given 4-by-4 matrix around the y-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotated matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotateY(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const m00 = m[0 * 4 + 0];\n const m01 = m[0 * 4 + 1];\n const m02 = m[0 * 4 + 2];\n const m03 = m[0 * 4 + 3];\n const m20 = m[2 * 4 + 0];\n const m21 = m[2 * 4 + 1];\n const m22 = m[2 * 4 + 2];\n const m23 = m[2 * 4 + 3];\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[ 0] = c * m00 - s * m20;\n dst[ 1] = c * m01 - s * m21;\n dst[ 2] = c * m02 - s * m22;\n dst[ 3] = c * m03 - s * m23;\n dst[ 8] = c * m20 + s * m00;\n dst[ 9] = c * m21 + s * m01;\n dst[10] = c * m22 + s * m02;\n dst[11] = c * m23 + s * m03;\n\n if (m !== dst) {\n dst[ 4] = m[ 4];\n dst[ 5] = m[ 5];\n dst[ 6] = m[ 6];\n dst[ 7] = m[ 7];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotation matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotationZ(angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[ 0] = c;\n dst[ 1] = s;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = -s;\n dst[ 5] = c;\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = 0;\n dst[ 9] = 0;\n dst[10] = 1;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Rotates the given 4-by-4 matrix around the z-axis by the given\n * angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotated matrix.\n * @memberOf module:twgl/m4\n */\nfunction rotateZ(m, angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n const m00 = m[0 * 4 + 0];\n const m01 = m[0 * 4 + 1];\n const m02 = m[0 * 4 + 2];\n const m03 = m[0 * 4 + 3];\n const m10 = m[1 * 4 + 0];\n const m11 = m[1 * 4 + 1];\n const m12 = m[1 * 4 + 2];\n const m13 = m[1 * 4 + 3];\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n\n dst[ 0] = c * m00 + s * m10;\n dst[ 1] = c * m01 + s * m11;\n dst[ 2] = c * m02 + s * m12;\n dst[ 3] = c * m03 + s * m13;\n dst[ 4] = c * m10 - s * m00;\n dst[ 5] = c * m11 - s * m01;\n dst[ 6] = c * m12 - s * m02;\n dst[ 7] = c * m13 - s * m03;\n\n if (m !== dst) {\n dst[ 8] = m[ 8];\n dst[ 9] = m[ 9];\n dst[10] = m[10];\n dst[11] = m[11];\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which rotates around the given axis by the given\n * angle.\n * @param {module:twgl/v3.Vec3} axis The axis\n * about which to rotate.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians\n * around the axis.\n * @memberOf module:twgl/m4\n */\nfunction axisRotation(axis, angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n let x = axis[0];\n let y = axis[1];\n let z = axis[2];\n const n = Math.sqrt(x * x + y * y + z * z);\n x /= n;\n y /= n;\n z /= n;\n const xx = x * x;\n const yy = y * y;\n const zz = z * z;\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n const oneMinusCosine = 1 - c;\n\n dst[ 0] = xx + (1 - xx) * c;\n dst[ 1] = x * y * oneMinusCosine + z * s;\n dst[ 2] = x * z * oneMinusCosine - y * s;\n dst[ 3] = 0;\n dst[ 4] = x * y * oneMinusCosine - z * s;\n dst[ 5] = yy + (1 - yy) * c;\n dst[ 6] = y * z * oneMinusCosine + x * s;\n dst[ 7] = 0;\n dst[ 8] = x * z * oneMinusCosine + y * s;\n dst[ 9] = y * z * oneMinusCosine - x * s;\n dst[10] = zz + (1 - zz) * c;\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Rotates the given 4-by-4 matrix around the given axis by the\n * given angle.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} axis The axis\n * about which to rotate.\n * @param {number} angleInRadians The angle by which to rotate (in radians).\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The rotated matrix.\n * @memberOf module:twgl/m4\n */\nfunction axisRotate(m, axis, angleInRadians, dst) {\n dst = dst || new MatType(16);\n\n let x = axis[0];\n let y = axis[1];\n let z = axis[2];\n const n = Math.sqrt(x * x + y * y + z * z);\n x /= n;\n y /= n;\n z /= n;\n const xx = x * x;\n const yy = y * y;\n const zz = z * z;\n const c = Math.cos(angleInRadians);\n const s = Math.sin(angleInRadians);\n const oneMinusCosine = 1 - c;\n\n const r00 = xx + (1 - xx) * c;\n const r01 = x * y * oneMinusCosine + z * s;\n const r02 = x * z * oneMinusCosine - y * s;\n const r10 = x * y * oneMinusCosine - z * s;\n const r11 = yy + (1 - yy) * c;\n const r12 = y * z * oneMinusCosine + x * s;\n const r20 = x * z * oneMinusCosine + y * s;\n const r21 = y * z * oneMinusCosine - x * s;\n const r22 = zz + (1 - zz) * c;\n\n const m00 = m[0];\n const m01 = m[1];\n const m02 = m[2];\n const m03 = m[3];\n const m10 = m[4];\n const m11 = m[5];\n const m12 = m[6];\n const m13 = m[7];\n const m20 = m[8];\n const m21 = m[9];\n const m22 = m[10];\n const m23 = m[11];\n\n dst[ 0] = r00 * m00 + r01 * m10 + r02 * m20;\n dst[ 1] = r00 * m01 + r01 * m11 + r02 * m21;\n dst[ 2] = r00 * m02 + r01 * m12 + r02 * m22;\n dst[ 3] = r00 * m03 + r01 * m13 + r02 * m23;\n dst[ 4] = r10 * m00 + r11 * m10 + r12 * m20;\n dst[ 5] = r10 * m01 + r11 * m11 + r12 * m21;\n dst[ 6] = r10 * m02 + r11 * m12 + r12 * m22;\n dst[ 7] = r10 * m03 + r11 * m13 + r12 * m23;\n dst[ 8] = r20 * m00 + r21 * m10 + r22 * m20;\n dst[ 9] = r20 * m01 + r21 * m11 + r22 * m21;\n dst[10] = r20 * m02 + r21 * m12 + r22 * m22;\n dst[11] = r20 * m03 + r21 * m13 + r22 * m23;\n\n if (m !== dst) {\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n\n/**\n * Creates a 4-by-4 matrix which scales in each dimension by an amount given by\n * the corresponding entry in the given vector; assumes the vector has three\n * entries.\n * @param {module:twgl/v3.Vec3} v A vector of\n * three entries specifying the factor by which to scale in each dimension.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The scaling matrix.\n * @memberOf module:twgl/m4\n */\nfunction scaling(v, dst) {\n dst = dst || new MatType(16);\n\n dst[ 0] = v[0];\n dst[ 1] = 0;\n dst[ 2] = 0;\n dst[ 3] = 0;\n dst[ 4] = 0;\n dst[ 5] = v[1];\n dst[ 6] = 0;\n dst[ 7] = 0;\n dst[ 8] = 0;\n dst[ 9] = 0;\n dst[10] = v[2];\n dst[11] = 0;\n dst[12] = 0;\n dst[13] = 0;\n dst[14] = 0;\n dst[15] = 1;\n\n return dst;\n}\n\n/**\n * Scales the given 4-by-4 matrix in each dimension by an amount\n * given by the corresponding entry in the given vector; assumes the vector has\n * three entries.\n * @param {module:twgl/m4.Mat4} m The matrix to be modified.\n * @param {module:twgl/v3.Vec3} v A vector of three entries specifying the\n * factor by which to scale in each dimension.\n * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created.\n * @return {module:twgl/m4.Mat4} The scaled matrix.\n * @memberOf module:twgl/m4\n */\nfunction scale(m, v, dst) {\n dst = dst || new MatType(16);\n\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n\n dst[ 0] = v0 * m[0 * 4 + 0];\n dst[ 1] = v0 * m[0 * 4 + 1];\n dst[ 2] = v0 * m[0 * 4 + 2];\n dst[ 3] = v0 * m[0 * 4 + 3];\n dst[ 4] = v1 * m[1 * 4 + 0];\n dst[ 5] = v1 * m[1 * 4 + 1];\n dst[ 6] = v1 * m[1 * 4 + 2];\n dst[ 7] = v1 * m[1 * 4 + 3];\n dst[ 8] = v2 * m[2 * 4 + 0];\n dst[ 9] = v2 * m[2 * 4 + 1];\n dst[10] = v2 * m[2 * 4 + 2];\n dst[11] = v2 * m[2 * 4 + 3];\n\n if (m !== dst) {\n dst[12] = m[12];\n dst[13] = m[13];\n dst[14] = m[14];\n dst[15] = m[15];\n }\n\n return dst;\n}\n\n/**\n * Takes a 4-by-4 matrix and a vector with 3 entries,\n * interprets the vector as a point, transforms that point by the matrix, and\n * returns the result as a vector with 3 entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} v The point.\n * @param {module:twgl/v3.Vec3} [dst] optional vec3 to store result. If not passed a new one is created.\n * @return {module:twgl/v3.Vec3} The transformed point.\n * @memberOf module:twgl/m4\n */\nfunction transformPoint(m, v, dst) {\n dst = dst || v3.create();\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n const d = v0 * m[0 * 4 + 3] + v1 * m[1 * 4 + 3] + v2 * m[2 * 4 + 3] + m[3 * 4 + 3];\n\n dst[0] = (v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0] + m[3 * 4 + 0]) / d;\n dst[1] = (v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1] + m[3 * 4 + 1]) / d;\n dst[2] = (v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2] + m[3 * 4 + 2]) / d;\n\n return dst;\n}\n\n/**\n * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a\n * direction, transforms that direction by the matrix, and returns the result;\n * assumes the transformation of 3-dimensional space represented by the matrix\n * is parallel-preserving, i.e. any combination of rotation, scaling and\n * translation, but not a perspective distortion. Returns a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} v The direction.\n * @param {module:twgl/v3.Vec3} [dst] optional Vec3 to store result. If not passed a new one is created.\n * @return {module:twgl/v3.Vec3} The transformed direction.\n * @memberOf module:twgl/m4\n */\nfunction transformDirection(m, v, dst) {\n dst = dst || v3.create();\n\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n\n dst[0] = v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0];\n dst[1] = v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1];\n dst[2] = v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2];\n\n return dst;\n}\n\n/**\n * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector\n * as a normal to a surface, and computes a vector which is normal upon\n * transforming that surface by the matrix. The effect of this function is the\n * same as transforming v (as a direction) by the inverse-transpose of m. This\n * function assumes the transformation of 3-dimensional space represented by the\n * matrix is parallel-preserving, i.e. any combination of rotation, scaling and\n * translation, but not a perspective distortion. Returns a vector with 3\n * entries.\n * @param {module:twgl/m4.Mat4} m The matrix.\n * @param {module:twgl/v3.Vec3} v The normal.\n * @param {module:twgl/v3.Vec3} [dst] The direction. If not passed a new one is created.\n * @return {module:twgl/v3.Vec3} The transformed normal.\n * @memberOf module:twgl/m4\n */\nfunction transformNormal(m, v, dst) {\n dst = dst || v3.create();\n const mi = inverse(m);\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n\n dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2];\n dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2];\n dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2];\n\n return dst;\n}\n\nexport {\n axisRotate,\n axisRotation,\n copy,\n create,\n frustum,\n getAxis,\n getTranslation,\n identity,\n inverse,\n lookAt,\n multiply,\n negate,\n ortho,\n perspective,\n rotateX,\n rotateY,\n rotateZ,\n rotationX,\n rotationY,\n rotationZ,\n scale,\n scaling,\n setAxis,\n setDefaultType,\n setTranslation,\n transformDirection,\n transformNormal,\n transformPoint,\n translate,\n translation,\n transpose,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Various functions to make simple primitives\n *\n * note: Most primitive functions come in 3 styles\n *\n * * `createSomeShapeBufferInfo`\n *\n * These functions are almost always the functions you want to call. They\n * create vertices then make WebGLBuffers and create {@link module:twgl.AttribInfo}s\n * returning a {@link module:twgl.BufferInfo} you can pass to {@link module:twgl.setBuffersAndAttributes}\n * and {@link module:twgl.drawBufferInfo} etc...\n *\n * * `createSomeShapeBuffers`\n *\n * These create WebGLBuffers and put your data in them but nothing else.\n * It's a shortcut to doing it yourself if you don't want to use\n * the higher level functions.\n *\n * * `createSomeShapeVertices`\n *\n * These just create vertices, no buffers. This allows you to manipulate the vertices\n * or add more data before generating a {@link module:twgl.BufferInfo}. Once you're finished\n * manipulating the vertices call {@link module:twgl.createBufferInfoFromArrays}.\n *\n * example:\n *\n * const arrays = twgl.primitives.createPlaneVertices(1);\n * twgl.primitives.reorientVertices(arrays, m4.rotationX(Math.PI * 0.5));\n * const bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * @module twgl/primitives\n */\nimport * as attributes from './attributes.js';\nimport * as helper from './helper.js';\nimport * as typedArrays from './typedarrays.js';\nimport * as m4 from './m4.js';\nimport * as v3 from './v3.js';\n\nconst getArray = attributes.getArray_; // eslint-disable-line\nconst getNumComponents = attributes.getNumComponents_; // eslint-disable-line\n\n/**\n * @typedef {(Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array)} TypedArray\n */\n\n/**\n * Add `push` to a typed array. It just keeps a 'cursor'\n * and allows use to `push` values into the array so we\n * don't have to manually compute offsets\n * @param {TypedArray} typedArray TypedArray to augment\n * @param {number} numComponents number of components.\n * @private\n */\nfunction augmentTypedArray(typedArray, numComponents) {\n let cursor = 0;\n typedArray.push = function() {\n for (let ii = 0; ii < arguments.length; ++ii) {\n const value = arguments[ii];\n if (value instanceof Array || typedArrays.isArrayBuffer(value)) {\n for (let jj = 0; jj < value.length; ++jj) {\n typedArray[cursor++] = value[jj];\n }\n } else {\n typedArray[cursor++] = value;\n }\n }\n };\n typedArray.reset = function(opt_index) {\n cursor = opt_index || 0;\n };\n typedArray.numComponents = numComponents;\n Object.defineProperty(typedArray, 'numElements', {\n get: function() {\n return this.length / this.numComponents | 0;\n },\n });\n return typedArray;\n}\n\n/**\n * creates a typed array with a `push` function attached\n * so that you can easily *push* values.\n *\n * `push` can take multiple arguments. If an argument is an array each element\n * of the array will be added to the typed array.\n *\n * Example:\n *\n * const array = createAugmentedTypedArray(3, 2); // creates a Float32Array with 6 values\n * array.push(1, 2, 3);\n * array.push([4, 5, 6]);\n * // array now contains [1, 2, 3, 4, 5, 6]\n *\n * Also has `numComponents` and `numElements` properties.\n *\n * @param {number} numComponents number of components\n * @param {number} numElements number of elements. The total size of the array will be `numComponents * numElements`.\n * @param {constructor} opt_type A constructor for the type. Default = `Float32Array`.\n * @return {ArrayBufferView} A typed array.\n * @memberOf module:twgl/primitives\n */\nfunction createAugmentedTypedArray(numComponents, numElements, opt_type) {\n const Type = opt_type || Float32Array;\n return augmentTypedArray(new Type(numComponents * numElements), numComponents);\n}\n\nfunction allButIndices(name) {\n return name !== \"indices\";\n}\n\n/**\n * Given indexed vertices creates a new set of vertices un-indexed by expanding the indexed vertices.\n * @param {Object.} vertices The indexed vertices to deindex\n * @return {Object.} The deindexed vertices\n * @memberOf module:twgl/primitives\n */\nfunction deindexVertices(vertices) {\n const indices = vertices.indices;\n const newVertices = {};\n const numElements = indices.length;\n\n function expandToUnindexed(channel) {\n const srcBuffer = vertices[channel];\n const numComponents = srcBuffer.numComponents;\n const dstBuffer = createAugmentedTypedArray(numComponents, numElements, srcBuffer.constructor);\n for (let ii = 0; ii < numElements; ++ii) {\n const ndx = indices[ii];\n const offset = ndx * numComponents;\n for (let jj = 0; jj < numComponents; ++jj) {\n dstBuffer.push(srcBuffer[offset + jj]);\n }\n }\n newVertices[channel] = dstBuffer;\n }\n\n Object.keys(vertices).filter(allButIndices).forEach(expandToUnindexed);\n\n return newVertices;\n}\n\n/**\n * flattens the normals of deindexed vertices in place.\n * @param {Object.} vertices The deindexed vertices who's normals to flatten\n * @return {Object.} The flattened vertices (same as was passed in)\n * @memberOf module:twgl/primitives\n */\nfunction flattenNormals(vertices) {\n if (vertices.indices) {\n throw new Error('can not flatten normals of indexed vertices. deindex them first');\n }\n\n const normals = vertices.normal;\n const numNormals = normals.length;\n for (let ii = 0; ii < numNormals; ii += 9) {\n // pull out the 3 normals for this triangle\n const nax = normals[ii + 0];\n const nay = normals[ii + 1];\n const naz = normals[ii + 2];\n\n const nbx = normals[ii + 3];\n const nby = normals[ii + 4];\n const nbz = normals[ii + 5];\n\n const ncx = normals[ii + 6];\n const ncy = normals[ii + 7];\n const ncz = normals[ii + 8];\n\n // add them\n let nx = nax + nbx + ncx;\n let ny = nay + nby + ncy;\n let nz = naz + nbz + ncz;\n\n // normalize them\n const length = Math.sqrt(nx * nx + ny * ny + nz * nz);\n\n nx /= length;\n ny /= length;\n nz /= length;\n\n // copy them back in\n normals[ii + 0] = nx;\n normals[ii + 1] = ny;\n normals[ii + 2] = nz;\n\n normals[ii + 3] = nx;\n normals[ii + 4] = ny;\n normals[ii + 5] = nz;\n\n normals[ii + 6] = nx;\n normals[ii + 7] = ny;\n normals[ii + 8] = nz;\n }\n\n return vertices;\n}\n\nfunction applyFuncToV3Array(array, matrix, fn) {\n const len = array.length;\n const tmp = new Float32Array(3);\n for (let ii = 0; ii < len; ii += 3) {\n fn(matrix, [array[ii], array[ii + 1], array[ii + 2]], tmp);\n array[ii ] = tmp[0];\n array[ii + 1] = tmp[1];\n array[ii + 2] = tmp[2];\n }\n}\n\nfunction transformNormal(mi, v, dst) {\n dst = dst || v3.create();\n const v0 = v[0];\n const v1 = v[1];\n const v2 = v[2];\n\n dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2];\n dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2];\n dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2];\n\n return dst;\n}\n\n/**\n * Reorients directions by the given matrix..\n * @param {(number[]|TypedArray)} array The array. Assumes value floats per element.\n * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by.\n * @return {(number[]|TypedArray)} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\nfunction reorientDirections(array, matrix) {\n applyFuncToV3Array(array, matrix, m4.transformDirection);\n return array;\n}\n\n/**\n * Reorients normals by the inverse-transpose of the given\n * matrix..\n * @param {(number[]|TypedArray)} array The array. Assumes value floats per element.\n * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by.\n * @return {(number[]|TypedArray)} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\nfunction reorientNormals(array, matrix) {\n applyFuncToV3Array(array, m4.inverse(matrix), transformNormal);\n return array;\n}\n\n/**\n * Reorients positions by the given matrix. In other words, it\n * multiplies each vertex by the given matrix.\n * @param {(number[]|TypedArray)} array The array. Assumes value floats per element.\n * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by.\n * @return {(number[]|TypedArray)} the same array that was passed in\n * @memberOf module:twgl/primitives\n */\nfunction reorientPositions(array, matrix) {\n applyFuncToV3Array(array, matrix, m4.transformPoint);\n return array;\n}\n\n/**\n * @typedef {(number[]|TypedArray)} NativeArrayOrTypedArray\n */\n\n/**\n * Reorients arrays by the given matrix. Assumes arrays have\n * names that contains 'pos' could be reoriented as positions,\n * 'binorm' or 'tan' as directions, and 'norm' as normals.\n *\n * @param {Object.} arrays The vertices to reorient\n * @param {module:twgl/m4.Mat4} matrix matrix to reorient by.\n * @return {Object.} same arrays that were passed in.\n * @memberOf module:twgl/primitives\n */\nfunction reorientVertices(arrays, matrix) {\n Object.keys(arrays).forEach(function(name) {\n const array = arrays[name];\n if (name.indexOf(\"pos\") >= 0) {\n reorientPositions(array, matrix);\n } else if (name.indexOf(\"tan\") >= 0 || name.indexOf(\"binorm\") >= 0) {\n reorientDirections(array, matrix);\n } else if (name.indexOf(\"norm\") >= 0) {\n reorientNormals(array, matrix);\n }\n });\n return arrays;\n}\n\n/**\n * Creates XY quad BufferInfo\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {Object.} the created XY Quad BufferInfo\n * @memberOf module:twgl/primitives\n * @function createXYQuadBuffers\n */\n\n/**\n * Creates XY quad Buffers\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {module:twgl.BufferInfo} the created XY Quad buffers\n * @memberOf module:twgl/primitives\n * @function createXYQuadBufferInfo\n */\n\n/**\n * Creates XY quad vertices\n *\n * The default with no parameters will return a 2x2 quad with values from -1 to +1.\n * If you want a unit quad with that goes from 0 to 1 you'd call it with\n *\n * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5);\n *\n * If you want a unit quad centered above 0,0 you'd call it with\n *\n * twgl.primitives.createXYQuadVertices(1, 0, 0.5);\n *\n * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1\n * @param {number} [xOffset] the amount to offset the quad in X\n * @param {number} [yOffset] the amount to offset the quad in Y\n * @return {Object.} the created XY Quad vertices\n * @memberOf module:twgl/primitives\n */\nfunction createXYQuadVertices(size, xOffset, yOffset) {\n size = size || 2;\n xOffset = xOffset || 0;\n yOffset = yOffset || 0;\n size *= 0.5;\n return {\n position: {\n numComponents: 2,\n data: [\n xOffset + -1 * size, yOffset + -1 * size,\n xOffset + 1 * size, yOffset + -1 * size,\n xOffset + -1 * size, yOffset + 1 * size,\n xOffset + 1 * size, yOffset + 1 * size,\n ],\n },\n normal: [\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n 0, 0, 1,\n ],\n texcoord: [\n 0, 0,\n 1, 0,\n 0, 1,\n 1, 1,\n ],\n indices: [ 0, 1, 2, 2, 1, 3 ],\n };\n}\n\n/**\n * Creates XZ plane BufferInfo.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices.\n * @return {module:twgl.BufferInfo} The created plane BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createPlaneBufferInfo\n */\n\n/**\n * Creates XZ plane buffers.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices.\n * @return {Object.} The created plane buffers.\n * @memberOf module:twgl/primitives\n * @function createPlaneBuffers\n */\n\n/**\n * Creates XZ plane vertices.\n *\n * The created plane has position, normal, and texcoord data\n *\n * @param {number} [width] Width of the plane. Default = 1\n * @param {number} [depth] Depth of the plane. Default = 1\n * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1\n * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1\n * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices.\n * @return {Object.} The created plane vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createPlaneVertices(\n width,\n depth,\n subdivisionsWidth,\n subdivisionsDepth,\n matrix) {\n width = width || 1;\n depth = depth || 1;\n subdivisionsWidth = subdivisionsWidth || 1;\n subdivisionsDepth = subdivisionsDepth || 1;\n matrix = matrix || m4.identity();\n\n const numVertices = (subdivisionsWidth + 1) * (subdivisionsDepth + 1);\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n\n for (let z = 0; z <= subdivisionsDepth; z++) {\n for (let x = 0; x <= subdivisionsWidth; x++) {\n const u = x / subdivisionsWidth;\n const v = z / subdivisionsDepth;\n positions.push(\n width * u - width * 0.5,\n 0,\n depth * v - depth * 0.5);\n normals.push(0, 1, 0);\n texcoords.push(u, v);\n }\n }\n\n const numVertsAcross = subdivisionsWidth + 1;\n const indices = createAugmentedTypedArray(\n 3, subdivisionsWidth * subdivisionsDepth * 2, Uint16Array);\n\n for (let z = 0; z < subdivisionsDepth; z++) { // eslint-disable-line\n for (let x = 0; x < subdivisionsWidth; x++) { // eslint-disable-line\n // Make triangle 1 of quad.\n indices.push(\n (z + 0) * numVertsAcross + x,\n (z + 1) * numVertsAcross + x,\n (z + 0) * numVertsAcross + x + 1);\n\n // Make triangle 2 of quad.\n indices.push(\n (z + 1) * numVertsAcross + x,\n (z + 1) * numVertsAcross + x + 1,\n (z + 0) * numVertsAcross + x + 1);\n }\n }\n\n const arrays = reorientVertices({\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n }, matrix);\n return arrays;\n}\n\n/**\n * Creates sphere BufferInfo.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {module:twgl.BufferInfo} The created sphere BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createSphereBufferInfo\n */\n\n/**\n * Creates sphere buffers.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {Object.} The created sphere buffers.\n * @memberOf module:twgl/primitives\n * @function createSphereBuffers\n */\n\n/**\n * Creates sphere vertices.\n *\n * The created sphere has position, normal, and texcoord data\n *\n * @param {number} radius radius of the sphere.\n * @param {number} subdivisionsAxis number of steps around the sphere.\n * @param {number} subdivisionsHeight number of vertically on the sphere.\n * @param {number} [opt_startLatitudeInRadians] where to start the\n * top of the sphere. Default = 0.\n * @param {number} [opt_endLatitudeInRadians] Where to end the\n * bottom of the sphere. Default = Math.PI.\n * @param {number} [opt_startLongitudeInRadians] where to start\n * wrapping the sphere. Default = 0.\n * @param {number} [opt_endLongitudeInRadians] where to end\n * wrapping the sphere. Default = 2 * Math.PI.\n * @return {Object.} The created sphere vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createSphereVertices(\n radius,\n subdivisionsAxis,\n subdivisionsHeight,\n opt_startLatitudeInRadians,\n opt_endLatitudeInRadians,\n opt_startLongitudeInRadians,\n opt_endLongitudeInRadians) {\n if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) {\n throw new Error('subdivisionAxis and subdivisionHeight must be > 0');\n }\n\n opt_startLatitudeInRadians = opt_startLatitudeInRadians || 0;\n opt_endLatitudeInRadians = opt_endLatitudeInRadians || Math.PI;\n opt_startLongitudeInRadians = opt_startLongitudeInRadians || 0;\n opt_endLongitudeInRadians = opt_endLongitudeInRadians || (Math.PI * 2);\n\n const latRange = opt_endLatitudeInRadians - opt_startLatitudeInRadians;\n const longRange = opt_endLongitudeInRadians - opt_startLongitudeInRadians;\n\n // We are going to generate our sphere by iterating through its\n // spherical coordinates and generating 2 triangles for each quad on a\n // ring of the sphere.\n const numVertices = (subdivisionsAxis + 1) * (subdivisionsHeight + 1);\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n\n // Generate the individual vertices in our vertex buffer.\n for (let y = 0; y <= subdivisionsHeight; y++) {\n for (let x = 0; x <= subdivisionsAxis; x++) {\n // Generate a vertex based on its spherical coordinates\n const u = x / subdivisionsAxis;\n const v = y / subdivisionsHeight;\n const theta = longRange * u + opt_startLongitudeInRadians;\n const phi = latRange * v + opt_startLatitudeInRadians;\n const sinTheta = Math.sin(theta);\n const cosTheta = Math.cos(theta);\n const sinPhi = Math.sin(phi);\n const cosPhi = Math.cos(phi);\n const ux = cosTheta * sinPhi;\n const uy = cosPhi;\n const uz = sinTheta * sinPhi;\n positions.push(radius * ux, radius * uy, radius * uz);\n normals.push(ux, uy, uz);\n texcoords.push(1 - u, v);\n }\n }\n\n const numVertsAround = subdivisionsAxis + 1;\n const indices = createAugmentedTypedArray(3, subdivisionsAxis * subdivisionsHeight * 2, Uint16Array);\n for (let x = 0; x < subdivisionsAxis; x++) { // eslint-disable-line\n for (let y = 0; y < subdivisionsHeight; y++) { // eslint-disable-line\n // Make triangle 1 of quad.\n indices.push(\n (y + 0) * numVertsAround + x,\n (y + 0) * numVertsAround + x + 1,\n (y + 1) * numVertsAround + x);\n\n // Make triangle 2 of quad.\n indices.push(\n (y + 1) * numVertsAround + x,\n (y + 0) * numVertsAround + x + 1,\n (y + 1) * numVertsAround + x + 1);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n/**\n * Array of the indices of corners of each face of a cube.\n * @type {Array.}\n * @private\n */\nconst CUBE_FACE_INDICES = [\n [3, 7, 5, 1], // right\n [6, 2, 0, 4], // left\n [6, 7, 3, 2], // ??\n [0, 1, 5, 4], // ??\n [7, 6, 4, 5], // front\n [2, 3, 1, 0], // back\n];\n\n/**\n * Creates a BufferInfo for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] width, height and depth of the cube.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCubeBufferInfo\n */\n\n/**\n * Creates the buffers and indices for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} [size] width, height and depth of the cube.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCubeBuffers\n */\n\n/**\n * Creates the vertices and indices for a cube.\n *\n * The cube is created around the origin. (-size / 2, size / 2).\n *\n * @param {number} [size] width, height and depth of the cube.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createCubeVertices(size) {\n size = size || 1;\n const k = size / 2;\n\n const cornerVertices = [\n [-k, -k, -k],\n [+k, -k, -k],\n [-k, +k, -k],\n [+k, +k, -k],\n [-k, -k, +k],\n [+k, -k, +k],\n [-k, +k, +k],\n [+k, +k, +k],\n ];\n\n const faceNormals = [\n [+1, +0, +0],\n [-1, +0, +0],\n [+0, +1, +0],\n [+0, -1, +0],\n [+0, +0, +1],\n [+0, +0, -1],\n ];\n\n const uvCoords = [\n [1, 0],\n [0, 0],\n [0, 1],\n [1, 1],\n ];\n\n const numVertices = 6 * 4;\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2 , numVertices);\n const indices = createAugmentedTypedArray(3, 6 * 2, Uint16Array);\n\n for (let f = 0; f < 6; ++f) {\n const faceIndices = CUBE_FACE_INDICES[f];\n for (let v = 0; v < 4; ++v) {\n const position = cornerVertices[faceIndices[v]];\n const normal = faceNormals[f];\n const uv = uvCoords[v];\n\n // Each face needs all four vertices because the normals and texture\n // coordinates are not all the same.\n positions.push(position);\n normals.push(normal);\n texcoords.push(uv);\n\n }\n // Two triangles make a square face.\n const offset = 4 * f;\n indices.push(offset + 0, offset + 1, offset + 2);\n indices.push(offset + 0, offset + 2, offset + 3);\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n/**\n * Creates a BufferInfo for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {module:twgl.BufferInfo} The created cone BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createTruncatedConeBufferInfo\n */\n\n/**\n * Creates buffers for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created cone buffers.\n * @memberOf module:twgl/primitives\n * @function createTruncatedConeBuffers\n */\n\n/**\n * Creates vertices for a truncated cone, which is like a cylinder\n * except that it has different top and bottom radii. A truncated cone\n * can also be used to create cylinders and regular cones. The\n * truncated cone will be created centered about the origin, with the\n * y axis as its vertical axis. .\n *\n * @param {number} bottomRadius Bottom radius of truncated cone.\n * @param {number} topRadius Top radius of truncated cone.\n * @param {number} height Height of truncated cone.\n * @param {number} radialSubdivisions The number of subdivisions around the\n * truncated cone.\n * @param {number} verticalSubdivisions The number of subdivisions down the\n * truncated cone.\n * @param {boolean} [opt_topCap] Create top cap. Default = true.\n * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created cone vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createTruncatedConeVertices(\n bottomRadius,\n topRadius,\n height,\n radialSubdivisions,\n verticalSubdivisions,\n opt_topCap,\n opt_bottomCap) {\n if (radialSubdivisions < 3) {\n throw new Error('radialSubdivisions must be 3 or greater');\n }\n\n if (verticalSubdivisions < 1) {\n throw new Error('verticalSubdivisions must be 1 or greater');\n }\n\n const topCap = (opt_topCap === undefined) ? true : opt_topCap;\n const bottomCap = (opt_bottomCap === undefined) ? true : opt_bottomCap;\n\n const extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0);\n\n const numVertices = (radialSubdivisions + 1) * (verticalSubdivisions + 1 + extra);\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n const indices = createAugmentedTypedArray(3, radialSubdivisions * (verticalSubdivisions + extra / 2) * 2, Uint16Array);\n\n const vertsAroundEdge = radialSubdivisions + 1;\n\n // The slant of the cone is constant across its surface\n const slant = Math.atan2(bottomRadius - topRadius, height);\n const cosSlant = Math.cos(slant);\n const sinSlant = Math.sin(slant);\n\n const start = topCap ? -2 : 0;\n const end = verticalSubdivisions + (bottomCap ? 2 : 0);\n\n for (let yy = start; yy <= end; ++yy) {\n let v = yy / verticalSubdivisions;\n let y = height * v;\n let ringRadius;\n if (yy < 0) {\n y = 0;\n v = 1;\n ringRadius = bottomRadius;\n } else if (yy > verticalSubdivisions) {\n y = height;\n v = 1;\n ringRadius = topRadius;\n } else {\n ringRadius = bottomRadius +\n (topRadius - bottomRadius) * (yy / verticalSubdivisions);\n }\n if (yy === -2 || yy === verticalSubdivisions + 2) {\n ringRadius = 0;\n v = 0;\n }\n y -= height / 2;\n for (let ii = 0; ii < vertsAroundEdge; ++ii) {\n const sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions);\n const cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions);\n positions.push(sin * ringRadius, y, cos * ringRadius);\n if (yy < 0) {\n normals.push(0, -1, 0);\n } else if (yy > verticalSubdivisions) {\n normals.push(0, 1, 0);\n } else if (ringRadius === 0.0) {\n normals.push(0, 0, 0);\n } else {\n normals.push(sin * cosSlant, sinSlant, cos * cosSlant);\n }\n texcoords.push((ii / radialSubdivisions), 1 - v);\n }\n }\n\n for (let yy = 0; yy < verticalSubdivisions + extra; ++yy) { // eslint-disable-line\n if (yy === 1 && topCap || yy === verticalSubdivisions + extra - 2 && bottomCap) {\n continue;\n }\n for (let ii = 0; ii < radialSubdivisions; ++ii) { // eslint-disable-line\n indices.push(vertsAroundEdge * (yy + 0) + 0 + ii,\n vertsAroundEdge * (yy + 0) + 1 + ii,\n vertsAroundEdge * (yy + 1) + 1 + ii);\n indices.push(vertsAroundEdge * (yy + 0) + 0 + ii,\n vertsAroundEdge * (yy + 1) + 1 + ii,\n vertsAroundEdge * (yy + 1) + 0 + ii);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n/**\n * Expands RLE data\n * @param {number[]} rleData data in format of run-length, x, y, z, run-length, x, y, z\n * @param {number[]} [padding] value to add each entry with.\n * @return {number[]} the expanded rleData\n * @private\n */\nfunction expandRLEData(rleData, padding) {\n padding = padding || [];\n const data = [];\n for (let ii = 0; ii < rleData.length; ii += 4) {\n const runLength = rleData[ii];\n const element = rleData.slice(ii + 1, ii + 4);\n element.push.apply(element, padding);\n for (let jj = 0; jj < runLength; ++jj) {\n data.push.apply(data, element);\n }\n }\n return data;\n}\n\n/**\n * Creates 3D 'F' BufferInfo.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function create3DFBufferInfo\n */\n\n/**\n * Creates 3D 'F' buffers.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function create3DFBuffers\n */\n\n/**\n * Creates 3D 'F' vertices.\n * An 'F' is useful because you can easily tell which way it is oriented.\n * The created 'F' has position, normal, texcoord, and color arrays.\n *\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\nfunction create3DFVertices() {\n\n const positions = [\n // left column front\n 0, 0, 0,\n 0, 150, 0,\n 30, 0, 0,\n 0, 150, 0,\n 30, 150, 0,\n 30, 0, 0,\n\n // top rung front\n 30, 0, 0,\n 30, 30, 0,\n 100, 0, 0,\n 30, 30, 0,\n 100, 30, 0,\n 100, 0, 0,\n\n // middle rung front\n 30, 60, 0,\n 30, 90, 0,\n 67, 60, 0,\n 30, 90, 0,\n 67, 90, 0,\n 67, 60, 0,\n\n // left column back\n 0, 0, 30,\n 30, 0, 30,\n 0, 150, 30,\n 0, 150, 30,\n 30, 0, 30,\n 30, 150, 30,\n\n // top rung back\n 30, 0, 30,\n 100, 0, 30,\n 30, 30, 30,\n 30, 30, 30,\n 100, 0, 30,\n 100, 30, 30,\n\n // middle rung back\n 30, 60, 30,\n 67, 60, 30,\n 30, 90, 30,\n 30, 90, 30,\n 67, 60, 30,\n 67, 90, 30,\n\n // top\n 0, 0, 0,\n 100, 0, 0,\n 100, 0, 30,\n 0, 0, 0,\n 100, 0, 30,\n 0, 0, 30,\n\n // top rung front\n 100, 0, 0,\n 100, 30, 0,\n 100, 30, 30,\n 100, 0, 0,\n 100, 30, 30,\n 100, 0, 30,\n\n // under top rung\n 30, 30, 0,\n 30, 30, 30,\n 100, 30, 30,\n 30, 30, 0,\n 100, 30, 30,\n 100, 30, 0,\n\n // between top rung and middle\n 30, 30, 0,\n 30, 60, 30,\n 30, 30, 30,\n 30, 30, 0,\n 30, 60, 0,\n 30, 60, 30,\n\n // top of middle rung\n 30, 60, 0,\n 67, 60, 30,\n 30, 60, 30,\n 30, 60, 0,\n 67, 60, 0,\n 67, 60, 30,\n\n // front of middle rung\n 67, 60, 0,\n 67, 90, 30,\n 67, 60, 30,\n 67, 60, 0,\n 67, 90, 0,\n 67, 90, 30,\n\n // bottom of middle rung.\n 30, 90, 0,\n 30, 90, 30,\n 67, 90, 30,\n 30, 90, 0,\n 67, 90, 30,\n 67, 90, 0,\n\n // front of bottom\n 30, 90, 0,\n 30, 150, 30,\n 30, 90, 30,\n 30, 90, 0,\n 30, 150, 0,\n 30, 150, 30,\n\n // bottom\n 0, 150, 0,\n 0, 150, 30,\n 30, 150, 30,\n 0, 150, 0,\n 30, 150, 30,\n 30, 150, 0,\n\n // left side\n 0, 0, 0,\n 0, 0, 30,\n 0, 150, 30,\n 0, 0, 0,\n 0, 150, 30,\n 0, 150, 0,\n ];\n\n const texcoords = [\n // left column front\n 0.22, 0.19,\n 0.22, 0.79,\n 0.34, 0.19,\n 0.22, 0.79,\n 0.34, 0.79,\n 0.34, 0.19,\n\n // top rung front\n 0.34, 0.19,\n 0.34, 0.31,\n 0.62, 0.19,\n 0.34, 0.31,\n 0.62, 0.31,\n 0.62, 0.19,\n\n // middle rung front\n 0.34, 0.43,\n 0.34, 0.55,\n 0.49, 0.43,\n 0.34, 0.55,\n 0.49, 0.55,\n 0.49, 0.43,\n\n // left column back\n 0, 0,\n 1, 0,\n 0, 1,\n 0, 1,\n 1, 0,\n 1, 1,\n\n // top rung back\n 0, 0,\n 1, 0,\n 0, 1,\n 0, 1,\n 1, 0,\n 1, 1,\n\n // middle rung back\n 0, 0,\n 1, 0,\n 0, 1,\n 0, 1,\n 1, 0,\n 1, 1,\n\n // top\n 0, 0,\n 1, 0,\n 1, 1,\n 0, 0,\n 1, 1,\n 0, 1,\n\n // top rung front\n 0, 0,\n 1, 0,\n 1, 1,\n 0, 0,\n 1, 1,\n 0, 1,\n\n // under top rung\n 0, 0,\n 0, 1,\n 1, 1,\n 0, 0,\n 1, 1,\n 1, 0,\n\n // between top rung and middle\n 0, 0,\n 1, 1,\n 0, 1,\n 0, 0,\n 1, 0,\n 1, 1,\n\n // top of middle rung\n 0, 0,\n 1, 1,\n 0, 1,\n 0, 0,\n 1, 0,\n 1, 1,\n\n // front of middle rung\n 0, 0,\n 1, 1,\n 0, 1,\n 0, 0,\n 1, 0,\n 1, 1,\n\n // bottom of middle rung.\n 0, 0,\n 0, 1,\n 1, 1,\n 0, 0,\n 1, 1,\n 1, 0,\n\n // front of bottom\n 0, 0,\n 1, 1,\n 0, 1,\n 0, 0,\n 1, 0,\n 1, 1,\n\n // bottom\n 0, 0,\n 0, 1,\n 1, 1,\n 0, 0,\n 1, 1,\n 1, 0,\n\n // left side\n 0, 0,\n 0, 1,\n 1, 1,\n 0, 0,\n 1, 1,\n 1, 0,\n ];\n\n const normals = expandRLEData([\n // left column front\n // top rung front\n // middle rung front\n 18, 0, 0, 1,\n\n // left column back\n // top rung back\n // middle rung back\n 18, 0, 0, -1,\n\n // top\n 6, 0, 1, 0,\n\n // top rung front\n 6, 1, 0, 0,\n\n // under top rung\n 6, 0, -1, 0,\n\n // between top rung and middle\n 6, 1, 0, 0,\n\n // top of middle rung\n 6, 0, 1, 0,\n\n // front of middle rung\n 6, 1, 0, 0,\n\n // bottom of middle rung.\n 6, 0, -1, 0,\n\n // front of bottom\n 6, 1, 0, 0,\n\n // bottom\n 6, 0, -1, 0,\n\n // left side\n 6, -1, 0, 0,\n ]);\n\n const colors = expandRLEData([\n // left column front\n // top rung front\n // middle rung front\n 18, 200, 70, 120,\n\n // left column back\n // top rung back\n // middle rung back\n 18, 80, 70, 200,\n\n // top\n 6, 70, 200, 210,\n\n // top rung front\n 6, 200, 200, 70,\n\n // under top rung\n 6, 210, 100, 70,\n\n // between top rung and middle\n 6, 210, 160, 70,\n\n // top of middle rung\n 6, 70, 180, 210,\n\n // front of middle rung\n 6, 100, 70, 210,\n\n // bottom of middle rung.\n 6, 76, 210, 100,\n\n // front of bottom\n 6, 140, 210, 80,\n\n // bottom\n 6, 90, 130, 110,\n\n // left side\n 6, 160, 160, 220,\n ], [255]);\n\n const numVerts = positions.length / 3;\n\n const arrays = {\n position: createAugmentedTypedArray(3, numVerts),\n texcoord: createAugmentedTypedArray(2, numVerts),\n normal: createAugmentedTypedArray(3, numVerts),\n color: createAugmentedTypedArray(4, numVerts, Uint8Array),\n indices: createAugmentedTypedArray(3, numVerts / 3, Uint16Array),\n };\n\n arrays.position.push(positions);\n arrays.texcoord.push(texcoords);\n arrays.normal.push(normals);\n arrays.color.push(colors);\n\n for (let ii = 0; ii < numVerts; ++ii) {\n arrays.indices.push(ii);\n }\n\n return arrays;\n}\n\n/**\n * Creates crescent BufferInfo.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCresentBufferInfo\n */\n\n/**\n * Creates crescent buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCresentBuffers\n */\n\n/**\n * Creates crescent vertices.\n *\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n * @function createCresentBuffers\n */\n\n/**\n * Creates crescent BufferInfo.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCrescentBufferInfo\n */\n\n/**\n * Creates crescent buffers.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCrescentBuffers\n */\n\n/**\n * Creates crescent vertices.\n *\n * @param {number} verticalRadius The vertical radius of the crescent.\n * @param {number} outerRadius The outer radius of the crescent.\n * @param {number} innerRadius The inner radius of the crescent.\n * @param {number} thickness The thickness of the crescent.\n * @param {number} subdivisionsDown number of steps around the crescent.\n * @param {number} [startOffset] Where to start arc. Default 0.\n * @param {number} [endOffset] Where to end arg. Default 1.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\n function createCrescentVertices(\n verticalRadius,\n outerRadius,\n innerRadius,\n thickness,\n subdivisionsDown,\n startOffset,\n endOffset) {\n if (subdivisionsDown <= 0) {\n throw new Error('subdivisionDown must be > 0');\n }\n\n startOffset = startOffset || 0;\n endOffset = endOffset || 1;\n\n const subdivisionsThick = 2;\n\n const offsetRange = endOffset - startOffset;\n const numVertices = (subdivisionsDown + 1) * 2 * (2 + subdivisionsThick);\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n\n function lerp(a, b, s) {\n return a + (b - a) * s;\n }\n\n function createArc(arcRadius, x, normalMult, normalAdd, uMult, uAdd) {\n for (let z = 0; z <= subdivisionsDown; z++) {\n const uBack = x / (subdivisionsThick - 1);\n const v = z / subdivisionsDown;\n const xBack = (uBack - 0.5) * 2;\n const angle = (startOffset + (v * offsetRange)) * Math.PI;\n const s = Math.sin(angle);\n const c = Math.cos(angle);\n const radius = lerp(verticalRadius, arcRadius, s);\n const px = xBack * thickness;\n const py = c * verticalRadius;\n const pz = s * radius;\n positions.push(px, py, pz);\n const n = v3.add(v3.multiply([0, s, c], normalMult), normalAdd);\n normals.push(n);\n texcoords.push(uBack * uMult + uAdd, v);\n }\n }\n\n // Generate the individual vertices in our vertex buffer.\n for (let x = 0; x < subdivisionsThick; x++) {\n const uBack = (x / (subdivisionsThick - 1) - 0.5) * 2;\n createArc(outerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0);\n createArc(outerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 0);\n createArc(innerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0);\n createArc(innerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 1);\n }\n\n // Do outer surface.\n const indices = createAugmentedTypedArray(3, (subdivisionsDown * 2) * (2 + subdivisionsThick), Uint16Array);\n\n function createSurface(leftArcOffset, rightArcOffset) {\n for (let z = 0; z < subdivisionsDown; ++z) {\n // Make triangle 1 of quad.\n indices.push(\n leftArcOffset + z + 0,\n leftArcOffset + z + 1,\n rightArcOffset + z + 0);\n\n // Make triangle 2 of quad.\n indices.push(\n leftArcOffset + z + 1,\n rightArcOffset + z + 1,\n rightArcOffset + z + 0);\n }\n }\n\n const numVerticesDown = subdivisionsDown + 1;\n // front\n createSurface(numVerticesDown * 0, numVerticesDown * 4);\n // right\n createSurface(numVerticesDown * 5, numVerticesDown * 7);\n // back\n createSurface(numVerticesDown * 6, numVerticesDown * 2);\n // left\n createSurface(numVerticesDown * 3, numVerticesDown * 1);\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n/**\n * Creates cylinder BufferInfo. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createCylinderBufferInfo\n */\n\n /**\n * Creates cylinder buffers. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createCylinderBuffers\n */\n\n /**\n * Creates cylinder vertices. The cylinder will be created around the origin\n * along the y-axis.\n *\n * @param {number} radius Radius of cylinder.\n * @param {number} height Height of cylinder.\n * @param {number} radialSubdivisions The number of subdivisions around the cylinder.\n * @param {number} verticalSubdivisions The number of subdivisions down the cylinder.\n * @param {boolean} [topCap] Create top cap. Default = true.\n * @param {boolean} [bottomCap] Create bottom cap. Default = true.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createCylinderVertices(\n radius,\n height,\n radialSubdivisions,\n verticalSubdivisions,\n topCap,\n bottomCap) {\n return createTruncatedConeVertices(\n radius,\n radius,\n height,\n radialSubdivisions,\n verticalSubdivisions,\n topCap,\n bottomCap);\n}\n\n/**\n * Creates BufferInfo for a torus\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createTorusBufferInfo\n */\n\n/**\n * Creates buffers for a torus\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createTorusBuffers\n */\n\n/**\n * Creates vertices for a torus\n *\n * @param {number} radius radius of center of torus circle.\n * @param {number} thickness radius of torus ring.\n * @param {number} radialSubdivisions The number of subdivisions around the torus.\n * @param {number} bodySubdivisions The number of subdivisions around the body torus.\n * @param {boolean} [startAngle] start angle in radians. Default = 0.\n * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createTorusVertices(\n radius,\n thickness,\n radialSubdivisions,\n bodySubdivisions,\n startAngle,\n endAngle) {\n if (radialSubdivisions < 3) {\n throw new Error('radialSubdivisions must be 3 or greater');\n }\n\n if (bodySubdivisions < 3) {\n throw new Error('verticalSubdivisions must be 3 or greater');\n }\n\n startAngle = startAngle || 0;\n endAngle = endAngle || Math.PI * 2;\n const range = endAngle - startAngle;\n\n const radialParts = radialSubdivisions + 1;\n const bodyParts = bodySubdivisions + 1;\n const numVertices = radialParts * bodyParts;\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n const indices = createAugmentedTypedArray(3, (radialSubdivisions) * (bodySubdivisions) * 2, Uint16Array);\n\n for (let slice = 0; slice < bodyParts; ++slice) {\n const v = slice / bodySubdivisions;\n const sliceAngle = v * Math.PI * 2;\n const sliceSin = Math.sin(sliceAngle);\n const ringRadius = radius + sliceSin * thickness;\n const ny = Math.cos(sliceAngle);\n const y = ny * thickness;\n for (let ring = 0; ring < radialParts; ++ring) {\n const u = ring / radialSubdivisions;\n const ringAngle = startAngle + u * range;\n const xSin = Math.sin(ringAngle);\n const zCos = Math.cos(ringAngle);\n const x = xSin * ringRadius;\n const z = zCos * ringRadius;\n const nx = xSin * sliceSin;\n const nz = zCos * sliceSin;\n positions.push(x, y, z);\n normals.push(nx, ny, nz);\n texcoords.push(u, 1 - v);\n }\n }\n\n for (let slice = 0; slice < bodySubdivisions; ++slice) { // eslint-disable-line\n for (let ring = 0; ring < radialSubdivisions; ++ring) { // eslint-disable-line\n const nextRingIndex = 1 + ring;\n const nextSliceIndex = 1 + slice;\n indices.push(radialParts * slice + ring,\n radialParts * nextSliceIndex + ring,\n radialParts * slice + nextRingIndex);\n indices.push(radialParts * nextSliceIndex + ring,\n radialParts * nextSliceIndex + nextRingIndex,\n radialParts * slice + nextRingIndex);\n }\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n\n/**\n * Creates a disc BufferInfo. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose outside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {module:twgl.BufferInfo} The created BufferInfo.\n * @memberOf module:twgl/primitives\n * @function createDiscBufferInfo\n */\n\n/**\n * Creates disc buffers. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose outside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext.\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {Object.} The created buffers.\n * @memberOf module:twgl/primitives\n * @function createDiscBuffers\n */\n\n/**\n * Creates disc vertices. The disc will be in the xz plane, centered at\n * the origin. When creating, at least 3 divisions, or pie\n * pieces, need to be specified, otherwise the triangles making\n * up the disc will be degenerate. You can also specify the\n * number of radial pieces `stacks`. A value of 1 for\n * stacks will give you a simple disc of pie pieces. If you\n * want to create an annulus you can set `innerRadius` to a\n * value > 0. Finally, `stackPower` allows you to have the widths\n * increase or decrease as you move away from the center. This\n * is particularly useful when using the disc as a ground plane\n * with a fixed camera such that you don't need the resolution\n * of small triangles near the perimeter. For example, a value\n * of 2 will produce stacks whose outside radius increases with\n * the square of the stack index. A value of 1 will give uniform\n * stacks.\n *\n * @param {number} radius Radius of the ground plane.\n * @param {number} divisions Number of triangles in the ground plane (at least 3).\n * @param {number} [stacks] Number of radial divisions (default=1).\n * @param {number} [innerRadius] Default 0.\n * @param {number} [stackPower] Power to raise stack size to for decreasing width.\n * @return {Object.} The created vertices.\n * @memberOf module:twgl/primitives\n */\nfunction createDiscVertices(\n radius,\n divisions,\n stacks,\n innerRadius,\n stackPower) {\n if (divisions < 3) {\n throw new Error('divisions must be at least 3');\n }\n\n stacks = stacks ? stacks : 1;\n stackPower = stackPower ? stackPower : 1;\n innerRadius = innerRadius ? innerRadius : 0;\n\n // Note: We don't share the center vertex because that would\n // mess up texture coordinates.\n const numVertices = (divisions + 1) * (stacks + 1);\n\n const positions = createAugmentedTypedArray(3, numVertices);\n const normals = createAugmentedTypedArray(3, numVertices);\n const texcoords = createAugmentedTypedArray(2, numVertices);\n const indices = createAugmentedTypedArray(3, stacks * divisions * 2, Uint16Array);\n\n let firstIndex = 0;\n const radiusSpan = radius - innerRadius;\n const pointsPerStack = divisions + 1;\n\n // Build the disk one stack at a time.\n for (let stack = 0; stack <= stacks; ++stack) {\n const stackRadius = innerRadius + radiusSpan * Math.pow(stack / stacks, stackPower);\n\n for (let i = 0; i <= divisions; ++i) {\n const theta = 2.0 * Math.PI * i / divisions;\n const x = stackRadius * Math.cos(theta);\n const z = stackRadius * Math.sin(theta);\n\n positions.push(x, 0, z);\n normals.push(0, 1, 0);\n texcoords.push(1 - (i / divisions), stack / stacks);\n if (stack > 0 && i !== divisions) {\n // a, b, c and d are the indices of the vertices of a quad. unless\n // the current stack is the one closest to the center, in which case\n // the vertices a and b connect to the center vertex.\n const a = firstIndex + (i + 1);\n const b = firstIndex + i;\n const c = firstIndex + i - pointsPerStack;\n const d = firstIndex + (i + 1) - pointsPerStack;\n\n // Make a quad of the vertices a, b, c, d.\n indices.push(a, b, c);\n indices.push(a, c, d);\n }\n }\n\n firstIndex += divisions + 1;\n }\n\n return {\n position: positions,\n normal: normals,\n texcoord: texcoords,\n indices: indices,\n };\n}\n\n/**\n * creates a random integer between 0 and range - 1 inclusive.\n * @param {number} range\n * @return {number} random value between 0 and range - 1 inclusive.\n * @private\n */\nfunction randInt(range) {\n return Math.random() * range | 0;\n}\n\n/**\n * Used to supply random colors\n * @callback RandomColorFunc\n * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed\n * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha\n * @return {number} a number from 0 to 255\n * @memberOf module:twgl/primitives\n */\n\n/**\n * @typedef {Object} RandomVerticesOptions\n * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices\n * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers\n * @memberOf module:twgl/primitives\n */\n\n/**\n * Creates an augmentedTypedArray of random vertex colors.\n * If the vertices are indexed (have an indices array) then will\n * just make random colors. Otherwise assumes they are triangles\n * and makes one random color for every 3 vertices.\n * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions.\n * @param {module:twgl/primitives.RandomVerticesOptions} [options] options.\n * @return {Object.} same vertices as passed in with `color` added.\n * @memberOf module:twgl/primitives\n */\nfunction makeRandomVertexColors(vertices, options) {\n options = options || {};\n const numElements = vertices.position.numElements;\n const vColors = createAugmentedTypedArray(4, numElements, Uint8Array);\n const rand = options.rand || function(ndx, channel) {\n return channel < 3 ? randInt(256) : 255;\n };\n vertices.color = vColors;\n if (vertices.indices) {\n // just make random colors if index\n for (let ii = 0; ii < numElements; ++ii) {\n vColors.push(rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3));\n }\n } else {\n // make random colors per triangle\n const numVertsPerColor = options.vertsPerColor || 3;\n const numSets = numElements / numVertsPerColor;\n for (let ii = 0; ii < numSets; ++ii) { // eslint-disable-line\n const color = [rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)];\n for (let jj = 0; jj < numVertsPerColor; ++jj) {\n vColors.push(color);\n }\n }\n }\n return vertices;\n}\n\n/**\n * creates a function that calls fn to create vertices and then\n * creates a buffers for them\n * @private\n */\nfunction createBufferFunc(fn) {\n return function(gl) {\n const arrays = fn.apply(this, Array.prototype.slice.call(arguments, 1));\n return attributes.createBuffersFromArrays(gl, arrays);\n };\n}\n\n/**\n * creates a function that calls fn to create vertices and then\n * creates a bufferInfo object for them\n * @private\n */\nfunction createBufferInfoFunc(fn) {\n return function(gl) {\n const arrays = fn.apply(null, Array.prototype.slice.call(arguments, 1));\n return attributes.createBufferInfoFromArrays(gl, arrays);\n };\n}\n\nconst arraySpecPropertyNames = [\n \"numComponents\",\n \"size\",\n \"type\",\n \"normalize\",\n \"stride\",\n \"offset\",\n \"attrib\",\n \"name\",\n \"attribName\",\n];\n\n/**\n * Copy elements from one array to another\n *\n * @param {Array|TypedArray} src source array\n * @param {Array|TypedArray} dst dest array\n * @param {number} dstNdx index in dest to copy src\n * @param {number} [offset] offset to add to copied values\n * @private\n */\nfunction copyElements(src, dst, dstNdx, offset) {\n offset = offset || 0;\n const length = src.length;\n for (let ii = 0; ii < length; ++ii) {\n dst[dstNdx + ii] = src[ii] + offset;\n }\n}\n\n/**\n * Creates an array of the same time\n *\n * @param {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} srcArray array who's type to copy\n * @param {number} length size of new array\n * @return {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} array with same type as srcArray\n * @private\n */\nfunction createArrayOfSameType(srcArray, length) {\n const arraySrc = getArray(srcArray);\n const newArray = new arraySrc.constructor(length);\n let newArraySpec = newArray;\n // If it appears to have been augmented make new one augmented\n if (arraySrc.numComponents && arraySrc.numElements) {\n augmentTypedArray(newArray, arraySrc.numComponents);\n }\n // If it was a full spec make new one a full spec\n if (srcArray.data) {\n newArraySpec = {\n data: newArray,\n };\n helper.copyNamedProperties(arraySpecPropertyNames, srcArray, newArraySpec);\n }\n return newArraySpec;\n}\n\n/**\n * Concatenates sets of vertices\n *\n * Assumes the vertices match in composition. For example\n * if one set of vertices has positions, normals, and indices\n * all sets of vertices must have positions, normals, and indices\n * and of the same type.\n *\n * Example:\n *\n * const cubeVertices = twgl.primitives.createCubeVertices(2);\n * const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10);\n * // move the sphere 2 units up\n * twgl.primitives.reorientVertices(\n * sphereVertices, twgl.m4.translation([0, 2, 0]));\n * // merge the sphere with the cube\n * const cubeSphereVertices = twgl.primitives.concatVertices(\n * [cubeVertices, sphereVertices]);\n * // turn them into WebGL buffers and attrib data\n * const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices);\n *\n * @param {module:twgl.Arrays[]} arrays Array of arrays of vertices\n * @return {module:twgl.Arrays} The concatenated vertices.\n * @memberOf module:twgl/primitives\n */\nfunction concatVertices(arrayOfArrays) {\n const names = {};\n let baseName;\n // get names of all arrays.\n // and numElements for each set of vertices\n for (let ii = 0; ii < arrayOfArrays.length; ++ii) {\n const arrays = arrayOfArrays[ii];\n Object.keys(arrays).forEach(function(name) { // eslint-disable-line\n if (!names[name]) {\n names[name] = [];\n }\n if (!baseName && name !== 'indices') {\n baseName = name;\n }\n const arrayInfo = arrays[name];\n const numComponents = getNumComponents(arrayInfo, name);\n const array = getArray(arrayInfo);\n const numElements = array.length / numComponents;\n names[name].push(numElements);\n });\n }\n\n // compute length of combined array\n // and return one for reference\n function getLengthOfCombinedArrays(name) {\n let length = 0;\n let arraySpec;\n for (let ii = 0; ii < arrayOfArrays.length; ++ii) {\n const arrays = arrayOfArrays[ii];\n const arrayInfo = arrays[name];\n const array = getArray(arrayInfo);\n length += array.length;\n if (!arraySpec || arrayInfo.data) {\n arraySpec = arrayInfo;\n }\n }\n return {\n length: length,\n spec: arraySpec,\n };\n }\n\n function copyArraysToNewArray(name, base, newArray) {\n let baseIndex = 0;\n let offset = 0;\n for (let ii = 0; ii < arrayOfArrays.length; ++ii) {\n const arrays = arrayOfArrays[ii];\n const arrayInfo = arrays[name];\n const array = getArray(arrayInfo);\n if (name === 'indices') {\n copyElements(array, newArray, offset, baseIndex);\n baseIndex += base[ii];\n } else {\n copyElements(array, newArray, offset);\n }\n offset += array.length;\n }\n }\n\n const base = names[baseName];\n\n const newArrays = {};\n Object.keys(names).forEach(function(name) {\n const info = getLengthOfCombinedArrays(name);\n const newArraySpec = createArrayOfSameType(info.spec, info.length);\n copyArraysToNewArray(name, base, getArray(newArraySpec));\n newArrays[name] = newArraySpec;\n });\n return newArrays;\n}\n\n/**\n * Creates a duplicate set of vertices\n *\n * This is useful for calling reorientVertices when you\n * also want to keep the original available\n *\n * @param {module:twgl.Arrays} arrays of vertices\n * @return {module:twgl.Arrays} The duplicated vertices.\n * @memberOf module:twgl/primitives\n */\nfunction duplicateVertices(arrays) {\n const newArrays = {};\n Object.keys(arrays).forEach(function(name) {\n const arraySpec = arrays[name];\n const srcArray = getArray(arraySpec);\n const newArraySpec = createArrayOfSameType(arraySpec, srcArray.length);\n copyElements(srcArray, getArray(newArraySpec), 0);\n newArrays[name] = newArraySpec;\n });\n return newArrays;\n}\n\nconst create3DFBufferInfo = createBufferInfoFunc(create3DFVertices);\nconst create3DFBuffers = createBufferFunc(create3DFVertices);\nconst createCubeBufferInfo = createBufferInfoFunc(createCubeVertices);\nconst createCubeBuffers = createBufferFunc(createCubeVertices);\nconst createPlaneBufferInfo = createBufferInfoFunc(createPlaneVertices);\nconst createPlaneBuffers = createBufferFunc(createPlaneVertices);\nconst createSphereBufferInfo = createBufferInfoFunc(createSphereVertices);\nconst createSphereBuffers = createBufferFunc(createSphereVertices);\nconst createTruncatedConeBufferInfo = createBufferInfoFunc(createTruncatedConeVertices);\nconst createTruncatedConeBuffers = createBufferFunc(createTruncatedConeVertices);\nconst createXYQuadBufferInfo = createBufferInfoFunc(createXYQuadVertices);\nconst createXYQuadBuffers = createBufferFunc(createXYQuadVertices);\nconst createCrescentBufferInfo = createBufferInfoFunc(createCrescentVertices);\nconst createCrescentBuffers = createBufferFunc(createCrescentVertices);\nconst createCylinderBufferInfo = createBufferInfoFunc(createCylinderVertices);\nconst createCylinderBuffers = createBufferFunc(createCylinderVertices);\nconst createTorusBufferInfo = createBufferInfoFunc(createTorusVertices);\nconst createTorusBuffers = createBufferFunc(createTorusVertices);\nconst createDiscBufferInfo = createBufferInfoFunc(createDiscVertices);\nconst createDiscBuffers = createBufferFunc(createDiscVertices);\n\n// these were mis-spelled until 4.12\nconst createCresentBufferInfo = createCrescentBufferInfo;\nconst createCresentBuffers = createCrescentBuffers;\nconst createCresentVertices = createCrescentVertices;\n\nexport {\n create3DFBufferInfo,\n create3DFBuffers,\n create3DFVertices,\n createAugmentedTypedArray,\n createCubeBufferInfo,\n createCubeBuffers,\n createCubeVertices,\n createPlaneBufferInfo,\n createPlaneBuffers,\n createPlaneVertices,\n createSphereBufferInfo,\n createSphereBuffers,\n createSphereVertices,\n createTruncatedConeBufferInfo,\n createTruncatedConeBuffers,\n createTruncatedConeVertices,\n createXYQuadBufferInfo,\n createXYQuadBuffers,\n createXYQuadVertices,\n createCresentBufferInfo,\n createCresentBuffers,\n createCresentVertices,\n createCrescentBufferInfo,\n createCrescentBuffers,\n createCrescentVertices,\n createCylinderBufferInfo,\n createCylinderBuffers,\n createCylinderVertices,\n createTorusBufferInfo,\n createTorusBuffers,\n createTorusVertices,\n createDiscBufferInfo,\n createDiscBuffers,\n createDiscVertices,\n deindexVertices,\n flattenNormals,\n makeRandomVertexColors,\n reorientDirections,\n reorientNormals,\n reorientPositions,\n reorientVertices,\n concatVertices,\n duplicateVertices,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level shader program related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.programs` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/programs\n */\n\nconst error = helper.error;\nconst warn = helper.warn;\nfunction getElementById(id) {\n return (typeof document !== 'undefined' && document.getElementById)\n ? document.getElementById(id)\n : null;\n}\n\nconst TEXTURE0 = 0x84c0;\nconst DYNAMIC_DRAW = 0x88e8;\n\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst UNIFORM_BUFFER = 0x8a11;\nconst TRANSFORM_FEEDBACK_BUFFER = 0x8c8e;\n\nconst TRANSFORM_FEEDBACK = 0x8e22;\n\nconst COMPILE_STATUS = 0x8b81;\nconst LINK_STATUS = 0x8b82;\nconst FRAGMENT_SHADER = 0x8b30;\nconst VERTEX_SHADER = 0x8b31;\nconst SEPARATE_ATTRIBS = 0x8c8d;\n\nconst ACTIVE_UNIFORMS = 0x8b86;\nconst ACTIVE_ATTRIBUTES = 0x8b89;\nconst TRANSFORM_FEEDBACK_VARYINGS = 0x8c83;\nconst ACTIVE_UNIFORM_BLOCKS = 0x8a36;\nconst UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44;\nconst UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46;\nconst UNIFORM_BLOCK_DATA_SIZE = 0x8a40;\nconst UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43;\n\nconst FLOAT = 0x1406;\nconst FLOAT_VEC2 = 0x8B50;\nconst FLOAT_VEC3 = 0x8B51;\nconst FLOAT_VEC4 = 0x8B52;\nconst INT = 0x1404;\nconst INT_VEC2 = 0x8B53;\nconst INT_VEC3 = 0x8B54;\nconst INT_VEC4 = 0x8B55;\nconst BOOL = 0x8B56;\nconst BOOL_VEC2 = 0x8B57;\nconst BOOL_VEC3 = 0x8B58;\nconst BOOL_VEC4 = 0x8B59;\nconst FLOAT_MAT2 = 0x8B5A;\nconst FLOAT_MAT3 = 0x8B5B;\nconst FLOAT_MAT4 = 0x8B5C;\nconst SAMPLER_2D = 0x8B5E;\nconst SAMPLER_CUBE = 0x8B60;\nconst SAMPLER_3D = 0x8B5F;\nconst SAMPLER_2D_SHADOW = 0x8B62;\nconst FLOAT_MAT2x3 = 0x8B65;\nconst FLOAT_MAT2x4 = 0x8B66;\nconst FLOAT_MAT3x2 = 0x8B67;\nconst FLOAT_MAT3x4 = 0x8B68;\nconst FLOAT_MAT4x2 = 0x8B69;\nconst FLOAT_MAT4x3 = 0x8B6A;\nconst SAMPLER_2D_ARRAY = 0x8DC1;\nconst SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;\nconst SAMPLER_CUBE_SHADOW = 0x8DC5;\nconst UNSIGNED_INT = 0x1405;\nconst UNSIGNED_INT_VEC2 = 0x8DC6;\nconst UNSIGNED_INT_VEC3 = 0x8DC7;\nconst UNSIGNED_INT_VEC4 = 0x8DC8;\nconst INT_SAMPLER_2D = 0x8DCA;\nconst INT_SAMPLER_3D = 0x8DCB;\nconst INT_SAMPLER_CUBE = 0x8DCC;\nconst INT_SAMPLER_2D_ARRAY = 0x8DCF;\nconst UNSIGNED_INT_SAMPLER_2D = 0x8DD2;\nconst UNSIGNED_INT_SAMPLER_3D = 0x8DD3;\nconst UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;\nconst UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;\n\nconst TEXTURE_2D = 0x0DE1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806F;\nconst TEXTURE_2D_ARRAY = 0x8C1A;\n\nconst typeMap = {};\n\n/**\n * Returns the corresponding bind point for a given sampler type\n * @private\n */\nfunction getBindPointForSamplerType(gl, type) {\n return typeMap[type].bindPoint;\n}\n\n// This kind of sucks! If you could compose functions as in `var fn = gl[name];`\n// this code could be a lot smaller but that is sadly really slow (T_T)\n\nfunction floatSetter(gl, location) {\n return function(v) {\n gl.uniform1f(location, v);\n };\n}\n\nfunction floatArraySetter(gl, location) {\n return function(v) {\n gl.uniform1fv(location, v);\n };\n}\n\nfunction floatVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2fv(location, v);\n };\n}\n\nfunction floatVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3fv(location, v);\n };\n}\n\nfunction floatVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4fv(location, v);\n };\n}\n\nfunction intSetter(gl, location) {\n return function(v) {\n gl.uniform1i(location, v);\n };\n}\n\nfunction intArraySetter(gl, location) {\n return function(v) {\n gl.uniform1iv(location, v);\n };\n}\n\nfunction intVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2iv(location, v);\n };\n}\n\nfunction intVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3iv(location, v);\n };\n}\n\nfunction intVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4iv(location, v);\n };\n}\n\nfunction uintSetter(gl, location) {\n return function(v) {\n gl.uniform1ui(location, v);\n };\n}\n\nfunction uintArraySetter(gl, location) {\n return function(v) {\n gl.uniform1uiv(location, v);\n };\n}\n\nfunction uintVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2uiv(location, v);\n };\n}\n\nfunction uintVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3uiv(location, v);\n };\n}\n\nfunction uintVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4uiv(location, v);\n };\n}\n\nfunction floatMat2Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2fv(location, false, v);\n };\n}\n\nfunction floatMat3Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3fv(location, false, v);\n };\n}\n\nfunction floatMat4Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4fv(location, false, v);\n };\n}\n\nfunction floatMat23Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x3fv(location, false, v);\n };\n}\n\nfunction floatMat32Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x2fv(location, false, v);\n };\n}\n\nfunction floatMat24Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x4fv(location, false, v);\n };\n}\n\nfunction floatMat42Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x2fv(location, false, v);\n };\n}\n\nfunction floatMat34Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x4fv(location, false, v);\n };\n}\n\nfunction floatMat43Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x3fv(location, false, v);\n };\n}\n\nfunction samplerSetter(gl, type, unit, location) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n return utils.isWebGL2(gl) ? function(textureOrPair) {\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n gl.bindSampler(unit, sampler);\n } : function(texture) {\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n };\n}\n\nfunction samplerArraySetter(gl, type, unit, location, size) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n const units = new Int32Array(size);\n for (let ii = 0; ii < size; ++ii) {\n units[ii] = unit + ii;\n }\n\n return utils.isWebGL2(gl) ? function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(textureOrPair, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.bindSampler(unit, sampler);\n gl.bindTexture(bindPoint, texture);\n });\n } : function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(texture, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n gl.bindTexture(bindPoint, texture);\n });\n };\n}\n\ntypeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, };\ntypeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, };\ntypeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, };\ntypeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, };\ntypeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, };\ntypeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, };\ntypeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, };\ntypeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, };\ntypeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, };\ntypeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, };\ntypeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, };\ntypeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, };\ntypeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, };\ntypeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, };\ntypeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, };\ntypeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, };\ntypeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, };\ntypeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\n\nfunction floatAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n switch (b.value.length) {\n case 4:\n gl.vertexAttrib4fv(index, b.value);\n break;\n case 3:\n gl.vertexAttrib3fv(index, b.value);\n break;\n case 2:\n gl.vertexAttrib2fv(index, b.value);\n break;\n case 1:\n gl.vertexAttrib1fv(index, b.value);\n break;\n default:\n throw new Error('the length of a float constant value must be between 1 and 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribPointer(\n index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction intAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4iv(index, b.value);\n } else {\n throw new Error('The length of an integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction uintAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4uiv(index, b.value);\n } else {\n throw new Error('The length of an unsigned integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction matAttribSetter(gl, index, typeInfo) {\n const defaultSize = typeInfo.size;\n const count = typeInfo.count;\n\n return function(b) {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n const numComponents = b.size || b.numComponents || defaultSize;\n const size = numComponents / count;\n const type = b.type || FLOAT;\n const typeInfo = typeMap[type];\n const stride = typeInfo.size * numComponents;\n const normalize = b.normalize || false;\n const offset = b.offset || 0;\n const rowOffset = stride / count;\n for (let i = 0; i < count; ++i) {\n gl.enableVertexAttribArray(index + i);\n gl.vertexAttribPointer(\n index + i, size, type, normalize, stride, offset + rowOffset * i);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index + i, b.divisor || 0);\n }\n }\n };\n}\n\n\n\nconst attrTypeMap = {};\nattrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, };\nattrTypeMap[INT] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, };\nattrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, };\nattrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, };\nattrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, };\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst errorRE = /ERROR:\\s*\\d+:(\\d+)/gi;\nfunction addLineNumbersWithError(src, log = '', lineOffset = 0) {\n // Note: Error message formats are not defined by any spec so this may or may not work.\n const matches = [...log.matchAll(errorRE)];\n const lineNoToErrorMap = new Map(matches.map((m, ndx) => {\n const lineNo = parseInt(m[1]);\n const next = matches[ndx + 1];\n const end = next ? next.index : log.length;\n const msg = log.substring(m.index, end);\n return [lineNo - 1, msg];\n }));\n return src.split('\\n').map((line, lineNo) => {\n const err = lineNoToErrorMap.get(lineNo);\n return `${lineNo + 1 + lineOffset}: ${line}${err ? `\\n\\n^^^ ${err}` : ''}`;\n }).join('\\n');\n}\n\n/**\n * Error Callback\n * @callback ErrorCallback\n * @param {string} msg error message.\n * @param {number} [lineOffset] amount to add to line number\n * @memberOf module:twgl\n */\n\n/**\n * Program Callback\n * @callback ProgramCallback\n * @param {string} [err] error message, falsy if no error\n * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo\n */\n\nconst spaceRE = /^[ \\t]*\\n/;\n\n/**\n * Remove the first end of line because WebGL 2.0 requires\n * #version 300 es\n * as the first line. No whitespace allowed before that line\n * so\n *\n * \n *\n * Has one line before it which is invalid according to GLSL ES 3.00\n *\n * @param {string} shaderSource The source of the shader\n * @returns {{shaderSource: string, lineOffset: number}}\n * @private\n */\nfunction prepShaderSource(shaderSource) {\n let lineOffset = 0;\n if (spaceRE.test(shaderSource)) {\n lineOffset = 1;\n shaderSource = shaderSource.replace(spaceRE, '');\n }\n return {lineOffset, shaderSource};\n}\n\n/**\n * @param {module:twgl.ProgramOptions} progOptions\n * @param {string} msg\n * @return null\n * @private\n */\nfunction reportError(progOptions, msg) {\n progOptions.errorCallback(msg);\n if (progOptions.callback) {\n setTimeout(() => {\n progOptions.callback(`${msg}\\n${progOptions.errors.join('\\n')}`);\n });\n }\n return null;\n}\n\n/**\n * Check Shader status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {number} shaderType The shader type\n * @param {WebGLShader} shader The shader\n * @param {ErrorCallback} [errFn] function to receive error message.\n * @return {string} errors or empty string\n * @private\n */\nfunction checkShaderStatus(gl, shaderType, shader, errFn) {\n errFn = errFn || error;\n // Check the compile status\n const compiled = gl.getShaderParameter(shader, COMPILE_STATUS);\n if (!compiled) {\n // Something went wrong during compilation; get the error\n const lastError = gl.getShaderInfoLog(shader);\n const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader));\n const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\\nError compiling ${utils.glEnumToString(gl, shaderType)}: ${lastError}`;\n errFn(error);\n return error;\n }\n return '';\n}\n\n/**\n * @typedef {Object} FullProgramSpec\n * @property {string[]} shaders the shader source or element ids.\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {Object} ProgramOptions\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * Gets the program options based on all these optional arguments\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in\n * @private\n */\nfunction getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) {\n let transformFeedbackVaryings;\n let transformFeedbackMode;\n let callback;\n if (typeof opt_locations === 'function') {\n opt_errorCallback = opt_locations;\n opt_locations = undefined;\n }\n if (typeof opt_attribs === 'function') {\n opt_errorCallback = opt_attribs;\n opt_attribs = undefined;\n } else if (opt_attribs && !Array.isArray(opt_attribs)) {\n const opt = opt_attribs;\n opt_errorCallback = opt.errorCallback;\n opt_attribs = opt.attribLocations;\n transformFeedbackVaryings = opt.transformFeedbackVaryings;\n transformFeedbackMode = opt.transformFeedbackMode;\n callback = opt.callback;\n }\n\n const errorCallback = opt_errorCallback || error;\n const errors = [];\n const options = {\n errorCallback(msg, ...args) {\n errors.push(msg);\n errorCallback(msg, ...args);\n },\n transformFeedbackVaryings,\n transformFeedbackMode,\n callback,\n errors,\n };\n\n {\n let attribLocations = {};\n if (Array.isArray(opt_attribs)) {\n opt_attribs.forEach(function(attrib, ndx) {\n attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx;\n });\n } else {\n attribLocations = opt_attribs || {};\n }\n options.attribLocations = attribLocations;\n }\n\n return options;\n}\n\nconst defaultShaderType = [\n \"VERTEX_SHADER\",\n \"FRAGMENT_SHADER\",\n];\n\nfunction getShaderTypeFromScriptType(gl, scriptType) {\n if (scriptType.indexOf(\"frag\") >= 0) {\n return FRAGMENT_SHADER;\n } else if (scriptType.indexOf(\"vert\") >= 0) {\n return VERTEX_SHADER;\n }\n return undefined;\n}\n\nfunction deleteProgramAndShaders(gl, program, notThese) {\n const shaders = gl.getAttachedShaders(program);\n for (const shader of shaders) {\n if (notThese.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n gl.deleteProgram(program);\n}\n\nconst wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));\n\nfunction createProgramNoCheck(gl, shaders, programOptions) {\n const program = gl.createProgram();\n const {\n attribLocations,\n transformFeedbackVaryings,\n transformFeedbackMode,\n } = getProgramOptions(programOptions);\n\n for (let ndx = 0; ndx < shaders.length; ++ndx) {\n let shader = shaders[ndx];\n if (typeof shader === 'string') {\n const elem = getElementById(shader);\n const src = elem ? elem.text : shader;\n let type = gl[defaultShaderType[ndx]];\n if (elem && elem.type) {\n type = getShaderTypeFromScriptType(gl, elem.type) || type;\n }\n shader = gl.createShader(type);\n gl.shaderSource(shader, prepShaderSource(src).shaderSource);\n gl.compileShader(shader);\n gl.attachShader(program, shader);\n }\n }\n\n Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib));\n\n {\n let varyings = transformFeedbackVaryings;\n if (varyings) {\n if (varyings.attribs) {\n varyings = varyings.attribs;\n }\n if (!Array.isArray(varyings)) {\n varyings = Object.keys(varyings);\n }\n gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS);\n }\n }\n\n gl.linkProgram(program);\n return program;\n}\n\n/**\n * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the\n * program.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgram(gl, [vs, fs], options);\n * twgl.createProgram(gl, [vs, fs], opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error of a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgram(\n gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {\n // This code is really convoluted, because it may or may not be async\n // Maybe it would be better to have a separate function\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaderSet = new Set(shaders);\n const program = createProgramNoCheck(gl, shaders, progOptions);\n\n function hasErrors(gl, program) {\n const errors = getProgramErrors(gl, program, progOptions.errorCallback);\n if (errors) {\n deleteProgramAndShaders(gl, program, shaderSet);\n }\n return errors;\n }\n\n if (progOptions.callback) {\n waitForProgramLinkCompletionAsync(gl, program).then(() => {\n const errors = hasErrors(gl, program);\n progOptions.callback(errors, errors ? undefined : program);\n });\n return undefined;\n }\n\n return hasErrors(gl, program) ? undefined : program;\n}\n\n/**\n * This only works because the functions it wraps the first 2 arguments\n * are gl and any, followed by things that become programOptions\n * @private\n */\nfunction wrapCallbackFnToAsyncFn(fn) {\n return function(gl, arg1, ...args) {\n return new Promise((resolve, reject) => {\n const programOptions = getProgramOptions(...args);\n programOptions.callback = (err, program) => {\n if (err) {\n reject(err);\n } else {\n resolve(program);\n }\n };\n fn(gl, arg1, programOptions);\n });\n };\n}\n\n/**\n * Same as createProgram but returns a promise\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramAsync(gl, [vs, fs], options);\n * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created program\n * @memberOf module:twgl/programs\n */\nconst createProgramAsync = wrapCallbackFnToAsyncFn(createProgram);\n\n/**\n * Same as createProgramInfo but returns a promise\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created ProgramInfo\n * @memberOf module:twgl/programs\n */\nconst createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo);\n\nasync function waitForProgramLinkCompletionAsync(gl, program) {\n const ext = gl.getExtension('KHR_parallel_shader_compile');\n const checkFn = ext\n ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR)\n : () => true;\n\n let waitTime = 0;\n do {\n await wait(waitTime); // must wait at least once\n waitTime = 1000 / 60;\n } while (!checkFn(gl, program));\n}\n\nasync function waitForAllProgramsLinkCompletionAsync(gl, programs) {\n for (const program of Object.values(programs)) {\n await waitForProgramLinkCompletionAsync(gl, program);\n }\n}\n\n/**\n * Check a program's link status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program Program to check\n * @param {ErrorCallback} [errFn] func for errors\n * @return {string?} errors if program is failed, else undefined\n * @private\n */\nfunction getProgramErrors(gl, program, errFn) {\n errFn = errFn || error;\n // Check the link status\n const linked = gl.getProgramParameter(program, LINK_STATUS);\n if (!linked) {\n // something went wrong with the link\n const lastError = gl.getProgramInfoLog(program);\n errFn(`Error in program linking: ${lastError}`);\n // print any errors from these shaders\n const shaders = gl.getAttachedShaders(program);\n const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn));\n return `${lastError}\\n${errors.filter(_ => _).join('\\n')}`;\n }\n return undefined;\n}\n\n/**\n * Creates a program from 2 script tags.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_options);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderScriptIds Array of ids of the script\n * tags for the shaders. The first is assumed to be the\n * vertex shader, the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromScripts(\n gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaders = [];\n for (const scriptId of shaderScriptIds) {\n const shaderScript = getElementById(scriptId);\n if (!shaderScript) {\n return reportError(progOptions, `unknown script element: ${scriptId}`);\n }\n shaders.push(shaderScript.text);\n }\n return createProgram(gl, shaders, progOptions);\n}\n\n/**\n * Creates a program from 2 sources.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromSource(gl, [vs, fs], opt_options);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromSources(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback);\n}\n\n/**\n * Returns true if attribute/uniform is a reserved/built in\n *\n * It makes no sense to me why GL returns these because it's\n * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation`\n * with names that start with `gl_` (and `webgl_` in WebGL)\n *\n * I can only assume they are there because they might count\n * when computing the number of uniforms/attributes used when you want to\n * know if you are near the limit. That doesn't really make sense\n * to me but the fact that these get returned are in the spec.\n *\n * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or\n * `gl.getActiveAttrib`.\n * @return {bool} true if it's reserved\n * @private\n */\nfunction isBuiltIn(info) {\n const name = info.name;\n return name.startsWith(\"gl_\") || name.startsWith(\"webgl_\");\n}\n\nconst tokenRE = /(\\.|\\[|]|\\w+)/g;\nconst isDigit = s => s >= '0' && s <= '9';\nfunction addSetterToUniformTree(fullPath, setter, node, uniformSetters) {\n const tokens = fullPath.split(tokenRE).filter(s => s !== '');\n let tokenNdx = 0;\n let path = '';\n\n for (;;) {\n const token = tokens[tokenNdx++]; // has to be name or number\n path += token;\n const isArrayIndex = isDigit(token[0]);\n const accessor = isArrayIndex\n ? parseInt(token)\n : token;\n if (isArrayIndex) {\n path += tokens[tokenNdx++]; // skip ']'\n }\n const isLastToken = tokenNdx === tokens.length;\n if (isLastToken) {\n node[accessor] = setter;\n break;\n } else {\n const token = tokens[tokenNdx++]; // has to be . or [\n const isArray = token === '[';\n const child = node[accessor] || (isArray ? [] : {});\n node[accessor] = child;\n node = child;\n uniformSetters[path] = uniformSetters[path] || function(node) {\n return function(value) {\n setUniformTree(node, value);\n };\n }(child);\n path += token;\n }\n }\n}\n\n/**\n * Creates setter functions for all uniforms of a shader\n * program.\n *\n * @see {@link module:twgl.setUniforms}\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @returns {Object.} an object with a setter by name for each uniform\n * @memberOf module:twgl/programs\n */\nfunction createUniformSetters(gl, program) {\n let textureUnit = 0;\n\n /**\n * Creates a setter for a uniform of the given program with it's\n * location embedded in the setter.\n * @param {WebGLProgram} program\n * @param {WebGLUniformInfo} uniformInfo\n * @returns {function} the created setter.\n */\n function createUniformSetter(program, uniformInfo, location) {\n const isArray = uniformInfo.name.endsWith(\"[0]\");\n const type = uniformInfo.type;\n const typeInfo = typeMap[type];\n if (!typeInfo) {\n throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here.\n }\n let setter;\n if (typeInfo.bindPoint) {\n // it's a sampler\n const unit = textureUnit;\n textureUnit += uniformInfo.size;\n if (isArray) {\n setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size);\n } else {\n setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size);\n }\n } else {\n if (typeInfo.arraySetter && isArray) {\n setter = typeInfo.arraySetter(gl, location);\n } else {\n setter = typeInfo.setter(gl, location);\n }\n }\n setter.location = location;\n return setter;\n }\n\n const uniformSetters = {};\n const uniformTree = {};\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n const uniformInfo = gl.getActiveUniform(program, ii);\n if (isBuiltIn(uniformInfo)) {\n continue;\n }\n let name = uniformInfo.name;\n // remove the array suffix.\n if (name.endsWith(\"[0]\")) {\n name = name.substr(0, name.length - 3);\n }\n const location = gl.getUniformLocation(program, uniformInfo.name);\n // the uniform will have no location if it's in a uniform block\n if (location) {\n const setter = createUniformSetter(program, uniformInfo, location);\n uniformSetters[name] = setter;\n addSetterToUniformTree(name, setter, uniformTree, uniformSetters);\n }\n }\n\n return uniformSetters;\n}\n\n/**\n * @typedef {Object} TransformFeedbackInfo\n * @property {number} index index of transform feedback\n * @property {number} type GL type\n * @property {number} size 1 - 4\n * @memberOf module:twgl\n */\n\n/**\n * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo.\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {Object}\n * @memberOf module:twgl\n */\nfunction createTransformFeedbackInfo(gl, program) {\n const info = {};\n const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS);\n for (let ii = 0; ii < numVaryings; ++ii) {\n const varying = gl.getTransformFeedbackVarying(program, ii);\n info[varying.name] = {\n index: ii,\n type: varying.type,\n size: varying.size,\n };\n }\n return info;\n}\n\n/**\n * Binds buffers for transform feedback.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo.\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @memberOf module:twgl\n */\nfunction bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) {\n if (transformFeedbackInfo.transformFeedbackInfo) {\n transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo;\n }\n if (bufferInfo.attribs) {\n bufferInfo = bufferInfo.attribs;\n }\n for (const name in bufferInfo) {\n const varying = transformFeedbackInfo[name];\n if (varying) {\n const buf = bufferInfo[name];\n if (buf.offset) {\n gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size);\n } else {\n gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer);\n }\n }\n }\n}\n\n/**\n * Creates a transform feedback and sets the buffers\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @return {WebGLTransformFeedback} the created transform feedback\n * @memberOf module:twgl\n */\nfunction createTransformFeedback(gl, programInfo, bufferInfo) {\n const tf = gl.createTransformFeedback();\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf);\n gl.useProgram(programInfo.program);\n bindTransformFeedbackInfo(gl, programInfo, bufferInfo);\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null);\n return tf;\n}\n\n/**\n * @typedef {Object} UniformData\n * @property {string} name The name of the uniform\n * @property {number} type The WebGL type enum for this uniform\n * @property {number} size The number of elements for this uniform\n * @property {number} blockNdx The block index this uniform appears in\n * @property {number} offset The byte offset in the block for this uniform's value\n * @memberOf module:twgl\n */\n\n/**\n * The specification for one UniformBlockObject\n *\n * @typedef {Object} BlockSpec\n * @property {number} index The index of the block.\n * @property {number} size The size in bytes needed for the block\n * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices\n * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}.\n * @property {bool} usedByVertexShader Self explanatory\n * @property {bool} usedByFragmentShader Self explanatory\n * @property {bool} used Self explanatory\n * @memberOf module:twgl\n */\n\n/**\n * A `UniformBlockSpec` represents the data needed to create and bind\n * UniformBlockObjects for a given program\n *\n * @typedef {Object} UniformBlockSpec\n * @property {Object.} blockSpecs The BlockSpec for each block by block name\n * @property {UniformData[]} uniformData An array of data for each uniform by uniform index.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a UniformBlockSpec for the given program.\n *\n * A UniformBlockSpec represents the data needed to create and bind\n * UniformBlockObjects\n *\n * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context\n * @param {WebGLProgram} program A WebGLProgram for a successfully linked program\n * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockSpecFromProgram(gl, program) {\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n const uniformData = [];\n const uniformIndices = [];\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n uniformIndices.push(ii);\n uniformData.push({});\n const uniformInfo = gl.getActiveUniform(program, ii);\n uniformData[ii].name = uniformInfo.name;\n }\n\n [\n [ \"UNIFORM_TYPE\", \"type\" ],\n [ \"UNIFORM_SIZE\", \"size\" ], // num elements\n [ \"UNIFORM_BLOCK_INDEX\", \"blockNdx\" ],\n [ \"UNIFORM_OFFSET\", \"offset\", ],\n ].forEach(function(pair) {\n const pname = pair[0];\n const key = pair[1];\n gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) {\n uniformData[ndx][key] = value;\n });\n });\n\n const blockSpecs = {};\n\n const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS);\n for (let ii = 0; ii < numUniformBlocks; ++ii) {\n const name = gl.getActiveUniformBlockName(program, ii);\n const blockSpec = {\n index: gl.getUniformBlockIndex(program, name),\n usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER),\n usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER),\n size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE),\n uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES),\n };\n blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader;\n blockSpecs[name] = blockSpec;\n }\n\n return {\n blockSpecs: blockSpecs,\n uniformData: uniformData,\n };\n}\n\nconst arraySuffixRE = /\\[\\d+\\]\\.$/; // better way to check?\n\nconst pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding;\n\nfunction createUniformBlockUniformSetter(view, isArray, rows, cols) {\n if (isArray || rows) {\n cols = cols || 1;\n const numElements = view.length;\n const totalRows = numElements / 4;\n return function(value) {\n let dst = 0;\n let src = 0;\n for (let row = 0; row < totalRows; ++row) {\n for (let col = 0; col < cols; ++col) {\n view[dst++] = value[src++];\n }\n dst += 4 - cols;\n }\n };\n } else {\n return function(value) {\n if (value.length) {\n view.set(value);\n } else {\n view[0] = value;\n }\n };\n }\n}\n\n/**\n * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values\n * and a corresponding WebGLBuffer to hold those values on the GPU\n *\n * @typedef {Object} UniformBlockInfo\n * @property {string} name The name of the block\n * @property {ArrayBuffer} array The array buffer that contains the uniform values\n * @property {Float32Array} asFloat A float view on the array buffer. This is useful\n * inspecting the contents of the buffer in the debugger.\n * @property {Uint8Array} asUint8t A uint8 view on the array buffer.\n * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering.\n * @property {number} [offset] offset into buffer\n * @property {Object} uniforms A uniform name to ArrayBufferView map.\n * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset\n * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array`\n * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an\n * `Int32Array` view, etc.\n * @property {Object} setters A setter for this uniform.\n * The reason to use setters is elements of arrays are padded to vec4 sizes which\n * means if you want to set an array of 4 floats you'd need to set 16 values\n * (or set elements 0, 4, 8, 12). In other words\n * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])`\n * where as the setter handles just passing in [0, 1, 2, 3] either directly as in\n * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended)\n * or via {@link module:twgl.setBlockUniforms}\n * @memberOf module:twgl\n */\n\n/**\n * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset\n * @typedef {Object} UniformBlockInfoOptions\n * @property {ArrayBuffer} [array] an existing array buffer to use for values\n * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0)\n * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info\n * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above)\n */\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {WebGLProgram} program A WebGLProgram\n * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned\n * from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) {\n const blockSpecs = uniformBlockSpec.blockSpecs;\n const uniformData = uniformBlockSpec.uniformData;\n const blockSpec = blockSpecs[blockName];\n if (!blockSpec) {\n warn(\"no uniform block object named:\", blockName);\n return {\n name: blockName,\n uniforms: {},\n };\n }\n const offset = options.offset ?? 0;\n const array = options.array ?? new ArrayBuffer(blockSpec.size);\n const buffer = options.buffer ?? gl.createBuffer();\n const uniformBufferIndex = blockSpec.index;\n gl.bindBuffer(UNIFORM_BUFFER, buffer);\n if (!options.buffer) {\n gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW);\n }\n gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex);\n\n let prefix = blockName + \".\";\n if (arraySuffixRE.test(prefix)) {\n prefix = prefix.replace(arraySuffixRE, \".\");\n }\n const uniforms = {};\n const setters = {};\n const setterTree = {};\n blockSpec.uniformIndices.forEach(function(uniformNdx) {\n const data = uniformData[uniformNdx];\n let name = data.name;\n if (name.startsWith(prefix)) {\n name = name.substr(prefix.length);\n }\n const isArray = name.endsWith('[0]');\n if (isArray) {\n name = name.substr(0, name.length - 3);\n }\n const typeInfo = typeMap[data.type];\n const Type = typeInfo.Type;\n const byteLength = isArray\n ? pad(typeInfo.size, 16) * data.size\n : typeInfo.size * data.size;\n const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT);\n uniforms[name] = uniformView;\n // Note: I'm not sure what to do here. The original\n // idea was to create TypedArray views into each part\n // of the block. This is useful, for example if you have\n // a block with { mat4: model; mat4 view; mat4 projection; }\n // you'll get a Float32Array for each one suitable for\n // passing to most JS math libraries including twgl's and glMatrix.js.\n //\n // But, if you have a an array of structures, especially if that\n // array is large, you get a whole bunch of TypedArray views.\n // Every one of them has overhead and switching between them all\n // is probably a cache miss. In that case it would really be better\n // to just have one view (asFloat) and have all the setters\n // just reference the correct portion. But, then you can't easily\n // treat a matrix, or a vec4, as a standalone thing like you can\n // with all the views.\n //\n // Another problem with the views is they are not shared. With\n // uniforms you have one set of setters. With UniformBlockInfo\n // you have a set of setters *pre block instance*. That's because\n // TypedArray views can't be mapped to different buffers.\n //\n // My gut right now is if you really want the speed and compactness\n // then you should probably roll your own solution. TWGL's goal\n // here is ease of use as AFAICT there is no simple generic efficient\n // solution.\n const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols);\n setters[name] = setter;\n addSetterToUniformTree(name, setter, setterTree, setters);\n });\n return {\n name: blockName,\n array,\n asFloat: new Float32Array(array), // for debugging\n asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer\n buffer,\n uniforms,\n setters,\n offset: options.bufferOffset ?? offset,\n size: blockSpec.size,\n };\n}\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo}\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfo(gl, programInfo, blockName, options = {}) {\n return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options);\n}\n\n/**\n * Binds a uniform block to the matching uniform block point.\n * Matches by blocks by name so blocks must have the same name not just the same\n * structure.\n *\n * If you have changed any values and you upload the values into the corresponding WebGLBuffer\n * call {@link module:twgl.setUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name\n * no buffer is bound.\n * @memberOf module:twgl/programs\n */\nfunction bindUniformBlock(gl, programInfo, uniformBlockInfo) {\n const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo;\n const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name];\n if (blockSpec) {\n const bufferBindIndex = blockSpec.index;\n gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength);\n return true;\n }\n return false;\n}\n\n/**\n * Uploads the current uniform values to the corresponding WebGLBuffer\n * and binds that buffer to the program's corresponding bind point for the uniform block object.\n *\n * If you haven't changed any values and you only need to bind the uniform block object\n * call {@link module:twgl.bindUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @memberOf module:twgl/programs\n */\nfunction setUniformBlock(gl, programInfo, uniformBlockInfo) {\n if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) {\n gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0);\n }\n}\n\n/**\n * Sets values of a uniform block object\n *\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}.\n * @param {Object.} values A uniform name to value map where the value is correct for the given\n * type of uniform. So for example given a block like\n *\n * uniform SomeBlock {\n * float someFloat;\n * vec2 someVec2;\n * vec3 someVec3Array[2];\n * int someInt;\n * }\n *\n * You can set the values of the uniform block with\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * someFloat: 12.3,\n * someVec2: [1, 2],\n * someVec3Array: [1, 2, 3, 4, 5, 6],\n * someInt: 5,\n * }\n *\n * Arrays can be JavaScript arrays or typed arrays\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Lights {\n * Light lights[2];\n * };\n *\n * // in JavaScript\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices.\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * **IMPORTANT!**, packing in a UniformBlock is unintuitive.\n * For example the actual layout of `someVec3Array` above in memory\n * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values\n * as shown about and copies them, skipping the padding. This might\n * be confusing if you're already familiar with Uniform blocks.\n *\n * If you want to deal with the padding yourself you can access the array\n * buffer views directly. eg:\n *\n * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]);\n *\n * Any name that doesn't match will be ignored\n * @memberOf module:twgl/programs\n */\nfunction setBlockUniforms(uniformBlockInfo, values) {\n const setters = uniformBlockInfo.setters;\n for (const name in values) {\n const setter = setters[name];\n if (setter) {\n const value = values[name];\n setter(value);\n }\n }\n}\n\nfunction setUniformTree(tree, values) {\n for (const name in values) {\n const prop = tree[name];\n if (typeof prop === 'function') {\n prop(values[name]);\n } else {\n setUniformTree(tree[name], values[name]);\n }\n }\n}\n\n/**\n * Set uniforms and binds related textures.\n *\n * example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\"]);\n *\n * const tex1 = gl.createTexture();\n * const tex2 = gl.createTexture();\n *\n * ... assume we setup the textures with data ...\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the textures AND set the\n * uniforms.\n *\n * twgl.setUniforms(programInfo, uniforms);\n *\n * For the example above it is equivalent to\n *\n * let texUnit = 0;\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex1);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex2);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);\n * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);\n * gl.uniformMatrix4fv(u_someMatrix, false, [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ]);\n *\n * Note it is perfectly reasonable to call `setUniforms` multiple times. For example\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * };\n *\n * const moreUniforms {\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * twgl.setUniforms(programInfo, uniforms);\n * twgl.setUniforms(programInfo, moreUniforms);\n *\n * You can also add WebGLSamplers to uniform samplers as in\n *\n * const uniforms = {\n * u_someSampler: {\n * texture: someWebGLTexture,\n * sampler: someWebGLSampler,\n * },\n * };\n *\n * In which case both the sampler and texture will be bound to the\n * same unit.\n *\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * uniforms.\n * You can pass multiple objects by putting them in an array or by calling with more arguments.For example\n *\n * const sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * const localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * twgl.setUniforms(programInfo, sharedUniforms, localUniforms);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, sharedUniforms);\n * twgl.setUniforms(programInfo, localUniforms};\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Light lights[2];\n *\n * // in JavaScript\n *\n * twgl.setUniforms(programInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setUniforms(programInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * @memberOf module:twgl/programs\n */\nfunction setUniforms(setters, ...args) { // eslint-disable-line\n const actualSetters = setters.uniformSetters || setters;\n const numArgs = args.length;\n for (let aNdx = 0; aNdx < numArgs; ++aNdx) {\n const values = args[aNdx];\n if (Array.isArray(values)) {\n const numValues = values.length;\n for (let ii = 0; ii < numValues; ++ii) {\n setUniforms(actualSetters, values[ii]);\n }\n } else {\n for (const name in values) {\n const setter = actualSetters[name];\n if (setter) {\n setter(values[name]);\n }\n }\n }\n }\n}\n\n/**\n * Alias for `setUniforms`\n * @function\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * @memberOf module:twgl/programs\n */\nconst setUniformsAndBindTextures = setUniforms;\n\n/**\n * Creates setter functions for all attributes of a shader\n * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes.\n *\n * @see {@link module:twgl.setAttributes} for example\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @return {Object.} an object with a setter for each attribute by name.\n * @memberOf module:twgl/programs\n */\nfunction createAttributeSetters(gl, program) {\n const attribSetters = {\n };\n\n const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES);\n for (let ii = 0; ii < numAttribs; ++ii) {\n const attribInfo = gl.getActiveAttrib(program, ii);\n if (isBuiltIn(attribInfo)) {\n continue;\n }\n const index = gl.getAttribLocation(program, attribInfo.name);\n const typeInfo = attrTypeMap[attribInfo.type];\n const setter = typeInfo.setter(gl, index, typeInfo);\n setter.location = index;\n attribSetters[attribInfo.name] = setter;\n }\n\n return attribSetters;\n}\n\n/**\n * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes})\n *\n * Example:\n *\n * const program = createProgramFromScripts(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const attribSetters = createAttributeSetters(program);\n *\n * const positionBuffer = gl.createBuffer();\n * const texcoordBuffer = gl.createBuffer();\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * };\n *\n * gl.useProgram(program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setAttributes(attribSetters, attribs);\n *\n * Properties of attribs. For each attrib you can add\n * properties:\n *\n * * type: the type of data in the buffer. Default = gl.FLOAT\n * * normalize: whether or not to normalize the data. Default = false\n * * stride: the stride. Default = 0\n * * offset: offset into the buffer. Default = 0\n * * divisor: the divisor for instances. Default = undefined\n *\n * For example if you had 3 value float positions, 2 value\n * float texcoord and 4 value uint8 colors you'd setup your\n * attribs like this\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * a_color: {\n * buffer: colorBuffer,\n * numComponents: 4,\n * type: gl.UNSIGNED_BYTE,\n * normalize: true,\n * },\n * };\n *\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} buffers AttribInfos mapped by attribute name.\n * @memberOf module:twgl/programs\n * @deprecated use {@link module:twgl.setBuffersAndAttributes}\n * @private\n */\nfunction setAttributes(setters, buffers) {\n for (const name in buffers) {\n const setter = setters[name];\n if (setter) {\n setter(buffers[name]);\n }\n }\n}\n\n/**\n * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate\n *\n * Example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * };\n *\n * const bufferInfo = createBufferInfoFromArrays(gl, arrays);\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setBuffersAndAttributes(gl, programInfo, bufferInfo);\n *\n * For the example above it is equivalent to\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n * gl.enableVertexAttribArray(a_positionLocation);\n * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0);\n * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);\n * gl.enableVertexAttribArray(a_texcoordLocation);\n * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters}\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}.\n * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo}\n * @memberOf module:twgl/programs\n */\nfunction setBuffersAndAttributes(gl, programInfo, buffers) {\n if (buffers.vertexArrayObject) {\n gl.bindVertexArray(buffers.vertexArrayObject);\n } else {\n setAttributes(programInfo.attribSetters || programInfo, buffers.attribs);\n if (buffers.indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices);\n }\n }\n}\n\n/**\n * @typedef {Object} ProgramInfo\n * @property {WebGLProgram} program A shader program\n * @property {Object} uniformLocations The uniform locations of each uniform\n * @property {Object} attribLocations The locations of each attribute\n * @property {Object} uniformSetters object of setters as returned from createUniformSetters,\n * @property {Object} attribSetters object of setters as returned from createAttribSetters,\n * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc..\n * @property {Object} [transformFeedbackInfo] info for transform feedbacks\n * @memberOf module:twgl\n */\n\n/**\n * Creates a ProgramInfo from an existing program.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {module:twgl.ProgramInfo} The created ProgramInfo.\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfoFromProgram(gl, program) {\n const uniformSetters = createUniformSetters(gl, program);\n const attribSetters = createAttributeSetters(gl, program);\n const programInfo = {\n program,\n uniformSetters,\n attribSetters,\n uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])),\n attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])),\n };\n\n if (utils.isWebGL2(gl)) {\n programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program);\n programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program);\n }\n\n return programInfo;\n}\n\nconst notIdRE = /\\s|{|}|;/;\n\n/**\n * Creates a ProgramInfo from 2 sources.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramInfo(gl, [vs, fs], options);\n * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfo(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const errors = [];\n shaderSources = shaderSources.map(function(source) {\n // Lets assume if there is no \\n it's an id\n if (!notIdRE.test(source)) {\n const script = getElementById(source);\n if (!script) {\n const err = `no element with id: ${source}`;\n progOptions.errorCallback(err);\n errors.push(err);\n } else {\n source = script.text;\n }\n }\n return source;\n });\n\n if (errors.length) {\n return reportError(progOptions, '');\n }\n\n const origCallback = progOptions.callback;\n if (origCallback) {\n progOptions.callback = (err, program) => {\n origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program));\n };\n }\n\n const program = createProgramFromSources(gl, shaderSources, progOptions);\n if (!program) {\n return null;\n }\n\n return createProgramInfoFromProgram(gl, program);\n}\n\nfunction checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) {\n // check errors for everything.\n for (const [name, program] of Object.entries(programs)) {\n const options = {...programOptions};\n const spec = programSpecs[name];\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n const errors = getProgramErrors(gl, program, options.errorCallback);\n if (errors) {\n // delete everything we created\n for (const program of Object.values(programs)) {\n const shaders = gl.getAttachedShaders(program);\n gl.deleteProgram(program);\n for (const shader of shaders) {\n // Don't delete it if we didn't create it.\n if (!noDeleteShadersSet.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n }\n return errors;\n }\n }\n\n return undefined;\n}\n\n/**\n * Creates multiple programs\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgram}\n *\n * Example:\n *\n * const programs = twgl.createPrograms(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createPrograms(gl, programSpecs, programOptions = {}) {\n // Remember existing shaders so that if there is an error we don't delete them\n const noDeleteShadersSet = new Set();\n\n // compile and link everything\n const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => {\n const options = {...programOptions};\n const shaders = Array.isArray(spec) ? spec : spec.shaders;\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet);\n return [name, createProgramNoCheck(gl, shaders, options)];\n }));\n\n if (programOptions.callback) {\n waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => {\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n programOptions.callback(errors, errors ? undefined : programs);\n });\n return undefined;\n }\n\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n return errors ? undefined : programs;\n}\n\n/**\n * Creates multiple programInfos\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgramInfo}\n *\n * Examples:\n *\n * const programInfos = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * or\n *\n * const {lambert, phong, particles} = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createProgramInfos(gl, programSpecs, programOptions) {\n programOptions = getProgramOptions(programOptions);\n\n function createProgramInfosForPrograms(gl, programs) {\n return Object.fromEntries(Object.entries(programs).map(([name, program]) =>\n [name, createProgramInfoFromProgram(gl, program)]\n ));\n }\n\n const origCallback = programOptions.callback;\n if (origCallback) {\n programOptions.callback = (err, programs) => {\n origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs));\n };\n }\n\n const programs = createPrograms(gl, programSpecs, programOptions);\n if (origCallback || !programs) {\n return undefined;\n }\n\n return createProgramInfosForPrograms(gl, programs);\n}\n\n/**\n * Creates multiple programs asynchronously\n *\n * @see {@link module:twgl.createProgramAsync}\n *\n * Example:\n *\n * const programs = await twgl.createProgramsAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nconst createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms);\n\n/**\n * Creates multiple programInfos asynchronously\n *\n * @see {@link module:twgl.createProgramInfoAsync}\n *\n * Example:\n *\n * const programInfos = await twgl.createProgramInfosAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Promise>} the created programInfos by name\n */\nconst createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos);\n\nexport {\n createAttributeSetters,\n\n createProgram,\n createProgramAsync,\n createPrograms,\n createProgramsAsync,\n createProgramFromScripts,\n createProgramFromSources,\n createProgramInfo,\n createProgramInfoAsync,\n createProgramInfos,\n createProgramInfosAsync,\n createProgramInfoFromProgram,\n createUniformSetters,\n createUniformBlockSpecFromProgram,\n createUniformBlockInfoFromProgram,\n createUniformBlockInfo,\n\n createTransformFeedback,\n createTransformFeedbackInfo,\n bindTransformFeedbackInfo,\n\n setAttributes,\n setBuffersAndAttributes,\n setUniforms,\n setUniformsAndBindTextures,\n setUniformBlock,\n setBlockUniforms,\n bindUniformBlock,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level texture related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.textures` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/textures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n textureColor: new Uint8Array([128, 192, 255, 255]),\n textureOptions: {},\n crossOrigin: undefined,\n};\nconst isArrayBuffer = typedArrays.isArrayBuffer;\n\n// Should we make this on demand?\nconst getShared2DContext = function() {\n let s_ctx;\n return function getShared2DContext() {\n s_ctx = s_ctx ||\n ((typeof document !== 'undefined' && document.createElement)\n ? document.createElement(\"canvas\").getContext(\"2d\")\n : null);\n return s_ctx;\n };\n}();\n\n// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but\n// not only does Firefox NOT support it but Firefox freezes immediately\n// if you try to create one instead of just returning null and continuing.\n// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext(\"2d\")); // OffscreenCanvas may not support 2d\n\n// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2\n// we can use the various unpack settings. Otherwise we could try using\n// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap\n// is async and the current TWGL code expects a non-Async result though that\n// might not be a problem. ImageBitmap though is not available in Edge or Safari\n// as of 2018-01-02\n\n/* PixelFormat */\nconst ALPHA = 0x1906;\nconst RGB = 0x1907;\nconst RGBA = 0x1908;\nconst LUMINANCE = 0x1909;\nconst LUMINANCE_ALPHA = 0x190A;\nconst DEPTH_COMPONENT = 0x1902;\nconst DEPTH_STENCIL = 0x84F9;\n\n/* TextureWrapMode */\n// const REPEAT = 0x2901;\n// const MIRRORED_REPEAT = 0x8370;\nconst CLAMP_TO_EDGE = 0x812f;\n\n/* TextureMagFilter */\nconst NEAREST = 0x2600;\nconst LINEAR = 0x2601;\n\n/* TextureMinFilter */\n// const NEAREST_MIPMAP_NEAREST = 0x2700;\n// const LINEAR_MIPMAP_NEAREST = 0x2701;\n// const NEAREST_MIPMAP_LINEAR = 0x2702;\n// const LINEAR_MIPMAP_LINEAR = 0x2703;\n\n/* Texture Target */\nconst TEXTURE_2D = 0x0de1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806f;\nconst TEXTURE_2D_ARRAY = 0x8c1a;\n\n/* Cubemap Targets */\nconst TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;\nconst TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;\nconst TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;\nconst TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a;\n\n/* Texture Parameters */\nconst TEXTURE_MIN_FILTER = 0x2801;\nconst TEXTURE_MAG_FILTER = 0x2800;\nconst TEXTURE_WRAP_S = 0x2802;\nconst TEXTURE_WRAP_T = 0x2803;\nconst TEXTURE_WRAP_R = 0x8072;\nconst TEXTURE_MIN_LOD = 0x813a;\nconst TEXTURE_MAX_LOD = 0x813b;\nconst TEXTURE_BASE_LEVEL = 0x813c;\nconst TEXTURE_MAX_LEVEL = 0x813d;\nconst TEXTURE_COMPARE_MODE = 0x884C;\nconst TEXTURE_COMPARE_FUNC = 0x884D;\n\n/* Pixel store */\nconst UNPACK_ALIGNMENT = 0x0cf5;\nconst UNPACK_ROW_LENGTH = 0x0cf2;\nconst UNPACK_IMAGE_HEIGHT = 0x806e;\nconst UNPACK_SKIP_PIXELS = 0x0cf4;\nconst UNPACK_SKIP_ROWS = 0x0cf3;\nconst UNPACK_SKIP_IMAGES = 0x806d;\nconst UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;\nconst UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;\nconst UNPACK_FLIP_Y_WEBGL = 0x9240;\n\nconst R8 = 0x8229;\nconst R8_SNORM = 0x8F94;\nconst R16F = 0x822D;\nconst R32F = 0x822E;\nconst R8UI = 0x8232;\nconst R8I = 0x8231;\nconst RG16UI = 0x823A;\nconst RG16I = 0x8239;\nconst RG32UI = 0x823C;\nconst RG32I = 0x823B;\nconst RG8 = 0x822B;\nconst RG8_SNORM = 0x8F95;\nconst RG16F = 0x822F;\nconst RG32F = 0x8230;\nconst RG8UI = 0x8238;\nconst RG8I = 0x8237;\nconst R16UI = 0x8234;\nconst R16I = 0x8233;\nconst R32UI = 0x8236;\nconst R32I = 0x8235;\nconst RGB8 = 0x8051;\nconst SRGB8 = 0x8C41;\nconst RGB565 = 0x8D62;\nconst RGB8_SNORM = 0x8F96;\nconst R11F_G11F_B10F = 0x8C3A;\nconst RGB9_E5 = 0x8C3D;\nconst RGB16F = 0x881B;\nconst RGB32F = 0x8815;\nconst RGB8UI = 0x8D7D;\nconst RGB8I = 0x8D8F;\nconst RGB16UI = 0x8D77;\nconst RGB16I = 0x8D89;\nconst RGB32UI = 0x8D71;\nconst RGB32I = 0x8D83;\nconst RGBA8 = 0x8058;\nconst SRGB8_ALPHA8 = 0x8C43;\nconst RGBA8_SNORM = 0x8F97;\nconst RGB5_A1 = 0x8057;\nconst RGBA4 = 0x8056;\nconst RGB10_A2 = 0x8059;\nconst RGBA16F = 0x881A;\nconst RGBA32F = 0x8814;\nconst RGBA8UI = 0x8D7C;\nconst RGBA8I = 0x8D8E;\nconst RGB10_A2UI = 0x906F;\nconst RGBA16UI = 0x8D76;\nconst RGBA16I = 0x8D88;\nconst RGBA32I = 0x8D82;\nconst RGBA32UI = 0x8D70;\n\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst DEPTH_COMPONENT24 = 0x81A6;\nconst DEPTH_COMPONENT32F = 0x8CAC;\nconst DEPTH32F_STENCIL8 = 0x8CAD;\nconst DEPTH24_STENCIL8 = 0x88F0;\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:(\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst RG = 0x8227;\nconst RG_INTEGER = 0x8228;\nconst RED = 0x1903;\nconst RED_INTEGER = 0x8D94;\nconst RGB_INTEGER = 0x8D98;\nconst RGBA_INTEGER = 0x8D99;\n\nconst formatInfo = {};\n{\n // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle\n // the name.\n const f = formatInfo;\n f[ALPHA] = { numColorComponents: 1, };\n f[LUMINANCE] = { numColorComponents: 1, };\n f[LUMINANCE_ALPHA] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RED] = { numColorComponents: 1, };\n f[RED_INTEGER] = { numColorComponents: 1, };\n f[RG] = { numColorComponents: 2, };\n f[RG_INTEGER] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGB_INTEGER] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RGBA_INTEGER] = { numColorComponents: 4, };\n f[DEPTH_COMPONENT] = { numColorComponents: 1, };\n f[DEPTH_STENCIL] = { numColorComponents: 2, };\n}\n\n/**\n * @typedef {Object} TextureFormatDetails\n * @property {number} textureFormat format to pass texImage2D and similar functions.\n * @property {boolean} colorRenderable true if you can render to this format of texture.\n * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`.\n * @property {number[]} type Array of possible types you can pass to texImage2D and similar function\n * @property {Object.} bytesPerElementMap A map of types to bytes per element\n * @private\n */\n\nlet s_textureInternalFormatInfo;\nfunction getTextureInternalFormatInfo(internalFormat) {\n if (!s_textureInternalFormatInfo) {\n // NOTE: these properties need unique names so we can let Uglify mangle the name.\n const t = {};\n // unsized formats\n t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5], };\n t[RGBA] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], };\n t[DEPTH_COMPONENT] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT, UNSIGNED_SHORT], };\n\n // sized formats\n t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], };\n t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT, HALF_FLOAT], };\n t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], };\n t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT], };\n t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], };\n t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT], };\n t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], };\n t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT, HALF_FLOAT], };\n t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT], };\n t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], };\n t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT], };\n t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], };\n t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT], };\n t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT], };\n t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB565] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5], };\n t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], };\n t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], };\n t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], };\n t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT, HALF_FLOAT], };\n t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT], };\n t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], };\n t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT], };\n t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], };\n t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT], };\n t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT], };\n t[RGBA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[SRGB8_ALPHA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8_SNORM] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], };\n t[RGB5_A1] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA4] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4], };\n t[RGB10_A2] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT, HALF_FLOAT], };\n t[RGBA32F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT], };\n t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], };\n t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT], };\n t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], };\n t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT], };\n t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT], };\n // Sized Internal\n t[DEPTH_COMPONENT16] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT, UNSIGNED_INT], };\n t[DEPTH_COMPONENT24] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[DEPTH_COMPONENT32F] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[DEPTH24_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], };\n t[DEPTH32F_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], };\n\n Object.keys(t).forEach(function(internalFormat) {\n const info = t[internalFormat];\n info.bytesPerElementMap = {};\n info.bytesPerElement.forEach(function(bytesPerElement, ndx) {\n const type = info.type[ndx];\n info.bytesPerElementMap[type] = bytesPerElement;\n });\n });\n s_textureInternalFormatInfo = t;\n }\n return s_textureInternalFormatInfo[internalFormat];\n}\n\n/**\n * Gets the number of bytes per element for a given internalFormat / type\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {number} the number of bytes per element for the given internalFormat, type combo\n * @memberOf module:twgl/textures\n */\nfunction getBytesPerElementForInternalFormat(internalFormat, type) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n const bytesPerElement = info.bytesPerElementMap[type];\n if (bytesPerElement === undefined) {\n throw \"unknown internal format\";\n }\n return bytesPerElement;\n}\n\n/**\n * Info related to a specific texture internalFormat as returned\n * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}.\n *\n * @typedef {Object} TextureFormatInfo\n * @property {number} format Format to pass to texImage2D and related functions\n * @property {number} type Type to pass to texImage2D and related functions\n * @memberOf module:twgl/textures\n */\n\n/**\n * Gets the format and type for a given internalFormat\n *\n * @param {number} internalFormat The internal format\n * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type,\n * @memberOf module:twgl/textures\n */\nfunction getFormatAndTypeForInternalFormat(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return {\n format: info.textureFormat,\n type: info.type[0],\n };\n}\n\n/**\n * Returns true if value is power of 2\n * @param {number} value number to check.\n * @return true if value is power of 2\n * @private\n */\nfunction isPowerOf2(value) {\n return (value & (value - 1)) === 0;\n}\n\n/**\n * Gets whether or not we can generate mips for the given\n * internal format.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number} width The width parameter from texImage2D etc..\n * @param {number} height The height parameter from texImage2D etc..\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canGenerateMipmap(gl, width, height, internalFormat) {\n if (!utils.isWebGL2(gl)) {\n return isPowerOf2(width) && isPowerOf2(height);\n }\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.colorRenderable && info.textureFilterable;\n}\n\n/**\n * Gets whether or not we can generate mips for the given format\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canFilter(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.textureFilterable;\n}\n\n/**\n * Gets the number of components for a given image format.\n * @param {number} format the format.\n * @return {number} the number of components for the format.\n * @memberOf module:twgl/textures\n */\nfunction getNumComponentsForFormat(format) {\n const info = formatInfo[format];\n if (!info) {\n throw \"unknown format: \" + format;\n }\n return info.numColorComponents;\n}\n\n/**\n * Gets the texture type for a given array type.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @return {number} the gl texture type\n * @private\n */\nfunction getTextureTypeForArrayType(gl, src, defaultType) {\n if (isArrayBuffer(src)) {\n return typedArrays.getGLTypeForTypedArray(src);\n }\n return defaultType || UNSIGNED_BYTE;\n}\n\nfunction guessDimensions(gl, target, width, height, numElements) {\n if (numElements % 1 !== 0) {\n throw \"can't guess dimensions\";\n }\n if (!width && !height) {\n const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1));\n if (size % 1 === 0) {\n width = size;\n height = size;\n } else {\n width = numElements;\n height = 1;\n }\n } else if (!height) {\n height = numElements / width;\n if (height % 1) {\n throw \"can't guess dimensions\";\n }\n } else if (!width) {\n width = numElements / height;\n if (width % 1) {\n throw \"can't guess dimensions\";\n }\n }\n return {\n width: width,\n height: height,\n };\n}\n\n/**\n * Sets the default texture color.\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * @param {number[]} color Array of 4 values in the range 0 to 1\n * @deprecated see {@link module:twgl.setDefaults}\n * @memberOf module:twgl/textures\n */\nfunction setDefaultTextureColor(color) {\n defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n if (newDefaults.textureColor) {\n setDefaultTextureColor(newDefaults.textureColor);\n }\n}\n\n/**\n * A function to generate the source for a texture.\n * @callback TextureFunc\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options the texture options\n * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}.\n * @memberOf module:twgl\n */\n\n/**\n * Texture options passed to most texture functions. Each function will use whatever options\n * are appropriate for its needs. This lets you pass the same options to all functions.\n *\n * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`,\n * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`.\n *\n * @typedef {Object} TextureOptions\n * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`.\n * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true.\n * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null.\n * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null.\n * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` .\n * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR`\n * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`.\n * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR`\n * @property {number} [minMag] both the min and mag filter settings.\n * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA`\n * @property {number} [format] format for texture. Defaults to `gl.RGBA`.\n * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src`\n * is ArrayBufferView defaults to type that matches ArrayBufferView type.\n * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube\n * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [minLod] TEXTURE_MIN_LOD setting\n * @property {number} [maxLod] TEXTURE_MAX_LOD setting\n * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting\n * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting\n * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting\n * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting\n * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1.\n * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously.\n * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults`\n * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink\n * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and\n * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above\n * then then `auto` is assumed to be `false` unless explicity set to `true`.\n * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is\n *\n * [gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]\n *\n * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture\n *\n * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable\n * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded.\n * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3.\n * The pieces will be uploaded in `cubeFaceOrder`\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map.\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture\n * and will be scaled to the specified width and height OR to the size of the first image that loads.\n *\n * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`,\n * `HTMLCanvasElement`, `HTMLVideoElement`.\n *\n * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is\n * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents`\n * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided\n * by 6. Then\n *\n * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height\n * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`.\n *\n * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`.\n *\n * If `number[]` will be converted to `type`.\n *\n * If `src` is a function it will be called with a `WebGLRenderingContext` and these options.\n * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement`\n * an array etc...\n *\n * If `src` is undefined then an empty texture will be created of size `width` by `height`.\n *\n * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded.\n * default: undefined. Also see {@link module:twgl.setDefaults}.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Saves the current packing state, sets the packing state as specified\n * then calls a function, after which the packing state will be restored.\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {function():void} [fn] A function to call, after which the packing state will be restored.\n * @private\n */\nfunction scopedSetPackState(gl, options, fn) {\n let colorspaceConversion;\n let premultiplyAlpha;\n let flipY;\n\n if (options.colorspaceConversion !== undefined) {\n colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL);\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion);\n }\n if (options.premultiplyAlpha !== undefined) {\n premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha);\n }\n if (options.flipY !== undefined) {\n flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL);\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY);\n }\n\n fn();\n\n if (colorspaceConversion !== undefined) {\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion);\n }\n if (premultiplyAlpha !== undefined) {\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha);\n }\n if (flipY !== undefined) {\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY);\n }\n}\n\n/**\n * Set skip state to defaults\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @private\n */\nfunction setSkipStateToDefault(gl) {\n gl.pixelStorei(UNPACK_ALIGNMENT, 4);\n if (utils.isWebGL2(gl)) {\n gl.pixelStorei(UNPACK_ROW_LENGTH, 0);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_PIXELS, 0);\n gl.pixelStorei(UNPACK_SKIP_ROWS, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n }\n}\n\n/**\n * Sets the parameters of a texture or sampler\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number|WebGLSampler} target texture target or sampler\n * @param {function()} parameteriFn texParameteri or samplerParameteri fn\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @private\n */\nfunction setTextureSamplerParameters(gl, target, parameteriFn, options) {\n if (options.minMag) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag);\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag);\n }\n if (options.min) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min);\n }\n if (options.mag) {\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag);\n }\n if (options.wrap) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap);\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap);\n if (target === TEXTURE_3D || helper.isSampler(gl, target)) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap);\n }\n }\n if (options.wrapR) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR);\n }\n if (options.wrapS) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS);\n }\n if (options.wrapT) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT);\n }\n if (options.minLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod);\n }\n if (options.maxLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod);\n }\n if (options.baseLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel);\n }\n if (options.maxLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel);\n }\n if (options.compareFunc !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc);\n }\n if (options.compareMode !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode);\n }\n}\n\n/**\n * Sets the texture parameters of a texture.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureParameters(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n setTextureSamplerParameters(gl, target, gl.texParameteri, options);\n}\n\n/**\n * Sets the sampler parameters of a sampler.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLSampler} sampler the WebGLSampler to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setSamplerParameters(gl, sampler, options) {\n setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options);\n}\n\n/**\n * Creates a new sampler object and sets parameters.\n *\n * Example:\n *\n * const sampler = twgl.createSampler(gl, {\n * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER\n * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per sampler.\n * @return {Object.} the created samplers by name\n * @private\n */\nfunction createSampler(gl, options) {\n const sampler = gl.createSampler();\n setSamplerParameters(gl, sampler, options);\n return sampler;\n}\n\n/**\n * Creates a multiple sampler objects and sets parameters on each.\n *\n * Example:\n *\n * const samplers = twgl.createSamplers(gl, {\n * nearest: {\n * minMag: gl.NEAREST,\n * },\n * nearestClampS: {\n * minMag: gl.NEAREST,\n * wrapS: gl.CLAMP_TO_NEAREST,\n * },\n * linear: {\n * minMag: gl.LINEAR,\n * },\n * nearestClamp: {\n * minMag: gl.NEAREST,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClamp: {\n * minMag: gl.LINEAR,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClampT: {\n * minMag: gl.LINEAR,\n * wrapT: gl.CLAMP_TO_EDGE,\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler\n * @private\n */\nfunction createSamplers(gl, samplerOptions) {\n const samplers = {};\n Object.keys(samplerOptions).forEach(function(name) {\n samplers[name] = createSampler(gl, samplerOptions[name]);\n });\n return samplers;\n}\n\n/**\n * Makes a 1x1 pixel\n * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`.\n * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values\n * @return {Uint8Array} Unit8Array with color.\n * @private\n */\nfunction make1Pixel(color) {\n color = color || defaults.textureColor;\n if (isArrayBuffer(color)) {\n return color;\n }\n return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\n/**\n * Sets filtering or generates mips for texture based on width or height\n * If width or height is not passed in uses `options.width` and//or `options.height`\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @param {number} [width] width of texture\n * @param {number} [height] height of texture\n * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc..\n * @memberOf module:twgl/textures\n */\nfunction setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) {\n options = options || defaults.textureOptions;\n internalFormat = internalFormat || RGBA;\n const target = options.target || TEXTURE_2D;\n width = width || options.width;\n height = height || options.height;\n gl.bindTexture(target, tex);\n if (canGenerateMipmap(gl, width, height, internalFormat)) {\n gl.generateMipmap(target);\n } else {\n const filtering = canFilter(internalFormat) ? LINEAR : NEAREST;\n gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n}\n\nfunction shouldAutomaticallySetTextureFilteringForSize(options) {\n return options.auto === true || (options.auto === undefined && options.level === undefined);\n}\n\n/**\n * Gets an array of cubemap face enums\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @return {number[]} cubemap face enums\n * @private\n */\nfunction getCubeFaceOrder(gl, options) {\n options = options || {};\n return options.cubeFaceOrder || [\n TEXTURE_CUBE_MAP_POSITIVE_X,\n TEXTURE_CUBE_MAP_NEGATIVE_X,\n TEXTURE_CUBE_MAP_POSITIVE_Y,\n TEXTURE_CUBE_MAP_NEGATIVE_Y,\n TEXTURE_CUBE_MAP_POSITIVE_Z,\n TEXTURE_CUBE_MAP_NEGATIVE_Z,\n ];\n}\n\n/**\n * @typedef {Object} FaceInfo\n * @property {number} face gl enum for texImage2D\n * @property {number} ndx face index (0 - 5) into source data\n * @ignore\n */\n\n/**\n * Gets an array of FaceInfos\n * There's a bug in some NVidia drivers that will crash the driver if\n * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take\n * the user's desired order from his faces to WebGL and make sure we\n * do the faces in WebGL order\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but\n * it's needed internally to sort the array of `ndx` properties by `face`.\n * @private\n */\nfunction getCubeFacesWithNdx(gl, options) {\n const faces = getCubeFaceOrder(gl, options);\n // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :(\n const facesWithNdx = faces.map(function(face, ndx) {\n return { face: face, ndx: ndx };\n });\n facesWithNdx.sort(function(a, b) {\n return a.face - b.face;\n });\n return facesWithNdx;\n}\n\n/**\n * Set a texture from the contents of an element. Will also set\n * texture filtering or generate mips based on the dimensions of the element\n * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will\n * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {HTMLElement} element a canvas, img, or video element.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @kind function\n */\nfunction setTextureFromElement(gl, tex, element, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n const level = options.level || 0;\n let width = element.width;\n let height = element.height;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // guess the parts\n const imgWidth = element.width;\n const imgHeight = element.height;\n let size;\n let slices;\n if (imgWidth / 6 === imgHeight) {\n // It's 6x1\n size = imgHeight;\n slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0];\n } else if (imgHeight / 6 === imgWidth) {\n // It's 1x6\n size = imgWidth;\n slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5];\n } else if (imgWidth / 3 === imgHeight / 2) {\n // It's 3x2\n size = imgWidth / 3;\n slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1];\n } else if (imgWidth / 2 === imgHeight / 3) {\n // It's 2x3\n size = imgWidth / 2;\n slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2];\n } else {\n throw \"can't figure out cube map from element: \" + (element.src ? element.src : element.nodeName);\n }\n const ctx = getShared2DContext();\n if (ctx) {\n ctx.canvas.width = size;\n ctx.canvas.height = size;\n width = size;\n height = size;\n scopedSetPackState(gl, options, () => {\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size);\n gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas);\n });\n // Free up the canvas memory\n ctx.canvas.width = 1;\n ctx.canvas.height = 1;\n });\n } else if (typeof createImageBitmap !== 'undefined') {\n // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's\n // note lossy? (alpha is not premultiplied? although I'm not sure what\n width = size;\n height = size;\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n // We can't easily use a default texture color here as it would have to match\n // the type across all faces where as with a 2D one there's only one face\n // so we're replacing everything all at once. It also has to be the correct size.\n // On the other hand we need all faces to be the same size so as one face loads\n // the rest match else the texture will be un-renderable.\n gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null);\n createImageBitmap(element, xOffset, yOffset, size, size, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n })\n .then(function(imageBitmap) {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap);\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n });\n });\n });\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n scopedSetPackState(gl, options, () => {\n const smallest = Math.min(element.width, element.height);\n const largest = Math.max(element.width, element.height);\n const depth = largest / smallest;\n if (depth % 1 !== 0) {\n throw \"can not compute 3D dimensions of element\";\n }\n const xMult = element.width === largest ? 1 : 0;\n const yMult = element.height === largest ? 1 : 0;\n gl.pixelStorei(UNPACK_ALIGNMENT, 1);\n gl.pixelStorei(UNPACK_ROW_LENGTH, element.width);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null);\n for (let d = 0; d < depth; ++d) {\n const srcX = d * smallest * xMult;\n const srcY = d * smallest * yMult;\n gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX);\n gl.pixelStorei(UNPACK_SKIP_ROWS, srcY);\n gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element);\n }\n setSkipStateToDefault(gl);\n });\n } else {\n scopedSetPackState(gl, options, () => {\n gl.texImage2D(target, level, internalFormat, format, type, element);\n });\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n}\n\nfunction noop() {\n}\n\n/**\n * Checks whether the url's origin is the same so that we can set the `crossOrigin`\n * @param {string} url url to image\n * @returns {boolean} true if the window's origin is the same as image's url\n * @private\n */\nfunction urlIsSameOrigin(url) {\n if (typeof document !== 'undefined') {\n // for IE really\n const a = document.createElement('a');\n a.href = url;\n return a.hostname === location.hostname &&\n a.port === location.port &&\n a.protocol === location.protocol;\n } else {\n const localOrigin = (new URL(location.href)).origin;\n const urlOrigin = (new URL(url, location.href)).origin;\n return urlOrigin === localOrigin;\n }\n}\n\nfunction setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) {\n return crossOrigin === undefined && !urlIsSameOrigin(url)\n ? 'anonymous'\n : crossOrigin;\n}\n\n/**\n * Loads an image\n * @param {string} url url to image\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @return {HTMLImageElement} the image being loaded.\n * @private\n */\nfunction loadImage(url, crossOrigin, callback) {\n callback = callback || noop;\n let img;\n crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin;\n crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin);\n if (typeof Image !== 'undefined') {\n img = new Image();\n if (crossOrigin !== undefined) {\n img.crossOrigin = crossOrigin;\n }\n\n const clearEventHandlers = function clearEventHandlers() {\n img.removeEventListener('error', onError); // eslint-disable-line\n img.removeEventListener('load', onLoad); // eslint-disable-line\n img = null;\n };\n\n const onError = function onError() {\n const msg = \"couldn't load image: \" + url;\n helper.error(msg);\n callback(msg, img);\n clearEventHandlers();\n };\n\n const onLoad = function onLoad() {\n callback(null, img);\n clearEventHandlers();\n };\n\n img.addEventListener('error', onError);\n img.addEventListener('load', onLoad);\n img.src = url;\n return img;\n } else if (typeof ImageBitmap !== 'undefined') {\n let err;\n let bm;\n const cb = function cb() {\n callback(err, bm);\n };\n\n const options = {};\n if (crossOrigin) {\n options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin\n }\n fetch(url, options).then(function(response) {\n if (!response.ok) {\n throw response;\n }\n return response.blob();\n }).then(function(blob) {\n return createImageBitmap(blob, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n });\n }).then(function(bitmap) {\n // not sure if this works. We don't want\n // to catch the user's error. So, call\n // the callback in a timeout so we're\n // not in this scope inside the promise.\n bm = bitmap;\n setTimeout(cb);\n }).catch(function(e) {\n err = e;\n setTimeout(cb);\n });\n img = null;\n }\n return img;\n}\n\n/**\n * check if object is a TexImageSource\n *\n * @param {Object} obj Object to test\n * @return {boolean} true if object is a TexImageSource\n * @private\n */\nfunction isTexImageSource(obj) {\n return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) ||\n (typeof ImageData !== 'undefined' && obj instanceof ImageData) ||\n (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement);\n}\n\n/**\n * if obj is an TexImageSource then just\n * uses it otherwise if obj is a string\n * then load it first.\n *\n * @param {string|TexImageSource} obj\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @private\n */\nfunction loadAndUseImage(obj, crossOrigin, callback) {\n if (isTexImageSource(obj)) {\n setTimeout(function() {\n callback(null, obj);\n });\n return obj;\n }\n\n return loadImage(obj, crossOrigin, callback);\n}\n\n/**\n * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set\n * the default texture color is used which can be set by calling `setDefaultTextureColor`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction setTextureTo1PixelColor(gl, tex, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n if (options.color === false) {\n return;\n }\n // Assume it's a URL\n // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering.\n const color = make1Pixel(options.color);\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n } else {\n gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n}\n\n/**\n * The src image(s) used to create a texture.\n *\n * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures}\n * you can pass in urls for images to load into the textures. If it's a single url\n * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap\n * this will be a corresponding array of images for the cubemap.\n *\n * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback TextureReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} texture the texture.\n * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when all images have finished downloading and been uploaded into their respective textures\n * @callback TexturesReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}.\n * @param {Object.} sources the image(s) used for the texture by name.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback CubemapReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each face.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback ThreeDReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each slice.\n * @memberOf module:twgl\n */\n\n/**\n * Loads a texture from an image from a Url as specified in `options.src`\n * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is\n * immediately useable. It will be updated with the contents of the image once the image has finished\n * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will\n * be non null if there was an error.\n * @return {HTMLImageElement} the image being downloaded.\n * @memberOf module:twgl/textures\n */\nfunction loadTextureFromUrl(gl, tex, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) {\n if (err) {\n callback(err, tex, img);\n } else {\n setTextureFromElement(gl, tex, img, options);\n callback(null, tex, img);\n }\n });\n return img;\n}\n\n/**\n * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadCubemapFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n if (urls.length !== 6) {\n throw \"there must be 6 urls for a cubemap\";\n }\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D;\n if (target !== TEXTURE_CUBE_MAP) {\n throw \"target must be TEXTURE_CUBE_MAP\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = 6;\n const errors = [];\n const faces = getCubeFaceOrder(gl, options);\n let imgs; // eslint-disable-line\n\n function uploadImg(faceTarget) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n if (img.width !== img.height) {\n errors.push(\"cubemap face img is not a square: \" + img.src);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n // So assuming this is the first image we now have one face that's img sized\n // and 5 faces that are 1x1 pixel so size the other faces\n if (numToLoad === 5) {\n // use the default order\n getCubeFaceOrder(gl).forEach(function(otherTarget) {\n // Should we re-use the same face or a color?\n gl.texImage2D(otherTarget, level, internalFormat, format, type, img);\n });\n } else {\n gl.texImage2D(faceTarget, level, internalFormat, format, type, img);\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx]));\n });\n}\n\n/**\n * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`.\n * Will set the texture to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n *\n * If the width and height is not specified the width and height of the first\n * image loaded will be used. Note that since images are loaded async\n * which image downloads first is unknown.\n *\n * If an image is not the same size as the width and height it will be scaled\n * to that width and height.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadSlicesFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D_ARRAY;\n if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) {\n throw \"target must be TEXTURE_3D or TEXTURE_2D_ARRAY\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = urls.length;\n const errors = [];\n let imgs; // eslint-disable-line\n const level = options.level || 0;\n let width = options.width;\n let height = options.height;\n const depth = urls.length;\n let firstImage = true;\n\n function uploadImg(slice) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n if (firstImage) {\n firstImage = false;\n width = options.width || img.width;\n height = options.height || img.height;\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n\n // put it in every slice otherwise some slices will be 0,0,0,0\n for (let s = 0; s < depth; ++s) {\n gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img);\n }\n } else {\n let src = img;\n let ctx;\n if (img.width !== width || img.height !== height) {\n // Size the image to fix\n ctx = getShared2DContext();\n src = ctx.canvas;\n ctx.canvas.width = width;\n ctx.canvas.height = height;\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src);\n\n // free the canvas memory\n if (ctx && src === ctx.canvas) {\n ctx.canvas.width = 0;\n ctx.canvas.height = 0;\n }\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx));\n });\n}\n\n/**\n * Sets a texture from an array or typed array. If the width or height is not provided will attempt to\n * guess the size. See {@link module:twgl.TextureOptions}.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureFromArray(gl, tex, src, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n let width = options.width;\n let height = options.height;\n let depth = options.depth;\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n if (!isArrayBuffer(src)) {\n const Type = typedArrays.getTypedArrayTypeForGLType(type);\n src = new Type(src);\n } else if (src instanceof Uint8ClampedArray) {\n src = new Uint8Array(src.buffer);\n }\n\n const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type);\n const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT?\n if (numElements % 1) {\n throw \"length wrong size for format: \" + utils.glEnumToString(gl, format);\n }\n let dimensions;\n if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n if (!width && !height && !depth) {\n const size = Math.cbrt(numElements);\n if (size % 1 !== 0) {\n throw \"can't guess cube size of array of numElements: \" + numElements;\n }\n width = size;\n height = size;\n depth = size;\n } else if (width && (!height || !depth)) {\n dimensions = guessDimensions(gl, target, height, depth, numElements / width);\n height = dimensions.width;\n depth = dimensions.height;\n } else if (height && (!width || !depth)) {\n dimensions = guessDimensions(gl, target, width, depth, numElements / height);\n width = dimensions.width;\n depth = dimensions.height;\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements / depth);\n width = dimensions.width;\n height = dimensions.height;\n }\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements);\n width = dimensions.width;\n height = dimensions.height;\n }\n setSkipStateToDefault(gl);\n gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1);\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT;\n const faceSize = numElements / 6 * elementsPerElement;\n\n getCubeFacesWithNdx(gl, options).forEach(f => {\n const offset = faceSize * f.ndx;\n const data = src.subarray(offset, offset + faceSize);\n gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data);\n });\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src);\n }\n });\n return {\n width: width,\n height: height,\n depth: depth,\n type: type,\n };\n}\n\n/**\n * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`.\n * You must set `options.width` and `options.height`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setEmptyTexture(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n });\n}\n\n/**\n * Creates a texture based on the options passed in.\n *\n * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES\n * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture.\n * @return {WebGLTexture} the created texture.\n * @memberOf module:twgl/textures\n */\nfunction createTexture(gl, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n const tex = gl.createTexture();\n const target = options.target || TEXTURE_2D;\n let width = options.width || 1;\n let height = options.height || 1;\n const internalFormat = options.internalFormat || RGBA;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // this should have been the default for cubemaps :(\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n let src = options.src;\n if (src) {\n if (typeof src === \"function\") {\n src = src(gl, options);\n }\n if (typeof (src) === \"string\") {\n loadTextureFromUrl(gl, tex, options, callback);\n } else if (isArrayBuffer(src) ||\n (Array.isArray(src) && (\n typeof src[0] === 'number' ||\n Array.isArray(src[0]) ||\n isArrayBuffer(src[0]))\n )\n ) {\n const dimensions = setTextureFromArray(gl, tex, src, options);\n width = dimensions.width;\n height = dimensions.height;\n } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) {\n if (target === TEXTURE_CUBE_MAP) {\n loadCubemapFromUrls(gl, tex, options, callback);\n } else {\n loadSlicesFromUrls(gl, tex, options, callback);\n }\n } else { // if (isTexImageSource(src))\n setTextureFromElement(gl, tex, src, options);\n width = src.width;\n height = src.height;\n }\n } else {\n setEmptyTexture(gl, tex, options);\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n return tex;\n}\n\n/**\n * Resizes a texture based on the options passed in.\n *\n * Note: This is not a generic resize anything function.\n * It's mostly used by {@link module:twgl.resizeFramebufferInfo}\n * It will use `options.src` if it exists to try to determine a `type`\n * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided\n * for the texture. Texture parameters will be set accordingly\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the texture to resize\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {number} [width] the new width. If not passed in will use `options.width`\n * @param {number} [height] the new height. If not passed in will use `options.height`\n * @param {number} [depth] the new depth. If not passed in will use `options.depth`\n * @memberOf module:twgl/textures\n */\nfunction resizeTexture(gl, tex, options, width, height, depth) {\n width = width || options.width;\n height = height || options.height;\n depth = depth || options.depth;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n let type;\n const src = options.src;\n if (!src) {\n type = options.type || formatType.type;\n } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) {\n type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n } else {\n type = options.type || formatType.type;\n }\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null);\n }\n}\n\n/**\n * Check if a src is an async request.\n * if src is a string we're going to download an image\n * if src is an array of strings we're going to download cubemap images\n * @param {*} src The src from a TextureOptions\n * @returns {bool} true if src is async.\n * @private\n */\nfunction isAsyncSrc(src) {\n return typeof src === 'string' ||\n (Array.isArray(src) && typeof src[0] === 'string');\n}\n\n/**\n * Creates a bunch of textures based on the passed in options.\n *\n * Example:\n *\n * const textures = twgl.createTextures(gl, {\n * // a power of 2 image\n * hftIcon: { src: \"images/hft-icon-16.png\", mag: gl.NEAREST },\n * // a non-power of 2 image\n * clover: { src: \"images/clover.jpg\" },\n * // From a canvas\n * fromCanvas: { src: ctx.canvas },\n * // A cubemap from 6 images\n * yokohama: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: [\n * 'images/yokohama/posx.jpg',\n * 'images/yokohama/negx.jpg',\n * 'images/yokohama/posy.jpg',\n * 'images/yokohama/negy.jpg',\n * 'images/yokohama/posz.jpg',\n * 'images/yokohama/negz.jpg',\n * ],\n * },\n * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)\n * goldengate: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: 'images/goldengate.jpg',\n * },\n * // A 2x2 pixel texture from a JavaScript array\n * checker: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * src: [\n * 255,255,255,255,\n * 192,192,192,255,\n * 192,192,192,255,\n * 255,255,255,255,\n * ],\n * },\n * // a 1x2 pixel texture from a typed array.\n * stripe: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * format: gl.LUMINANCE,\n * src: new Uint8Array([\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * ]),\n * width: 1,\n * },\n * });\n *\n * Now\n *\n * * `textures.hftIcon` will be a 2d texture\n * * `textures.clover` will be a 2d texture\n * * `textures.fromCanvas` will be a 2d texture\n * * `textures.yohohama` will be a cubemap texture\n * * `textures.goldengate` will be a cubemap texture\n * * `textures.checker` will be a 2d texture\n * * `textures.stripe` will be a 2d texture\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per texture.\n * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded.\n * @return {Object.} the created textures by name\n * @memberOf module:twgl/textures\n */\nfunction createTextures(gl, textureOptions, callback) {\n callback = callback || noop;\n let numDownloading = 0;\n const errors = [];\n const textures = {};\n const images = {};\n\n function callCallbackIfReady() {\n if (numDownloading === 0) {\n setTimeout(function() {\n callback(errors.length ? errors : undefined, textures, images);\n }, 0);\n }\n }\n\n Object.keys(textureOptions).forEach(function(name) {\n const options = textureOptions[name];\n let onLoadFn;\n if (isAsyncSrc(options.src)) {\n onLoadFn = function(err, tex, img) {\n images[name] = img;\n --numDownloading;\n if (err) {\n errors.push(err);\n }\n callCallbackIfReady();\n };\n ++numDownloading;\n }\n textures[name] = createTexture(gl, options, onLoadFn);\n });\n\n // queue the callback if there are no images to download.\n // We do this because if your code is structured to wait for\n // images to download but then you comment out all the async\n // images your code would break.\n callCallbackIfReady();\n\n return textures;\n}\n\nexport {\n setDefaults as setTextureDefaults_,\n\n createSampler,\n createSamplers,\n setSamplerParameters,\n\n createTexture,\n setEmptyTexture,\n setTextureFromArray,\n loadTextureFromUrl,\n setTextureFromElement,\n setTextureFilteringForSize,\n setTextureParameters,\n setDefaultTextureColor,\n createTextures,\n resizeTexture,\n\n canGenerateMipmap,\n canFilter,\n getNumComponentsForFormat,\n getBytesPerElementForInternalFormat,\n getFormatAndTypeForInternalFormat,\n};\n\n","import * as m4 from './m4.js';\nimport * as v3 from './v3.js';\nimport * as primitives from './primitives.js';\n\nexport * from './twgl.js';\nexport {\n m4,\n v3,\n primitives,\n};\n\n\n\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as attributes from './attributes.js';\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\nimport * as utils from './utils.js';\n\nimport * as draw from './draw.js';\nimport * as framebuffers from './framebuffers.js';\nimport * as programs from './programs.js';\nimport * as typedarrays from './typedarrays.js';\nimport * as vertexArrays from './vertex-arrays.js';\n\n/**\n * The main TWGL module.\n *\n * For most use cases you shouldn't need anything outside this module.\n * Exceptions between the stuff added to twgl-full (v3, m4, primitives)\n *\n * @module twgl\n * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray\n * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays\n * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo\n * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo\n * @borrows module:twgl/draw.drawObjectList as drawObjectList\n * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo\n * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo\n * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo\n * @borrows module:twgl/programs.createProgramInfo as createProgramInfo\n * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo\n * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock\n * @borrows module:twgl/programs.setUniformBlock as setUniformBlock\n * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms\n * @borrows module:twgl/programs.setUniforms as setUniforms\n * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes\n * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray\n * @borrows module:twgl/textures.createTexture as createTexture\n * @borrows module:twgl/textures.resizeTexture as resizeTexture\n * @borrows module:twgl/textures.createTextures as createTextures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n addExtensionsToContext: true,\n};\n\n/**\n * Various default settings for twgl.\n *\n * Note: You can call this any number of times. Example:\n *\n * twgl.setDefaults({ textureColor: [1, 0, 0, 1] });\n * twgl.setDefaults({ attribPrefix: 'a_' });\n *\n * is equivalent to\n *\n * twgl.setDefaults({\n * textureColor: [1, 0, 0, 1],\n * attribPrefix: 'a_',\n * });\n *\n * @typedef {Object} Defaults\n * @property {string} [attribPrefix] The prefix to stick on attributes\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * const arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * Default: `\"\"`\n *\n * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * Default: `[0.5, 0.75, 1, 1]`\n *\n * @property {string} [crossOrigin]\n *\n * If not undefined sets the crossOrigin attribute on images\n * that twgl creates when downloading images for textures.\n *\n * Also see {@link module:twgl.TextureOptions}.\n *\n * @property {bool} [addExtensionsToContext]\n *\n * If true, then, when twgl will try to add any supported WebGL extensions\n * directly to the context under their normal GL names. For example\n * if ANGLE_instances_arrays exists then twgl would enable it,\n * add the functions `vertexAttribDivisor`, `drawArraysInstanced`,\n * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR`\n * to the `WebGLRenderingContext`.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Sets various defaults for twgl.\n *\n * In the interest of terseness which is kind of the point\n * of twgl I've integrated a few of the older functions here\n *\n * @param {module:twgl.Defaults} newDefaults The default settings.\n * @memberOf module:twgl\n */\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line\n textures.setTextureDefaults_(newDefaults); // eslint-disable-line\n}\n\nconst prefixRE = /^(.*?)_/;\nfunction addExtensionToContext(gl, extensionName) {\n utils.glEnumToString(gl, 0);\n const ext = gl.getExtension(extensionName);\n if (ext) {\n const enums = {};\n const fnSuffix = prefixRE.exec(extensionName)[1];\n const enumSuffix = '_' + fnSuffix;\n for (const key in ext) {\n const value = ext[key];\n const isFunc = typeof (value) === 'function';\n const suffix = isFunc ? fnSuffix : enumSuffix;\n let name = key;\n // examples of where this is not true are WEBGL_compressed_texture_s3tc\n // and WEBGL_compressed_texture_pvrtc\n if (key.endsWith(suffix)) {\n name = key.substring(0, key.length - suffix.length);\n }\n if (gl[name] !== undefined) {\n if (!isFunc && gl[name] !== value) {\n helper.warn(name, gl[name], value, key);\n }\n } else {\n if (isFunc) {\n gl[name] = function(origFn) {\n return function() {\n return origFn.apply(ext, arguments);\n };\n }(value);\n } else {\n gl[name] = value;\n enums[name] = value;\n }\n }\n }\n // pass the modified enums to glEnumToString\n enums.constructor = {\n name: ext.constructor.name,\n };\n utils.glEnumToString(enums, 0);\n }\n return ext;\n}\n\n/*\n * If you're wondering why the code doesn't just iterate\n * over all extensions using `gl.getExtensions` is that it's possible\n * some future extension is incompatible with this code. Rather than\n * have thing suddenly break it seems better to manually add to this\n * list.\n *\n */\nconst supportedExtensions = [\n 'ANGLE_instanced_arrays',\n 'EXT_blend_minmax',\n 'EXT_color_buffer_float',\n 'EXT_color_buffer_half_float',\n 'EXT_disjoint_timer_query',\n 'EXT_disjoint_timer_query_webgl2',\n 'EXT_frag_depth',\n 'EXT_sRGB',\n 'EXT_shader_texture_lod',\n 'EXT_texture_filter_anisotropic',\n 'OES_element_index_uint',\n 'OES_standard_derivatives',\n 'OES_texture_float',\n 'OES_texture_float_linear',\n 'OES_texture_half_float',\n 'OES_texture_half_float_linear',\n 'OES_vertex_array_object',\n 'WEBGL_color_buffer_float',\n 'WEBGL_compressed_texture_atc',\n 'WEBGL_compressed_texture_etc1',\n 'WEBGL_compressed_texture_pvrtc',\n 'WEBGL_compressed_texture_s3tc',\n 'WEBGL_compressed_texture_s3tc_srgb',\n 'WEBGL_depth_texture',\n 'WEBGL_draw_buffers',\n];\n\n/**\n * Attempts to enable all of the following extensions\n * and add their functions and constants to the\n * `WebGLRenderingContext` using their normal non-extension like names.\n *\n * ANGLE_instanced_arrays\n * EXT_blend_minmax\n * EXT_color_buffer_float\n * EXT_color_buffer_half_float\n * EXT_disjoint_timer_query\n * EXT_disjoint_timer_query_webgl2\n * EXT_frag_depth\n * EXT_sRGB\n * EXT_shader_texture_lod\n * EXT_texture_filter_anisotropic\n * OES_element_index_uint\n * OES_standard_derivatives\n * OES_texture_float\n * OES_texture_float_linear\n * OES_texture_half_float\n * OES_texture_half_float_linear\n * OES_vertex_array_object\n * WEBGL_color_buffer_float\n * WEBGL_compressed_texture_atc\n * WEBGL_compressed_texture_etc1\n * WEBGL_compressed_texture_pvrtc\n * WEBGL_compressed_texture_s3tc\n * WEBGL_compressed_texture_s3tc_srgb\n * WEBGL_depth_texture\n * WEBGL_draw_buffers\n *\n * For example if `ANGLE_instanced_arrays` exists then the functions\n * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor`\n * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the\n * `WebGLRenderingContext`.\n *\n * Note that if you want to know if the extension exists you should\n * probably call `gl.getExtension` for each extension. Alternatively\n * you can check for the existence of the functions or constants that\n * are expected to be added. For example\n *\n * if (gl.drawBuffers) {\n * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2\n * ....\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @memberOf module:twgl\n */\nfunction addExtensionsToContext(gl) {\n for (let ii = 0; ii < supportedExtensions.length; ++ii) {\n addExtensionToContext(gl, supportedExtensions[ii]);\n }\n}\n\n/**\n * Creates a webgl context.\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n * @private\n */\nfunction create3DContext(canvas, opt_attribs) {\n const names = [\"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL1 context.\n *\n * Note: Will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n * @deprecated\n * @private\n */\nfunction getWebGLContext(canvas, opt_attribs) {\n const gl = create3DContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Creates a webgl context.\n *\n * Will return a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * twgl.isWebGL2(gl);\n *\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n */\nfunction createContext(canvas, opt_attribs) {\n const names = [\"webgl2\", \"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL context. Will create a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * function isWebGL2(gl) {\n * return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0 \") == 0;\n * }\n *\n * Note: For a WebGL1 context will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n */\nfunction getContext(canvas, opt_attribs) {\n const gl = createContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Resize a canvas to match the size it's displayed.\n * @param {HTMLCanvasElement} canvas The canvas to resize.\n * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to.\n * @return {boolean} true if the canvas was resized.\n * @memberOf module:twgl\n */\nfunction resizeCanvasToDisplaySize(canvas, multiplier) {\n multiplier = multiplier || 1;\n multiplier = Math.max(0, multiplier);\n const width = canvas.clientWidth * multiplier | 0;\n const height = canvas.clientHeight * multiplier | 0;\n if (canvas.width !== width || canvas.height !== height) {\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n return false;\n}\n\nexport {\n addExtensionsToContext,\n getContext,\n getWebGLContext,\n resizeCanvasToDisplaySize,\n setDefaults,\n\n attributes,\n draw,\n framebuffers,\n programs,\n textures,\n typedarrays,\n utils,\n vertexArrays,\n};\n\n// function notPrivate(name) {\n// return name[name.length - 1] !== '_';\n// }\n//\n// function copyPublicProperties(src, dst) {\n// Object.keys(src).filter(notPrivate).forEach(function(key) {\n// dst[key] = src[key];\n// });\n// return dst;\n// }\n\nexport * from './attributes.js';\nexport * from './draw.js';\nexport * from './framebuffers.js';\nexport * from './programs.js';\nexport * from './textures.js';\nexport * from './typedarrays.js';\nexport * from './utils.js';\nexport * from './vertex-arrays.js';\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Low level shader typed array related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.typedArray` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/typedArray\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst glTypeToTypedArray = {};\n{\n const tt = glTypeToTypedArray;\n tt[BYTE] = Int8Array;\n tt[UNSIGNED_BYTE] = Uint8Array;\n tt[SHORT] = Int16Array;\n tt[UNSIGNED_SHORT] = Uint16Array;\n tt[INT] = Int32Array;\n tt[UNSIGNED_INT] = Uint32Array;\n tt[FLOAT] = Float32Array;\n tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array;\n tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array;\n tt[UNSIGNED_SHORT_5_6_5] = Uint16Array;\n tt[HALF_FLOAT] = Uint16Array;\n tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array;\n tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array;\n tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array;\n tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array;\n tt[UNSIGNED_INT_24_8] = Uint32Array;\n}\n\n/**\n * Get the GL type for a typedArray\n * @param {ArrayBufferView} typedArray a typedArray\n * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will\n * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArray(typedArray) {\n if (typedArray instanceof Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArray instanceof Int32Array) { return INT; } // eslint-disable-line\n if (typedArray instanceof Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArray instanceof Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the GL type for a typedArray type\n * @param {ArrayBufferView} typedArrayType a typedArray constructor\n * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will\n * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArrayType === Int32Array) { return INT; } // eslint-disable-line\n if (typedArrayType === Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArrayType === Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the typed array constructor for a given GL type\n * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`)\n * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`).\n * @memberOf module:twgl/typedArray\n */\nfunction getTypedArrayTypeForGLType(type) {\n const CTOR = glTypeToTypedArray[type];\n if (!CTOR) {\n throw new Error('unknown gl type');\n }\n return CTOR;\n}\n\nconst isArrayBuffer = typeof SharedArrayBuffer !== 'undefined'\n ? function isArrayBufferOrSharedArrayBuffer(a) {\n return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer);\n }\n : function isArrayBuffer(a) {\n return a && a.buffer && a.buffer instanceof ArrayBuffer;\n };\n\nexport {\n getGLTypeForTypedArray,\n getGLTypeForTypedArrayType,\n getTypedArrayTypeForGLType,\n isArrayBuffer,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Gets the gl version as a number\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {number} version of gl\n * @private\n */\n//function getVersionAsNumber(gl) {\n// return parseFloat(gl.getParameter(gl.VERSION).substr(6));\n//}\n\n/**\n * Check if context is WebGL 2.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 2.0\n * @memberOf module:twgl\n */\nfunction isWebGL2(gl) {\n // This is the correct check but it's slow\n // return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0\") === 0;\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGL2RenderingContext;\n return !!gl.texStorage2D;\n}\n\n/**\n * Check if context is WebGL 1.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 1.0\n * @memberOf module:twgl\n */\nfunction isWebGL1(gl) {\n // This is the correct check but it's slow\n // const version = getVersionAsNumber(gl);\n // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGLRenderingContext;\n return !gl.texStorage2D;\n}\n\n/**\n * Gets a string for WebGL enum\n *\n * Note: Several enums are the same. Without more\n * context (which function) it's impossible to always\n * give the correct enum. As it is, for matching values\n * it gives all enums. Checking the WebGL2RenderingContext\n * that means\n *\n * 0 = ZERO | POINT | NONE | NO_ERROR\n * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT\n * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB\n * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING\n * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING\n * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING\n *\n * It's also not useful for bits really unless you pass in individual bits.\n * In other words\n *\n * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT;\n * twgl.glEnumToString(gl, bits); // not going to work\n *\n * Note that some enums only exist on extensions. If you\n * want them to show up you need to pass the extension at least\n * once. For example\n *\n * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc');\n * if (ext) {\n * twgl.glEnumToString(ext, 0); // just prime the function\n *\n * ..later..\n *\n * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT;\n * console.log(twgl.glEnumToString(gl, internalFormat));\n *\n * Notice I didn't have to pass the extension the second time. This means\n * you can have place that generically gets an enum for texture formats for example.\n * and as long as you primed the function with the extensions\n *\n * If you're using `twgl.addExtensionsToContext` to enable your extensions\n * then twgl will automatically get the extension's enums.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object\n * @param {number} value the value of the enum you want to look up.\n * @return {string} enum string or hex value\n * @memberOf module:twgl\n * @function glEnumToString\n */\nconst glEnumToString = (function() {\n const haveEnumsForType = {};\n const enums = {};\n\n function addEnums(gl) {\n const type = gl.constructor.name;\n if (!haveEnumsForType[type]) {\n for (const key in gl) {\n if (typeof gl[key] === 'number') {\n const existing = enums[gl[key]];\n enums[gl[key]] = existing ? `${existing} | ${key}` : key;\n }\n }\n haveEnumsForType[type] = true;\n }\n }\n\n return function glEnumToString(gl, value) {\n addEnums(gl);\n return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value);\n };\n}());\n\nexport {\n glEnumToString,\n isWebGL1,\n isWebGL2,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n *\n * Vec3 math math functions.\n *\n * Almost all functions take an optional `dst` argument. If it is not passed in the\n * functions will create a new Vec3. In other words you can do this\n *\n * var v = v3.cross(v1, v2); // Creates a new Vec3 with the cross product of v1 x v2.\n *\n * or\n *\n * var v = v3.create();\n * v3.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v\n *\n * The first style is often easier but depending on where it's used it generates garbage where\n * as there is almost never allocation with the second style.\n *\n * It is always save to pass any vector as the destination. So for example\n *\n * v3.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1\n *\n * @module twgl/v3\n */\n\nlet VecType = Float32Array;\n\n/**\n * A JavaScript array with 3 values or a Float32Array with 3 values.\n * When created by the library will create the default type which is `Float32Array`\n * but can be set by calling {@link module:twgl/v3.setDefaultType}.\n * @typedef {(number[]|Float32Array)} Vec3\n * @memberOf module:twgl/v3\n */\n\n/**\n * Sets the type this library creates for a Vec3\n * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array`\n * @return {constructor} previous constructor for Vec3\n * @memberOf module:twgl/v3\n */\nfunction setDefaultType(ctor) {\n const oldType = VecType;\n VecType = ctor;\n return oldType;\n}\n\n/**\n * Creates a vec3; may be called with x, y, z to set initial values.\n * @param {number} [x] Initial x value.\n * @param {number} [y] Initial y value.\n * @param {number} [z] Initial z value.\n * @return {module:twgl/v3.Vec3} the created vector\n * @memberOf module:twgl/v3\n */\nfunction create(x, y, z) {\n const dst = new VecType(3);\n if (x) {\n dst[0] = x;\n }\n if (y) {\n dst[1] = y;\n }\n if (z) {\n dst[2] = z;\n }\n return dst;\n}\n\n/**\n * Adds two vectors; assumes a and b have the same dimension.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} A vector tha tis the sum of a and b.\n * @memberOf module:twgl/v3\n */\nfunction add(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] + b[0];\n dst[1] = a[1] + b[1];\n dst[2] = a[2] + b[2];\n\n return dst;\n}\n\n/**\n * Subtracts two vectors.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} A vector that is the difference of a and b.\n * @memberOf module:twgl/v3\n */\nfunction subtract(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] - b[0];\n dst[1] = a[1] - b[1];\n dst[2] = a[2] - b[2];\n\n return dst;\n}\n\n/**\n * Performs linear interpolation on two vectors.\n * Given vectors a and b and interpolation coefficient t, returns\n * a + t * (b - a).\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {number} t Interpolation coefficient.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The linear interpolated result.\n * @memberOf module:twgl/v3\n */\nfunction lerp(a, b, t, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] + t * (b[0] - a[0]);\n dst[1] = a[1] + t * (b[1] - a[1]);\n dst[2] = a[2] + t * (b[2] - a[2]);\n\n return dst;\n}\n\n/**\n * Performs linear interpolation on two vectors.\n * Given vectors a and b and interpolation coefficient vector t, returns\n * a + t * (b - a).\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} t Interpolation coefficients vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} the linear interpolated result.\n * @memberOf module:twgl/v3\n */\nfunction lerpV(a, b, t, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] + t[0] * (b[0] - a[0]);\n dst[1] = a[1] + t[1] * (b[1] - a[1]);\n dst[2] = a[2] + t[2] * (b[2] - a[2]);\n\n return dst;\n}\n\n/**\n * Return max values of two vectors.\n * Given vectors a and b returns\n * [max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2])].\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The max components vector.\n * @memberOf module:twgl/v3\n */\nfunction max(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = Math.max(a[0], b[0]);\n dst[1] = Math.max(a[1], b[1]);\n dst[2] = Math.max(a[2], b[2]);\n\n return dst;\n}\n\n/**\n * Return min values of two vectors.\n * Given vectors a and b returns\n * [min(a[0], b[0]), min(a[1], b[1]), min(a[2], b[2])].\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The min components vector.\n * @memberOf module:twgl/v3\n */\nfunction min(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = Math.min(a[0], b[0]);\n dst[1] = Math.min(a[1], b[1]);\n dst[2] = Math.min(a[2], b[2]);\n\n return dst;\n}\n\n/**\n * Multiplies a vector by a scalar.\n * @param {module:twgl/v3.Vec3} v The vector.\n * @param {number} k The scalar.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The scaled vector.\n * @memberOf module:twgl/v3\n */\nfunction mulScalar(v, k, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = v[0] * k;\n dst[1] = v[1] * k;\n dst[2] = v[2] * k;\n\n return dst;\n}\n\n/**\n * Divides a vector by a scalar.\n * @param {module:twgl/v3.Vec3} v The vector.\n * @param {number} k The scalar.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The scaled vector.\n * @memberOf module:twgl/v3\n */\nfunction divScalar(v, k, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = v[0] / k;\n dst[1] = v[1] / k;\n dst[2] = v[2] / k;\n\n return dst;\n}\n\n/**\n * Computes the cross product of two vectors; assumes both vectors have\n * three entries.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The vector of a cross b.\n * @memberOf module:twgl/v3\n */\nfunction cross(a, b, dst) {\n dst = dst || new VecType(3);\n\n const t1 = a[2] * b[0] - a[0] * b[2];\n const t2 = a[0] * b[1] - a[1] * b[0];\n dst[0] = a[1] * b[2] - a[2] * b[1];\n dst[1] = t1;\n dst[2] = t2;\n\n return dst;\n}\n\n/**\n * Computes the dot product of two vectors; assumes both vectors have\n * three entries.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @return {number} dot product\n * @memberOf module:twgl/v3\n */\nfunction dot(a, b) {\n return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);\n}\n\n/**\n * Computes the length of vector\n * @param {module:twgl/v3.Vec3} v vector.\n * @return {number} length of vector.\n * @memberOf module:twgl/v3\n */\nfunction length(v) {\n return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);\n}\n\n/**\n * Computes the square of the length of vector\n * @param {module:twgl/v3.Vec3} v vector.\n * @return {number} square of the length of vector.\n * @memberOf module:twgl/v3\n */\nfunction lengthSq(v) {\n return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];\n}\n\n/**\n * Computes the distance between 2 points\n * @param {module:twgl/v3.Vec3} a vector.\n * @param {module:twgl/v3.Vec3} b vector.\n * @return {number} distance between a and b\n * @memberOf module:twgl/v3\n */\nfunction distance(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Computes the square of the distance between 2 points\n * @param {module:twgl/v3.Vec3} a vector.\n * @param {module:twgl/v3.Vec3} b vector.\n * @return {number} square of the distance between a and b\n * @memberOf module:twgl/v3\n */\nfunction distanceSq(a, b) {\n const dx = a[0] - b[0];\n const dy = a[1] - b[1];\n const dz = a[2] - b[2];\n return dx * dx + dy * dy + dz * dz;\n}\n\n/**\n * Divides a vector by its Euclidean length and returns the quotient.\n * @param {module:twgl/v3.Vec3} a The vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The normalized vector.\n * @memberOf module:twgl/v3\n */\nfunction normalize(a, dst) {\n dst = dst || new VecType(3);\n\n const lenSq = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];\n const len = Math.sqrt(lenSq);\n if (len > 0.00001) {\n dst[0] = a[0] / len;\n dst[1] = a[1] / len;\n dst[2] = a[2] / len;\n } else {\n dst[0] = 0;\n dst[1] = 0;\n dst[2] = 0;\n }\n\n return dst;\n}\n\n/**\n * Negates a vector.\n * @param {module:twgl/v3.Vec3} v The vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} -v.\n * @memberOf module:twgl/v3\n */\nfunction negate(v, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = -v[0];\n dst[1] = -v[1];\n dst[2] = -v[2];\n\n return dst;\n}\n\n/**\n * Copies a vector.\n * @param {module:twgl/v3.Vec3} v The vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} A copy of v.\n * @memberOf module:twgl/v3\n */\nfunction copy(v, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = v[0];\n dst[1] = v[1];\n dst[2] = v[2];\n\n return dst;\n}\n\n/**\n * Multiplies a vector by another vector (component-wise); assumes a and\n * b have the same length.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The vector of products of entries of a and\n * b.\n * @memberOf module:twgl/v3\n */\nfunction multiply(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] * b[0];\n dst[1] = a[1] * b[1];\n dst[2] = a[2] * b[2];\n\n return dst;\n}\n\n/**\n * Divides a vector by another vector (component-wise); assumes a and\n * b have the same length.\n * @param {module:twgl/v3.Vec3} a Operand vector.\n * @param {module:twgl/v3.Vec3} b Operand vector.\n * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created.\n * @return {module:twgl/v3.Vec3} The vector of quotients of entries of a and\n * b.\n * @memberOf module:twgl/v3\n */\nfunction divide(a, b, dst) {\n dst = dst || new VecType(3);\n\n dst[0] = a[0] / b[0];\n dst[1] = a[1] / b[1];\n dst[2] = a[2] / b[2];\n\n return dst;\n}\n\nexport {\n add,\n copy,\n create,\n cross,\n distance,\n distanceSq,\n divide,\n divScalar,\n dot,\n lerp,\n lerpV,\n length,\n lengthSq,\n max,\n min,\n mulScalar,\n multiply,\n negate,\n normalize,\n setDefaultType,\n subtract,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\n/**\n * vertex array object related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/vertexArrays\n */\n\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\n\n/**\n * @typedef {Object} VertexArrayInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object\n * @memberOf module:twgl\n */\n\n/**\n * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects\n * assign buffers to specific attributes at creation time. That means they can only be used with programs\n * who's attributes use the same attribute locations for the same purposes.\n *\n * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo}\n * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match.\n *\n * also\n *\n * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object\n * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES**\n * will affect the Vertex Array Object state.\n *\n * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n *\n * You need to make sure every attribute that will be used is bound. So for example assume shader 1\n * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo\n * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't\n * now attribute D's location.\n *\n * So, you can pass in both shader 1 and shader 2's programInfo\n *\n * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVertexArrayInfo(gl, programInfos, bufferInfo) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n if (!programInfos.length) {\n programInfos = [programInfos];\n }\n programInfos.forEach(function(programInfo) {\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n });\n gl.bindVertexArray(null);\n return {\n numElements: bufferInfo.numElements,\n elementType: bufferInfo.elementType,\n vertexArrayObject: vao,\n };\n}\n\n/**\n * Creates a vertex array object and then sets the attributes on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} attribs AttribInfos mapped by attribute name.\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOAndSetAttributes(gl, setters, attribs, indices) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n programs.setAttributes(setters, attribs);\n if (indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, indices);\n }\n // We unbind this because otherwise any change to ELEMENT_ARRAY_BUFFER\n // like when creating buffers for other stuff will mess up this VAO's binding\n gl.bindVertexArray(null);\n return vao;\n}\n\n/**\n * Creates a vertex array object and then sets the attributes\n * on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {Object.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOFromBufferInfo(gl, programInfo, bufferInfo) {\n return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices);\n}\n\nexport {\n createVertexArrayInfo,\n createVAOAndSetAttributes,\n createVAOFromBufferInfo,\n};\n\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/twgl-full.js\");\n",""],"names":["typedArrays","_interopRequireWildcard","require","helper","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","_typeof","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","STATIC_DRAW","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","BUFFER_SIZE","BYTE","UNSIGNED_BYTE","SHORT","UNSIGNED_SHORT","INT","UNSIGNED_INT","FLOAT","gl","undefined","defaults","attribPrefix","setAttributePrefix","prefix","setDefaults","newDefaults","copyExistingProperties","setBufferFromTypedArray","type","buffer","array","drawType","bindBuffer","bufferData","createBufferFromTypedArray","typedArray","isBuffer","createBuffer","isIndices","name","getNormalizationForTypedArrayType","typedArrayType","Int8Array","Uint8Array","getArray","length","data","texcoordRE","colorRE","guessNumComponentsFromName","numComponents","test","Error","concat","getNumComponents","arrayName","numValues","size","makeTypedArray","isArrayBuffer","Array","isArray","Type","typedArrayTypeFromGLTypeOrTypedArrayCtor","Uint16Array","Float32Array","glTypeFromGLTypeOrTypedArrayType","glTypeOrTypedArrayCtor","getGLTypeForTypedArrayType","getTypedArrayTypeForGLType","attribBufferFromBuffer","arrayType","attribBufferFromSize","numBytes","BYTES_PER_ELEMENT","attribBufferFromArrayLike","constructor","getGLTypeForTypedArray","createAttribsFromArrays","arrays","attribs","keys","forEach","attribName","attrib","value","fn","WebGLBuffer","_fn","normalization","normalize","stride","offset","divisor","setAttribInfoBufferFromArray","attribInfo","bufferSubData","getBytesPerValueForGLType","positionKeys","getNumElementsFromNonIndexedArrays","key","ii","numElements","getNumElementsFromAttributes","getBufferParameter","bytesPerValue","totalElements","createBufferInfoFromArrays","srcBufferInfo","newAttribs","bufferInfo","assign","indices","newIndices","elementType","createBufferFromArray","createBuffersFromArrays","buffers","programs","TRIANGLES","drawBufferInfo","count","instanceCount","drawElementsInstanced","drawElements","drawArraysInstanced","drawArrays","drawObjectList","objectsToDraw","lastUsedProgramInfo","lastUsedBufferInfo","object","active","programInfo","vertexArrayInfo","bindBuffers","useProgram","program","vertexArrayObject","bindVertexArray","setBuffersAndAttributes","setUniforms","uniforms","textures","FRAMEBUFFER","RENDERBUFFER","TEXTURE_2D","DEPTH_COMPONENT","RGBA","DEPTH_COMPONENT24","DEPTH_COMPONENT32F","DEPTH24_STENCIL8","DEPTH32F_STENCIL8","RGBA4","RGB5_A1","RGB565","DEPTH_COMPONENT16","STENCIL_INDEX","STENCIL_INDEX8","DEPTH_STENCIL","COLOR_ATTACHMENT0","DEPTH_ATTACHMENT","STENCIL_ATTACHMENT","DEPTH_STENCIL_ATTACHMENT","CLAMP_TO_EDGE","LINEAR","defaultAttachments","format","min","wrap","attachmentsByFormat","getAttachmentPointForFormat","internalFormat","renderbufferFormats","isRenderbufferFormat","MAX_COLOR_ATTACHMENT_POINTS","isColorAttachmentPoint","attachmentPoint","createFramebufferInfo","attachments","width","height","target","fb","createFramebuffer","bindFramebuffer","drawingBufferWidth","drawingBufferHeight","usedColorAttachmentsPoints","framebufferInfo","framebuffer","attachmentOptions","attachment","samples","push","createRenderbuffer","bindRenderbuffer","renderbufferStorageMultisample","renderbufferStorage","textureOptions","auto","minMag","mag","wrapS","wrapT","createTexture","isRenderbuffer","framebufferRenderbuffer","isTexture","layer","framebufferTextureLayer","level","framebufferTexture2D","drawBuffers","resizeFramebufferInfo","ndx","resizeTexture","bindFramebufferInfo","viewport","copyNamedProperties","names","src","dst","error","_console","console","apply","arguments","warn","_console2","isTypeWeakMaps","Map","isType","weakMap","isOfType","s","toString","substring","WebGLRenderbuffer","isShader","WebGLShader","WebGLTexture","isSampler","WebGLSampler","v3","MatType","setDefaultType","ctor","oldType","negate","m","create","fill","copy","identity","transpose","m00","m01","m02","m03","m10","m11","m12","m13","m20","m21","m22","m23","m30","m31","m32","m33","inverse","tmp_0","tmp_1","tmp_2","tmp_3","tmp_4","tmp_5","tmp_6","tmp_7","tmp_8","tmp_9","tmp_10","tmp_11","tmp_12","tmp_13","tmp_14","tmp_15","tmp_16","tmp_17","tmp_18","tmp_19","tmp_20","tmp_21","tmp_22","tmp_23","t0","t1","t2","t3","d","multiply","b","a00","a01","a02","a03","a10","a11","a12","a13","a20","a21","a22","a23","a30","a31","a32","a33","b00","b01","b02","b03","b10","b11","b12","b13","b20","b21","b22","b23","b30","b31","b32","b33","setTranslation","v","getTranslation","getAxis","axis","off","setAxis","perspective","fieldOfViewYInRadians","aspect","zNear","zFar","f","Math","tan","PI","rangeInv","ortho","left","right","bottom","top","near","far","frustum","dx","dy","dz","xAxis","yAxis","zAxis","lookAt","eye","up","subtract","cross","translation","translate","v0","v1","v2","rotationX","angleInRadians","c","cos","sin","rotateX","rotationY","rotateY","rotationZ","rotateZ","axisRotation","x","y","z","sqrt","xx","yy","zz","oneMinusCosine","axisRotate","r00","r01","r02","r10","r11","r12","r20","r21","r22","scaling","scale","transformPoint","transformDirection","transformNormal","mi","attributes","m4","getArray_","getNumComponents_","augmentTypedArray","cursor","jj","reset","opt_index","createAugmentedTypedArray","opt_type","allButIndices","deindexVertices","vertices","newVertices","expandToUnindexed","channel","srcBuffer","dstBuffer","filter","flattenNormals","normals","normal","numNormals","nax","nay","naz","nbx","nby","nbz","ncx","ncy","ncz","nx","ny","nz","applyFuncToV3Array","matrix","len","tmp","reorientDirections","reorientNormals","reorientPositions","reorientVertices","indexOf","createXYQuadVertices","xOffset","yOffset","position","texcoord","createPlaneVertices","depth","subdivisionsWidth","subdivisionsDepth","numVertices","positions","texcoords","numVertsAcross","createSphereVertices","radius","subdivisionsAxis","subdivisionsHeight","opt_startLatitudeInRadians","opt_endLatitudeInRadians","opt_startLongitudeInRadians","opt_endLongitudeInRadians","latRange","longRange","theta","phi","sinTheta","cosTheta","sinPhi","cosPhi","ux","uy","uz","numVertsAround","CUBE_FACE_INDICES","createCubeVertices","k","cornerVertices","faceNormals","uvCoords","faceIndices","uv","createTruncatedConeVertices","bottomRadius","topRadius","radialSubdivisions","verticalSubdivisions","opt_topCap","opt_bottomCap","topCap","bottomCap","extra","vertsAroundEdge","slant","atan2","cosSlant","sinSlant","start","end","ringRadius","expandRLEData","rleData","padding","runLength","element","slice","create3DFVertices","colors","numVerts","color","createCrescentVertices","verticalRadius","outerRadius","innerRadius","thickness","subdivisionsDown","startOffset","endOffset","subdivisionsThick","offsetRange","lerp","createArc","arcRadius","normalMult","normalAdd","uMult","uAdd","uBack","xBack","angle","px","py","pz","add","createSurface","leftArcOffset","rightArcOffset","numVerticesDown","createCylinderVertices","createTorusVertices","bodySubdivisions","startAngle","endAngle","range","radialParts","bodyParts","sliceAngle","sliceSin","ring","ringAngle","xSin","zCos","nextRingIndex","nextSliceIndex","createDiscVertices","divisions","stacks","stackPower","firstIndex","radiusSpan","pointsPerStack","stack","stackRadius","pow","randInt","random","makeRandomVertexColors","options","vColors","rand","numVertsPerColor","vertsPerColor","numSets","createBufferFunc","createBufferInfoFunc","arraySpecPropertyNames","copyElements","dstNdx","createArrayOfSameType","srcArray","arraySrc","newArray","newArraySpec","concatVertices","arrayOfArrays","baseName","_loop","arrayInfo","getLengthOfCombinedArrays","arraySpec","spec","copyArraysToNewArray","base","baseIndex","newArrays","info","duplicateVertices","create3DFBufferInfo","exports","create3DFBuffers","createCubeBufferInfo","createCubeBuffers","createPlaneBufferInfo","createPlaneBuffers","createSphereBufferInfo","createSphereBuffers","createTruncatedConeBufferInfo","createTruncatedConeBuffers","createXYQuadBufferInfo","createXYQuadBuffers","createCrescentBufferInfo","createCrescentBuffers","createCylinderBufferInfo","createCylinderBuffers","createTorusBufferInfo","createTorusBuffers","createDiscBufferInfo","createDiscBuffers","createCresentBufferInfo","createCresentBuffers","createCresentVertices","utils","_regeneratorRuntime","o","Symbol","iterator","asyncIterator","toStringTag","define","enumerable","configurable","writable","Generator","Context","makeInvokeMethod","tryCatch","arg","h","l","GeneratorFunction","GeneratorFunctionPrototype","p","getPrototypeOf","values","g","defineIteratorMethods","_invoke","AsyncIterator","invoke","resolve","__await","then","callInvokeWithMethodAndArg","done","method","delegate","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","TypeError","resultName","next","nextLoc","pushTryEntry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","isNaN","displayName","isGeneratorFunction","mark","setPrototypeOf","awrap","async","Promise","reverse","pop","prev","charAt","stop","rval","handle","complete","finish","_catch","delegateYield","ownKeys","getOwnPropertySymbols","_objectSpread","_defineProperty","getOwnPropertyDescriptors","defineProperties","obj","_toPropertyKey","_toPrimitive","String","toPrimitive","Number","asyncGeneratorStep","gen","reject","_next","_throw","_asyncToGenerator","self","args","err","_slicedToArray","arr","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","_createForOfIteratorHelper","allowArrayLike","it","F","_e","normalCompletion","didErr","step","_e2","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","minLen","_arrayLikeToArray","from","iter","arr2","getElementById","id","document","TEXTURE0","DYNAMIC_DRAW","UNIFORM_BUFFER","TRANSFORM_FEEDBACK_BUFFER","TRANSFORM_FEEDBACK","COMPILE_STATUS","LINK_STATUS","FRAGMENT_SHADER","VERTEX_SHADER","SEPARATE_ATTRIBS","ACTIVE_UNIFORMS","ACTIVE_ATTRIBUTES","TRANSFORM_FEEDBACK_VARYINGS","ACTIVE_UNIFORM_BLOCKS","UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER","UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER","UNIFORM_BLOCK_DATA_SIZE","UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES","FLOAT_VEC2","FLOAT_VEC3","FLOAT_VEC4","INT_VEC2","INT_VEC3","INT_VEC4","BOOL","BOOL_VEC2","BOOL_VEC3","BOOL_VEC4","FLOAT_MAT2","FLOAT_MAT3","FLOAT_MAT4","SAMPLER_2D","SAMPLER_CUBE","SAMPLER_3D","SAMPLER_2D_SHADOW","FLOAT_MAT2x3","FLOAT_MAT2x4","FLOAT_MAT3x2","FLOAT_MAT3x4","FLOAT_MAT4x2","FLOAT_MAT4x3","SAMPLER_2D_ARRAY","SAMPLER_2D_ARRAY_SHADOW","SAMPLER_CUBE_SHADOW","UNSIGNED_INT_VEC2","UNSIGNED_INT_VEC3","UNSIGNED_INT_VEC4","INT_SAMPLER_2D","INT_SAMPLER_3D","INT_SAMPLER_CUBE","INT_SAMPLER_2D_ARRAY","UNSIGNED_INT_SAMPLER_2D","UNSIGNED_INT_SAMPLER_3D","UNSIGNED_INT_SAMPLER_CUBE","UNSIGNED_INT_SAMPLER_2D_ARRAY","TEXTURE_CUBE_MAP","TEXTURE_3D","TEXTURE_2D_ARRAY","typeMap","getBindPointForSamplerType","bindPoint","floatSetter","location","uniform1f","floatArraySetter","uniform1fv","floatVec2Setter","uniform2fv","floatVec3Setter","uniform3fv","floatVec4Setter","uniform4fv","intSetter","uniform1i","intArraySetter","uniform1iv","intVec2Setter","uniform2iv","intVec3Setter","uniform3iv","intVec4Setter","uniform4iv","uintSetter","uniform1ui","uintArraySetter","uniform1uiv","uintVec2Setter","uniform2uiv","uintVec3Setter","uniform3uiv","uintVec4Setter","uniform4uiv","floatMat2Setter","uniformMatrix2fv","floatMat3Setter","uniformMatrix3fv","floatMat4Setter","uniformMatrix4fv","floatMat23Setter","uniformMatrix2x3fv","floatMat32Setter","uniformMatrix3x2fv","floatMat24Setter","uniformMatrix2x4fv","floatMat42Setter","uniformMatrix4x2fv","floatMat34Setter","uniformMatrix3x4fv","floatMat43Setter","uniformMatrix4x3fv","samplerSetter","unit","isWebGL2","textureOrPair","texture","sampler","activeTexture","bindTexture","bindSampler","samplerArraySetter","units","Int32Array","index","setter","arraySetter","cols","Uint32Array","rows","floatAttribSetter","disableVertexAttribArray","vertexAttrib4fv","vertexAttrib3fv","vertexAttrib2fv","vertexAttrib1fv","enableVertexAttribArray","vertexAttribPointer","vertexAttribDivisor","intAttribSetter","vertexAttrib4iv","vertexAttribIPointer","uintAttribSetter","vertexAttrib4uiv","matAttribSetter","typeInfo","defaultSize","rowOffset","attrTypeMap","errorRE","addLineNumbersWithError","log","lineOffset","matches","matchAll","lineNoToErrorMap","map","lineNo","parseInt","msg","split","line","join","spaceRE","prepShaderSource","shaderSource","replace","reportError","progOptions","errorCallback","callback","setTimeout","errors","checkShaderStatus","shaderType","shader","errFn","compiled","getShaderParameter","lastError","getShaderInfoLog","_prepShaderSource","getShaderSource","glEnumToString","getProgramOptions","opt_attribs","opt_locations","opt_errorCallback","transformFeedbackVaryings","transformFeedbackMode","opt","attribLocations","_len","_key","defaultShaderType","getShaderTypeFromScriptType","scriptType","deleteProgramAndShaders","notThese","shaders","getAttachedShaders","_iterator","_step","deleteShader","deleteProgram","wait","ms","createProgramNoCheck","programOptions","createProgram","_getProgramOptions","elem","text","createShader","compileShader","attachShader","entries","_ref","_ref2","loc","bindAttribLocation","varyings","linkProgram","shaderSet","Set","hasErrors","getProgramErrors","waitForProgramLinkCompletionAsync","wrapCallbackFnToAsyncFn","arg1","_len2","_key2","createProgramAsync","createProgramInfoAsync","createProgramInfo","_x","_x2","_waitForProgramLinkCompletionAsync","_callee","ext","checkFn","waitTime","_callee$","_context","getExtension","getProgramParameter","COMPLETION_STATUS_KHR","waitForAllProgramsLinkCompletionAsync","_x3","_x4","_waitForAllProgramsLinkCompletionAsync","_callee2","_i3","_Object$values2","_callee2$","_context2","linked","getProgramInfoLog","SHADER_TYPE","_","createProgramFromScripts","shaderScriptIds","_iterator2","_step2","scriptId","shaderScript","createProgramFromSources","shaderSources","isBuiltIn","startsWith","tokenRE","isDigit","addSetterToUniformTree","fullPath","node","uniformSetters","tokens","tokenNdx","path","token","isArrayIndex","accessor","isLastToken","child","setUniformTree","createUniformSetters","textureUnit","createUniformSetter","uniformInfo","endsWith","uniformTree","numUniforms","getActiveUniform","substr","getUniformLocation","createTransformFeedbackInfo","numVaryings","varying","getTransformFeedbackVarying","bindTransformFeedbackInfo","transformFeedbackInfo","buf","bindBufferRange","bindBufferBase","createTransformFeedback","tf","bindTransformFeedback","createUniformBlockSpecFromProgram","uniformData","uniformIndices","pair","pname","getActiveUniforms","blockSpecs","numUniformBlocks","getActiveUniformBlockName","blockSpec","getUniformBlockIndex","usedByVertexShader","getActiveUniformBlockParameter","usedByFragmentShader","used","arraySuffixRE","pad","createUniformBlockUniformSetter","view","totalRows","row","col","createUniformBlockInfoFromProgram","uniformBlockSpec","blockName","_options$offset","_options$array","_options$buffer","_options$bufferOffset","ArrayBuffer","uniformBufferIndex","byteLength","uniformBlockBinding","setters","setterTree","uniformNdx","uniformView","asFloat","asUint8","bufferOffset","createUniformBlockInfo","bindUniformBlock","uniformBlockInfo","_uniformBlockInfo$siz","bufferBindIndex","setUniformBlock","setBlockUniforms","tree","prop","actualSetters","numArgs","aNdx","setUniformsAndBindTextures","createAttributeSetters","attribSetters","numAttribs","getActiveAttrib","getAttribLocation","setAttributes","createProgramInfoFromProgram","uniformLocations","fromEntries","_ref3","_ref4","_ref5","_ref6","notIdRE","source","script","origCallback","checkAllPrograms","programSpecs","noDeleteShadersSet","_i","_Object$entries","_Object$entries$_i","_i2","_Object$values","_iterator3","_step3","createPrograms","_ref7","_ref8","createProgramInfos","createProgramInfosForPrograms","_ref9","_ref10","createProgramsAsync","createProgramInfosAsync","textureColor","crossOrigin","getShared2DContext","s_ctx","createElement","getContext","ALPHA","RGB","LUMINANCE","LUMINANCE_ALPHA","NEAREST","TEXTURE_CUBE_MAP_POSITIVE_X","TEXTURE_CUBE_MAP_NEGATIVE_X","TEXTURE_CUBE_MAP_POSITIVE_Y","TEXTURE_CUBE_MAP_NEGATIVE_Y","TEXTURE_CUBE_MAP_POSITIVE_Z","TEXTURE_CUBE_MAP_NEGATIVE_Z","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","TEXTURE_WRAP_R","TEXTURE_MIN_LOD","TEXTURE_MAX_LOD","TEXTURE_BASE_LEVEL","TEXTURE_MAX_LEVEL","TEXTURE_COMPARE_MODE","TEXTURE_COMPARE_FUNC","UNPACK_ALIGNMENT","UNPACK_ROW_LENGTH","UNPACK_IMAGE_HEIGHT","UNPACK_SKIP_PIXELS","UNPACK_SKIP_ROWS","UNPACK_SKIP_IMAGES","UNPACK_COLORSPACE_CONVERSION_WEBGL","UNPACK_PREMULTIPLY_ALPHA_WEBGL","UNPACK_FLIP_Y_WEBGL","R8","R8_SNORM","R16F","R32F","R8UI","R8I","RG16UI","RG16I","RG32UI","RG32I","RG8","RG8_SNORM","RG16F","RG32F","RG8UI","RG8I","R16UI","R16I","R32UI","R32I","RGB8","SRGB8","RGB8_SNORM","R11F_G11F_B10F","RGB9_E5","RGB16F","RGB32F","RGB8UI","RGB8I","RGB16UI","RGB16I","RGB32UI","RGB32I","RGBA8","SRGB8_ALPHA8","RGBA8_SNORM","RGB10_A2","RGBA16F","RGBA32F","RGBA8UI","RGBA8I","RGB10_A2UI","RGBA16UI","RGBA16I","RGBA32I","RGBA32UI","UNSIGNED_SHORT_4_4_4_4","UNSIGNED_SHORT_5_5_5_1","UNSIGNED_SHORT_5_6_5","HALF_FLOAT","HALF_FLOAT_OES","UNSIGNED_INT_2_10_10_10_REV","UNSIGNED_INT_10F_11F_11F_REV","UNSIGNED_INT_5_9_9_9_REV","FLOAT_32_UNSIGNED_INT_24_8_REV","UNSIGNED_INT_24_8","RG","RG_INTEGER","RED","RED_INTEGER","RGB_INTEGER","RGBA_INTEGER","formatInfo","numColorComponents","s_textureInternalFormatInfo","getTextureInternalFormatInfo","textureFormat","colorRenderable","textureFilterable","bytesPerElement","bytesPerElementMap","getBytesPerElementForInternalFormat","getFormatAndTypeForInternalFormat","isPowerOf2","canGenerateMipmap","canFilter","getNumComponentsForFormat","getTextureTypeForArrayType","defaultType","guessDimensions","setDefaultTextureColor","scopedSetPackState","colorspaceConversion","premultiplyAlpha","flipY","getParameter","pixelStorei","setSkipStateToDefault","setTextureSamplerParameters","parameteriFn","wrapR","minLod","maxLod","baseLevel","maxLevel","compareFunc","compareMode","setTextureParameters","tex","texParameteri","setSamplerParameters","samplerParameteri","createSampler","createSamplers","samplerOptions","samplers","make1Pixel","setTextureFilteringForSize","generateMipmap","filtering","shouldAutomaticallySetTextureFilteringForSize","getCubeFaceOrder","cubeFaceOrder","getCubeFacesWithNdx","faces","facesWithNdx","face","sort","setTextureFromElement","formatType","imgWidth","imgHeight","slices","nodeName","ctx","canvas","drawImage","texImage2D","createImageBitmap","colorSpaceConversion","imageBitmap","smallest","largest","max","xMult","yMult","texImage3D","srcX","srcY","texSubImage3D","noop","urlIsSameOrigin","url","href","hostname","port","protocol","localOrigin","URL","origin","urlOrigin","setToAnonymousIfUndefinedAndURLIsNotSameOrigin","loadImage","img","Image","clearEventHandlers","removeEventListener","onError","onLoad","addEventListener","ImageBitmap","bm","cb","mode","fetch","response","ok","blob","bitmap","isTexImageSource","ImageData","HTMLElement","loadAndUseImage","setTextureTo1PixelColor","loadTextureFromUrl","loadCubemapFromUrls","urls","numToLoad","imgs","uploadImg","faceTarget","otherTarget","loadSlicesFromUrls","firstImage","setTextureFromArray","Uint8ClampedArray","dimensions","cbrt","unpackAlignment","elementsPerElement","faceSize","subarray","setEmptyTexture","isAsyncSrc","createTextures","numDownloading","images","callCallbackIfReady","onLoadFn","primitives","_twgl","_exportNames","draw","framebuffers","typedarrays","vertexArrays","addExtensionsToContext","setAttributeDefaults_","setTextureDefaults_","prefixRE","addExtensionToContext","extensionName","enums","fnSuffix","exec","enumSuffix","isFunc","suffix","origFn","supportedExtensions","create3DContext","context","getWebGLContext","createContext","resizeCanvasToDisplaySize","multiplier","clientWidth","clientHeight","glTypeToTypedArray","tt","Int16Array","CTOR","SharedArrayBuffer","isArrayBufferOrSharedArrayBuffer","texStorage2D","isWebGL1","haveEnumsForType","addEnums","existing","VecType","lerpV","mulScalar","divScalar","dot","lengthSq","distance","distanceSq","lenSq","divide","createVertexArrayInfo","programInfos","vao","createVertexArray","createVAOAndSetAttributes","createVAOFromBufferInfo"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/6.x/twgl-full.min.js b/dist/6.x/twgl-full.min.js new file mode 100644 index 00000000..98a2bfa4 --- /dev/null +++ b/dist/6.x/twgl-full.min.js @@ -0,0 +1,6 @@ +/*! + * @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. + * Available via the MIT license. + * see: http://github.com/greggman/twgl.js for details + */ +!function(r,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.twgl=t():r.twgl=t()}("undefined"!=typeof self?self:this,(()=>(()=>{"use strict";var r={650:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.createAttribsFromArrays=R,t.createBufferFromArray=k,t.createBufferFromTypedArray=j,t.createBufferInfoFromArrays=function(r,t,e){var n=R(r,t),i=Object.assign({},e||{});i.attribs=Object.assign({},e?e.attribs:{},n);var u=t.indices;if(u){var a=S(u,"indices");i.indices=j(r,a,l),i.numElements=a.length,i.elementType=o.getGLTypeForTypedArray(a)}else i.numElements||(i.numElements=function(r,t){var e,n;for(n=0;n0)throw new Error("numComponents ".concat(i," not correct for length ").concat(o));return u}(t);return e},t.getArray_=_,t.getNumComponents_=A,t.setAttribInfoBufferFromArray=function(r,t,e,n){e=S(e),void 0!==n?(r.bindBuffer(c,t.buffer),r.bufferSubData(c,n,e)):x(r,c,t.buffer,e,t.drawType)},t.setAttributeDefaults_=function(r){i.copyExistingProperties(r,w)},t.setAttributePrefix=function(r){w.attribPrefix=r};var o=a(e(801)),i=a(e(303));function u(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(u=function(r){return r?e:t})(r)}function a(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=u(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=i?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}var f=35044,c=34962,l=34963,s=34660,v=5120,y=5121,b=5122,m=5123,d=5124,p=5125,h=5126,w={attribPrefix:""};function x(r,t,e,n,o){r.bindBuffer(t,e),r.bufferData(t,n,o||f)}function j(r,t,e,n){if(i.isBuffer(r,t))return t;e=e||c;var o=r.createBuffer();return x(r,e,o,t,n),o}function F(r){return"indices"===r}function _(r){return r.length?r:r.data}var O=/coord|texture/i,E=/color|colour/i;function A(r,t,e){return r.numComponents||r.size||function(r,t){var e;if(t%(e=O.test(r)?2:E.test(r)?4:3)>0)throw new Error("Can not guess numComponents for attribute '".concat(r,"'. Tried ").concat(e," but ").concat(t," values is not evenly divisible by ").concat(e,". You should specify it."));return e}(t,e||_(r).length)}function S(r,t){if(o.isArrayBuffer(r))return r;if(o.isArrayBuffer(r.data))return r.data;Array.isArray(r)&&(r={data:r});var e=r.type?M(r.type):void 0;return e||(e=F(t)?Uint16Array:Float32Array),new e(r.data)}function M(r){return"number"==typeof r?o.getTypedArrayTypeForGLType(r):r||Float32Array}function g(r,t){return{buffer:t.buffer,numValues:24,type:(e=t.type,"number"==typeof e?e:e?o.getGLTypeForTypedArrayType(e):h),arrayType:M(t.type)};var e}function T(r,t){var e=t.data||t,n=M(t.type),i=e*n.BYTES_PER_ELEMENT,u=r.createBuffer();return r.bindBuffer(c,u),r.bufferData(c,i,t.drawType||f),{buffer:u,numValues:e,type:o.getGLTypeForTypedArrayType(n),arrayType:n}}function P(r,t,e){var n=S(t,e);return{arrayType:n.constructor,buffer:j(r,n,void 0,t.drawType),type:o.getGLTypeForTypedArray(n),numValues:0}}function R(r,t){var e={};return Object.keys(t).forEach((function(n){if(!F(n)){var i=t[n],u=i.attrib||i.name||i.attribName||w.attribPrefix+n;if(i.value){if(!Array.isArray(i.value)&&!o.isArrayBuffer(i.value))throw new Error("array.value is not array or typedarray");e[u]={value:i.value}}else{var a=(i.buffer&&i.buffer instanceof WebGLBuffer?g:"number"==typeof i||"number"==typeof i.data?T:P)(r,i,n),f=a.buffer,c=a.type,l=a.numValues,s=a.arrayType,v=void 0!==i.normalize?i.normalize:(b=s)===Int8Array||b===Uint8Array,y=A(i,n,l);e[u]={buffer:f,numComponents:y,type:c,normalize:v,stride:i.stride||0,offset:i.offset||0,divisor:void 0===i.divisor?void 0:i.divisor,drawType:i.drawType}}}var b})),r.bindBuffer(c,null),e}var z=["position","positions","a_position"];function k(r,t,e){var n="indices"===e?l:c;return j(r,S(t,e),n)}},341:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.drawBufferInfo=f,t.drawObjectList=function(r,t){var e=null,n=null;t.forEach((function(t){if(!1!==t.active){var i=t.programInfo,a=t.vertexArrayInfo||t.bufferInfo,c=!1,l=void 0===t.type?u:t.type;i!==e&&(e=i,r.useProgram(i.program),c=!0),(c||a!==n)&&(n&&n.vertexArrayObject&&!a.vertexArrayObject&&r.bindVertexArray(null),n=a,o.setBuffersAndAttributes(r,i,a)),o.setUniforms(i,t.uniforms),f(r,a,l,t.count,t.offset,t.instanceCount)}})),n&&n.vertexArrayObject&&r.bindVertexArray(null)};var o=function(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=i(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},u=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=u?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}(e(38));function i(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(i=function(r){return r?e:t})(r)}var u=4,a=5123;function f(r,t,e,n,o,i){e=void 0===e?u:e;var f=t.indices,c=t.elementType,l=void 0===n?t.numElements:n;o=void 0===o?0:o,c||f?void 0!==i?r.drawElementsInstanced(e,l,void 0===c?a:t.elementType,o,i):r.drawElements(e,l,void 0===c?a:t.elementType,o):void 0!==i?r.drawArraysInstanced(e,o,l,i):r.drawArrays(e,o,l)}},167:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.bindFramebufferInfo=function(r,t,e){e=e||f,t?(r.bindFramebuffer(e,t.framebuffer),r.viewport(0,0,t.width,t.height)):(r.bindFramebuffer(e,null),r.viewport(0,0,r.drawingBufferWidth,r.drawingBufferHeight))},t.createFramebufferInfo=function(r,t,e,n){var u=f,a=r.createFramebuffer();r.bindFramebuffer(u,a),e=e||r.drawingBufferWidth,n=n||r.drawingBufferHeight;var s=[],y={framebuffer:a,attachments:[],width:e,height:n};(t=t||p).forEach((function(t,a){var f=t.attachment,b=t.samples,p=t.format,j=t.attachmentPoint||function(r,t){return h[r]||h[t]}(p,t.internalFormat);if(j||(j=v+a),function(r){return r>=v&&r1?r.renderbufferStorageMultisample(c,b,p,e,n):r.renderbufferStorage(c,p,e,n);else{var F=Object.assign({},t);F.width=e,F.height=n,void 0===F.auto&&(F.auto=!1,F.min=F.min||F.minMag||d,F.mag=F.mag||F.minMag||d,F.wrapS=F.wrapS||F.wrap||m,F.wrapT=F.wrapT||F.wrap||m),f=o.createTexture(r,F)}if(i.isRenderbuffer(r,f))r.framebufferRenderbuffer(u,j,c,f);else{if(!i.isTexture(r,f))throw new Error("unknown attachment type");void 0!==t.layer?r.framebufferTextureLayer(u,j,f,t.level||0,t.layer):r.framebufferTexture2D(u,j,t.target||l,f,t.level||0)}y.attachments.push(f)})),r.drawBuffers&&r.drawBuffers(s);return y},t.resizeFramebufferInfo=function(r,t,e,n,u){n=n||r.drawingBufferWidth,u=u||r.drawingBufferHeight,t.width=n,t.height=u,(e=e||p).forEach((function(e,a){var f=t.attachments[a],l=e.format,s=e.samples;if(void 0!==s||i.isRenderbuffer(r,f))r.bindRenderbuffer(c,f),s>1?r.renderbufferStorageMultisample(c,s,l,n,u):r.renderbufferStorage(c,l,n,u);else{if(!i.isTexture(r,f))throw new Error("unknown attachment type");o.resizeTexture(r,f,e,n,u)}}))};var o=a(e(175)),i=a(e(303));function u(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(u=function(r){return r?e:t})(r)}function a(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=u(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=i?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}var f=36160,c=36161,l=3553,s=34041,v=36064,y=36096,b=33306,m=33071,d=9729,p=[{format:6408,type:5121,min:d,wrap:m},{format:s}],h={};h[34041]=b,h[6401]=36128,h[36168]=36128,h[6402]=y,h[33189]=y,h[33190]=y,h[36012]=y,h[35056]=b,h[36013]=b;var w={};w[32854]=!0,w[32855]=!0,w[36194]=!0,w[34041]=!0,w[33189]=!0,w[6401]=!0,w[36168]=!0;var x=32},303:(r,t)=>{function e(r){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},e(r)}t.__esModule=!0,t.copyExistingProperties=function(r,t){Object.keys(t).forEach((function(e){t.hasOwnProperty(e)&&r.hasOwnProperty(e)&&(t[e]=r[e])}))},t.copyNamedProperties=function(r,t,e){r.forEach((function(r){var n=t[r];void 0!==n&&(e[r]=n)}))},t.error=function(){var r;(r=console).error.apply(r,arguments)},t.isBuffer=function(r,t){return"undefined"!=typeof WebGLBuffer&&o(t,"WebGLBuffer")},t.isRenderbuffer=function(r,t){return"undefined"!=typeof WebGLRenderbuffer&&o(t,"WebGLRenderbuffer")},t.isSampler=function(r,t){return"undefined"!=typeof WebGLSampler&&o(t,"WebGLSampler")},t.isShader=function(r,t){return"undefined"!=typeof WebGLShader&&o(t,"WebGLShader")},t.isTexture=function(r,t){return"undefined"!=typeof WebGLTexture&&o(t,"WebGLTexture")},t.warn=function(){var r;(r=console).warn.apply(r,arguments)};var n=new Map;function o(r,t){if(!r||"object"!==e(r))return!1;var o=n.get(t);o||(o=new WeakMap,n.set(t,o));var i=o.get(r);if(void 0===i){var u=Object.prototype.toString.call(r);i=u.substring(8,u.length-1)===t,o.set(r,i)}return i}},362:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.axisRotate=function(r,t,e,n){n=n||new c(16);var o=t[0],i=t[1],u=t[2],a=Math.sqrt(o*o+i*i+u*u),f=(o/=a)*o,l=(i/=a)*i,s=(u/=a)*u,v=Math.cos(e),y=Math.sin(e),b=1-v,m=f+(1-f)*v,d=o*i*b+u*y,p=o*u*b-i*y,h=o*i*b-u*y,w=l+(1-l)*v,x=i*u*b+o*y,j=o*u*b+i*y,F=i*u*b-o*y,_=s+(1-s)*v,O=r[0],E=r[1],A=r[2],S=r[3],M=r[4],g=r[5],T=r[6],P=r[7],R=r[8],z=r[9],k=r[10],U=r[11];n[0]=m*O+d*M+p*R,n[1]=m*E+d*g+p*z,n[2]=m*A+d*T+p*k,n[3]=m*S+d*P+p*U,n[4]=h*O+w*M+x*R,n[5]=h*E+w*g+x*z,n[6]=h*A+w*T+x*k,n[7]=h*S+w*P+x*U,n[8]=j*O+F*M+_*R,n[9]=j*E+F*g+_*z,n[10]=j*A+F*T+_*k,n[11]=j*S+F*P+_*U,r!==n&&(n[12]=r[12],n[13]=r[13],n[14]=r[14],n[15]=r[15]);return n},t.axisRotation=function(r,t,e){e=e||new c(16);var n=r[0],o=r[1],i=r[2],u=Math.sqrt(n*n+o*o+i*i),a=(n/=u)*n,f=(o/=u)*o,l=(i/=u)*i,s=Math.cos(t),v=Math.sin(t),y=1-s;return e[0]=a+(1-a)*s,e[1]=n*o*y+i*v,e[2]=n*i*y-o*v,e[3]=0,e[4]=n*o*y-i*v,e[5]=f+(1-f)*s,e[6]=o*i*y+n*v,e[7]=0,e[8]=n*i*y+o*v,e[9]=o*i*y-n*v,e[10]=l+(1-l)*s,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e},t.copy=l,t.create=function(){return new c(16).fill(0)},t.frustum=function(r,t,e,n,o,i,u){u=u||new c(16);var a=t-r,f=n-e,l=o-i;return u[0]=2*o/a,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=2*o/f,u[6]=0,u[7]=0,u[8]=(r+t)/a,u[9]=(n+e)/f,u[10]=i/l,u[11]=-1,u[12]=0,u[13]=0,u[14]=o*i/l,u[15]=0,u},t.getAxis=function(r,t,e){e=e||o.create();var n=4*t;return e[0]=r[n+0],e[1]=r[n+1],e[2]=r[n+2],e},t.getTranslation=function(r,t){return(t=t||o.create())[0]=r[12],t[1]=r[13],t[2]=r[14],t},t.identity=s,t.inverse=v,t.lookAt=function(r,t,e,n){return n=n||new c(16),u=u||o.create(),a=a||o.create(),f=f||o.create(),o.normalize(o.subtract(r,t,f),f),o.normalize(o.cross(e,f,u),u),o.normalize(o.cross(f,u,a),a),n[0]=u[0],n[1]=u[1],n[2]=u[2],n[3]=0,n[4]=a[0],n[5]=a[1],n[6]=a[2],n[7]=0,n[8]=f[0],n[9]=f[1],n[10]=f[2],n[11]=0,n[12]=r[0],n[13]=r[1],n[14]=r[2],n[15]=1,n},t.multiply=function(r,t,e){e=e||new c(16);var n=r[0],o=r[1],i=r[2],u=r[3],a=r[4],f=r[5],l=r[6],s=r[7],v=r[8],y=r[9],b=r[10],m=r[11],d=r[12],p=r[13],h=r[14],w=r[15],x=t[0],j=t[1],F=t[2],_=t[3],O=t[4],E=t[5],A=t[6],S=t[7],M=t[8],g=t[9],T=t[10],P=t[11],R=t[12],z=t[13],k=t[14],U=t[15];return e[0]=n*x+a*j+v*F+d*_,e[1]=o*x+f*j+y*F+p*_,e[2]=i*x+l*j+b*F+h*_,e[3]=u*x+s*j+m*F+w*_,e[4]=n*O+a*E+v*A+d*S,e[5]=o*O+f*E+y*A+p*S,e[6]=i*O+l*E+b*A+h*S,e[7]=u*O+s*E+m*A+w*S,e[8]=n*M+a*g+v*T+d*P,e[9]=o*M+f*g+y*T+p*P,e[10]=i*M+l*g+b*T+h*P,e[11]=u*M+s*g+m*T+w*P,e[12]=n*R+a*z+v*k+d*U,e[13]=o*R+f*z+y*k+p*U,e[14]=i*R+l*z+b*k+h*U,e[15]=u*R+s*z+m*k+w*U,e},t.negate=function(r,t){return(t=t||new c(16))[0]=-r[0],t[1]=-r[1],t[2]=-r[2],t[3]=-r[3],t[4]=-r[4],t[5]=-r[5],t[6]=-r[6],t[7]=-r[7],t[8]=-r[8],t[9]=-r[9],t[10]=-r[10],t[11]=-r[11],t[12]=-r[12],t[13]=-r[13],t[14]=-r[14],t[15]=-r[15],t},t.ortho=function(r,t,e,n,o,i,u){return(u=u||new c(16))[0]=2/(t-r),u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=2/(n-e),u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=2/(o-i),u[11]=0,u[12]=(t+r)/(r-t),u[13]=(n+e)/(e-n),u[14]=(i+o)/(o-i),u[15]=1,u},t.perspective=function(r,t,e,n,o){o=o||new c(16);var i=Math.tan(.5*Math.PI-.5*r),u=1/(e-n);return o[0]=i/t,o[1]=0,o[2]=0,o[3]=0,o[4]=0,o[5]=i,o[6]=0,o[7]=0,o[8]=0,o[9]=0,o[10]=(e+n)*u,o[11]=-1,o[12]=0,o[13]=0,o[14]=e*n*u*2,o[15]=0,o},t.rotateX=function(r,t,e){e=e||new c(16);var n=r[4],o=r[5],i=r[6],u=r[7],a=r[8],f=r[9],l=r[10],s=r[11],v=Math.cos(t),y=Math.sin(t);e[4]=v*n+y*a,e[5]=v*o+y*f,e[6]=v*i+y*l,e[7]=v*u+y*s,e[8]=v*a-y*n,e[9]=v*f-y*o,e[10]=v*l-y*i,e[11]=v*s-y*u,r!==e&&(e[0]=r[0],e[1]=r[1],e[2]=r[2],e[3]=r[3],e[12]=r[12],e[13]=r[13],e[14]=r[14],e[15]=r[15]);return e},t.rotateY=function(r,t,e){e=e||new c(16);var n=r[0],o=r[1],i=r[2],u=r[3],a=r[8],f=r[9],l=r[10],s=r[11],v=Math.cos(t),y=Math.sin(t);e[0]=v*n-y*a,e[1]=v*o-y*f,e[2]=v*i-y*l,e[3]=v*u-y*s,e[8]=v*a+y*n,e[9]=v*f+y*o,e[10]=v*l+y*i,e[11]=v*s+y*u,r!==e&&(e[4]=r[4],e[5]=r[5],e[6]=r[6],e[7]=r[7],e[12]=r[12],e[13]=r[13],e[14]=r[14],e[15]=r[15]);return e},t.rotateZ=function(r,t,e){e=e||new c(16);var n=r[0],o=r[1],i=r[2],u=r[3],a=r[4],f=r[5],l=r[6],s=r[7],v=Math.cos(t),y=Math.sin(t);e[0]=v*n+y*a,e[1]=v*o+y*f,e[2]=v*i+y*l,e[3]=v*u+y*s,e[4]=v*a-y*n,e[5]=v*f-y*o,e[6]=v*l-y*i,e[7]=v*s-y*u,r!==e&&(e[8]=r[8],e[9]=r[9],e[10]=r[10],e[11]=r[11],e[12]=r[12],e[13]=r[13],e[14]=r[14],e[15]=r[15]);return e},t.rotationX=function(r,t){t=t||new c(16);var e=Math.cos(r),n=Math.sin(r);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e,t[6]=n,t[7]=0,t[8]=0,t[9]=-n,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},t.rotationY=function(r,t){t=t||new c(16);var e=Math.cos(r),n=Math.sin(r);return t[0]=e,t[1]=0,t[2]=-n,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=n,t[9]=0,t[10]=e,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},t.rotationZ=function(r,t){t=t||new c(16);var e=Math.cos(r),n=Math.sin(r);return t[0]=e,t[1]=n,t[2]=0,t[3]=0,t[4]=-n,t[5]=e,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},t.scale=function(r,t,e){e=e||new c(16);var n=t[0],o=t[1],i=t[2];e[0]=n*r[0],e[1]=n*r[1],e[2]=n*r[2],e[3]=n*r[3],e[4]=o*r[4],e[5]=o*r[5],e[6]=o*r[6],e[7]=o*r[7],e[8]=i*r[8],e[9]=i*r[9],e[10]=i*r[10],e[11]=i*r[11],r!==e&&(e[12]=r[12],e[13]=r[13],e[14]=r[14],e[15]=r[15]);return e},t.scaling=function(r,t){return(t=t||new c(16))[0]=r[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=r[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=r[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},t.setAxis=function(r,t,e,n){n!==r&&(n=l(r,n));var o=4*e;return n[o+0]=t[0],n[o+1]=t[1],n[o+2]=t[2],n},t.setDefaultType=function(r){var t=c;return c=r,t},t.setTranslation=function(r,t,e){e=e||s(),r!==e&&(e[0]=r[0],e[1]=r[1],e[2]=r[2],e[3]=r[3],e[4]=r[4],e[5]=r[5],e[6]=r[6],e[7]=r[7],e[8]=r[8],e[9]=r[9],e[10]=r[10],e[11]=r[11]);return e[12]=t[0],e[13]=t[1],e[14]=t[2],e[15]=1,e},t.transformDirection=function(r,t,e){e=e||o.create();var n=t[0],i=t[1],u=t[2];return e[0]=n*r[0]+i*r[4]+u*r[8],e[1]=n*r[1]+i*r[5]+u*r[9],e[2]=n*r[2]+i*r[6]+u*r[10],e},t.transformNormal=function(r,t,e){e=e||o.create();var n=v(r),i=t[0],u=t[1],a=t[2];return e[0]=i*n[0]+u*n[1]+a*n[2],e[1]=i*n[4]+u*n[5]+a*n[6],e[2]=i*n[8]+u*n[9]+a*n[10],e},t.transformPoint=function(r,t,e){e=e||o.create();var n=t[0],i=t[1],u=t[2],a=n*r[3]+i*r[7]+u*r[11]+r[15];return e[0]=(n*r[0]+i*r[4]+u*r[8]+r[12])/a,e[1]=(n*r[1]+i*r[5]+u*r[9]+r[13])/a,e[2]=(n*r[2]+i*r[6]+u*r[10]+r[14])/a,e},t.translate=function(r,t,e){e=e||new c(16);var n=t[0],o=t[1],i=t[2],u=r[0],a=r[1],f=r[2],l=r[3],s=r[4],v=r[5],y=r[6],b=r[7],m=r[8],d=r[9],p=r[10],h=r[11],w=r[12],x=r[13],j=r[14],F=r[15];r!==e&&(e[0]=u,e[1]=a,e[2]=f,e[3]=l,e[4]=s,e[5]=v,e[6]=y,e[7]=b,e[8]=m,e[9]=d,e[10]=p,e[11]=h);return e[12]=u*n+s*o+m*i+w,e[13]=a*n+v*o+d*i+x,e[14]=f*n+y*o+p*i+j,e[15]=l*n+b*o+h*i+F,e},t.translation=function(r,t){return(t=t||new c(16))[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},t.transpose=function(r,t){if((t=t||new c(16))===r){var e;return e=r[1],r[1]=r[4],r[4]=e,e=r[2],r[2]=r[8],r[8]=e,e=r[3],r[3]=r[12],r[12]=e,e=r[6],r[6]=r[9],r[9]=e,e=r[7],r[7]=r[13],r[13]=e,e=r[11],r[11]=r[14],r[14]=e,t}var n=r[0],o=r[1],i=r[2],u=r[3],a=r[4],f=r[5],l=r[6],s=r[7],v=r[8],y=r[9],b=r[10],m=r[11],d=r[12],p=r[13],h=r[14],w=r[15];return t[0]=n,t[1]=a,t[2]=v,t[3]=d,t[4]=o,t[5]=f,t[6]=y,t[7]=p,t[8]=i,t[9]=l,t[10]=b,t[11]=h,t[12]=u,t[13]=s,t[14]=m,t[15]=w,t};var o=function(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=i(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},u=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=u?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}(e(304));function i(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(i=function(r){return r?e:t})(r)}var u,a,f,c=Float32Array;function l(r,t){return(t=t||new c(16))[0]=r[0],t[1]=r[1],t[2]=r[2],t[3]=r[3],t[4]=r[4],t[5]=r[5],t[6]=r[6],t[7]=r[7],t[8]=r[8],t[9]=r[9],t[10]=r[10],t[11]=r[11],t[12]=r[12],t[13]=r[13],t[14]=r[14],t[15]=r[15],t}function s(r){return(r=r||new c(16))[0]=1,r[1]=0,r[2]=0,r[3]=0,r[4]=0,r[5]=1,r[6]=0,r[7]=0,r[8]=0,r[9]=0,r[10]=1,r[11]=0,r[12]=0,r[13]=0,r[14]=0,r[15]=1,r}function v(r,t){t=t||new c(16);var e=r[0],n=r[1],o=r[2],i=r[3],u=r[4],a=r[5],f=r[6],l=r[7],s=r[8],v=r[9],y=r[10],b=r[11],m=r[12],d=r[13],p=r[14],h=r[15],w=y*h,x=p*b,j=f*h,F=p*l,_=f*b,O=y*l,E=o*h,A=p*i,S=o*b,M=y*i,g=o*l,T=f*i,P=s*d,R=m*v,z=u*d,k=m*a,U=u*v,C=s*a,W=e*d,I=m*n,L=e*v,G=s*n,B=e*a,N=u*n,X=w*a+F*v+_*d-(x*a+j*v+O*d),D=x*n+E*v+M*d-(w*n+A*v+S*d),H=j*n+A*a+g*d-(F*n+E*a+T*d),V=O*n+S*a+T*v-(_*n+M*a+g*v),Y=1/(e*X+u*D+s*H+m*V);return t[0]=Y*X,t[1]=Y*D,t[2]=Y*H,t[3]=Y*V,t[4]=Y*(x*u+j*s+O*m-(w*u+F*s+_*m)),t[5]=Y*(w*e+A*s+S*m-(x*e+E*s+M*m)),t[6]=Y*(F*e+E*u+T*m-(j*e+A*u+g*m)),t[7]=Y*(_*e+M*u+g*s-(O*e+S*u+T*s)),t[8]=Y*(P*l+k*b+U*h-(R*l+z*b+C*h)),t[9]=Y*(R*i+W*b+G*h-(P*i+I*b+L*h)),t[10]=Y*(z*i+I*l+B*h-(k*i+W*l+N*h)),t[11]=Y*(C*i+L*l+N*b-(U*i+G*l+B*b)),t[12]=Y*(z*y+C*p+R*f-(U*p+P*f+k*y)),t[13]=Y*(L*p+P*o+I*y-(W*y+G*p+R*o)),t[14]=Y*(W*f+N*p+k*o-(B*p+z*o+I*f)),t[15]=Y*(B*y+U*o+G*f-(L*f+N*y+C*o)),t}},777:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.concatVertices=function(r){for(var t,e={},n=function(){var n=r[o];Object.keys(n).forEach((function(r){e[r]||(e[r]=[]),t||"indices"===r||(t=r);var o=n[r],i=v(o,r),u=s(o).length/i;e[r].push(u)}))},o=0;o=0?x(n,t):e.indexOf("tan")>=0||e.indexOf("binorm")>=0?h(n,t):e.indexOf("norm")>=0&&w(n,t)})),r}function F(r,t,e){return r=r||2,{position:{numComponents:2,data:[(t=t||0)+-1*(r*=.5),(e=e||0)+-1*r,t+1*r,e+-1*r,t+-1*r,e+1*r,t+1*r,e+1*r]},normal:[0,0,1,0,0,1,0,0,1,0,0,1],texcoord:[0,0,1,0,0,1,1,1],indices:[0,1,2,2,1,3]}}function _(r,t,e,n,o){r=r||1,t=t||1,e=e||1,n=n||1,o=o||a.identity();for(var i=(e+1)*(n+1),u=b(3,i),f=b(3,i),c=b(2,i),l=0;l<=n;l++)for(var s=0;s<=e;s++){var v=s/e,y=l/n;u.push(r*v-.5*r,0,t*y-.5*t),f.push(0,1,0),c.push(v,y)}for(var m=e+1,d=b(3,e*n*2,Uint16Array),p=0;p 0");n=n||0,i=i||0;for(var a=(o=o||Math.PI)-n,f=(u=u||2*Math.PI)-i,c=(t+1)*(e+1),l=b(3,c),s=b(3,c),v=b(2,c),y=0;y<=e;y++)for(var m=0;m<=t;m++){var d=m/t,p=y/e,h=f*d+i,w=a*p+n,x=Math.sin(h),j=Math.cos(h),F=Math.sin(w),_=j*F,O=Math.cos(w),E=x*F;l.push(r*_,r*O,r*E),s.push(_,O,E),v.push(1-d,p)}for(var A=t+1,S=b(3,t*e*2,Uint16Array),M=0;Mo?(_=e,F=1,O=t):O=r+j/o*(t-r),-2!==j&&j!==o+2||(O=0,F=0),_-=e/2;for(var E=0;Eo?v.push(0,1,0):0===O?v.push(0,0,0):v.push(A*h,w,S*h),y.push(E/n,1-F)}}for(var M=0;M 0");var a=(u=u||1)-(i=i||0),c=2*(o+1)*4,l=b(3,c),s=b(3,c),v=b(2,c);function y(r,t,e){return r+(t-r)*e}function m(t,e,u,c,b,m){for(var d=0;d<=o;d++){var p=e/1,h=d/o,w=2*(p-.5),x=(i+h*a)*Math.PI,j=Math.sin(x),F=Math.cos(x),_=y(r,t,j),O=w*n,E=F*r,A=j*_;l.push(O,E,A);var S=f.add(f.multiply([0,j,F],u),c);s.push(S),v.push(p*b+m,h)}}for(var d=0;d<2;d++){var p=2*(d/1-.5);m(t,d,[1,1,1],[0,0,0],1,0),m(t,d,[0,0,0],[p,0,0],0,0),m(e,d,[1,1,1],[0,0,0],1,0),m(e,d,[0,0,0],[p,0,0],0,1)}var h=b(3,2*o*4,Uint16Array);function w(r,t){for(var e=0;e0&&d!==t){var x=l+(d+1),j=l+d,F=l+d-v,_=l+(d+1)-v;c.push(x,j,F),c.push(x,F,_)}}l+=t+1}return{position:u,normal:a,texcoord:f,indices:c}}function k(r){return function(t){var e=r.apply(this,Array.prototype.slice.call(arguments,1));return o.createBuffersFromArrays(t,e)}}function U(r){return function(t){var e=r.apply(null,Array.prototype.slice.call(arguments,1));return o.createBufferInfoFromArrays(t,e)}}var C=["numComponents","size","type","normalize","stride","offset","attrib","name","attribName"];function W(r,t,e,n){n=n||0;for(var o=r.length,i=0;i{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.bindTransformFeedbackInfo=Pr,t.bindUniformBlock=Cr,t.createAttributeSetters=Lr,t.createProgram=hr,t.createProgramAsync=void 0,t.createProgramFromScripts=function(r,t,e,n,o){var i,u=br(e,n,o),a=[],f=m(t);try{for(f.s();!(i=f.n()).done;){var c=i.value,l=j(c);if(!l)return vr(u,"unknown script element: ".concat(c));a.push(l.text)}}catch(r){f.e(r)}finally{f.f()}return hr(r,a,u)},t.createProgramFromSources=Or,t.createProgramInfo=Xr,t.createProgramInfoAsync=void 0,t.createProgramInfoFromProgram=Br,t.createProgramInfos=Vr,t.createProgramInfosAsync=void 0,t.createPrograms=Hr,t.createProgramsAsync=void 0,t.createTransformFeedback=function(r,t,e){var n=r.createTransformFeedback();return r.bindTransformFeedback(M,n),r.useProgram(t.program),Pr(r,t,e),r.bindTransformFeedback(M,null),n},t.createTransformFeedbackInfo=Tr,t.createUniformBlockInfo=function(r,t,e){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return Ur(r,t.program,t.uniformBlockSpec,e,n)},t.createUniformBlockInfoFromProgram=Ur,t.createUniformBlockSpecFromProgram=Rr,t.createUniformSetters=gr,t.setAttributes=Gr,t.setBlockUniforms=function(r,t){var e=r.setters;for(var n in t){var o=e[n];if(o)o(t[n])}},t.setBuffersAndAttributes=function(r,t,e){e.vertexArrayObject?r.bindVertexArray(e.vertexArrayObject):(Gr(t.attribSetters||t,e.attribs),e.indices&&r.bindBuffer(E,e.indices))},t.setUniformBlock=function(r,t,e){Cr(r,t,e)&&r.bufferSubData(A,0,e.asUint8,e.offset||0,e.size||0)},t.setUniforms=Ir,t.setUniformsAndBindTextures=void 0;var o=a(e(854)),i=a(e(303));function u(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(u=function(r){return r?e:t})(r)}function a(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=u(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=i?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}function f(){f=function(){return t};var r,t={},e=Object.prototype,o=e.hasOwnProperty,i=Object.defineProperty||function(r,t,e){r[t]=e.value},u="function"==typeof Symbol?Symbol:{},a=u.iterator||"@@iterator",c=u.asyncIterator||"@@asyncIterator",l=u.toStringTag||"@@toStringTag";function s(r,t,e){return Object.defineProperty(r,t,{value:e,enumerable:!0,configurable:!0,writable:!0}),r[t]}try{s({},"")}catch(r){s=function(r,t,e){return r[t]=e}}function v(r,t,e,n){var o=t&&t.prototype instanceof w?t:w,u=Object.create(o.prototype),a=new R(n||[]);return i(u,"_invoke",{value:M(r,e,a)}),u}function y(r,t,e){try{return{type:"normal",arg:r.call(t,e)}}catch(r){return{type:"throw",arg:r}}}t.wrap=v;var b="suspendedStart",m="suspendedYield",d="executing",p="completed",h={};function w(){}function x(){}function j(){}var F={};s(F,a,(function(){return this}));var _=Object.getPrototypeOf,O=_&&_(_(z([])));O&&O!==e&&o.call(O,a)&&(F=O);var E=j.prototype=w.prototype=Object.create(F);function A(r){["next","throw","return"].forEach((function(t){s(r,t,(function(r){return this._invoke(t,r)}))}))}function S(r,t){function e(i,u,a,f){var c=y(r[i],r,u);if("throw"!==c.type){var l=c.arg,s=l.value;return s&&"object"==n(s)&&o.call(s,"__await")?t.resolve(s.__await).then((function(r){e("next",r,a,f)}),(function(r){e("throw",r,a,f)})):t.resolve(s).then((function(r){l.value=r,a(l)}),(function(r){return e("throw",r,a,f)}))}f(c.arg)}var u;i(this,"_invoke",{value:function(r,n){function o(){return new t((function(t,o){e(r,n,t,o)}))}return u=u?u.then(o,o):o()}})}function M(t,e,n){var o=b;return function(i,u){if(o===d)throw new Error("Generator is already running");if(o===p){if("throw"===i)throw u;return{value:r,done:!0}}for(n.method=i,n.arg=u;;){var a=n.delegate;if(a){var f=g(a,n);if(f){if(f===h)continue;return f}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===b)throw o=p,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var c=y(t,e,n);if("normal"===c.type){if(o=n.done?p:m,c.arg===h)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=p,n.method="throw",n.arg=c.arg)}}}function g(t,e){var n=e.method,o=t.iterator[n];if(o===r)return e.delegate=null,"throw"===n&&t.iterator.return&&(e.method="return",e.arg=r,g(t,e),"throw"===e.method)||"return"!==n&&(e.method="throw",e.arg=new TypeError("The iterator does not provide a '"+n+"' method")),h;var i=y(o,t.iterator,e.arg);if("throw"===i.type)return e.method="throw",e.arg=i.arg,e.delegate=null,h;var u=i.arg;return u?u.done?(e[t.resultName]=u.value,e.next=t.nextLoc,"return"!==e.method&&(e.method="next",e.arg=r),e.delegate=null,h):u:(e.method="throw",e.arg=new TypeError("iterator result is not an object"),e.delegate=null,h)}function T(r){var t={tryLoc:r[0]};1 in r&&(t.catchLoc=r[1]),2 in r&&(t.finallyLoc=r[2],t.afterLoc=r[3]),this.tryEntries.push(t)}function P(r){var t=r.completion||{};t.type="normal",delete t.arg,r.completion=t}function R(r){this.tryEntries=[{tryLoc:"root"}],r.forEach(T,this),this.reset(!0)}function z(t){if(t||""===t){var e=t[a];if(e)return e.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var i=-1,u=function e(){for(;++i=0;--i){var u=this.tryEntries[i],a=u.completion;if("root"===u.tryLoc)return n("end");if(u.tryLoc<=this.prev){var f=o.call(u,"catchLoc"),c=o.call(u,"finallyLoc");if(f&&c){if(this.prev=0;--e){var n=this.tryEntries[e];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev=0;--t){var e=this.tryEntries[t];if(e.finallyLoc===r)return this.complete(e.completion,e.afterLoc),P(e),h}},catch:function(r){for(var t=this.tryEntries.length-1;t>=0;--t){var e=this.tryEntries[t];if(e.tryLoc===r){var n=e.completion;if("throw"===n.type){var o=n.arg;P(e)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,e,n){return this.delegate={iterator:z(t),resultName:e,nextLoc:n},"next"===this.method&&(this.arg=r),h}},t}function c(r,t){var e=Object.keys(r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(r);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(r,t).enumerable}))),e.push.apply(e,n)}return e}function l(r){for(var t=1;t=r.length?{done:!0}:{done:!1,value:r[n++]}},e:function(r){throw r},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,u=!0,a=!1;return{s:function(){e=e.call(r)},n:function(){var r=e.next();return u=r.done,r},e:function(r){a=!0,i=r},f:function(){try{u||null==e.return||e.return()}finally{if(a)throw i}}}}function d(r){return function(r){if(Array.isArray(r))return h(r)}(r)||function(r){if("undefined"!=typeof Symbol&&null!=r[Symbol.iterator]||null!=r["@@iterator"])return Array.from(r)}(r)||p(r)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(r,t){if(r){if("string"==typeof r)return h(r,t);var e=Object.prototype.toString.call(r).slice(8,-1);return"Object"===e&&r.constructor&&(e=r.constructor.name),"Map"===e||"Set"===e?Array.from(r):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?h(r,t):void 0}}function h(r,t){(null==t||t>r.length)&&(t=r.length);for(var e=0,n=new Array(t);e1&&void 0!==arguments[1]?arguments[1]:"",e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=d(t.matchAll(cr)),o=new Map(n.map((function(r,e){var o=parseInt(r[1]),i=n[e+1],u=i?i.index:t.length;return[o-1,t.substring(r.index,u)]})));return r.split("\n").map((function(r,t){var n=o.get(t);return"".concat(t+1+e,": ").concat(r).concat(n?"\n\n^^^ ".concat(n):"")})).join("\n")}(f,i,a),"\nError compiling ").concat(o.glEnumToString(r,t),": ").concat(i);return n(c),c}return""}function br(r,t,e){var n,o,i;if("function"==typeof t&&(e=t,t=void 0),"function"==typeof r)e=r,r=void 0;else if(r&&!Array.isArray(r)){var u=r;e=u.errorCallback,r=u.attribLocations,n=u.transformFeedbackVaryings,o=u.transformFeedbackMode,i=u.callback}var a=e||w,f=[],c={errorCallback:function(r){f.push(r);for(var t=arguments.length,e=new Array(t>1?t-1:0),n=1;n0&&void 0!==arguments[0]?arguments[0]:0;return new Promise((function(t){return setTimeout(t,r)}))};function pr(r,t,e){for(var n,o=r.createProgram(),i=br(e),u=i.attribLocations,a=i.transformFeedbackVaryings,f=i.transformFeedbackMode,c=0;c=0?P:n.indexOf("vert")>=0?R:void 0)||y),l=r.createShader(y),r.shaderSource(l,sr(v).shaderSource),r.compileShader(l),r.attachShader(o,l)}}Object.entries(u).forEach((function(t){var e=b(t,2),n=e[0],i=e[1];return r.bindAttribLocation(o,i,n)}));var m=a;return m&&(m.attribs&&(m=m.attribs),Array.isArray(m)||(m=Object.keys(m)),r.transformFeedbackVaryings(o,m,f||z)),r.linkProgram(o),o}function hr(r,t,e,n,o){var i=br(e,n,o),u=new Set(t),a=pr(r,t,i);function f(r,t){var e=_r(r,t,i.errorCallback);return e&&function(r,t,e){var n,o=m(r.getAttachedShaders(t));try{for(o.s();!(n=o.n()).done;){var i=n.value;e.has(i)&&r.deleteShader(i)}}catch(r){o.e(r)}finally{o.f()}r.deleteProgram(t)}(r,t,u),e}if(!i.callback)return f(r,a)?void 0:a;xr(r,a).then((function(){var t=f(r,a);i.callback(t,t?void 0:a)}))}function wr(r){return function(t,e){for(var n=arguments.length,o=new Array(n>2?n-2:0),i=2;i="0"&&r<="9"};function Mr(r,t,e,n){for(var o=r.split(Ar).filter((function(r){return""!==r})),i=0,u="";;){var a=o[i++];u+=a;var f=Sr(a[0]),c=f?parseInt(a):a;if(f&&(u+=o[i++]),i===o.length){e[c]=t;break}var l=o[i++],s="["===l,v=e[c]||(s?[]:{});e[c]=v,e=v,n[u]=n[u]||function(r){return function(t){Wr(r,t)}}(v),u+=l}}function gr(r,t){var e=0;function n(t,n,o){var i,u=n.name.endsWith("[0]"),a=n.type,f=K[a];if(!f)throw new Error("unknown type: 0x".concat(a.toString(16)));if(f.bindPoint){var c=e;e+=n.size,i=u?f.arraySetter(r,a,c,o,n.size):f.setter(r,a,c,o,n.size)}else i=f.arraySetter&&u?f.arraySetter(r,o):f.setter(r,o);return i.location=o,i}for(var o={},i={},u=r.getProgramParameter(t,k),a=0;a4&&void 0!==arguments[4]?arguments[4]:{},c=e.blockSpecs,l=e.uniformData,s=c[n];if(!s)return x("no uniform block object named:",n),{name:n,uniforms:{}};var v=null!==(o=f.offset)&&void 0!==o?o:0,y=null!==(i=f.array)&&void 0!==i?i:new ArrayBuffer(s.size),b=null!==(u=f.buffer)&&void 0!==u?u:r.createBuffer(),m=s.index;r.bindBuffer(A,b),f.buffer||r.bufferData(A,y.byteLength,_),r.uniformBlockBinding(t,s.index,m);var d=n+".";zr.test(d)&&(d=d.replace(zr,"."));var p={},h={},w={};return s.uniformIndices.forEach((function(r){var t=l[r],e=t.name;e.startsWith(d)&&(e=e.substr(d.length));var n=e.endsWith("[0]");n&&(e=e.substr(0,e.length-3));var o=K[t.type],i=o.Type,u=n?kr(o.size,16)*t.size:o.size*t.size,a=new i(y,v+t.offset,u/i.BYTES_PER_ELEMENT);p[e]=a;var f=function(r,t,e,n){if(t||e){n=n||1;var o=r.length/4;return function(t){for(var e=0,i=0,u=0;u2&&void 0!==arguments[2]?arguments[2]:{},n=new Set,o=Object.fromEntries(Object.entries(t).map((function(t){var o=b(t,2),i=o[0],u=o[1],a=l({},e),f=Array.isArray(u)?u:u.shaders;return Array.isArray(u)||Object.assign(a,u),f.forEach(n.add,n),[i,pr(r,f,a)]})));if(!e.callback)return Dr(r,o,t,n,e)?void 0:o;(function(r,t){return Fr.apply(this,arguments)})(r,o).then((function(){var i=Dr(r,o,t,n,e);e.callback(i,i?void 0:o)}))}function Vr(r,t,e){function n(r,t){return Object.fromEntries(Object.entries(t).map((function(t){var e=b(t,2),n=e[0],o=e[1];return[n,Br(r,o)]})))}var o=(e=br(e)).callback;o&&(e.callback=function(t,e){o(t,t?void 0:n(r,e))});var i=Hr(r,t,e);if(!o&&i)return n(r,i)}t.createProgramsAsync=wr(Hr),t.createProgramInfosAsync=wr(Vr)},175:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.canFilter=Tt,t.canGenerateMipmap=gt,t.createSampler=Lt,t.createSamplers=function(r,t){var e={};return Object.keys(t).forEach((function(n){e[n]=Lt(r,t[n])})),e},t.createTexture=te,t.createTextures=function(r,t,e){e=e||Ht;var n=0,o=[],i={},u={};function a(){0===n&&setTimeout((function(){e(o.length?o:void 0,i,u)}),0)}return Object.keys(t).forEach((function(e){var f,c,l=t[e];("string"==typeof(c=l.src)||Array.isArray(c)&&"string"==typeof c[0])&&(f=function(r,t,i){u[e]=i,--n,r&&o.push(r),a()},++n),i[e]=te(r,l,f)})),a(),i},t.getBytesPerElementForInternalFormat=At,t.getFormatAndTypeForInternalFormat=St,t.getNumComponentsForFormat=function(r){var t=_t[r];if(!t)throw"unknown format: "+r;return t.t},t.loadTextureFromUrl=$t,t.resizeTexture=function(r,t,e,n,o,i){n=n||e.width,o=o||e.height,i=i||e.depth;var u=e.target||O;r.bindTexture(u,t);var a,f=e.level||0,c=e.internalFormat||e.format||d,l=St(c),s=e.format||l.format,y=e.src;a=y&&(v(y)||Array.isArray(y)&&"number"==typeof y[0])?e.type||Pt(r,y,l.type):e.type||l.type;if(u===E)for(var b=0;b<6;++b)r.texImage2D(M+b,f,c,n,o,0,s,a,null);else u===A||u===S?r.texImage3D(u,f,c,n,o,i,0,s,a,null):r.texImage2D(u,f,c,n,o,0,s,a,null)},t.setDefaultTextureColor=zt,t.setEmptyTexture=re,t.setSamplerParameters=It,t.setTextureDefaults_=function(r){u.copyExistingProperties(r,s),r.textureColor&&zt(r.textureColor)},t.setTextureFilteringForSize=Gt,t.setTextureFromArray=Qt,t.setTextureFromElement=Dt,t.setTextureParameters=Wt;var o=f(e(854)),i=f(e(801)),u=f(e(303));function a(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(a=function(r){return r?e:t})(r)}function f(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=a(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var u in r)if("default"!==u&&Object.prototype.hasOwnProperty.call(r,u)){var f=i?Object.getOwnPropertyDescriptor(r,u):null;f&&(f.get||f.set)?Object.defineProperty(o,u,f):o[u]=r[u]}return o.default=r,e&&e.set(r,o),o}var c,l,s={textureColor:new Uint8Array([128,192,255,255]),textureOptions:{},crossOrigin:void 0},v=i.isArrayBuffer,y=function(){return c=c||("undefined"!=typeof document&&document.createElement?document.createElement("canvas").getContext("2d"):null)},b=6406,m=6407,d=6408,p=6409,h=6410,w=6402,x=34041,j=33071,F=9728,_=9729,O=3553,E=34067,A=32879,S=35866,M=34069,g=34070,T=34071,P=34072,R=34073,z=34074,k=10241,U=10240,C=10242,W=10243,I=32882,L=33082,G=33083,B=33084,N=33085,X=34892,D=34893,H=3317,V=3314,Y=32878,q=3316,K=3315,$=32877,Z=37443,J=37441,Q=37440,rr=33321,tr=36756,er=33325,nr=33326,or=33330,ir=33329,ur=33338,ar=33337,fr=33340,cr=33339,lr=33323,sr=36757,vr=33327,yr=33328,br=33336,mr=33335,dr=33332,pr=33331,hr=33334,wr=33333,xr=32849,jr=35905,Fr=36194,_r=36758,Or=35898,Er=35901,Ar=34843,Sr=34837,Mr=36221,gr=36239,Tr=36215,Pr=36233,Rr=36209,zr=36227,kr=32856,Ur=35907,Cr=36759,Wr=32855,Ir=32854,Lr=32857,Gr=34842,Br=34836,Nr=36220,Xr=36238,Dr=36975,Hr=36214,Vr=36232,Yr=36226,qr=36208,Kr=33189,$r=33190,Zr=36012,Jr=36013,Qr=35056,rt=5120,tt=5121,et=5122,nt=5123,ot=5124,it=5125,ut=5126,at=32819,ft=32820,ct=33635,lt=5131,st=36193,vt=33640,yt=35899,bt=35902,mt=36269,dt=34042,pt=33319,ht=33320,wt=6403,xt=36244,jt=36248,Ft=36249,_t={},Ot=_t;function Et(r){if(!l){var t={};t[b]={o:b,i:!0,u:!0,l:[1,2,2,4],type:[tt,lt,st,ut]},t[p]={o:p,i:!0,u:!0,l:[1,2,2,4],type:[tt,lt,st,ut]},t[h]={o:h,i:!0,u:!0,l:[2,4,4,8],type:[tt,lt,st,ut]},t[m]={o:m,i:!0,u:!0,l:[3,6,6,12,2],type:[tt,lt,st,ut,ct]},t[d]={o:d,i:!0,u:!0,l:[4,8,8,16,2,2],type:[tt,lt,st,ut,at,ft]},t[w]={o:w,i:!0,u:!1,l:[2,4],type:[it,nt]},t[rr]={o:wt,i:!0,u:!0,l:[1],type:[tt]},t[tr]={o:wt,i:!1,u:!0,l:[1],type:[rt]},t[er]={o:wt,i:!1,u:!0,l:[4,2],type:[ut,lt]},t[nr]={o:wt,i:!1,u:!1,l:[4],type:[ut]},t[or]={o:xt,i:!0,u:!1,l:[1],type:[tt]},t[ir]={o:xt,i:!0,u:!1,l:[1],type:[rt]},t[dr]={o:xt,i:!0,u:!1,l:[2],type:[nt]},t[pr]={o:xt,i:!0,u:!1,l:[2],type:[et]},t[hr]={o:xt,i:!0,u:!1,l:[4],type:[it]},t[wr]={o:xt,i:!0,u:!1,l:[4],type:[ot]},t[lr]={o:pt,i:!0,u:!0,l:[2],type:[tt]},t[sr]={o:pt,i:!1,u:!0,l:[2],type:[rt]},t[vr]={o:pt,i:!1,u:!0,l:[8,4],type:[ut,lt]},t[yr]={o:pt,i:!1,u:!1,l:[8],type:[ut]},t[br]={o:ht,i:!0,u:!1,l:[2],type:[tt]},t[mr]={o:ht,i:!0,u:!1,l:[2],type:[rt]},t[ur]={o:ht,i:!0,u:!1,l:[4],type:[nt]},t[ar]={o:ht,i:!0,u:!1,l:[4],type:[et]},t[fr]={o:ht,i:!0,u:!1,l:[8],type:[it]},t[cr]={o:ht,i:!0,u:!1,l:[8],type:[ot]},t[xr]={o:m,i:!0,u:!0,l:[3],type:[tt]},t[jr]={o:m,i:!1,u:!0,l:[3],type:[tt]},t[Fr]={o:m,i:!0,u:!0,l:[3,2],type:[tt,ct]},t[_r]={o:m,i:!1,u:!0,l:[3],type:[rt]},t[Or]={o:m,i:!1,u:!0,l:[12,6,4],type:[ut,lt,yt]},t[Er]={o:m,i:!1,u:!0,l:[12,6,4],type:[ut,lt,bt]},t[Ar]={o:m,i:!1,u:!0,l:[12,6],type:[ut,lt]},t[Sr]={o:m,i:!1,u:!1,l:[12],type:[ut]},t[Mr]={o:jt,i:!1,u:!1,l:[3],type:[tt]},t[gr]={o:jt,i:!1,u:!1,l:[3],type:[rt]},t[Tr]={o:jt,i:!1,u:!1,l:[6],type:[nt]},t[Pr]={o:jt,i:!1,u:!1,l:[6],type:[et]},t[Rr]={o:jt,i:!1,u:!1,l:[12],type:[it]},t[zr]={o:jt,i:!1,u:!1,l:[12],type:[ot]},t[kr]={o:d,i:!0,u:!0,l:[4],type:[tt]},t[Ur]={o:d,i:!0,u:!0,l:[4],type:[tt]},t[Cr]={o:d,i:!1,u:!0,l:[4],type:[rt]},t[Wr]={o:d,i:!0,u:!0,l:[4,2,4],type:[tt,ft,vt]},t[Ir]={o:d,i:!0,u:!0,l:[4,2],type:[tt,at]},t[Lr]={o:d,i:!0,u:!0,l:[4],type:[vt]},t[Gr]={o:d,i:!1,u:!0,l:[16,8],type:[ut,lt]},t[Br]={o:d,i:!1,u:!1,l:[16],type:[ut]},t[Nr]={o:Ft,i:!0,u:!1,l:[4],type:[tt]},t[Xr]={o:Ft,i:!0,u:!1,l:[4],type:[rt]},t[Dr]={o:Ft,i:!0,u:!1,l:[4],type:[vt]},t[Hr]={o:Ft,i:!0,u:!1,l:[8],type:[nt]},t[Vr]={o:Ft,i:!0,u:!1,l:[8],type:[et]},t[Yr]={o:Ft,i:!0,u:!1,l:[16],type:[ot]},t[qr]={o:Ft,i:!0,u:!1,l:[16],type:[it]},t[Kr]={o:w,i:!0,u:!1,l:[2,4],type:[nt,it]},t[$r]={o:w,i:!0,u:!1,l:[4],type:[it]},t[Zr]={o:w,i:!0,u:!1,l:[4],type:[ut]},t[Qr]={o:x,i:!0,u:!1,l:[4],type:[dt]},t[Jr]={o:x,i:!0,u:!1,l:[4],type:[mt]},Object.keys(t).forEach((function(r){var e=t[r];e.bytesPerElementMap={},e.l.forEach((function(r,t){var n=e.type[t];e.bytesPerElementMap[n]=r}))})),l=t}return l[r]}function At(r,t){var e=Et(r);if(!e)throw"unknown internal format";var n=e.bytesPerElementMap[t];if(void 0===n)throw"unknown internal format";return n}function St(r){var t=Et(r);if(!t)throw"unknown internal format";return{format:t.o,type:t.type[0]}}function Mt(r){return 0==(r&r-1)}function gt(r,t,e,n){if(!o.isWebGL2(r))return Mt(t)&&Mt(e);var i=Et(n);if(!i)throw"unknown internal format";return i.i&&i.u}function Tt(r){var t=Et(r);if(!t)throw"unknown internal format";return t.u}function Pt(r,t,e){return v(t)?i.getGLTypeForTypedArray(t):e||tt}function Rt(r,t,e,n,o){if(o%1!=0)throw"can't guess dimensions";if(e||n){if(n){if(!e&&(e=o/n)%1)throw"can't guess dimensions"}else if((n=o/e)%1)throw"can't guess dimensions"}else{var i=Math.sqrt(o/(t===E?6:1));i%1==0?(e=i,n=i):(e=o,n=1)}return{width:e,height:n}}function zt(r){s.textureColor=new Uint8Array([255*r[0],255*r[1],255*r[2],255*r[3]])}function kt(r,t,e){var n,o,i;void 0!==t.colorspaceConversion&&(n=r.getParameter(Z),r.pixelStorei(Z,t.colorspaceConversion)),void 0!==t.premultiplyAlpha&&(o=r.getParameter(J),r.pixelStorei(J,t.premultiplyAlpha)),void 0!==t.flipY&&(i=r.getParameter(Q),r.pixelStorei(Q,t.flipY)),e(),void 0!==n&&r.pixelStorei(Z,n),void 0!==o&&r.pixelStorei(J,o),void 0!==i&&r.pixelStorei(Q,i)}function Ut(r){r.pixelStorei(H,4),o.isWebGL2(r)&&(r.pixelStorei(V,0),r.pixelStorei(Y,0),r.pixelStorei(q,0),r.pixelStorei(K,0),r.pixelStorei($,0))}function Ct(r,t,e,n){n.minMag&&(e.call(r,t,k,n.minMag),e.call(r,t,U,n.minMag)),n.min&&e.call(r,t,k,n.min),n.mag&&e.call(r,t,U,n.mag),n.wrap&&(e.call(r,t,C,n.wrap),e.call(r,t,W,n.wrap),(t===A||u.isSampler(r,t))&&e.call(r,t,I,n.wrap)),n.wrapR&&e.call(r,t,I,n.wrapR),n.wrapS&&e.call(r,t,C,n.wrapS),n.wrapT&&e.call(r,t,W,n.wrapT),void 0!==n.minLod&&e.call(r,t,L,n.minLod),void 0!==n.maxLod&&e.call(r,t,G,n.maxLod),void 0!==n.baseLevel&&e.call(r,t,B,n.baseLevel),void 0!==n.maxLevel&&e.call(r,t,N,n.maxLevel),void 0!==n.compareFunc&&e.call(r,t,D,n.compareFunc),void 0!==n.compareMode&&e.call(r,t,X,n.compareMode)}function Wt(r,t,e){var n=e.target||O;r.bindTexture(n,t),Ct(r,n,r.texParameteri,e)}function It(r,t,e){Ct(r,t,r.samplerParameteri,e)}function Lt(r,t){var e=r.createSampler();return It(r,e,t),e}function Gt(r,t,e,n,o,i){e=e||s.textureOptions,i=i||d;var u=e.target||O;if(n=n||e.width,o=o||e.height,r.bindTexture(u,t),gt(r,n,o,i))r.generateMipmap(u);else{var a=Tt(i)?_:F;r.texParameteri(u,k,a),r.texParameteri(u,U,a),r.texParameteri(u,C,j),r.texParameteri(u,W,j)}}function Bt(r){return!0===r.auto||void 0===r.auto&&void 0===r.level}function Nt(r,t){return(t=t||{}).cubeFaceOrder||[M,g,T,P,R,z]}function Xt(r,t){var e=Nt(0,t).map((function(r,t){return{face:r,ndx:t}}));return e.sort((function(r,t){return r.face-t.face})),e}function Dt(r,t,e,n){var o=(n=n||s.textureOptions).target||O,i=n.level||0,u=e.width,a=e.height,f=n.internalFormat||n.format||d,c=St(f),l=n.format||c.format,v=n.type||c.type;if(r.bindTexture(o,t),o===E){var b,m,p=e.width,h=e.height;if(p/6===h)b=h,m=[0,0,1,0,2,0,3,0,4,0,5,0];else if(h/6===p)b=p,m=[0,0,0,1,0,2,0,3,0,4,0,5];else if(p/3==h/2)b=p/3,m=[0,0,1,0,2,0,0,1,1,1,2,1];else{if(p/2!=h/3)throw"can't figure out cube map from element: "+(e.src?e.src:e.nodeName);b=p/2,m=[0,0,1,0,0,1,1,1,0,2,1,2]}var w=y();w?(w.canvas.width=b,w.canvas.height=b,u=b,a=b,kt(r,n,(function(){Xt(0,n).forEach((function(t){var n=m[2*t.ndx+0]*b,o=m[2*t.ndx+1]*b;w.drawImage(e,n,o,b,b,0,0,b,b),r.texImage2D(t.face,i,f,l,v,w.canvas)})),w.canvas.width=1,w.canvas.height=1}))):"undefined"!=typeof createImageBitmap&&(u=b,a=b,Xt(0,n).forEach((function(c){var s=m[2*c.ndx+0]*b,y=m[2*c.ndx+1]*b;r.texImage2D(c.face,i,f,b,b,0,l,v,null),createImageBitmap(e,s,y,b,b,{premultiplyAlpha:"none",colorSpaceConversion:"none"}).then((function(e){kt(r,n,(function(){r.bindTexture(o,t),r.texImage2D(c.face,i,f,l,v,e),Bt(n)&&Gt(r,t,n,u,a,f)}))}))})))}else kt(r,n,o===A||o===S?function(){var t=Math.min(e.width,e.height),n=Math.max(e.width,e.height),u=n/t;if(u%1!=0)throw"can not compute 3D dimensions of element";var a=e.width===n?1:0,c=e.height===n?1:0;r.pixelStorei(H,1),r.pixelStorei(V,e.width),r.pixelStorei(Y,0),r.pixelStorei($,0),r.texImage3D(o,i,f,t,t,t,0,l,v,null);for(var s=0;s{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0;var o={m4:!0,v3:!0,primitives:!0};t.v3=t.primitives=t.m4=void 0;var i=l(e(362));t.m4=i;var u=l(e(304));t.v3=u;var a=l(e(777));t.primitives=a;var f=e(373);function c(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(c=function(r){return r?e:t})(r)}function l(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=c(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var u in r)if("default"!==u&&Object.prototype.hasOwnProperty.call(r,u)){var a=i?Object.getOwnPropertyDescriptor(r,u):null;a&&(a.get||a.set)?Object.defineProperty(o,u,a):o[u]=r[u]}return o.default=r,e&&e.set(r,o),o}Object.keys(f).forEach((function(r){"default"!==r&&"__esModule"!==r&&(Object.prototype.hasOwnProperty.call(o,r)||r in t&&t[r]===f[r]||(t[r]=f[r]))}))},373:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0;var o={addExtensionsToContext:!0,getContext:!0,getWebGLContext:!0,resizeCanvasToDisplaySize:!0,setDefaults:!0,attributes:!0,textures:!0,utils:!0,draw:!0,framebuffers:!0,programs:!0,typedarrays:!0,vertexArrays:!0};t.addExtensionsToContext=x,t.framebuffers=t.draw=t.attributes=void 0,t.getContext=function(r,t){var e=function(r,t){for(var e=["webgl2","webgl","experimental-webgl"],n=null,o=0;o{t.__esModule=!0,t.getGLTypeForTypedArray=function(r){if(r instanceof Int8Array)return e;if(r instanceof Uint8Array)return n;if(r instanceof Uint8ClampedArray)return n;if(r instanceof Int16Array)return o;if(r instanceof Uint16Array)return i;if(r instanceof Int32Array)return u;if(r instanceof Uint32Array)return a;if(r instanceof Float32Array)return f;throw new Error("unsupported typed array type")},t.getGLTypeForTypedArrayType=function(r){if(r===Int8Array)return e;if(r===Uint8Array)return n;if(r===Uint8ClampedArray)return n;if(r===Int16Array)return o;if(r===Uint16Array)return i;if(r===Int32Array)return u;if(r===Uint32Array)return a;if(r===Float32Array)return f;throw new Error("unsupported typed array type")},t.getTypedArrayTypeForGLType=function(r){var t=c[r];if(!t)throw new Error("unknown gl type");return t},t.isArrayBuffer=void 0;var e=5120,n=5121,o=5122,i=5123,u=5124,a=5125,f=5126,c={},l=c;l[e]=Int8Array,l[n]=Uint8Array,l[o]=Int16Array,l[i]=Uint16Array,l[u]=Int32Array,l[a]=Uint32Array,l[f]=Float32Array,l[32819]=Uint16Array,l[32820]=Uint16Array,l[33635]=Uint16Array,l[5131]=Uint16Array,l[33640]=Uint32Array,l[35899]=Uint32Array,l[35902]=Uint32Array,l[36269]=Uint32Array,l[34042]=Uint32Array;t.isArrayBuffer="undefined"!=typeof SharedArrayBuffer?function(r){return r&&r.buffer&&(r.buffer instanceof ArrayBuffer||r.buffer instanceof SharedArrayBuffer)}:function(r){return r&&r.buffer&&r.buffer instanceof ArrayBuffer}},854:(r,t)=>{t.__esModule=!0,t.glEnumToString=void 0,t.isWebGL1=function(r){return!r.texStorage2D},t.isWebGL2=function(r){return!!r.texStorage2D};var e,n;t.glEnumToString=(e={},n={},function(r,t){return function(r){var t=r.constructor.name;if(!e[t]){for(var o in r)if("number"==typeof r[o]){var i=n[r[o]];n[r[o]]=i?"".concat(i," | ").concat(o):o}e[t]=!0}}(r),n[t]||("number"==typeof t?"0x".concat(t.toString(16)):t)})},304:(r,t)=>{t.__esModule=!0,t.add=function(r,t,n){return(n=n||new e(3))[0]=r[0]+t[0],n[1]=r[1]+t[1],n[2]=r[2]+t[2],n},t.copy=function(r,t){return(t=t||new e(3))[0]=r[0],t[1]=r[1],t[2]=r[2],t},t.create=function(r,t,n){var o=new e(3);r&&(o[0]=r);t&&(o[1]=t);n&&(o[2]=n);return o},t.cross=function(r,t,n){n=n||new e(3);var o=r[2]*t[0]-r[0]*t[2],i=r[0]*t[1]-r[1]*t[0];return n[0]=r[1]*t[2]-r[2]*t[1],n[1]=o,n[2]=i,n},t.distance=function(r,t){var e=r[0]-t[0],n=r[1]-t[1],o=r[2]-t[2];return Math.sqrt(e*e+n*n+o*o)},t.distanceSq=function(r,t){var e=r[0]-t[0],n=r[1]-t[1],o=r[2]-t[2];return e*e+n*n+o*o},t.divScalar=function(r,t,n){return(n=n||new e(3))[0]=r[0]/t,n[1]=r[1]/t,n[2]=r[2]/t,n},t.divide=function(r,t,n){return(n=n||new e(3))[0]=r[0]/t[0],n[1]=r[1]/t[1],n[2]=r[2]/t[2],n},t.dot=function(r,t){return r[0]*t[0]+r[1]*t[1]+r[2]*t[2]},t.length=function(r){return Math.sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2])},t.lengthSq=function(r){return r[0]*r[0]+r[1]*r[1]+r[2]*r[2]},t.lerp=function(r,t,n,o){return(o=o||new e(3))[0]=r[0]+n*(t[0]-r[0]),o[1]=r[1]+n*(t[1]-r[1]),o[2]=r[2]+n*(t[2]-r[2]),o},t.lerpV=function(r,t,n,o){return(o=o||new e(3))[0]=r[0]+n[0]*(t[0]-r[0]),o[1]=r[1]+n[1]*(t[1]-r[1]),o[2]=r[2]+n[2]*(t[2]-r[2]),o},t.max=function(r,t,n){return(n=n||new e(3))[0]=Math.max(r[0],t[0]),n[1]=Math.max(r[1],t[1]),n[2]=Math.max(r[2],t[2]),n},t.min=function(r,t,n){return(n=n||new e(3))[0]=Math.min(r[0],t[0]),n[1]=Math.min(r[1],t[1]),n[2]=Math.min(r[2],t[2]),n},t.mulScalar=function(r,t,n){return(n=n||new e(3))[0]=r[0]*t,n[1]=r[1]*t,n[2]=r[2]*t,n},t.multiply=function(r,t,n){return(n=n||new e(3))[0]=r[0]*t[0],n[1]=r[1]*t[1],n[2]=r[2]*t[2],n},t.negate=function(r,t){return(t=t||new e(3))[0]=-r[0],t[1]=-r[1],t[2]=-r[2],t},t.normalize=function(r,t){t=t||new e(3);var n=r[0]*r[0]+r[1]*r[1]+r[2]*r[2],o=Math.sqrt(n);o>1e-5?(t[0]=r[0]/o,t[1]=r[1]/o,t[2]=r[2]/o):(t[0]=0,t[1]=0,t[2]=0);return t},t.setDefaultType=function(r){var t=e;return e=r,t},t.subtract=function(r,t,n){return(n=n||new e(3))[0]=r[0]-t[0],n[1]=r[1]-t[1],n[2]=r[2]-t[2],n};var e=Float32Array},496:(r,t,e)=>{function n(r){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},n(r)}t.__esModule=!0,t.createVAOAndSetAttributes=a,t.createVAOFromBufferInfo=function(r,t,e){return a(r,t.attribSetters||t,e.attribs,e.indices)},t.createVertexArrayInfo=function(r,t,e){var n=r.createVertexArray();r.bindVertexArray(n),t.length||(t=[t]);return t.forEach((function(t){o.setBuffersAndAttributes(r,t,e)})),r.bindVertexArray(null),{numElements:e.numElements,elementType:e.elementType,vertexArrayObject:n}};var o=function(r,t){if(!t&&r&&r.__esModule)return r;if(null===r||"object"!=n(r)&&"function"!=typeof r)return{default:r};var e=i(t);if(e&&e.has(r))return e.get(r);var o={__proto__:null},u=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in r)if("default"!==a&&Object.prototype.hasOwnProperty.call(r,a)){var f=u?Object.getOwnPropertyDescriptor(r,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=r[a]}return o.default=r,e&&e.set(r,o),o}(e(38));function i(r){if("function"!=typeof WeakMap)return null;var t=new WeakMap,e=new WeakMap;return(i=function(r){return r?e:t})(r)}var u=34963;function a(r,t,e,n){var i=r.createVertexArray();return r.bindVertexArray(i),o.setAttributes(t,e),n&&r.bindBuffer(u,n),r.bindVertexArray(null),i}}},t={};var e=function e(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return r[n](i,i.exports,e),i.exports}(395);return e})())); \ No newline at end of file diff --git a/dist/6.x/twgl-full.module.js b/dist/6.x/twgl-full.module.js new file mode 100644 index 00000000..63a79787 --- /dev/null +++ b/dist/6.x/twgl-full.module.js @@ -0,0 +1,10139 @@ +/* @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. +Available via the MIT license. +see: http://github.com/greggman/twgl.js for details */ +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * + * Vec3 math math functions. + * + * Almost all functions take an optional `dst` argument. If it is not passed in the + * functions will create a new Vec3. In other words you can do this + * + * var v = v3.cross(v1, v2); // Creates a new Vec3 with the cross product of v1 x v2. + * + * or + * + * var v = v3.create(); + * v3.cross(v1, v2, v); // Puts the cross product of v1 x v2 in v + * + * The first style is often easier but depending on where it's used it generates garbage where + * as there is almost never allocation with the second style. + * + * It is always save to pass any vector as the destination. So for example + * + * v3.cross(v1, v2, v1); // Puts the cross product of v1 x v2 in v1 + * + * @module twgl/v3 + */ + +let VecType = Float32Array; + +/** + * A JavaScript array with 3 values or a Float32Array with 3 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link module:twgl/v3.setDefaultType}. + * @typedef {(number[]|Float32Array)} Vec3 + * @memberOf module:twgl/v3 + */ + +/** + * Sets the type this library creates for a Vec3 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Vec3 + * @memberOf module:twgl/v3 + */ +function setDefaultType$1(ctor) { + const oldType = VecType; + VecType = ctor; + return oldType; +} + +/** + * Creates a vec3; may be called with x, y, z to set initial values. + * @param {number} [x] Initial x value. + * @param {number} [y] Initial y value. + * @param {number} [z] Initial z value. + * @return {module:twgl/v3.Vec3} the created vector + * @memberOf module:twgl/v3 + */ +function create$1(x, y, z) { + const dst = new VecType(3); + if (x) { + dst[0] = x; + } + if (y) { + dst[1] = y; + } + if (z) { + dst[2] = z; + } + return dst; +} + +/** + * Adds two vectors; assumes a and b have the same dimension. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A vector tha tis the sum of a and b. + * @memberOf module:twgl/v3 + */ +function add(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] + b[0]; + dst[1] = a[1] + b[1]; + dst[2] = a[2] + b[2]; + + return dst; +} + +/** + * Subtracts two vectors. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A vector that is the difference of a and b. + * @memberOf module:twgl/v3 + */ +function subtract(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] - b[0]; + dst[1] = a[1] - b[1]; + dst[2] = a[2] - b[2]; + + return dst; +} + +/** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient t, returns + * a + t * (b - a). + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {number} t Interpolation coefficient. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The linear interpolated result. + * @memberOf module:twgl/v3 + */ +function lerp(a, b, t, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] + t * (b[0] - a[0]); + dst[1] = a[1] + t * (b[1] - a[1]); + dst[2] = a[2] + t * (b[2] - a[2]); + + return dst; +} + +/** + * Performs linear interpolation on two vectors. + * Given vectors a and b and interpolation coefficient vector t, returns + * a + t * (b - a). + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} t Interpolation coefficients vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} the linear interpolated result. + * @memberOf module:twgl/v3 + */ +function lerpV(a, b, t, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] + t[0] * (b[0] - a[0]); + dst[1] = a[1] + t[1] * (b[1] - a[1]); + dst[2] = a[2] + t[2] * (b[2] - a[2]); + + return dst; +} + +/** + * Return max values of two vectors. + * Given vectors a and b returns + * [max(a[0], b[0]), max(a[1], b[1]), max(a[2], b[2])]. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The max components vector. + * @memberOf module:twgl/v3 + */ +function max(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = Math.max(a[0], b[0]); + dst[1] = Math.max(a[1], b[1]); + dst[2] = Math.max(a[2], b[2]); + + return dst; +} + +/** + * Return min values of two vectors. + * Given vectors a and b returns + * [min(a[0], b[0]), min(a[1], b[1]), min(a[2], b[2])]. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The min components vector. + * @memberOf module:twgl/v3 + */ +function min(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = Math.min(a[0], b[0]); + dst[1] = Math.min(a[1], b[1]); + dst[2] = Math.min(a[2], b[2]); + + return dst; +} + +/** + * Multiplies a vector by a scalar. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ +function mulScalar(v, k, dst) { + dst = dst || new VecType(3); + + dst[0] = v[0] * k; + dst[1] = v[1] * k; + dst[2] = v[2] * k; + + return dst; +} + +/** + * Divides a vector by a scalar. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {number} k The scalar. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The scaled vector. + * @memberOf module:twgl/v3 + */ +function divScalar(v, k, dst) { + dst = dst || new VecType(3); + + dst[0] = v[0] / k; + dst[1] = v[1] / k; + dst[2] = v[2] / k; + + return dst; +} + +/** + * Computes the cross product of two vectors; assumes both vectors have + * three entries. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of a cross b. + * @memberOf module:twgl/v3 + */ +function cross(a, b, dst) { + dst = dst || new VecType(3); + + const t1 = a[2] * b[0] - a[0] * b[2]; + const t2 = a[0] * b[1] - a[1] * b[0]; + dst[0] = a[1] * b[2] - a[2] * b[1]; + dst[1] = t1; + dst[2] = t2; + + return dst; +} + +/** + * Computes the dot product of two vectors; assumes both vectors have + * three entries. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @return {number} dot product + * @memberOf module:twgl/v3 + */ +function dot(a, b) { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); +} + +/** + * Computes the length of vector + * @param {module:twgl/v3.Vec3} v vector. + * @return {number} length of vector. + * @memberOf module:twgl/v3 + */ +function length$1(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); +} + +/** + * Computes the square of the length of vector + * @param {module:twgl/v3.Vec3} v vector. + * @return {number} square of the length of vector. + * @memberOf module:twgl/v3 + */ +function lengthSq(v) { + return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; +} + +/** + * Computes the distance between 2 points + * @param {module:twgl/v3.Vec3} a vector. + * @param {module:twgl/v3.Vec3} b vector. + * @return {number} distance between a and b + * @memberOf module:twgl/v3 + */ +function distance(a, b) { + const dx = a[0] - b[0]; + const dy = a[1] - b[1]; + const dz = a[2] - b[2]; + return Math.sqrt(dx * dx + dy * dy + dz * dz); +} + +/** + * Computes the square of the distance between 2 points + * @param {module:twgl/v3.Vec3} a vector. + * @param {module:twgl/v3.Vec3} b vector. + * @return {number} square of the distance between a and b + * @memberOf module:twgl/v3 + */ +function distanceSq(a, b) { + const dx = a[0] - b[0]; + const dy = a[1] - b[1]; + const dz = a[2] - b[2]; + return dx * dx + dy * dy + dz * dz; +} + +/** + * Divides a vector by its Euclidean length and returns the quotient. + * @param {module:twgl/v3.Vec3} a The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The normalized vector. + * @memberOf module:twgl/v3 + */ +function normalize(a, dst) { + dst = dst || new VecType(3); + + const lenSq = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; + const len = Math.sqrt(lenSq); + if (len > 0.00001) { + dst[0] = a[0] / len; + dst[1] = a[1] / len; + dst[2] = a[2] / len; + } else { + dst[0] = 0; + dst[1] = 0; + dst[2] = 0; + } + + return dst; +} + +/** + * Negates a vector. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} -v. + * @memberOf module:twgl/v3 + */ +function negate$1(v, dst) { + dst = dst || new VecType(3); + + dst[0] = -v[0]; + dst[1] = -v[1]; + dst[2] = -v[2]; + + return dst; +} + +/** + * Copies a vector. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} A copy of v. + * @memberOf module:twgl/v3 + */ +function copy$1(v, dst) { + dst = dst || new VecType(3); + + dst[0] = v[0]; + dst[1] = v[1]; + dst[2] = v[2]; + + return dst; +} + +/** + * Multiplies a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of products of entries of a and + * b. + * @memberOf module:twgl/v3 + */ +function multiply$1(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] * b[0]; + dst[1] = a[1] * b[1]; + dst[2] = a[2] * b[2]; + + return dst; +} + +/** + * Divides a vector by another vector (component-wise); assumes a and + * b have the same length. + * @param {module:twgl/v3.Vec3} a Operand vector. + * @param {module:twgl/v3.Vec3} b Operand vector. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not new one is created. + * @return {module:twgl/v3.Vec3} The vector of quotients of entries of a and + * b. + * @memberOf module:twgl/v3 + */ +function divide(a, b, dst) { + dst = dst || new VecType(3); + + dst[0] = a[0] / b[0]; + dst[1] = a[1] / b[1]; + dst[2] = a[2] / b[2]; + + return dst; +} + +var v3 = /*#__PURE__*/Object.freeze({ + __proto__: null, + add: add, + copy: copy$1, + create: create$1, + cross: cross, + distance: distance, + distanceSq: distanceSq, + divide: divide, + divScalar: divScalar, + dot: dot, + lerp: lerp, + lerpV: lerpV, + length: length$1, + lengthSq: lengthSq, + max: max, + min: min, + mulScalar: mulScalar, + multiply: multiply$1, + negate: negate$1, + normalize: normalize, + setDefaultType: setDefaultType$1, + subtract: subtract +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * 4x4 Matrix math math functions. + * + * Almost all functions take an optional `dst` argument. If it is not passed in the + * functions will create a new matrix. In other words you can do this + * + * const mat = m4.translation([1, 2, 3]); // Creates a new translation matrix + * + * or + * + * const mat = m4.create(); + * m4.translation([1, 2, 3], mat); // Puts translation matrix in mat. + * + * The first style is often easier but depending on where it's used it generates garbage where + * as there is almost never allocation with the second style. + * + * It is always save to pass any matrix as the destination. So for example + * + * const mat = m4.identity(); + * const trans = m4.translation([1, 2, 3]); + * m4.multiply(mat, trans, mat); // Multiplies mat * trans and puts result in mat. + * + * @module twgl/m4 + */ +let MatType = Float32Array; + +/** + * A JavaScript array with 16 values or a Float32Array with 16 values. + * When created by the library will create the default type which is `Float32Array` + * but can be set by calling {@link module:twgl/m4.setDefaultType}. + * @typedef {(number[]|Float32Array)} Mat4 + * @memberOf module:twgl/m4 + */ + +/** + * Sets the type this library creates for a Mat4 + * @param {constructor} ctor the constructor for the type. Either `Float32Array` or `Array` + * @return {constructor} previous constructor for Mat4 + * @memberOf module:twgl/m4 + */ +function setDefaultType(ctor) { + const oldType = MatType; + MatType = ctor; + return oldType; +} + +/** + * Negates a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} -m. + * @memberOf module:twgl/m4 + */ +function negate(m, dst) { + dst = dst || new MatType(16); + + dst[ 0] = -m[ 0]; + dst[ 1] = -m[ 1]; + dst[ 2] = -m[ 2]; + dst[ 3] = -m[ 3]; + dst[ 4] = -m[ 4]; + dst[ 5] = -m[ 5]; + dst[ 6] = -m[ 6]; + dst[ 7] = -m[ 7]; + dst[ 8] = -m[ 8]; + dst[ 9] = -m[ 9]; + dst[10] = -m[10]; + dst[11] = -m[11]; + dst[12] = -m[12]; + dst[13] = -m[13]; + dst[14] = -m[14]; + dst[15] = -m[15]; + + return dst; +} + +/** + * Creates a matrix. + * @return {module:twgl/m4.Mat4} A new matrix. + * @memberOf module:twgl/m4 + */ +function create() { + return new MatType(16).fill(0); +} + +/** + * Copies a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] The matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A copy of m. + * @memberOf module:twgl/m4 + */ +function copy(m, dst) { + dst = dst || new MatType(16); + + dst[ 0] = m[ 0]; + dst[ 1] = m[ 1]; + dst[ 2] = m[ 2]; + dst[ 3] = m[ 3]; + dst[ 4] = m[ 4]; + dst[ 5] = m[ 5]; + dst[ 6] = m[ 6]; + dst[ 7] = m[ 7]; + dst[ 8] = m[ 8]; + dst[ 9] = m[ 9]; + dst[10] = m[10]; + dst[11] = m[11]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + + return dst; +} + +/** + * Creates an n-by-n identity matrix. + * + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} An n-by-n identity matrix. + * @memberOf module:twgl/m4 + */ +function identity(dst) { + dst = dst || new MatType(16); + + dst[ 0] = 1; + dst[ 1] = 0; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = 1; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = 0; + dst[ 9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Takes the transpose of a matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The transpose of m. + * @memberOf module:twgl/m4 + */ + function transpose(m, dst) { + dst = dst || new MatType(16); + if (dst === m) { + let t; + + t = m[1]; + m[1] = m[4]; + m[4] = t; + + t = m[2]; + m[2] = m[8]; + m[8] = t; + + t = m[3]; + m[3] = m[12]; + m[12] = t; + + t = m[6]; + m[6] = m[9]; + m[9] = t; + + t = m[7]; + m[7] = m[13]; + m[13] = t; + + t = m[11]; + m[11] = m[14]; + m[14] = t; + return dst; + } + + const m00 = m[0 * 4 + 0]; + const m01 = m[0 * 4 + 1]; + const m02 = m[0 * 4 + 2]; + const m03 = m[0 * 4 + 3]; + const m10 = m[1 * 4 + 0]; + const m11 = m[1 * 4 + 1]; + const m12 = m[1 * 4 + 2]; + const m13 = m[1 * 4 + 3]; + const m20 = m[2 * 4 + 0]; + const m21 = m[2 * 4 + 1]; + const m22 = m[2 * 4 + 2]; + const m23 = m[2 * 4 + 3]; + const m30 = m[3 * 4 + 0]; + const m31 = m[3 * 4 + 1]; + const m32 = m[3 * 4 + 2]; + const m33 = m[3 * 4 + 3]; + + dst[ 0] = m00; + dst[ 1] = m10; + dst[ 2] = m20; + dst[ 3] = m30; + dst[ 4] = m01; + dst[ 5] = m11; + dst[ 6] = m21; + dst[ 7] = m31; + dst[ 8] = m02; + dst[ 9] = m12; + dst[10] = m22; + dst[11] = m32; + dst[12] = m03; + dst[13] = m13; + dst[14] = m23; + dst[15] = m33; + + return dst; +} + +/** + * Computes the inverse of a 4-by-4 matrix. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The inverse of m. + * @memberOf module:twgl/m4 + */ +function inverse(m, dst) { + dst = dst || new MatType(16); + + const m00 = m[0 * 4 + 0]; + const m01 = m[0 * 4 + 1]; + const m02 = m[0 * 4 + 2]; + const m03 = m[0 * 4 + 3]; + const m10 = m[1 * 4 + 0]; + const m11 = m[1 * 4 + 1]; + const m12 = m[1 * 4 + 2]; + const m13 = m[1 * 4 + 3]; + const m20 = m[2 * 4 + 0]; + const m21 = m[2 * 4 + 1]; + const m22 = m[2 * 4 + 2]; + const m23 = m[2 * 4 + 3]; + const m30 = m[3 * 4 + 0]; + const m31 = m[3 * 4 + 1]; + const m32 = m[3 * 4 + 2]; + const m33 = m[3 * 4 + 3]; + const tmp_0 = m22 * m33; + const tmp_1 = m32 * m23; + const tmp_2 = m12 * m33; + const tmp_3 = m32 * m13; + const tmp_4 = m12 * m23; + const tmp_5 = m22 * m13; + const tmp_6 = m02 * m33; + const tmp_7 = m32 * m03; + const tmp_8 = m02 * m23; + const tmp_9 = m22 * m03; + const tmp_10 = m02 * m13; + const tmp_11 = m12 * m03; + const tmp_12 = m20 * m31; + const tmp_13 = m30 * m21; + const tmp_14 = m10 * m31; + const tmp_15 = m30 * m11; + const tmp_16 = m10 * m21; + const tmp_17 = m20 * m11; + const tmp_18 = m00 * m31; + const tmp_19 = m30 * m01; + const tmp_20 = m00 * m21; + const tmp_21 = m20 * m01; + const tmp_22 = m00 * m11; + const tmp_23 = m10 * m01; + + const t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - + (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); + const t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - + (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); + const t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - + (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); + const t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - + (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); + + const d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); + + dst[ 0] = d * t0; + dst[ 1] = d * t1; + dst[ 2] = d * t2; + dst[ 3] = d * t3; + dst[ 4] = d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - + (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)); + dst[ 5] = d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - + (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)); + dst[ 6] = d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - + (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)); + dst[ 7] = d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - + (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)); + dst[ 8] = d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - + (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)); + dst[ 9] = d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - + (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)); + dst[10] = d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - + (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)); + dst[11] = d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - + (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)); + dst[12] = d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - + (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)); + dst[13] = d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - + (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)); + dst[14] = d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - + (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)); + dst[15] = d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - + (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)); + + return dst; +} + +/** + * Multiplies two 4-by-4 matrices with a on the left and b on the right + * @param {module:twgl/m4.Mat4} a The matrix on the left. + * @param {module:twgl/m4.Mat4} b The matrix on the right. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix product of a and b. + * @memberOf module:twgl/m4 + */ +function multiply(a, b, dst) { + dst = dst || new MatType(16); + + const a00 = a[0]; + const a01 = a[1]; + const a02 = a[2]; + const a03 = a[3]; + const a10 = a[ 4 + 0]; + const a11 = a[ 4 + 1]; + const a12 = a[ 4 + 2]; + const a13 = a[ 4 + 3]; + const a20 = a[ 8 + 0]; + const a21 = a[ 8 + 1]; + const a22 = a[ 8 + 2]; + const a23 = a[ 8 + 3]; + const a30 = a[12 + 0]; + const a31 = a[12 + 1]; + const a32 = a[12 + 2]; + const a33 = a[12 + 3]; + const b00 = b[0]; + const b01 = b[1]; + const b02 = b[2]; + const b03 = b[3]; + const b10 = b[ 4 + 0]; + const b11 = b[ 4 + 1]; + const b12 = b[ 4 + 2]; + const b13 = b[ 4 + 3]; + const b20 = b[ 8 + 0]; + const b21 = b[ 8 + 1]; + const b22 = b[ 8 + 2]; + const b23 = b[ 8 + 3]; + const b30 = b[12 + 0]; + const b31 = b[12 + 1]; + const b32 = b[12 + 2]; + const b33 = b[12 + 3]; + + dst[ 0] = a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03; + dst[ 1] = a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03; + dst[ 2] = a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03; + dst[ 3] = a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03; + dst[ 4] = a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13; + dst[ 5] = a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13; + dst[ 6] = a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13; + dst[ 7] = a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13; + dst[ 8] = a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23; + dst[ 9] = a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23; + dst[10] = a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23; + dst[11] = a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23; + dst[12] = a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33; + dst[13] = a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33; + dst[14] = a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33; + dst[15] = a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33; + + return dst; +} + +/** + * Sets the translation component of a 4-by-4 matrix to the given + * vector. + * @param {module:twgl/m4.Mat4} a The matrix. + * @param {module:twgl/v3.Vec3} v The vector. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with translation set. + * @memberOf module:twgl/m4 + */ +function setTranslation(a, v, dst) { + dst = dst || identity(); + if (a !== dst) { + dst[ 0] = a[ 0]; + dst[ 1] = a[ 1]; + dst[ 2] = a[ 2]; + dst[ 3] = a[ 3]; + dst[ 4] = a[ 4]; + dst[ 5] = a[ 5]; + dst[ 6] = a[ 6]; + dst[ 7] = a[ 7]; + dst[ 8] = a[ 8]; + dst[ 9] = a[ 9]; + dst[10] = a[10]; + dst[11] = a[11]; + } + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; + return dst; +} + +/** + * Returns the translation component of a 4-by-4 matrix as a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} [dst] vector to hold result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The translation component of m. + * @memberOf module:twgl/m4 + */ +function getTranslation(m, dst) { + dst = dst || create$1(); + dst[0] = m[12]; + dst[1] = m[13]; + dst[2] = m[14]; + return dst; +} + +/** + * Returns an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @return {module:twgl/v3.Vec3} [dst] vector. + * @return {module:twgl/v3.Vec3} The axis component of m. + * @memberOf module:twgl/m4 + */ +function getAxis(m, axis, dst) { + dst = dst || create$1(); + const off = axis * 4; + dst[0] = m[off + 0]; + dst[1] = m[off + 1]; + dst[2] = m[off + 2]; + return dst; +} + +/** + * Sets an axis of a 4x4 matrix as a vector with 3 entries + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v the axis vector + * @param {number} axis The axis 0 = x, 1 = y, 2 = z; + * @param {module:twgl/m4.Mat4} [dst] The matrix to set. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The matrix with axis set. + * @memberOf module:twgl/m4 + */ +function setAxis(a, v, axis, dst) { + if (dst !== a) { + dst = copy(a, dst); + } + const off = axis * 4; + dst[off + 0] = v[0]; + dst[off + 1] = v[1]; + dst[off + 2] = v[2]; + return dst; +} + +/** + * Computes a 4-by-4 perspective transformation matrix given the angular height + * of the frustum, the aspect ratio, and the near and far clipping planes. The + * arguments define a frustum extending in the negative z direction. The given + * angle is the vertical angle of the frustum, and the horizontal angle is + * determined to produce the given aspect ratio. The arguments near and far are + * the distances to the near and far clipping planes. Note that near and far + * are not z coordinates, but rather they are distances along the negative + * z-axis. The matrix generated sends the viewing frustum to the unit box. + * We assume a unit box extending from -1 to 1 in the x and y dimensions and + * from 0 to 1 in the z dimension. + * @param {number} fieldOfViewYInRadians The camera angle from top to bottom (in radians). + * @param {number} aspect The aspect ratio width / height. + * @param {number} zNear The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} zFar The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ +function perspective(fieldOfViewYInRadians, aspect, zNear, zFar, dst) { + dst = dst || new MatType(16); + + const f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewYInRadians); + const rangeInv = 1.0 / (zNear - zFar); + + dst[0] = f / aspect; + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + + dst[4] = 0; + dst[5] = f; + dst[6] = 0; + dst[7] = 0; + + dst[8] = 0; + dst[9] = 0; + dst[10] = (zNear + zFar) * rangeInv; + dst[11] = -1; + + dst[12] = 0; + dst[13] = 0; + dst[14] = zNear * zFar * rangeInv * 2; + dst[15] = 0; + + return dst; +} + +/** + * Computes a 4-by-4 orthogonal transformation matrix given the left, right, + * bottom, and top dimensions of the near clipping plane as well as the + * near and far clipping plane distances. + * @param {number} left Left side of the near clipping plane viewport. + * @param {number} right Right side of the near clipping plane viewport. + * @param {number} bottom Bottom of the near clipping plane viewport. + * @param {number} top Top of the near clipping plane viewport. + * @param {number} near The depth (negative z coordinate) + * of the near clipping plane. + * @param {number} far The depth (negative z coordinate) + * of the far clipping plane. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective matrix. + * @memberOf module:twgl/m4 + */ +function ortho(left, right, bottom, top, near, far, dst) { + dst = dst || new MatType(16); + + dst[0] = 2 / (right - left); + dst[1] = 0; + dst[2] = 0; + dst[3] = 0; + + dst[4] = 0; + dst[5] = 2 / (top - bottom); + dst[6] = 0; + dst[7] = 0; + + dst[8] = 0; + dst[9] = 0; + dst[10] = 2 / (near - far); + dst[11] = 0; + + dst[12] = (right + left) / (left - right); + dst[13] = (top + bottom) / (bottom - top); + dst[14] = (far + near) / (near - far); + dst[15] = 1; + + return dst; +} + +/** + * Computes a 4-by-4 perspective transformation matrix given the left, right, + * top, bottom, near and far clipping planes. The arguments define a frustum + * extending in the negative z direction. The arguments near and far are the + * distances to the near and far clipping planes. Note that near and far are not + * z coordinates, but rather they are distances along the negative z-axis. The + * matrix generated sends the viewing frustum to the unit box. We assume a unit + * box extending from -1 to 1 in the x and y dimensions and from 0 to 1 in the z + * dimension. + * @param {number} left The x coordinate of the left plane of the box. + * @param {number} right The x coordinate of the right plane of the box. + * @param {number} bottom The y coordinate of the bottom plane of the box. + * @param {number} top The y coordinate of the right plane of the box. + * @param {number} near The negative z coordinate of the near plane of the box. + * @param {number} far The negative z coordinate of the far plane of the box. + * @param {module:twgl/m4.Mat4} [dst] Output matrix. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The perspective projection matrix. + * @memberOf module:twgl/m4 + */ +function frustum(left, right, bottom, top, near, far, dst) { + dst = dst || new MatType(16); + + const dx = (right - left); + const dy = (top - bottom); + const dz = (near - far); + + dst[ 0] = 2 * near / dx; + dst[ 1] = 0; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = 2 * near / dy; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = (left + right) / dx; + dst[ 9] = (top + bottom) / dy; + dst[10] = far / dz; + dst[11] = -1; + dst[12] = 0; + dst[13] = 0; + dst[14] = near * far / dz; + dst[15] = 0; + + return dst; +} + +let xAxis; +let yAxis; +let zAxis; + +/** + * Computes a 4-by-4 look-at transformation. + * + * This is a matrix which positions the camera itself. If you want + * a view matrix (a matrix which moves things in front of the camera) + * take the inverse of this. + * + * @param {module:twgl/v3.Vec3} eye The position of the eye. + * @param {module:twgl/v3.Vec3} target The position meant to be viewed. + * @param {module:twgl/v3.Vec3} up A vector pointing up. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The look-at matrix. + * @memberOf module:twgl/m4 + */ +function lookAt(eye, target, up, dst) { + dst = dst || new MatType(16); + + xAxis = xAxis || create$1(); + yAxis = yAxis || create$1(); + zAxis = zAxis || create$1(); + + normalize( + subtract(eye, target, zAxis), zAxis); + normalize(cross(up, zAxis, xAxis), xAxis); + normalize(cross(zAxis, xAxis, yAxis), yAxis); + + dst[ 0] = xAxis[0]; + dst[ 1] = xAxis[1]; + dst[ 2] = xAxis[2]; + dst[ 3] = 0; + dst[ 4] = yAxis[0]; + dst[ 5] = yAxis[1]; + dst[ 6] = yAxis[2]; + dst[ 7] = 0; + dst[ 8] = zAxis[0]; + dst[ 9] = zAxis[1]; + dst[10] = zAxis[2]; + dst[11] = 0; + dst[12] = eye[0]; + dst[13] = eye[1]; + dst[14] = eye[2]; + dst[15] = 1; + + return dst; +} + +/** + * Creates a 4-by-4 matrix which translates by the given vector v. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translation matrix. + * @memberOf module:twgl/m4 + */ +function translation(v, dst) { + dst = dst || new MatType(16); + + dst[ 0] = 1; + dst[ 1] = 0; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = 1; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = 0; + dst[ 9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = v[0]; + dst[13] = v[1]; + dst[14] = v[2]; + dst[15] = 1; + return dst; +} + +/** + * Translates the given 4-by-4 matrix by the given vector v. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The vector by + * which to translate. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The translated matrix. + * @memberOf module:twgl/m4 + */ +function translate(m, v, dst) { + dst = dst || new MatType(16); + + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + const m00 = m[0]; + const m01 = m[1]; + const m02 = m[2]; + const m03 = m[3]; + const m10 = m[1 * 4 + 0]; + const m11 = m[1 * 4 + 1]; + const m12 = m[1 * 4 + 2]; + const m13 = m[1 * 4 + 3]; + const m20 = m[2 * 4 + 0]; + const m21 = m[2 * 4 + 1]; + const m22 = m[2 * 4 + 2]; + const m23 = m[2 * 4 + 3]; + const m30 = m[3 * 4 + 0]; + const m31 = m[3 * 4 + 1]; + const m32 = m[3 * 4 + 2]; + const m33 = m[3 * 4 + 3]; + + if (m !== dst) { + dst[ 0] = m00; + dst[ 1] = m01; + dst[ 2] = m02; + dst[ 3] = m03; + dst[ 4] = m10; + dst[ 5] = m11; + dst[ 6] = m12; + dst[ 7] = m13; + dst[ 8] = m20; + dst[ 9] = m21; + dst[10] = m22; + dst[11] = m23; + } + + dst[12] = m00 * v0 + m10 * v1 + m20 * v2 + m30; + dst[13] = m01 * v0 + m11 * v1 + m21 * v2 + m31; + dst[14] = m02 * v0 + m12 * v1 + m22 * v2 + m32; + dst[15] = m03 * v0 + m13 * v1 + m23 * v2 + m33; + + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationX(angleInRadians, dst) { + dst = dst || new MatType(16); + + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[ 0] = 1; + dst[ 1] = 0; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = c; + dst[ 6] = s; + dst[ 7] = 0; + dst[ 8] = 0; + dst[ 9] = -s; + dst[10] = c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the x-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateX(m, angleInRadians, dst) { + dst = dst || new MatType(16); + + const m10 = m[4]; + const m11 = m[5]; + const m12 = m[6]; + const m13 = m[7]; + const m20 = m[8]; + const m21 = m[9]; + const m22 = m[10]; + const m23 = m[11]; + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[4] = c * m10 + s * m20; + dst[5] = c * m11 + s * m21; + dst[6] = c * m12 + s * m22; + dst[7] = c * m13 + s * m23; + dst[8] = c * m20 - s * m10; + dst[9] = c * m21 - s * m11; + dst[10] = c * m22 - s * m12; + dst[11] = c * m23 - s * m13; + + if (m !== dst) { + dst[ 0] = m[ 0]; + dst[ 1] = m[ 1]; + dst[ 2] = m[ 2]; + dst[ 3] = m[ 3]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationY(angleInRadians, dst) { + dst = dst || new MatType(16); + + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[ 0] = c; + dst[ 1] = 0; + dst[ 2] = -s; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = 1; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = s; + dst[ 9] = 0; + dst[10] = c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the y-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateY(m, angleInRadians, dst) { + dst = dst || new MatType(16); + + const m00 = m[0 * 4 + 0]; + const m01 = m[0 * 4 + 1]; + const m02 = m[0 * 4 + 2]; + const m03 = m[0 * 4 + 3]; + const m20 = m[2 * 4 + 0]; + const m21 = m[2 * 4 + 1]; + const m22 = m[2 * 4 + 2]; + const m23 = m[2 * 4 + 3]; + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[ 0] = c * m00 - s * m20; + dst[ 1] = c * m01 - s * m21; + dst[ 2] = c * m02 - s * m22; + dst[ 3] = c * m03 - s * m23; + dst[ 8] = c * m20 + s * m00; + dst[ 9] = c * m21 + s * m01; + dst[10] = c * m22 + s * m02; + dst[11] = c * m23 + s * m03; + + if (m !== dst) { + dst[ 4] = m[ 4]; + dst[ 5] = m[ 5]; + dst[ 6] = m[ 6]; + dst[ 7] = m[ 7]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotation matrix. + * @memberOf module:twgl/m4 + */ +function rotationZ(angleInRadians, dst) { + dst = dst || new MatType(16); + + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[ 0] = c; + dst[ 1] = s; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = -s; + dst[ 5] = c; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = 0; + dst[ 9] = 0; + dst[10] = 1; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the z-axis by the given + * angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function rotateZ(m, angleInRadians, dst) { + dst = dst || new MatType(16); + + const m00 = m[0 * 4 + 0]; + const m01 = m[0 * 4 + 1]; + const m02 = m[0 * 4 + 2]; + const m03 = m[0 * 4 + 3]; + const m10 = m[1 * 4 + 0]; + const m11 = m[1 * 4 + 1]; + const m12 = m[1 * 4 + 2]; + const m13 = m[1 * 4 + 3]; + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + + dst[ 0] = c * m00 + s * m10; + dst[ 1] = c * m01 + s * m11; + dst[ 2] = c * m02 + s * m12; + dst[ 3] = c * m03 + s * m13; + dst[ 4] = c * m10 - s * m00; + dst[ 5] = c * m11 - s * m01; + dst[ 6] = c * m12 - s * m02; + dst[ 7] = c * m13 - s * m03; + + if (m !== dst) { + dst[ 8] = m[ 8]; + dst[ 9] = m[ 9]; + dst[10] = m[10]; + dst[11] = m[11]; + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + + return dst; +} + +/** + * Creates a 4-by-4 matrix which rotates around the given axis by the given + * angle. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} A matrix which rotates angle radians + * around the axis. + * @memberOf module:twgl/m4 + */ +function axisRotation(axis, angleInRadians, dst) { + dst = dst || new MatType(16); + + let x = axis[0]; + let y = axis[1]; + let z = axis[2]; + const n = Math.sqrt(x * x + y * y + z * z); + x /= n; + y /= n; + z /= n; + const xx = x * x; + const yy = y * y; + const zz = z * z; + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + const oneMinusCosine = 1 - c; + + dst[ 0] = xx + (1 - xx) * c; + dst[ 1] = x * y * oneMinusCosine + z * s; + dst[ 2] = x * z * oneMinusCosine - y * s; + dst[ 3] = 0; + dst[ 4] = x * y * oneMinusCosine - z * s; + dst[ 5] = yy + (1 - yy) * c; + dst[ 6] = y * z * oneMinusCosine + x * s; + dst[ 7] = 0; + dst[ 8] = x * z * oneMinusCosine + y * s; + dst[ 9] = y * z * oneMinusCosine - x * s; + dst[10] = zz + (1 - zz) * c; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Rotates the given 4-by-4 matrix around the given axis by the + * given angle. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} axis The axis + * about which to rotate. + * @param {number} angleInRadians The angle by which to rotate (in radians). + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The rotated matrix. + * @memberOf module:twgl/m4 + */ +function axisRotate(m, axis, angleInRadians, dst) { + dst = dst || new MatType(16); + + let x = axis[0]; + let y = axis[1]; + let z = axis[2]; + const n = Math.sqrt(x * x + y * y + z * z); + x /= n; + y /= n; + z /= n; + const xx = x * x; + const yy = y * y; + const zz = z * z; + const c = Math.cos(angleInRadians); + const s = Math.sin(angleInRadians); + const oneMinusCosine = 1 - c; + + const r00 = xx + (1 - xx) * c; + const r01 = x * y * oneMinusCosine + z * s; + const r02 = x * z * oneMinusCosine - y * s; + const r10 = x * y * oneMinusCosine - z * s; + const r11 = yy + (1 - yy) * c; + const r12 = y * z * oneMinusCosine + x * s; + const r20 = x * z * oneMinusCosine + y * s; + const r21 = y * z * oneMinusCosine - x * s; + const r22 = zz + (1 - zz) * c; + + const m00 = m[0]; + const m01 = m[1]; + const m02 = m[2]; + const m03 = m[3]; + const m10 = m[4]; + const m11 = m[5]; + const m12 = m[6]; + const m13 = m[7]; + const m20 = m[8]; + const m21 = m[9]; + const m22 = m[10]; + const m23 = m[11]; + + dst[ 0] = r00 * m00 + r01 * m10 + r02 * m20; + dst[ 1] = r00 * m01 + r01 * m11 + r02 * m21; + dst[ 2] = r00 * m02 + r01 * m12 + r02 * m22; + dst[ 3] = r00 * m03 + r01 * m13 + r02 * m23; + dst[ 4] = r10 * m00 + r11 * m10 + r12 * m20; + dst[ 5] = r10 * m01 + r11 * m11 + r12 * m21; + dst[ 6] = r10 * m02 + r11 * m12 + r12 * m22; + dst[ 7] = r10 * m03 + r11 * m13 + r12 * m23; + dst[ 8] = r20 * m00 + r21 * m10 + r22 * m20; + dst[ 9] = r20 * m01 + r21 * m11 + r22 * m21; + dst[10] = r20 * m02 + r21 * m12 + r22 * m22; + dst[11] = r20 * m03 + r21 * m13 + r22 * m23; + + if (m !== dst) { + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + + return dst; +} + +/** + * Creates a 4-by-4 matrix which scales in each dimension by an amount given by + * the corresponding entry in the given vector; assumes the vector has three + * entries. + * @param {module:twgl/v3.Vec3} v A vector of + * three entries specifying the factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaling matrix. + * @memberOf module:twgl/m4 + */ +function scaling(v, dst) { + dst = dst || new MatType(16); + + dst[ 0] = v[0]; + dst[ 1] = 0; + dst[ 2] = 0; + dst[ 3] = 0; + dst[ 4] = 0; + dst[ 5] = v[1]; + dst[ 6] = 0; + dst[ 7] = 0; + dst[ 8] = 0; + dst[ 9] = 0; + dst[10] = v[2]; + dst[11] = 0; + dst[12] = 0; + dst[13] = 0; + dst[14] = 0; + dst[15] = 1; + + return dst; +} + +/** + * Scales the given 4-by-4 matrix in each dimension by an amount + * given by the corresponding entry in the given vector; assumes the vector has + * three entries. + * @param {module:twgl/m4.Mat4} m The matrix to be modified. + * @param {module:twgl/v3.Vec3} v A vector of three entries specifying the + * factor by which to scale in each dimension. + * @param {module:twgl/m4.Mat4} [dst] matrix to hold result. If not passed a new one is created. + * @return {module:twgl/m4.Mat4} The scaled matrix. + * @memberOf module:twgl/m4 + */ +function scale(m, v, dst) { + dst = dst || new MatType(16); + + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + + dst[ 0] = v0 * m[0 * 4 + 0]; + dst[ 1] = v0 * m[0 * 4 + 1]; + dst[ 2] = v0 * m[0 * 4 + 2]; + dst[ 3] = v0 * m[0 * 4 + 3]; + dst[ 4] = v1 * m[1 * 4 + 0]; + dst[ 5] = v1 * m[1 * 4 + 1]; + dst[ 6] = v1 * m[1 * 4 + 2]; + dst[ 7] = v1 * m[1 * 4 + 3]; + dst[ 8] = v2 * m[2 * 4 + 0]; + dst[ 9] = v2 * m[2 * 4 + 1]; + dst[10] = v2 * m[2 * 4 + 2]; + dst[11] = v2 * m[2 * 4 + 3]; + + if (m !== dst) { + dst[12] = m[12]; + dst[13] = m[13]; + dst[14] = m[14]; + dst[15] = m[15]; + } + + return dst; +} + +/** + * Takes a 4-by-4 matrix and a vector with 3 entries, + * interprets the vector as a point, transforms that point by the matrix, and + * returns the result as a vector with 3 entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The point. + * @param {module:twgl/v3.Vec3} [dst] optional vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed point. + * @memberOf module:twgl/m4 + */ +function transformPoint(m, v, dst) { + dst = dst || create$1(); + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + const d = v0 * m[0 * 4 + 3] + v1 * m[1 * 4 + 3] + v2 * m[2 * 4 + 3] + m[3 * 4 + 3]; + + dst[0] = (v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0] + m[3 * 4 + 0]) / d; + dst[1] = (v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1] + m[3 * 4 + 1]) / d; + dst[2] = (v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2] + m[3 * 4 + 2]) / d; + + return dst; +} + +/** + * Takes a 4-by-4 matrix and a vector with 3 entries, interprets the vector as a + * direction, transforms that direction by the matrix, and returns the result; + * assumes the transformation of 3-dimensional space represented by the matrix + * is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The direction. + * @param {module:twgl/v3.Vec3} [dst] optional Vec3 to store result. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed direction. + * @memberOf module:twgl/m4 + */ +function transformDirection(m, v, dst) { + dst = dst || create$1(); + + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + + dst[0] = v0 * m[0 * 4 + 0] + v1 * m[1 * 4 + 0] + v2 * m[2 * 4 + 0]; + dst[1] = v0 * m[0 * 4 + 1] + v1 * m[1 * 4 + 1] + v2 * m[2 * 4 + 1]; + dst[2] = v0 * m[0 * 4 + 2] + v1 * m[1 * 4 + 2] + v2 * m[2 * 4 + 2]; + + return dst; +} + +/** + * Takes a 4-by-4 matrix m and a vector v with 3 entries, interprets the vector + * as a normal to a surface, and computes a vector which is normal upon + * transforming that surface by the matrix. The effect of this function is the + * same as transforming v (as a direction) by the inverse-transpose of m. This + * function assumes the transformation of 3-dimensional space represented by the + * matrix is parallel-preserving, i.e. any combination of rotation, scaling and + * translation, but not a perspective distortion. Returns a vector with 3 + * entries. + * @param {module:twgl/m4.Mat4} m The matrix. + * @param {module:twgl/v3.Vec3} v The normal. + * @param {module:twgl/v3.Vec3} [dst] The direction. If not passed a new one is created. + * @return {module:twgl/v3.Vec3} The transformed normal. + * @memberOf module:twgl/m4 + */ +function transformNormal$1(m, v, dst) { + dst = dst || create$1(); + const mi = inverse(m); + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + + dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; + dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; + dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; + + return dst; +} + +var m4 = /*#__PURE__*/Object.freeze({ + __proto__: null, + axisRotate: axisRotate, + axisRotation: axisRotation, + copy: copy, + create: create, + frustum: frustum, + getAxis: getAxis, + getTranslation: getTranslation, + identity: identity, + inverse: inverse, + lookAt: lookAt, + multiply: multiply, + negate: negate, + ortho: ortho, + perspective: perspective, + rotateX: rotateX, + rotateY: rotateY, + rotateZ: rotateZ, + rotationX: rotationX, + rotationY: rotationY, + rotationZ: rotationZ, + scale: scale, + scaling: scaling, + setAxis: setAxis, + setDefaultType: setDefaultType, + setTranslation: setTranslation, + transformDirection: transformDirection, + transformNormal: transformNormal$1, + transformPoint: transformPoint, + translate: translate, + translation: translation, + transpose: transpose +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* DataType */ +const BYTE$2 = 0x1400; +const UNSIGNED_BYTE$3 = 0x1401; +const SHORT$2 = 0x1402; +const UNSIGNED_SHORT$3 = 0x1403; +const INT$3 = 0x1404; +const UNSIGNED_INT$3 = 0x1405; +const FLOAT$3 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4$1 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1$1 = 0x8034; +const UNSIGNED_SHORT_5_6_5$1 = 0x8363; +const HALF_FLOAT$1 = 0x140B; +const UNSIGNED_INT_2_10_10_10_REV$1 = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV$1 = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV$1 = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV$1 = 0x8DAD; +const UNSIGNED_INT_24_8$1 = 0x84FA; + +const glTypeToTypedArray = {}; +{ + const tt = glTypeToTypedArray; + tt[BYTE$2] = Int8Array; + tt[UNSIGNED_BYTE$3] = Uint8Array; + tt[SHORT$2] = Int16Array; + tt[UNSIGNED_SHORT$3] = Uint16Array; + tt[INT$3] = Int32Array; + tt[UNSIGNED_INT$3] = Uint32Array; + tt[FLOAT$3] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5$1] = Uint16Array; + tt[HALF_FLOAT$1] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV$1] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV$1] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV$1] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV$1] = Uint32Array; + tt[UNSIGNED_INT_24_8$1] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArray instanceof Int32Array) { return INT$3; } // eslint-disable-line + if (typedArray instanceof Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArray instanceof Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArrayType === Int32Array) { return INT$3; } // eslint-disable-line + if (typedArrayType === Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArrayType === Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + const CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} + +const isArrayBuffer$1 = typeof SharedArrayBuffer !== 'undefined' + ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); + } + : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; + }; + +var typedarrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + getGLTypeForTypedArray: getGLTypeForTypedArray, + getGLTypeForTypedArrayType: getGLTypeForTypedArrayType, + getTypedArrayTypeForGLType: getTypedArrayTypeForGLType, + isArrayBuffer: isArrayBuffer$1 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* eslint no-console: "off" */ + +/** + * Copy named properties + * + * @param {string[]} names names of properties to copy + * @param {object} src object to copy properties from + * @param {object} dst object to copy properties to + * @private + */ +function copyNamedProperties(names, src, dst) { + names.forEach(function(name) { + const value = src[name]; + if (value !== undefined) { + dst[name] = value; + } + }); +} + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function(key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} + +function error$1(...args) { + console.error(...args); +} + +function warn$1(...args) { + console.warn(...args); +} + +const isTypeWeakMaps = new Map(); + +function isType(object, type) { + if (!object || typeof object !== 'object') { + return false; + } + let weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + let isOfType = weakMap.get(object); + if (isOfType === undefined) { + const s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} + +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} + +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} + +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} + +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const STATIC_DRAW = 0x88e4; +const ARRAY_BUFFER$1 = 0x8892; +const ELEMENT_ARRAY_BUFFER$2 = 0x8893; +const BUFFER_SIZE = 0x8764; + +const BYTE$1 = 0x1400; +const UNSIGNED_BYTE$2 = 0x1401; +const SHORT$1 = 0x1402; +const UNSIGNED_SHORT$2 = 0x1403; +const INT$2 = 0x1404; +const UNSIGNED_INT$2 = 0x1405; +const FLOAT$2 = 0x1406; +const defaults$2 = { + attribPrefix: "", +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults$2.attribPrefix = prefix; +} + +function setDefaults$2(newDefaults) { + copyExistingProperties(newDefaults, defaults$2); +} + +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER$1; + const buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} + +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return true; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line + return false; +} + +function getArray$1(array) { + return array.length ? array : array.data; +} + +const texcoordRE = /coord|texture/i; +const colorRE = /color|colour/i; + +function guessNumComponentsFromName(name, length) { + let numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + + if (length % numComponents > 0) { + throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`); + } + + return numComponents; +} + +function getNumComponents$1(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray$1(array).length); +} + +function makeTypedArray(array, name) { + if (isArrayBuffer$1(array)) { + return array; + } + + if (isArrayBuffer$1(array.data)) { + return array.data; + } + + if (Array.isArray(array)) { + array = { + data: array, + }; + } + + let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} + +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? glTypeOrTypedArrayCtor + : glTypeOrTypedArrayCtor ? getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT$2; +} + +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) + : glTypeOrTypedArrayCtor || Float32Array; +} + +function attribBufferFromBuffer(gl, array/*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type), + }; +} + +function attribBufferFromSize(gl, array/*, arrayName*/) { + const numValues = array.data || array; + const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + const numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + const buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER$1, buffer); + gl.bufferData(ARRAY_BUFFER$1, numBytes, array.drawType || STATIC_DRAW); + return { + buffer, + numValues, + type: getGLTypeForTypedArrayType(arrayType), + arrayType, + }; +} + +function attribBufferFromArrayLike(gl, array, arrayName) { + const typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: getGLTypeForTypedArray(typedArray), + numValues: 0, + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + const attribs = {}; + Object.keys(arrays).forEach(function(arrayName) { + if (!isIndices(arrayName)) { + const array = arrays[arrayName]; + const attribName = array.attrib || array.name || array.attribName || (defaults$2.attribPrefix + arrayName); + if (array.value) { + if (!Array.isArray(array.value) && !isArrayBuffer$1(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value, + }; + } else { + let fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName); + const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + const numComponents = getNumComponents$1(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType, + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER$1, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER$1, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER$1, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER$1, attribInfo.buffer, array, attribInfo.drawType); + } +} + +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE$1) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE$2) return 1; // eslint-disable-line + if (type === SHORT$1) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT$2) return 2; // eslint-disable-line + if (type === INT$2) return 4; // eslint-disable-line + if (type === UNSIGNED_INT$2) return 4; // eslint-disable-line + if (type === FLOAT$2) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +const positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + const array = arrays[key]; + const length = getArray$1(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + const numComponents = getNumComponents$1(array, key); + const numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +function getNumElementsFromAttributes(gl, attribs) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults$2.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + const attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER$1, attrib.buffer); + const numBytes = gl.getBufferParameter(ARRAY_BUFFER$1, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER$1, null); + + const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + const totalElements = numBytes / bytesPerValue; + const numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + const numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + const newAttribs = createAttribsFromArrays(gl, arrays); + const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + const indices = arrays.indices; + if (indices) { + const newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER$2); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + const type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER$2 : ARRAY_BUFFER$1; + const typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + const buffers = { }; + Object.keys(arrays).forEach(function(key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = getGLTypeForTypedArray(makeTypedArray(arrays.indices)); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + + return buffers; +} + +var attributes = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttribsFromArrays: createAttribsFromArrays, + createBuffersFromArrays: createBuffersFromArrays, + createBufferFromArray: createBufferFromArray, + createBufferFromTypedArray: createBufferFromTypedArray, + createBufferInfoFromArrays: createBufferInfoFromArrays, + setAttribInfoBufferFromArray: setAttribInfoBufferFromArray, + setAttributePrefix: setAttributePrefix, + setAttributeDefaults_: setDefaults$2, + getNumComponents_: getNumComponents$1, + getArray_: getArray$1 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const getArray = getArray$1; // eslint-disable-line +const getNumComponents = getNumComponents$1; // eslint-disable-line + +/** + * @typedef {(Int8Array|Uint8Array|Int16Array|Uint16Array|Int32Array|Uint32Array|Float32Array)} TypedArray + */ + +/** + * 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 + * @param {TypedArray} typedArray TypedArray to augment + * @param {number} numComponents number of components. + * @private + */ +function augmentTypedArray(typedArray, numComponents) { + let cursor = 0; + typedArray.push = function() { + for (let ii = 0; ii < arguments.length; ++ii) { + const value = arguments[ii]; + if (value instanceof Array || isArrayBuffer$1(value)) { + for (let 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: + * + * const 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 {ArrayBufferView} A typed array. + * @memberOf module:twgl/primitives + */ +function createAugmentedTypedArray(numComponents, numElements, opt_type) { + const Type = opt_type || Float32Array; + return augmentTypedArray(new Type(numComponents * numElements), numComponents); +} + +function allButIndices(name) { + return name !== "indices"; +} + +/** + * Given indexed vertices creates a new set of vertices un-indexed by expanding the indexed vertices. + * @param {Object.} vertices The indexed vertices to deindex + * @return {Object.} The deindexed vertices + * @memberOf module:twgl/primitives + */ +function deindexVertices(vertices) { + const indices = vertices.indices; + const newVertices = {}; + const numElements = indices.length; + + function expandToUnindexed(channel) { + const srcBuffer = vertices[channel]; + const numComponents = srcBuffer.numComponents; + const dstBuffer = createAugmentedTypedArray(numComponents, numElements, srcBuffer.constructor); + for (let ii = 0; ii < numElements; ++ii) { + const ndx = indices[ii]; + const offset = ndx * numComponents; + for (let jj = 0; jj < numComponents; ++jj) { + dstBuffer.push(srcBuffer[offset + jj]); + } + } + newVertices[channel] = dstBuffer; + } + + Object.keys(vertices).filter(allButIndices).forEach(expandToUnindexed); + + return newVertices; +} + +/** + * flattens the normals of deindexed vertices in place. + * @param {Object.} vertices The deindexed vertices who's normals to flatten + * @return {Object.} The flattened vertices (same as was passed in) + * @memberOf module:twgl/primitives + */ +function flattenNormals(vertices) { + if (vertices.indices) { + throw new Error('can not flatten normals of indexed vertices. deindex them first'); + } + + const normals = vertices.normal; + const numNormals = normals.length; + for (let ii = 0; ii < numNormals; ii += 9) { + // pull out the 3 normals for this triangle + const nax = normals[ii + 0]; + const nay = normals[ii + 1]; + const naz = normals[ii + 2]; + + const nbx = normals[ii + 3]; + const nby = normals[ii + 4]; + const nbz = normals[ii + 5]; + + const ncx = normals[ii + 6]; + const ncy = normals[ii + 7]; + const ncz = normals[ii + 8]; + + // add them + let nx = nax + nbx + ncx; + let ny = nay + nby + ncy; + let nz = naz + nbz + ncz; + + // normalize them + const length = Math.sqrt(nx * nx + ny * ny + nz * nz); + + nx /= length; + ny /= length; + nz /= length; + + // copy them back in + normals[ii + 0] = nx; + normals[ii + 1] = ny; + normals[ii + 2] = nz; + + normals[ii + 3] = nx; + normals[ii + 4] = ny; + normals[ii + 5] = nz; + + normals[ii + 6] = nx; + normals[ii + 7] = ny; + normals[ii + 8] = nz; + } + + return vertices; +} + +function applyFuncToV3Array(array, matrix, fn) { + const len = array.length; + const tmp = new Float32Array(3); + for (let ii = 0; ii < len; ii += 3) { + fn(matrix, [array[ii], array[ii + 1], array[ii + 2]], tmp); + array[ii ] = tmp[0]; + array[ii + 1] = tmp[1]; + array[ii + 2] = tmp[2]; + } +} + +function transformNormal(mi, v, dst) { + dst = dst || create$1(); + const v0 = v[0]; + const v1 = v[1]; + const v2 = v[2]; + + dst[0] = v0 * mi[0 * 4 + 0] + v1 * mi[0 * 4 + 1] + v2 * mi[0 * 4 + 2]; + dst[1] = v0 * mi[1 * 4 + 0] + v1 * mi[1 * 4 + 1] + v2 * mi[1 * 4 + 2]; + dst[2] = v0 * mi[2 * 4 + 0] + v1 * mi[2 * 4 + 1] + v2 * mi[2 * 4 + 2]; + + return dst; +} + +/** + * Reorients directions by the given matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientDirections(array, matrix) { + applyFuncToV3Array(array, matrix, transformDirection); + return array; +} + +/** + * Reorients normals by the inverse-transpose of the given + * matrix.. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientNormals(array, matrix) { + applyFuncToV3Array(array, inverse(matrix), transformNormal); + return array; +} + +/** + * Reorients positions by the given matrix. In other words, it + * multiplies each vertex by the given matrix. + * @param {(number[]|TypedArray)} array The array. Assumes value floats per element. + * @param {module:twgl/m4.Mat4} matrix A matrix to multiply by. + * @return {(number[]|TypedArray)} the same array that was passed in + * @memberOf module:twgl/primitives + */ +function reorientPositions(array, matrix) { + applyFuncToV3Array(array, matrix, transformPoint); + return array; +} + +/** + * @typedef {(number[]|TypedArray)} NativeArrayOrTypedArray + */ + +/** + * Reorients arrays by the given matrix. Assumes arrays have + * names that contains 'pos' could be reoriented as positions, + * 'binorm' or 'tan' as directions, and 'norm' as normals. + * + * @param {Object.} arrays The vertices to reorient + * @param {module:twgl/m4.Mat4} matrix matrix to reorient by. + * @return {Object.} same arrays that were passed in. + * @memberOf module:twgl/primitives + */ +function reorientVertices(arrays, matrix) { + Object.keys(arrays).forEach(function(name) { + const array = arrays[name]; + if (name.indexOf("pos") >= 0) { + reorientPositions(array, matrix); + } else if (name.indexOf("tan") >= 0 || name.indexOf("binorm") >= 0) { + reorientDirections(array, matrix); + } else if (name.indexOf("norm") >= 0) { + reorientNormals(array, matrix); + } + }); + return arrays; +} + +/** + * Creates XY quad BufferInfo + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad BufferInfo + * @memberOf module:twgl/primitives + * @function createXYQuadBuffers + */ + +/** + * Creates XY quad Buffers + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadBufferInfo(gl, 1, 0, 0.5); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {module:twgl.BufferInfo} the created XY Quad buffers + * @memberOf module:twgl/primitives + * @function createXYQuadBufferInfo + */ + +/** + * Creates XY quad vertices + * + * The default with no parameters will return a 2x2 quad with values from -1 to +1. + * If you want a unit quad with that goes from 0 to 1 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0.5, 0.5); + * + * If you want a unit quad centered above 0,0 you'd call it with + * + * twgl.primitives.createXYQuadVertices(1, 0, 0.5); + * + * @param {number} [size] the size across the quad. Defaults to 2 which means vertices will go from -1 to +1 + * @param {number} [xOffset] the amount to offset the quad in X + * @param {number} [yOffset] the amount to offset the quad in Y + * @return {Object.} the created XY Quad vertices + * @memberOf module:twgl/primitives + */ +function createXYQuadVertices(size, xOffset, yOffset) { + size = size || 2; + xOffset = xOffset || 0; + yOffset = yOffset || 0; + size *= 0.5; + return { + position: { + numComponents: 2, + data: [ + xOffset + -1 * size, yOffset + -1 * size, + xOffset + 1 * size, yOffset + -1 * size, + xOffset + -1 * size, yOffset + 1 * size, + xOffset + 1 * size, yOffset + 1 * size, + ], + }, + normal: [ + 0, 0, 1, + 0, 0, 1, + 0, 0, 1, + 0, 0, 1, + ], + texcoord: [ + 0, 0, + 1, 0, + 0, 1, + 1, 1, + ], + indices: [ 0, 1, 2, 2, 1, 3 ], + }; +} + +/** + * Creates XZ plane BufferInfo. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {module:twgl.BufferInfo} The created plane BufferInfo. + * @memberOf module:twgl/primitives + * @function createPlaneBufferInfo + */ + +/** + * Creates XZ plane buffers. + * + * The created plane has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane buffers. + * @memberOf module:twgl/primitives + * @function createPlaneBuffers + */ + +/** + * Creates XZ plane vertices. + * + * The created plane has position, normal, and texcoord data + * + * @param {number} [width] Width of the plane. Default = 1 + * @param {number} [depth] Depth of the plane. Default = 1 + * @param {number} [subdivisionsWidth] Number of steps across the plane. Default = 1 + * @param {number} [subdivisionsDepth] Number of steps down the plane. Default = 1 + * @param {module:twgl/m4.Mat4} [matrix] A matrix by which to multiply all the vertices. + * @return {Object.} The created plane vertices. + * @memberOf module:twgl/primitives + */ +function createPlaneVertices( + width, + depth, + subdivisionsWidth, + subdivisionsDepth, + matrix) { + width = width || 1; + depth = depth || 1; + subdivisionsWidth = subdivisionsWidth || 1; + subdivisionsDepth = subdivisionsDepth || 1; + matrix = matrix || identity(); + + const numVertices = (subdivisionsWidth + 1) * (subdivisionsDepth + 1); + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + + for (let z = 0; z <= subdivisionsDepth; z++) { + for (let x = 0; x <= subdivisionsWidth; x++) { + const u = x / subdivisionsWidth; + const v = z / subdivisionsDepth; + positions.push( + width * u - width * 0.5, + 0, + depth * v - depth * 0.5); + normals.push(0, 1, 0); + texcoords.push(u, v); + } + } + + const numVertsAcross = subdivisionsWidth + 1; + const indices = createAugmentedTypedArray( + 3, subdivisionsWidth * subdivisionsDepth * 2, Uint16Array); + + for (let z = 0; z < subdivisionsDepth; z++) { // eslint-disable-line + for (let x = 0; x < subdivisionsWidth; x++) { // eslint-disable-line + // Make triangle 1 of quad. + indices.push( + (z + 0) * numVertsAcross + x, + (z + 1) * numVertsAcross + x, + (z + 0) * numVertsAcross + x + 1); + + // Make triangle 2 of quad. + indices.push( + (z + 1) * numVertsAcross + x, + (z + 1) * numVertsAcross + x + 1, + (z + 0) * numVertsAcross + x + 1); + } + } + + const arrays = reorientVertices({ + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }, matrix); + return arrays; +} + +/** + * Creates sphere BufferInfo. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {module:twgl.BufferInfo} The created sphere BufferInfo. + * @memberOf module:twgl/primitives + * @function createSphereBufferInfo + */ + +/** + * Creates sphere buffers. + * + * The created sphere has position, normal, and texcoord data + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere buffers. + * @memberOf module:twgl/primitives + * @function createSphereBuffers + */ + +/** + * Creates sphere vertices. + * + * The created sphere has position, normal, and texcoord data + * + * @param {number} radius radius of the sphere. + * @param {number} subdivisionsAxis number of steps around the sphere. + * @param {number} subdivisionsHeight number of vertically on the sphere. + * @param {number} [opt_startLatitudeInRadians] where to start the + * top of the sphere. Default = 0. + * @param {number} [opt_endLatitudeInRadians] Where to end the + * bottom of the sphere. Default = Math.PI. + * @param {number} [opt_startLongitudeInRadians] where to start + * wrapping the sphere. Default = 0. + * @param {number} [opt_endLongitudeInRadians] where to end + * wrapping the sphere. Default = 2 * Math.PI. + * @return {Object.} The created sphere vertices. + * @memberOf module:twgl/primitives + */ +function createSphereVertices( + radius, + subdivisionsAxis, + subdivisionsHeight, + opt_startLatitudeInRadians, + opt_endLatitudeInRadians, + opt_startLongitudeInRadians, + opt_endLongitudeInRadians) { + if (subdivisionsAxis <= 0 || subdivisionsHeight <= 0) { + throw new Error('subdivisionAxis and subdivisionHeight must be > 0'); + } + + opt_startLatitudeInRadians = opt_startLatitudeInRadians || 0; + opt_endLatitudeInRadians = opt_endLatitudeInRadians || Math.PI; + opt_startLongitudeInRadians = opt_startLongitudeInRadians || 0; + opt_endLongitudeInRadians = opt_endLongitudeInRadians || (Math.PI * 2); + + const latRange = opt_endLatitudeInRadians - opt_startLatitudeInRadians; + const longRange = opt_endLongitudeInRadians - opt_startLongitudeInRadians; + + // We are going to generate our sphere by iterating through its + // spherical coordinates and generating 2 triangles for each quad on a + // ring of the sphere. + const numVertices = (subdivisionsAxis + 1) * (subdivisionsHeight + 1); + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + + // Generate the individual vertices in our vertex buffer. + for (let y = 0; y <= subdivisionsHeight; y++) { + for (let x = 0; x <= subdivisionsAxis; x++) { + // Generate a vertex based on its spherical coordinates + const u = x / subdivisionsAxis; + const v = y / subdivisionsHeight; + const theta = longRange * u + opt_startLongitudeInRadians; + const phi = latRange * v + opt_startLatitudeInRadians; + const sinTheta = Math.sin(theta); + const cosTheta = Math.cos(theta); + const sinPhi = Math.sin(phi); + const cosPhi = Math.cos(phi); + const ux = cosTheta * sinPhi; + const uy = cosPhi; + const uz = sinTheta * sinPhi; + positions.push(radius * ux, radius * uy, radius * uz); + normals.push(ux, uy, uz); + texcoords.push(1 - u, v); + } + } + + const numVertsAround = subdivisionsAxis + 1; + const indices = createAugmentedTypedArray(3, subdivisionsAxis * subdivisionsHeight * 2, Uint16Array); + for (let x = 0; x < subdivisionsAxis; x++) { // eslint-disable-line + for (let y = 0; y < subdivisionsHeight; y++) { // eslint-disable-line + // Make triangle 1 of quad. + indices.push( + (y + 0) * numVertsAround + x, + (y + 0) * numVertsAround + x + 1, + (y + 1) * numVertsAround + x); + + // Make triangle 2 of quad. + indices.push( + (y + 1) * numVertsAround + x, + (y + 0) * numVertsAround + x + 1, + (y + 1) * numVertsAround + x + 1); + } + } + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + +/** + * Array of the indices of corners of each face of a cube. + * @type {Array.} + * @private + */ +const CUBE_FACE_INDICES = [ + [3, 7, 5, 1], // right + [6, 2, 0, 4], // left + [6, 7, 3, 2], // ?? + [0, 1, 5, 4], // ?? + [7, 6, 4, 5], // front + [2, 3, 1, 0], // back +]; + +/** + * Creates a BufferInfo for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCubeBufferInfo + */ + +/** + * Creates the buffers and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCubeBuffers + */ + +/** + * Creates the vertices and indices for a cube. + * + * The cube is created around the origin. (-size / 2, size / 2). + * + * @param {number} [size] width, height and depth of the cube. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createCubeVertices(size) { + size = size || 1; + const k = size / 2; + + const cornerVertices = [ + [-k, -k, -k], + [+k, -k, -k], + [-k, +k, -k], + [+k, +k, -k], + [-k, -k, +k], + [+k, -k, +k], + [-k, +k, +k], + [+k, +k, +k], + ]; + + const faceNormals = [ + [+1, +0, +0], + [-1, +0, +0], + [+0, +1, +0], + [+0, -1, +0], + [+0, +0, +1], + [+0, +0, -1], + ]; + + const uvCoords = [ + [1, 0], + [0, 0], + [0, 1], + [1, 1], + ]; + + const numVertices = 6 * 4; + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2 , numVertices); + const indices = createAugmentedTypedArray(3, 6 * 2, Uint16Array); + + for (let f = 0; f < 6; ++f) { + const faceIndices = CUBE_FACE_INDICES[f]; + for (let v = 0; v < 4; ++v) { + const position = cornerVertices[faceIndices[v]]; + const normal = faceNormals[f]; + const uv = uvCoords[v]; + + // Each face needs all four vertices because the normals and texture + // coordinates are not all the same. + positions.push(position); + normals.push(normal); + texcoords.push(uv); + + } + // Two triangles make a square face. + const offset = 4 * f; + indices.push(offset + 0, offset + 1, offset + 2); + indices.push(offset + 0, offset + 2, offset + 3); + } + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + +/** + * Creates a BufferInfo for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {module:twgl.BufferInfo} The created cone BufferInfo. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBufferInfo + */ + +/** + * Creates buffers for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone buffers. + * @memberOf module:twgl/primitives + * @function createTruncatedConeBuffers + */ + +/** + * Creates vertices for a truncated cone, which is like a cylinder + * except that it has different top and bottom radii. A truncated cone + * can also be used to create cylinders and regular cones. The + * truncated cone will be created centered about the origin, with the + * y axis as its vertical axis. . + * + * @param {number} bottomRadius Bottom radius of truncated cone. + * @param {number} topRadius Top radius of truncated cone. + * @param {number} height Height of truncated cone. + * @param {number} radialSubdivisions The number of subdivisions around the + * truncated cone. + * @param {number} verticalSubdivisions The number of subdivisions down the + * truncated cone. + * @param {boolean} [opt_topCap] Create top cap. Default = true. + * @param {boolean} [opt_bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created cone vertices. + * @memberOf module:twgl/primitives + */ +function createTruncatedConeVertices( + bottomRadius, + topRadius, + height, + radialSubdivisions, + verticalSubdivisions, + opt_topCap, + opt_bottomCap) { + if (radialSubdivisions < 3) { + throw new Error('radialSubdivisions must be 3 or greater'); + } + + if (verticalSubdivisions < 1) { + throw new Error('verticalSubdivisions must be 1 or greater'); + } + + const topCap = (opt_topCap === undefined) ? true : opt_topCap; + const bottomCap = (opt_bottomCap === undefined) ? true : opt_bottomCap; + + const extra = (topCap ? 2 : 0) + (bottomCap ? 2 : 0); + + const numVertices = (radialSubdivisions + 1) * (verticalSubdivisions + 1 + extra); + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + const indices = createAugmentedTypedArray(3, radialSubdivisions * (verticalSubdivisions + extra / 2) * 2, Uint16Array); + + const vertsAroundEdge = radialSubdivisions + 1; + + // The slant of the cone is constant across its surface + const slant = Math.atan2(bottomRadius - topRadius, height); + const cosSlant = Math.cos(slant); + const sinSlant = Math.sin(slant); + + const start = topCap ? -2 : 0; + const end = verticalSubdivisions + (bottomCap ? 2 : 0); + + for (let yy = start; yy <= end; ++yy) { + let v = yy / verticalSubdivisions; + let y = height * v; + let ringRadius; + if (yy < 0) { + y = 0; + v = 1; + ringRadius = bottomRadius; + } else if (yy > verticalSubdivisions) { + y = height; + v = 1; + ringRadius = topRadius; + } else { + ringRadius = bottomRadius + + (topRadius - bottomRadius) * (yy / verticalSubdivisions); + } + if (yy === -2 || yy === verticalSubdivisions + 2) { + ringRadius = 0; + v = 0; + } + y -= height / 2; + for (let ii = 0; ii < vertsAroundEdge; ++ii) { + const sin = Math.sin(ii * Math.PI * 2 / radialSubdivisions); + const cos = Math.cos(ii * Math.PI * 2 / radialSubdivisions); + positions.push(sin * ringRadius, y, cos * ringRadius); + if (yy < 0) { + normals.push(0, -1, 0); + } else if (yy > verticalSubdivisions) { + normals.push(0, 1, 0); + } else if (ringRadius === 0.0) { + normals.push(0, 0, 0); + } else { + normals.push(sin * cosSlant, sinSlant, cos * cosSlant); + } + texcoords.push((ii / radialSubdivisions), 1 - v); + } + } + + for (let yy = 0; yy < verticalSubdivisions + extra; ++yy) { // eslint-disable-line + if (yy === 1 && topCap || yy === verticalSubdivisions + extra - 2 && bottomCap) { + continue; + } + for (let ii = 0; ii < radialSubdivisions; ++ii) { // eslint-disable-line + indices.push(vertsAroundEdge * (yy + 0) + 0 + ii, + vertsAroundEdge * (yy + 0) + 1 + ii, + vertsAroundEdge * (yy + 1) + 1 + ii); + indices.push(vertsAroundEdge * (yy + 0) + 0 + ii, + vertsAroundEdge * (yy + 1) + 1 + ii, + vertsAroundEdge * (yy + 1) + 0 + ii); + } + } + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + +/** + * Expands RLE data + * @param {number[]} rleData data in format of run-length, x, y, z, run-length, x, y, z + * @param {number[]} [padding] value to add each entry with. + * @return {number[]} the expanded rleData + * @private + */ +function expandRLEData(rleData, padding) { + padding = padding || []; + const data = []; + for (let ii = 0; ii < rleData.length; ii += 4) { + const runLength = rleData[ii]; + const element = rleData.slice(ii + 1, ii + 4); + element.push.apply(element, padding); + for (let jj = 0; jj < runLength; ++jj) { + data.push.apply(data, element); + } + } + return data; +} + +/** + * Creates 3D 'F' BufferInfo. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function create3DFBufferInfo + */ + +/** + * Creates 3D 'F' buffers. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function create3DFBuffers + */ + +/** + * Creates 3D 'F' vertices. + * An 'F' is useful because you can easily tell which way it is oriented. + * The created 'F' has position, normal, texcoord, and color arrays. + * + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function create3DFVertices() { + + const positions = [ + // left column front + 0, 0, 0, + 0, 150, 0, + 30, 0, 0, + 0, 150, 0, + 30, 150, 0, + 30, 0, 0, + + // top rung front + 30, 0, 0, + 30, 30, 0, + 100, 0, 0, + 30, 30, 0, + 100, 30, 0, + 100, 0, 0, + + // middle rung front + 30, 60, 0, + 30, 90, 0, + 67, 60, 0, + 30, 90, 0, + 67, 90, 0, + 67, 60, 0, + + // left column back + 0, 0, 30, + 30, 0, 30, + 0, 150, 30, + 0, 150, 30, + 30, 0, 30, + 30, 150, 30, + + // top rung back + 30, 0, 30, + 100, 0, 30, + 30, 30, 30, + 30, 30, 30, + 100, 0, 30, + 100, 30, 30, + + // middle rung back + 30, 60, 30, + 67, 60, 30, + 30, 90, 30, + 30, 90, 30, + 67, 60, 30, + 67, 90, 30, + + // top + 0, 0, 0, + 100, 0, 0, + 100, 0, 30, + 0, 0, 0, + 100, 0, 30, + 0, 0, 30, + + // top rung front + 100, 0, 0, + 100, 30, 0, + 100, 30, 30, + 100, 0, 0, + 100, 30, 30, + 100, 0, 30, + + // under top rung + 30, 30, 0, + 30, 30, 30, + 100, 30, 30, + 30, 30, 0, + 100, 30, 30, + 100, 30, 0, + + // between top rung and middle + 30, 30, 0, + 30, 60, 30, + 30, 30, 30, + 30, 30, 0, + 30, 60, 0, + 30, 60, 30, + + // top of middle rung + 30, 60, 0, + 67, 60, 30, + 30, 60, 30, + 30, 60, 0, + 67, 60, 0, + 67, 60, 30, + + // front of middle rung + 67, 60, 0, + 67, 90, 30, + 67, 60, 30, + 67, 60, 0, + 67, 90, 0, + 67, 90, 30, + + // bottom of middle rung. + 30, 90, 0, + 30, 90, 30, + 67, 90, 30, + 30, 90, 0, + 67, 90, 30, + 67, 90, 0, + + // front of bottom + 30, 90, 0, + 30, 150, 30, + 30, 90, 30, + 30, 90, 0, + 30, 150, 0, + 30, 150, 30, + + // bottom + 0, 150, 0, + 0, 150, 30, + 30, 150, 30, + 0, 150, 0, + 30, 150, 30, + 30, 150, 0, + + // left side + 0, 0, 0, + 0, 0, 30, + 0, 150, 30, + 0, 0, 0, + 0, 150, 30, + 0, 150, 0, + ]; + + const texcoords = [ + // left column front + 0.22, 0.19, + 0.22, 0.79, + 0.34, 0.19, + 0.22, 0.79, + 0.34, 0.79, + 0.34, 0.19, + + // top rung front + 0.34, 0.19, + 0.34, 0.31, + 0.62, 0.19, + 0.34, 0.31, + 0.62, 0.31, + 0.62, 0.19, + + // middle rung front + 0.34, 0.43, + 0.34, 0.55, + 0.49, 0.43, + 0.34, 0.55, + 0.49, 0.55, + 0.49, 0.43, + + // left column back + 0, 0, + 1, 0, + 0, 1, + 0, 1, + 1, 0, + 1, 1, + + // top rung back + 0, 0, + 1, 0, + 0, 1, + 0, 1, + 1, 0, + 1, 1, + + // middle rung back + 0, 0, + 1, 0, + 0, 1, + 0, 1, + 1, 0, + 1, 1, + + // top + 0, 0, + 1, 0, + 1, 1, + 0, 0, + 1, 1, + 0, 1, + + // top rung front + 0, 0, + 1, 0, + 1, 1, + 0, 0, + 1, 1, + 0, 1, + + // under top rung + 0, 0, + 0, 1, + 1, 1, + 0, 0, + 1, 1, + 1, 0, + + // between top rung and middle + 0, 0, + 1, 1, + 0, 1, + 0, 0, + 1, 0, + 1, 1, + + // top of middle rung + 0, 0, + 1, 1, + 0, 1, + 0, 0, + 1, 0, + 1, 1, + + // front of middle rung + 0, 0, + 1, 1, + 0, 1, + 0, 0, + 1, 0, + 1, 1, + + // bottom of middle rung. + 0, 0, + 0, 1, + 1, 1, + 0, 0, + 1, 1, + 1, 0, + + // front of bottom + 0, 0, + 1, 1, + 0, 1, + 0, 0, + 1, 0, + 1, 1, + + // bottom + 0, 0, + 0, 1, + 1, 1, + 0, 0, + 1, 1, + 1, 0, + + // left side + 0, 0, + 0, 1, + 1, 1, + 0, 0, + 1, 1, + 1, 0, + ]; + + const normals = expandRLEData([ + // left column front + // top rung front + // middle rung front + 18, 0, 0, 1, + + // left column back + // top rung back + // middle rung back + 18, 0, 0, -1, + + // top + 6, 0, 1, 0, + + // top rung front + 6, 1, 0, 0, + + // under top rung + 6, 0, -1, 0, + + // between top rung and middle + 6, 1, 0, 0, + + // top of middle rung + 6, 0, 1, 0, + + // front of middle rung + 6, 1, 0, 0, + + // bottom of middle rung. + 6, 0, -1, 0, + + // front of bottom + 6, 1, 0, 0, + + // bottom + 6, 0, -1, 0, + + // left side + 6, -1, 0, 0, + ]); + + const colors = expandRLEData([ + // left column front + // top rung front + // middle rung front + 18, 200, 70, 120, + + // left column back + // top rung back + // middle rung back + 18, 80, 70, 200, + + // top + 6, 70, 200, 210, + + // top rung front + 6, 200, 200, 70, + + // under top rung + 6, 210, 100, 70, + + // between top rung and middle + 6, 210, 160, 70, + + // top of middle rung + 6, 70, 180, 210, + + // front of middle rung + 6, 100, 70, 210, + + // bottom of middle rung. + 6, 76, 210, 100, + + // front of bottom + 6, 140, 210, 80, + + // bottom + 6, 90, 130, 110, + + // left side + 6, 160, 160, 220, + ], [255]); + + const numVerts = positions.length / 3; + + const arrays = { + position: createAugmentedTypedArray(3, numVerts), + texcoord: createAugmentedTypedArray(2, numVerts), + normal: createAugmentedTypedArray(3, numVerts), + color: createAugmentedTypedArray(4, numVerts, Uint8Array), + indices: createAugmentedTypedArray(3, numVerts / 3, Uint16Array), + }; + + arrays.position.push(positions); + arrays.texcoord.push(texcoords); + arrays.normal.push(normals); + arrays.color.push(colors); + + for (let ii = 0; ii < numVerts; ++ii) { + arrays.indices.push(ii); + } + + return arrays; +} + +/** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCresentBufferInfo + */ + +/** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + +/** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + * @function createCresentBuffers + */ + +/** + * Creates crescent BufferInfo. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCrescentBufferInfo + */ + +/** + * Creates crescent buffers. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCrescentBuffers + */ + +/** + * Creates crescent vertices. + * + * @param {number} verticalRadius The vertical radius of the crescent. + * @param {number} outerRadius The outer radius of the crescent. + * @param {number} innerRadius The inner radius of the crescent. + * @param {number} thickness The thickness of the crescent. + * @param {number} subdivisionsDown number of steps around the crescent. + * @param {number} [startOffset] Where to start arc. Default 0. + * @param {number} [endOffset] Where to end arg. Default 1. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ + function createCrescentVertices( + verticalRadius, + outerRadius, + innerRadius, + thickness, + subdivisionsDown, + startOffset, + endOffset) { + if (subdivisionsDown <= 0) { + throw new Error('subdivisionDown must be > 0'); + } + + startOffset = startOffset || 0; + endOffset = endOffset || 1; + + const subdivisionsThick = 2; + + const offsetRange = endOffset - startOffset; + const numVertices = (subdivisionsDown + 1) * 2 * (2 + subdivisionsThick); + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + + function lerp(a, b, s) { + return a + (b - a) * s; + } + + function createArc(arcRadius, x, normalMult, normalAdd, uMult, uAdd) { + for (let z = 0; z <= subdivisionsDown; z++) { + const uBack = x / (subdivisionsThick - 1); + const v = z / subdivisionsDown; + const xBack = (uBack - 0.5) * 2; + const angle = (startOffset + (v * offsetRange)) * Math.PI; + const s = Math.sin(angle); + const c = Math.cos(angle); + const radius = lerp(verticalRadius, arcRadius, s); + const px = xBack * thickness; + const py = c * verticalRadius; + const pz = s * radius; + positions.push(px, py, pz); + const n = add(multiply$1([0, s, c], normalMult), normalAdd); + normals.push(n); + texcoords.push(uBack * uMult + uAdd, v); + } + } + + // Generate the individual vertices in our vertex buffer. + for (let x = 0; x < subdivisionsThick; x++) { + const uBack = (x / (subdivisionsThick - 1) - 0.5) * 2; + createArc(outerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); + createArc(outerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 0); + createArc(innerRadius, x, [1, 1, 1], [0, 0, 0], 1, 0); + createArc(innerRadius, x, [0, 0, 0], [uBack, 0, 0], 0, 1); + } + + // Do outer surface. + const indices = createAugmentedTypedArray(3, (subdivisionsDown * 2) * (2 + subdivisionsThick), Uint16Array); + + function createSurface(leftArcOffset, rightArcOffset) { + for (let z = 0; z < subdivisionsDown; ++z) { + // Make triangle 1 of quad. + indices.push( + leftArcOffset + z + 0, + leftArcOffset + z + 1, + rightArcOffset + z + 0); + + // Make triangle 2 of quad. + indices.push( + leftArcOffset + z + 1, + rightArcOffset + z + 1, + rightArcOffset + z + 0); + } + } + + const numVerticesDown = subdivisionsDown + 1; + // front + createSurface(numVerticesDown * 0, numVerticesDown * 4); + // right + createSurface(numVerticesDown * 5, numVerticesDown * 7); + // back + createSurface(numVerticesDown * 6, numVerticesDown * 2); + // left + createSurface(numVerticesDown * 3, numVerticesDown * 1); + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + +/** + * Creates cylinder BufferInfo. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createCylinderBufferInfo + */ + + /** + * Creates cylinder buffers. The cylinder will be created around the origin + * along the y-axis. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createCylinderBuffers + */ + + /** + * Creates cylinder vertices. The cylinder will be created around the origin + * along the y-axis. + * + * @param {number} radius Radius of cylinder. + * @param {number} height Height of cylinder. + * @param {number} radialSubdivisions The number of subdivisions around the cylinder. + * @param {number} verticalSubdivisions The number of subdivisions down the cylinder. + * @param {boolean} [topCap] Create top cap. Default = true. + * @param {boolean} [bottomCap] Create bottom cap. Default = true. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createCylinderVertices( + radius, + height, + radialSubdivisions, + verticalSubdivisions, + topCap, + bottomCap) { + return createTruncatedConeVertices( + radius, + radius, + height, + radialSubdivisions, + verticalSubdivisions, + topCap, + bottomCap); +} + +/** + * Creates BufferInfo for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createTorusBufferInfo + */ + +/** + * Creates buffers for a torus + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createTorusBuffers + */ + +/** + * Creates vertices for a torus + * + * @param {number} radius radius of center of torus circle. + * @param {number} thickness radius of torus ring. + * @param {number} radialSubdivisions The number of subdivisions around the torus. + * @param {number} bodySubdivisions The number of subdivisions around the body torus. + * @param {boolean} [startAngle] start angle in radians. Default = 0. + * @param {boolean} [endAngle] end angle in radians. Default = Math.PI * 2. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createTorusVertices( + radius, + thickness, + radialSubdivisions, + bodySubdivisions, + startAngle, + endAngle) { + if (radialSubdivisions < 3) { + throw new Error('radialSubdivisions must be 3 or greater'); + } + + if (bodySubdivisions < 3) { + throw new Error('verticalSubdivisions must be 3 or greater'); + } + + startAngle = startAngle || 0; + endAngle = endAngle || Math.PI * 2; + const range = endAngle - startAngle; + + const radialParts = radialSubdivisions + 1; + const bodyParts = bodySubdivisions + 1; + const numVertices = radialParts * bodyParts; + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + const indices = createAugmentedTypedArray(3, (radialSubdivisions) * (bodySubdivisions) * 2, Uint16Array); + + for (let slice = 0; slice < bodyParts; ++slice) { + const v = slice / bodySubdivisions; + const sliceAngle = v * Math.PI * 2; + const sliceSin = Math.sin(sliceAngle); + const ringRadius = radius + sliceSin * thickness; + const ny = Math.cos(sliceAngle); + const y = ny * thickness; + for (let ring = 0; ring < radialParts; ++ring) { + const u = ring / radialSubdivisions; + const ringAngle = startAngle + u * range; + const xSin = Math.sin(ringAngle); + const zCos = Math.cos(ringAngle); + const x = xSin * ringRadius; + const z = zCos * ringRadius; + const nx = xSin * sliceSin; + const nz = zCos * sliceSin; + positions.push(x, y, z); + normals.push(nx, ny, nz); + texcoords.push(u, 1 - v); + } + } + + for (let slice = 0; slice < bodySubdivisions; ++slice) { // eslint-disable-line + for (let ring = 0; ring < radialSubdivisions; ++ring) { // eslint-disable-line + const nextRingIndex = 1 + ring; + const nextSliceIndex = 1 + slice; + indices.push(radialParts * slice + ring, + radialParts * nextSliceIndex + ring, + radialParts * slice + nextRingIndex); + indices.push(radialParts * nextSliceIndex + ring, + radialParts * nextSliceIndex + nextRingIndex, + radialParts * slice + nextRingIndex); + } + } + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + + +/** + * Creates a disc BufferInfo. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {module:twgl.BufferInfo} The created BufferInfo. + * @memberOf module:twgl/primitives + * @function createDiscBufferInfo + */ + +/** + * Creates disc buffers. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext. + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created buffers. + * @memberOf module:twgl/primitives + * @function createDiscBuffers + */ + +/** + * Creates disc vertices. The disc will be in the xz plane, centered at + * the origin. When creating, at least 3 divisions, or pie + * pieces, need to be specified, otherwise the triangles making + * up the disc will be degenerate. You can also specify the + * number of radial pieces `stacks`. A value of 1 for + * stacks will give you a simple disc of pie pieces. If you + * want to create an annulus you can set `innerRadius` to a + * value > 0. Finally, `stackPower` allows you to have the widths + * increase or decrease as you move away from the center. This + * is particularly useful when using the disc as a ground plane + * with a fixed camera such that you don't need the resolution + * of small triangles near the perimeter. For example, a value + * of 2 will produce stacks whose outside radius increases with + * the square of the stack index. A value of 1 will give uniform + * stacks. + * + * @param {number} radius Radius of the ground plane. + * @param {number} divisions Number of triangles in the ground plane (at least 3). + * @param {number} [stacks] Number of radial divisions (default=1). + * @param {number} [innerRadius] Default 0. + * @param {number} [stackPower] Power to raise stack size to for decreasing width. + * @return {Object.} The created vertices. + * @memberOf module:twgl/primitives + */ +function createDiscVertices( + radius, + divisions, + stacks, + innerRadius, + stackPower) { + if (divisions < 3) { + throw new Error('divisions must be at least 3'); + } + + stacks = stacks ? stacks : 1; + stackPower = stackPower ? stackPower : 1; + innerRadius = innerRadius ? innerRadius : 0; + + // Note: We don't share the center vertex because that would + // mess up texture coordinates. + const numVertices = (divisions + 1) * (stacks + 1); + + const positions = createAugmentedTypedArray(3, numVertices); + const normals = createAugmentedTypedArray(3, numVertices); + const texcoords = createAugmentedTypedArray(2, numVertices); + const indices = createAugmentedTypedArray(3, stacks * divisions * 2, Uint16Array); + + let firstIndex = 0; + const radiusSpan = radius - innerRadius; + const pointsPerStack = divisions + 1; + + // Build the disk one stack at a time. + for (let stack = 0; stack <= stacks; ++stack) { + const stackRadius = innerRadius + radiusSpan * Math.pow(stack / stacks, stackPower); + + for (let i = 0; i <= divisions; ++i) { + const theta = 2.0 * Math.PI * i / divisions; + const x = stackRadius * Math.cos(theta); + const z = stackRadius * Math.sin(theta); + + positions.push(x, 0, z); + normals.push(0, 1, 0); + texcoords.push(1 - (i / divisions), stack / stacks); + if (stack > 0 && i !== divisions) { + // a, b, c and d are the indices of the vertices of a quad. unless + // the current stack is the one closest to the center, in which case + // the vertices a and b connect to the center vertex. + const a = firstIndex + (i + 1); + const b = firstIndex + i; + const c = firstIndex + i - pointsPerStack; + const d = firstIndex + (i + 1) - pointsPerStack; + + // Make a quad of the vertices a, b, c, d. + indices.push(a, b, c); + indices.push(a, c, d); + } + } + + firstIndex += divisions + 1; + } + + return { + position: positions, + normal: normals, + texcoord: texcoords, + indices: indices, + }; +} + +/** + * creates a random integer between 0 and range - 1 inclusive. + * @param {number} range + * @return {number} random value between 0 and range - 1 inclusive. + * @private + */ +function randInt(range) { + return Math.random() * range | 0; +} + +/** + * Used to supply random colors + * @callback RandomColorFunc + * @param {number} ndx index of triangle/quad if unindexed or index of vertex if indexed + * @param {number} channel 0 = red, 1 = green, 2 = blue, 3 = alpha + * @return {number} a number from 0 to 255 + * @memberOf module:twgl/primitives + */ + +/** + * @typedef {Object} RandomVerticesOptions + * @property {number} [vertsPerColor] Defaults to 3 for non-indexed vertices + * @property {module:twgl/primitives.RandomColorFunc} [rand] A function to generate random numbers + * @memberOf module:twgl/primitives + */ + +/** + * Creates an augmentedTypedArray of random vertex colors. + * If the vertices are indexed (have an indices array) then will + * just make random colors. Otherwise assumes they are triangles + * and makes one random color for every 3 vertices. + * @param {Object.} vertices Vertices as returned from one of the createXXXVertices functions. + * @param {module:twgl/primitives.RandomVerticesOptions} [options] options. + * @return {Object.} same vertices as passed in with `color` added. + * @memberOf module:twgl/primitives + */ +function makeRandomVertexColors(vertices, options) { + options = options || {}; + const numElements = vertices.position.numElements; + const vColors = createAugmentedTypedArray(4, numElements, Uint8Array); + const rand = options.rand || function(ndx, channel) { + return channel < 3 ? randInt(256) : 255; + }; + vertices.color = vColors; + if (vertices.indices) { + // just make random colors if index + for (let ii = 0; ii < numElements; ++ii) { + vColors.push(rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)); + } + } else { + // make random colors per triangle + const numVertsPerColor = options.vertsPerColor || 3; + const numSets = numElements / numVertsPerColor; + for (let ii = 0; ii < numSets; ++ii) { // eslint-disable-line + const color = [rand(ii, 0), rand(ii, 1), rand(ii, 2), rand(ii, 3)]; + for (let jj = 0; jj < numVertsPerColor; ++jj) { + vColors.push(color); + } + } + } + return vertices; +} + +/** + * creates a function that calls fn to create vertices and then + * creates a buffers for them + * @private + */ +function createBufferFunc(fn) { + return function(gl) { + const arrays = fn.apply(this, Array.prototype.slice.call(arguments, 1)); + return createBuffersFromArrays(gl, arrays); + }; +} + +/** + * creates a function that calls fn to create vertices and then + * creates a bufferInfo object for them + * @private + */ +function createBufferInfoFunc(fn) { + return function(gl) { + const arrays = fn.apply(null, Array.prototype.slice.call(arguments, 1)); + return createBufferInfoFromArrays(gl, arrays); + }; +} + +const arraySpecPropertyNames = [ + "numComponents", + "size", + "type", + "normalize", + "stride", + "offset", + "attrib", + "name", + "attribName", +]; + +/** + * Copy elements from one array to another + * + * @param {Array|TypedArray} src source array + * @param {Array|TypedArray} dst dest array + * @param {number} dstNdx index in dest to copy src + * @param {number} [offset] offset to add to copied values + * @private + */ +function copyElements(src, dst, dstNdx, offset) { + offset = offset || 0; + const length = src.length; + for (let ii = 0; ii < length; ++ii) { + dst[dstNdx + ii] = src[ii] + offset; + } +} + +/** + * Creates an array of the same time + * + * @param {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} srcArray array who's type to copy + * @param {number} length size of new array + * @return {(number[]|ArrayBufferView|module:twgl.FullArraySpec)} array with same type as srcArray + * @private + */ +function createArrayOfSameType(srcArray, length) { + const arraySrc = getArray(srcArray); + const newArray = new arraySrc.constructor(length); + let newArraySpec = newArray; + // If it appears to have been augmented make new one augmented + if (arraySrc.numComponents && arraySrc.numElements) { + augmentTypedArray(newArray, arraySrc.numComponents); + } + // If it was a full spec make new one a full spec + if (srcArray.data) { + newArraySpec = { + data: newArray, + }; + copyNamedProperties(arraySpecPropertyNames, srcArray, newArraySpec); + } + return newArraySpec; +} + +/** + * Concatenates sets of vertices + * + * Assumes the vertices match in composition. For example + * if one set of vertices has positions, normals, and indices + * all sets of vertices must have positions, normals, and indices + * and of the same type. + * + * Example: + * + * const cubeVertices = twgl.primitives.createCubeVertices(2); + * const sphereVertices = twgl.primitives.createSphereVertices(1, 10, 10); + * // move the sphere 2 units up + * twgl.primitives.reorientVertices( + * sphereVertices, twgl.m4.translation([0, 2, 0])); + * // merge the sphere with the cube + * const cubeSphereVertices = twgl.primitives.concatVertices( + * [cubeVertices, sphereVertices]); + * // turn them into WebGL buffers and attrib data + * const bufferInfo = twgl.createBufferInfoFromArrays(gl, cubeSphereVertices); + * + * @param {module:twgl.Arrays[]} arrays Array of arrays of vertices + * @return {module:twgl.Arrays} The concatenated vertices. + * @memberOf module:twgl/primitives + */ +function concatVertices(arrayOfArrays) { + const names = {}; + let baseName; + // get names of all arrays. + // and numElements for each set of vertices + for (let ii = 0; ii < arrayOfArrays.length; ++ii) { + const arrays = arrayOfArrays[ii]; + Object.keys(arrays).forEach(function(name) { // eslint-disable-line + if (!names[name]) { + names[name] = []; + } + if (!baseName && name !== 'indices') { + baseName = name; + } + const arrayInfo = arrays[name]; + const numComponents = getNumComponents(arrayInfo, name); + const array = getArray(arrayInfo); + const numElements = array.length / numComponents; + names[name].push(numElements); + }); + } + + // compute length of combined array + // and return one for reference + function getLengthOfCombinedArrays(name) { + let length = 0; + let arraySpec; + for (let ii = 0; ii < arrayOfArrays.length; ++ii) { + const arrays = arrayOfArrays[ii]; + const arrayInfo = arrays[name]; + const array = getArray(arrayInfo); + length += array.length; + if (!arraySpec || arrayInfo.data) { + arraySpec = arrayInfo; + } + } + return { + length: length, + spec: arraySpec, + }; + } + + function copyArraysToNewArray(name, base, newArray) { + let baseIndex = 0; + let offset = 0; + for (let ii = 0; ii < arrayOfArrays.length; ++ii) { + const arrays = arrayOfArrays[ii]; + const arrayInfo = arrays[name]; + const array = getArray(arrayInfo); + if (name === 'indices') { + copyElements(array, newArray, offset, baseIndex); + baseIndex += base[ii]; + } else { + copyElements(array, newArray, offset); + } + offset += array.length; + } + } + + const base = names[baseName]; + + const newArrays = {}; + Object.keys(names).forEach(function(name) { + const info = getLengthOfCombinedArrays(name); + const newArraySpec = createArrayOfSameType(info.spec, info.length); + copyArraysToNewArray(name, base, getArray(newArraySpec)); + newArrays[name] = newArraySpec; + }); + return newArrays; +} + +/** + * Creates a duplicate set of vertices + * + * This is useful for calling reorientVertices when you + * also want to keep the original available + * + * @param {module:twgl.Arrays} arrays of vertices + * @return {module:twgl.Arrays} The duplicated vertices. + * @memberOf module:twgl/primitives + */ +function duplicateVertices(arrays) { + const newArrays = {}; + Object.keys(arrays).forEach(function(name) { + const arraySpec = arrays[name]; + const srcArray = getArray(arraySpec); + const newArraySpec = createArrayOfSameType(arraySpec, srcArray.length); + copyElements(srcArray, getArray(newArraySpec), 0); + newArrays[name] = newArraySpec; + }); + return newArrays; +} + +const create3DFBufferInfo = createBufferInfoFunc(create3DFVertices); +const create3DFBuffers = createBufferFunc(create3DFVertices); +const createCubeBufferInfo = createBufferInfoFunc(createCubeVertices); +const createCubeBuffers = createBufferFunc(createCubeVertices); +const createPlaneBufferInfo = createBufferInfoFunc(createPlaneVertices); +const createPlaneBuffers = createBufferFunc(createPlaneVertices); +const createSphereBufferInfo = createBufferInfoFunc(createSphereVertices); +const createSphereBuffers = createBufferFunc(createSphereVertices); +const createTruncatedConeBufferInfo = createBufferInfoFunc(createTruncatedConeVertices); +const createTruncatedConeBuffers = createBufferFunc(createTruncatedConeVertices); +const createXYQuadBufferInfo = createBufferInfoFunc(createXYQuadVertices); +const createXYQuadBuffers = createBufferFunc(createXYQuadVertices); +const createCrescentBufferInfo = createBufferInfoFunc(createCrescentVertices); +const createCrescentBuffers = createBufferFunc(createCrescentVertices); +const createCylinderBufferInfo = createBufferInfoFunc(createCylinderVertices); +const createCylinderBuffers = createBufferFunc(createCylinderVertices); +const createTorusBufferInfo = createBufferInfoFunc(createTorusVertices); +const createTorusBuffers = createBufferFunc(createTorusVertices); +const createDiscBufferInfo = createBufferInfoFunc(createDiscVertices); +const createDiscBuffers = createBufferFunc(createDiscVertices); + +// these were mis-spelled until 4.12 +const createCresentBufferInfo = createCrescentBufferInfo; +const createCresentBuffers = createCrescentBuffers; +const createCresentVertices = createCrescentVertices; + +var primitives = /*#__PURE__*/Object.freeze({ + __proto__: null, + create3DFBufferInfo: create3DFBufferInfo, + create3DFBuffers: create3DFBuffers, + create3DFVertices: create3DFVertices, + createAugmentedTypedArray: createAugmentedTypedArray, + createCubeBufferInfo: createCubeBufferInfo, + createCubeBuffers: createCubeBuffers, + createCubeVertices: createCubeVertices, + createPlaneBufferInfo: createPlaneBufferInfo, + createPlaneBuffers: createPlaneBuffers, + createPlaneVertices: createPlaneVertices, + createSphereBufferInfo: createSphereBufferInfo, + createSphereBuffers: createSphereBuffers, + createSphereVertices: createSphereVertices, + createTruncatedConeBufferInfo: createTruncatedConeBufferInfo, + createTruncatedConeBuffers: createTruncatedConeBuffers, + createTruncatedConeVertices: createTruncatedConeVertices, + createXYQuadBufferInfo: createXYQuadBufferInfo, + createXYQuadBuffers: createXYQuadBuffers, + createXYQuadVertices: createXYQuadVertices, + createCresentBufferInfo: createCresentBufferInfo, + createCresentBuffers: createCresentBuffers, + createCresentVertices: createCresentVertices, + createCrescentBufferInfo: createCrescentBufferInfo, + createCrescentBuffers: createCrescentBuffers, + createCrescentVertices: createCrescentVertices, + createCylinderBufferInfo: createCylinderBufferInfo, + createCylinderBuffers: createCylinderBuffers, + createCylinderVertices: createCylinderVertices, + createTorusBufferInfo: createTorusBufferInfo, + createTorusBuffers: createTorusBuffers, + createTorusVertices: createTorusVertices, + createDiscBufferInfo: createDiscBufferInfo, + createDiscBuffers: createDiscBuffers, + createDiscVertices: createDiscVertices, + deindexVertices: deindexVertices, + flattenNormals: flattenNormals, + makeRandomVertexColors: makeRandomVertexColors, + reorientDirections: reorientDirections, + reorientNormals: reorientNormals, + reorientPositions: reorientPositions, + reorientVertices: reorientVertices, + concatVertices: concatVertices, + duplicateVertices: duplicateVertices +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +const glEnumToString = (function() { + const haveEnumsForType = {}; + const enums = {}; + + function addEnums(gl) { + const type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (const key in gl) { + if (typeof gl[key] === 'number') { + const existing = enums[gl[key]]; + enums[gl[key]] = existing ? `${existing} | ${key}` : key; + } + } + haveEnumsForType[type] = true; + } + } + + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value); + }; +}()); + +var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + glEnumToString: glEnumToString, + isWebGL1: isWebGL1, + isWebGL2: isWebGL2 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults$1 = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined, +}; +const isArrayBuffer = isArrayBuffer$1; + +// Should we make this on demand? +const getShared2DContext = function() { + let s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || + ((typeof document !== 'undefined' && document.createElement) + ? document.createElement("canvas").getContext("2d") + : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +const ALPHA = 0x1906; +const RGB = 0x1907; +const RGBA$1 = 0x1908; +const LUMINANCE = 0x1909; +const LUMINANCE_ALPHA = 0x190A; +const DEPTH_COMPONENT$1 = 0x1902; +const DEPTH_STENCIL$1 = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +const CLAMP_TO_EDGE$1 = 0x812f; + +/* TextureMagFilter */ +const NEAREST = 0x2600; +const LINEAR$1 = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +const TEXTURE_2D$2 = 0x0de1; +const TEXTURE_CUBE_MAP$1 = 0x8513; +const TEXTURE_3D$1 = 0x806f; +const TEXTURE_2D_ARRAY$1 = 0x8c1a; + +/* Cubemap Targets */ +const TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +const TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +const TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +const TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +const TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +const TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +const TEXTURE_MIN_FILTER = 0x2801; +const TEXTURE_MAG_FILTER = 0x2800; +const TEXTURE_WRAP_S = 0x2802; +const TEXTURE_WRAP_T = 0x2803; +const TEXTURE_WRAP_R = 0x8072; +const TEXTURE_MIN_LOD = 0x813a; +const TEXTURE_MAX_LOD = 0x813b; +const TEXTURE_BASE_LEVEL = 0x813c; +const TEXTURE_MAX_LEVEL = 0x813d; +const TEXTURE_COMPARE_MODE = 0x884C; +const TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +const UNPACK_ALIGNMENT = 0x0cf5; +const UNPACK_ROW_LENGTH = 0x0cf2; +const UNPACK_IMAGE_HEIGHT = 0x806e; +const UNPACK_SKIP_PIXELS = 0x0cf4; +const UNPACK_SKIP_ROWS = 0x0cf3; +const UNPACK_SKIP_IMAGES = 0x806d; +const UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +const UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +const UNPACK_FLIP_Y_WEBGL = 0x9240; + +const R8 = 0x8229; +const R8_SNORM = 0x8F94; +const R16F = 0x822D; +const R32F = 0x822E; +const R8UI = 0x8232; +const R8I = 0x8231; +const RG16UI = 0x823A; +const RG16I = 0x8239; +const RG32UI = 0x823C; +const RG32I = 0x823B; +const RG8 = 0x822B; +const RG8_SNORM = 0x8F95; +const RG16F = 0x822F; +const RG32F = 0x8230; +const RG8UI = 0x8238; +const RG8I = 0x8237; +const R16UI = 0x8234; +const R16I = 0x8233; +const R32UI = 0x8236; +const R32I = 0x8235; +const RGB8 = 0x8051; +const SRGB8 = 0x8C41; +const RGB565$1 = 0x8D62; +const RGB8_SNORM = 0x8F96; +const R11F_G11F_B10F = 0x8C3A; +const RGB9_E5 = 0x8C3D; +const RGB16F = 0x881B; +const RGB32F = 0x8815; +const RGB8UI = 0x8D7D; +const RGB8I = 0x8D8F; +const RGB16UI = 0x8D77; +const RGB16I = 0x8D89; +const RGB32UI = 0x8D71; +const RGB32I = 0x8D83; +const RGBA8 = 0x8058; +const SRGB8_ALPHA8 = 0x8C43; +const RGBA8_SNORM = 0x8F97; +const RGB5_A1$1 = 0x8057; +const RGBA4$1 = 0x8056; +const RGB10_A2 = 0x8059; +const RGBA16F = 0x881A; +const RGBA32F = 0x8814; +const RGBA8UI = 0x8D7C; +const RGBA8I = 0x8D8E; +const RGB10_A2UI = 0x906F; +const RGBA16UI = 0x8D76; +const RGBA16I = 0x8D88; +const RGBA32I = 0x8D82; +const RGBA32UI = 0x8D70; + +const DEPTH_COMPONENT16$1 = 0x81A5; +const DEPTH_COMPONENT24$1 = 0x81A6; +const DEPTH_COMPONENT32F$1 = 0x8CAC; +const DEPTH32F_STENCIL8$1 = 0x8CAD; +const DEPTH24_STENCIL8$1 = 0x88F0; + +/* DataType */ +const BYTE = 0x1400; +const UNSIGNED_BYTE$1 = 0x1401; +const SHORT = 0x1402; +const UNSIGNED_SHORT$1 = 0x1403; +const INT$1 = 0x1404; +const UNSIGNED_INT$1 = 0x1405; +const FLOAT$1 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1 = 0x8034; +const UNSIGNED_SHORT_5_6_5 = 0x8363; +const HALF_FLOAT = 0x140B; +const HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +const UNSIGNED_INT_2_10_10_10_REV = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +const UNSIGNED_INT_24_8 = 0x84FA; + +const RG = 0x8227; +const RG_INTEGER = 0x8228; +const RED = 0x1903; +const RED_INTEGER = 0x8D94; +const RGB_INTEGER = 0x8D98; +const RGBA_INTEGER = 0x8D99; + +const formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + const f = formatInfo; + f[ALPHA] = { numColorComponents: 1, }; + f[LUMINANCE] = { numColorComponents: 1, }; + f[LUMINANCE_ALPHA] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RED] = { numColorComponents: 1, }; + f[RED_INTEGER] = { numColorComponents: 1, }; + f[RG] = { numColorComponents: 2, }; + f[RG_INTEGER] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGB_INTEGER] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RGBA_INTEGER] = { numColorComponents: 4, }; + f[DEPTH_COMPONENT$1] = { numColorComponents: 1, }; + f[DEPTH_STENCIL$1] = { numColorComponents: 2, }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +let s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + const t = {}; + // unsized formats + t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_5_6_5], }; + t[RGBA$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], }; + t[DEPTH_COMPONENT$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT$1, UNSIGNED_SHORT$1], }; + + // sized formats + t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], }; + t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT$1, HALF_FLOAT], }; + t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], }; + t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT$1], }; + t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], }; + t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT$1], }; + t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], }; + t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT$1, HALF_FLOAT], }; + t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT$1], }; + t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], }; + t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT$1], }; + t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], }; + t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT$1], }; + t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT$1], }; + t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB565$1] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_6_5], }; + t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], }; + t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], }; + t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], }; + t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT$1, HALF_FLOAT], }; + t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT$1], }; + t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], }; + t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT$1], }; + t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], }; + t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT$1], }; + t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT$1], }; + t[RGBA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[SRGB8_ALPHA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8_SNORM] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], }; + t[RGB5_A1$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA4$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_4_4_4_4], }; + t[RGB10_A2] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT$1, HALF_FLOAT], }; + t[RGBA32F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT$1], }; + t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], }; + t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT$1], }; + t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], }; + t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT$1], }; + t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT$1], }; + // Sized Internal + t[DEPTH_COMPONENT16$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT$1, UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT24$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT32F$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[DEPTH24_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], }; + t[DEPTH32F_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], }; + + Object.keys(t).forEach(function(internalFormat) { + const info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function(bytesPerElement, ndx) { + const type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + const bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0], + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & (value - 1)) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + const info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE$1; +} + +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP$1 ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height, + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults$1.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +function setDefaults$1(newDefaults) { + copyExistingProperties(newDefaults, defaults$1); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + let colorspaceConversion; + let premultiplyAlpha; + let flipY; + + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + + fn(); + + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D$1 || isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + const sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + const samplers = {}; + Object.keys(samplerOptions).forEach(function(name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults$1.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults$1.textureOptions; + internalFormat = internalFormat || RGBA$1; + const target = options.target || TEXTURE_2D$2; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + const filtering = canFilter(internalFormat) ? LINEAR$1 : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } +} + +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || (options.auto === undefined && options.level === undefined); +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [ + TEXTURE_CUBE_MAP_POSITIVE_X, + TEXTURE_CUBE_MAP_NEGATIVE_X, + TEXTURE_CUBE_MAP_POSITIVE_Y, + TEXTURE_CUBE_MAP_NEGATIVE_Y, + TEXTURE_CUBE_MAP_POSITIVE_Z, + TEXTURE_CUBE_MAP_NEGATIVE_Z, + ]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + const faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + const facesWithNdx = faces.map(function(face, ndx) { + return { face: face, ndx: ndx }; + }); + facesWithNdx.sort(function(a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + const level = options.level || 0; + let width = element.width; + let height = element.height; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // guess the parts + const imgWidth = element.width; + const imgHeight = element.height; + let size; + let slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + const ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, () => { + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }) + .then(function(imageBitmap) { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + scopedSetPackState(gl, options, () => { + const smallest = Math.min(element.width, element.height); + const largest = Math.max(element.width, element.height); + const depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + const xMult = element.width === largest ? 1 : 0; + const yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (let d = 0; d < depth; ++d) { + const srcX = d * smallest * xMult; + const srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, () => { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} + +function noop() { +} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + const a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && + a.port === location.port && + a.protocol === location.protocol; + } else { + const localOrigin = (new URL(location.href)).origin; + const urlOrigin = (new URL(url, location.href)).origin; + return urlOrigin === localOrigin; + } +} + +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) + ? 'anonymous' + : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + let img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults$1.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + + const clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + + const onError = function onError() { + const msg = "couldn't load image: " + url; + error$1(msg); + callback(msg, img); + clearEventHandlers(); + }; + + const onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + let err; + let bm; + const cb = function cb() { + callback(err, bm); + }; + + const options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function(response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function(blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }); + }).then(function(bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + }).catch(function(e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) || + (typeof ImageData !== 'undefined' && obj instanceof ImageData) || + (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement); +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function() { + callback(null, obj); + }); + return obj; + } + + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + const color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, 0, RGBA$1, 1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } else { + gl.texImage2D(target, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D$2; + if (target !== TEXTURE_CUBE_MAP$1) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = 6; + const errors = []; + const faces = getCubeFaceOrder(gl, options); + let imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder().forEach(function(otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D_ARRAY$1; + if (target !== TEXTURE_3D$1 && target !== TEXTURE_2D_ARRAY$1) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = urls.length; + const errors = []; + let imgs; // eslint-disable-line + const level = options.level || 0; + let width = options.width; + let height = options.height; + const depth = urls.length; + let firstImage = true; + + function uploadImg(slice) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (let s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + let src = img; + let ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + let width = options.width; + let height = options.height; + let depth = options.depth; + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + const Type = getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + + const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + glEnumToString(gl, format); + } + let dimensions; + if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + if (!width && !height && !depth) { + const size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + const faceSize = numElements / 6 * elementsPerElement; + + getCubeFacesWithNdx(gl, options).forEach(f => { + const offset = faceSize * f.ndx; + const data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type, + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + const tex = gl.createTexture(); + const target = options.target || TEXTURE_2D$2; + let width = options.width || 1; + let height = options.height || 1; + const internalFormat = options.internalFormat || RGBA$1; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } + let src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof (src) === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || + (Array.isArray(src) && ( + typeof src[0] === 'number' || + Array.isArray(src[0]) || + isArrayBuffer(src[0])) + ) + ) { + const dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP$1) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + let type; + const src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || + (Array.isArray(src) && typeof src[0] === 'string'); +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + let numDownloading = 0; + const errors = []; + const textures = {}; + const images = {}; + + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function() { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + + Object.keys(textureOptions).forEach(function(name) { + const options = textureOptions[name]; + let onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + + return textures; +} + +var textures = /*#__PURE__*/Object.freeze({ + __proto__: null, + setTextureDefaults_: setDefaults$1, + createSampler: createSampler, + createSamplers: createSamplers, + setSamplerParameters: setSamplerParameters, + createTexture: createTexture, + setEmptyTexture: setEmptyTexture, + setTextureFromArray: setTextureFromArray, + loadTextureFromUrl: loadTextureFromUrl, + setTextureFromElement: setTextureFromElement, + setTextureFilteringForSize: setTextureFilteringForSize, + setTextureParameters: setTextureParameters, + setDefaultTextureColor: setDefaultTextureColor, + createTextures: createTextures, + resizeTexture: resizeTexture, + canGenerateMipmap: canGenerateMipmap, + canFilter: canFilter, + getNumComponentsForFormat: getNumComponentsForFormat, + getBytesPerElementForInternalFormat: getBytesPerElementForInternalFormat, + getFormatAndTypeForInternalFormat: getFormatAndTypeForInternalFormat +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +const error = error$1; +const warn = warn$1; +function getElementById(id) { + return (typeof document !== 'undefined' && document.getElementById) + ? document.getElementById(id) + : null; +} + +const TEXTURE0 = 0x84c0; +const DYNAMIC_DRAW = 0x88e8; + +const ARRAY_BUFFER = 0x8892; +const ELEMENT_ARRAY_BUFFER$1 = 0x8893; +const UNIFORM_BUFFER = 0x8a11; +const TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; + +const TRANSFORM_FEEDBACK = 0x8e22; + +const COMPILE_STATUS = 0x8b81; +const LINK_STATUS = 0x8b82; +const FRAGMENT_SHADER = 0x8b30; +const VERTEX_SHADER = 0x8b31; +const SEPARATE_ATTRIBS = 0x8c8d; + +const ACTIVE_UNIFORMS = 0x8b86; +const ACTIVE_ATTRIBUTES = 0x8b89; +const TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +const ACTIVE_UNIFORM_BLOCKS = 0x8a36; +const UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +const UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +const UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +const UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; + +const FLOAT = 0x1406; +const FLOAT_VEC2 = 0x8B50; +const FLOAT_VEC3 = 0x8B51; +const FLOAT_VEC4 = 0x8B52; +const INT = 0x1404; +const INT_VEC2 = 0x8B53; +const INT_VEC3 = 0x8B54; +const INT_VEC4 = 0x8B55; +const BOOL = 0x8B56; +const BOOL_VEC2 = 0x8B57; +const BOOL_VEC3 = 0x8B58; +const BOOL_VEC4 = 0x8B59; +const FLOAT_MAT2 = 0x8B5A; +const FLOAT_MAT3 = 0x8B5B; +const FLOAT_MAT4 = 0x8B5C; +const SAMPLER_2D = 0x8B5E; +const SAMPLER_CUBE = 0x8B60; +const SAMPLER_3D = 0x8B5F; +const SAMPLER_2D_SHADOW = 0x8B62; +const FLOAT_MAT2x3 = 0x8B65; +const FLOAT_MAT2x4 = 0x8B66; +const FLOAT_MAT3x2 = 0x8B67; +const FLOAT_MAT3x4 = 0x8B68; +const FLOAT_MAT4x2 = 0x8B69; +const FLOAT_MAT4x3 = 0x8B6A; +const SAMPLER_2D_ARRAY = 0x8DC1; +const SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +const SAMPLER_CUBE_SHADOW = 0x8DC5; +const UNSIGNED_INT = 0x1405; +const UNSIGNED_INT_VEC2 = 0x8DC6; +const UNSIGNED_INT_VEC3 = 0x8DC7; +const UNSIGNED_INT_VEC4 = 0x8DC8; +const INT_SAMPLER_2D = 0x8DCA; +const INT_SAMPLER_3D = 0x8DCB; +const INT_SAMPLER_CUBE = 0x8DCC; +const INT_SAMPLER_2D_ARRAY = 0x8DCF; +const UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +const UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +const UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +const UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; + +const TEXTURE_2D$1 = 0x0DE1; +const TEXTURE_CUBE_MAP = 0x8513; +const TEXTURE_3D = 0x806F; +const TEXTURE_2D_ARRAY = 0x8C1A; + +const typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function(v) { + gl.uniform1f(location, v); + }; +} + +function floatArraySetter(gl, location) { + return function(v) { + gl.uniform1fv(location, v); + }; +} + +function floatVec2Setter(gl, location) { + return function(v) { + gl.uniform2fv(location, v); + }; +} + +function floatVec3Setter(gl, location) { + return function(v) { + gl.uniform3fv(location, v); + }; +} + +function floatVec4Setter(gl, location) { + return function(v) { + gl.uniform4fv(location, v); + }; +} + +function intSetter(gl, location) { + return function(v) { + gl.uniform1i(location, v); + }; +} + +function intArraySetter(gl, location) { + return function(v) { + gl.uniform1iv(location, v); + }; +} + +function intVec2Setter(gl, location) { + return function(v) { + gl.uniform2iv(location, v); + }; +} + +function intVec3Setter(gl, location) { + return function(v) { + gl.uniform3iv(location, v); + }; +} + +function intVec4Setter(gl, location) { + return function(v) { + gl.uniform4iv(location, v); + }; +} + +function uintSetter(gl, location) { + return function(v) { + gl.uniform1ui(location, v); + }; +} + +function uintArraySetter(gl, location) { + return function(v) { + gl.uniform1uiv(location, v); + }; +} + +function uintVec2Setter(gl, location) { + return function(v) { + gl.uniform2uiv(location, v); + }; +} + +function uintVec3Setter(gl, location) { + return function(v) { + gl.uniform3uiv(location, v); + }; +} + +function uintVec4Setter(gl, location) { + return function(v) { + gl.uniform4uiv(location, v); + }; +} + +function floatMat2Setter(gl, location) { + return function(v) { + gl.uniformMatrix2fv(location, false, v); + }; +} + +function floatMat3Setter(gl, location) { + return function(v) { + gl.uniformMatrix3fv(location, false, v); + }; +} + +function floatMat4Setter(gl, location) { + return function(v) { + gl.uniformMatrix4fv(location, false, v); + }; +} + +function floatMat23Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} + +function floatMat32Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} + +function floatMat24Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} + +function floatMat42Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} + +function floatMat34Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} + +function floatMat43Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} + +function samplerSetter(gl, type, unit, location) { + const bindPoint = getBindPointForSamplerType(gl, type); + return isWebGL2(gl) ? function(textureOrPair) { + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function(texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} + +function samplerArraySetter(gl, type, unit, location, size) { + const bindPoint = getBindPointForSamplerType(gl, type); + const units = new Int32Array(size); + for (let ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + + return isWebGL2(gl) ? function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} + +typeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, }; +typeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, }; +typeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, }; +typeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, }; +typeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, }; +typeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, }; +typeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, }; +typeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, }; +typeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, }; +typeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, }; +typeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, }; +typeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, }; +typeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, }; +typeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, }; +typeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, }; +typeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, }; +typeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, }; +typeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; + +function floatAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer( + index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function intAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function uintAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function matAttribSetter(gl, index, typeInfo) { + const defaultSize = typeInfo.size; + const count = typeInfo.count; + + return function(b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + const numComponents = b.size || b.numComponents || defaultSize; + const size = numComponents / count; + const type = b.type || FLOAT; + const typeInfo = typeMap[type]; + const stride = typeInfo.size * numComponents; + const normalize = b.normalize || false; + const offset = b.offset || 0; + const rowOffset = stride / count; + for (let i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer( + index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} + + + +const attrTypeMap = {}; +attrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, }; +attrTypeMap[INT] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, }; +attrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, }; +attrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, }; +attrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, }; + +const errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src, log = '', lineOffset = 0) { + // Note: Error message formats are not defined by any spec so this may or may not work. + const matches = [...log.matchAll(errorRE)]; + const lineNoToErrorMap = new Map(matches.map((m, ndx) => { + const lineNo = parseInt(m[1]); + const next = matches[ndx + 1]; + const end = next ? next.index : log.length; + const msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map((line, lineNo) => { + const err = lineNoToErrorMap.get(lineNo); + return `${lineNo + 1 + lineOffset}: ${line}${err ? `\n\n^^^ ${err}` : ''}`; + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +const spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + let lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return {lineOffset, shaderSource}; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(() => { + progOptions.callback(`${msg}\n${progOptions.errors.join('\n')}`); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + const compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + const lastError = gl.getShaderInfoLog(shader); + const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader)); + const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\nError compiling ${glEnumToString(gl, shaderType)}: ${lastError}`; + errFn(error); + return error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + let transformFeedbackVaryings; + let transformFeedbackMode; + let callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + const opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + + const errorCallback = opt_errorCallback || error; + const errors = []; + const options = { + errorCallback(msg, ...args) { + errors.push(msg); + errorCallback(msg, ...args); + }, + transformFeedbackVaryings, + transformFeedbackMode, + callback, + errors, + }; + + { + let attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function(attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + + return options; +} + +const defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER", +]; + +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} + +function deleteProgramAndShaders(gl, program, notThese) { + const shaders = gl.getAttachedShaders(program); + for (const shader of shaders) { + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + gl.deleteProgram(program); +} + +const wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms)); + +function createProgramNoCheck(gl, shaders, programOptions) { + const program = gl.createProgram(); + const { + attribLocations, + transformFeedbackVaryings, + transformFeedbackMode, + } = getProgramOptions(programOptions); + + for (let ndx = 0; ndx < shaders.length; ++ndx) { + let shader = shaders[ndx]; + if (typeof shader === 'string') { + const elem = getElementById(shader); + const src = elem ? elem.text : shader; + let type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + + Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib)); + + { + let varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram( + gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaderSet = new Set(shaders); + const program = createProgramNoCheck(gl, shaders, progOptions); + + function hasErrors(gl, program) { + const errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(() => { + const errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function(gl, arg1, ...args) { + return new Promise((resolve, reject) => { + const programOptions = getProgramOptions(...args); + programOptions.callback = (err, program) => { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +const createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +const createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); + +async function waitForProgramLinkCompletionAsync(gl, program) { + const ext = gl.getExtension('KHR_parallel_shader_compile'); + const checkFn = ext + ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR) + : () => true; + + let waitTime = 0; + do { + await wait(waitTime); // must wait at least once + waitTime = 1000 / 60; + } while (!checkFn(gl, program)); +} + +async function waitForAllProgramsLinkCompletionAsync(gl, programs) { + for (const program of Object.values(programs)) { + await waitForProgramLinkCompletionAsync(gl, program); + } +} + +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + const linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + const lastError = gl.getProgramInfoLog(program); + errFn(`Error in program linking: ${lastError}`); + // print any errors from these shaders + const shaders = gl.getAttachedShaders(program); + const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn)); + return `${lastError}\n${errors.filter(_ => _).join('\n')}`; + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts( + gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaders = []; + for (const scriptId of shaderScriptIds) { + const shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, `unknown script element: ${scriptId}`); + } + shaders.push(shaderScript.text); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + const name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} + +const tokenRE = /(\.|\[|]|\w+)/g; +const isDigit = s => s >= '0' && s <= '9'; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + const tokens = fullPath.split(tokenRE).filter(s => s !== ''); + let tokenNdx = 0; + let path = ''; + + for (;;) { + const token = tokens[tokenNdx++]; // has to be name or number + path += token; + const isArrayIndex = isDigit(token[0]); + const accessor = isArrayIndex + ? parseInt(token) + : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + const isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + const token = tokens[tokenNdx++]; // has to be . or [ + const isArray = token === '['; + const child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function(node) { + return function(value) { + setUniformTree(node, value); + }; + }(child); + path += token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +function createUniformSetters(gl, program) { + let 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, location) { + const isArray = uniformInfo.name.endsWith("[0]"); + const type = uniformInfo.type; + const typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here. + } + let setter; + if (typeInfo.bindPoint) { + // it's a sampler + const unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + + const uniformSetters = {}; + const uniformTree = {}; + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + + for (let ii = 0; ii < numUniforms; ++ii) { + const uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + let name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + const location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + const setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + const info = {}; + const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (let ii = 0; ii < numVaryings; ++ii) { + const varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size, + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (const name in bufferInfo) { + const varying = transformFeedbackInfo[name]; + if (varying) { + const buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + const tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + const uniformData = []; + const uniformIndices = []; + + for (let ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + const uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + + [ + [ "UNIFORM_TYPE", "type" ], + [ "UNIFORM_SIZE", "size" ], // num elements + [ "UNIFORM_BLOCK_INDEX", "blockNdx" ], + [ "UNIFORM_OFFSET", "offset", ], + ].forEach(function(pair) { + const pname = pair[0]; + const key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) { + uniformData[ndx][key] = value; + }); + }); + + const blockSpecs = {}; + + const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (let ii = 0; ii < numUniformBlocks; ++ii) { + const name = gl.getActiveUniformBlockName(program, ii); + const blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES), + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + + return { + blockSpecs: blockSpecs, + uniformData: uniformData, + }; +} + +const arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +const pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding; + +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + const numElements = view.length; + const totalRows = numElements / 4; + return function(value) { + let dst = 0; + let src = 0; + for (let row = 0; row < totalRows; ++row) { + for (let col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function(value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) { + const blockSpecs = uniformBlockSpec.blockSpecs; + const uniformData = uniformBlockSpec.uniformData; + const blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {}, + }; + } + const offset = options.offset ?? 0; + const array = options.array ?? new ArrayBuffer(blockSpec.size); + const buffer = options.buffer ?? gl.createBuffer(); + const uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + + let prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + const uniforms = {}; + const setters = {}; + const setterTree = {}; + blockSpec.uniformIndices.forEach(function(uniformNdx) { + const data = uniformData[uniformNdx]; + let name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + const isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + const typeInfo = typeMap[data.type]; + const Type = typeInfo.Type; + const byteLength = isArray + ? pad(typeInfo.size, 16) * data.size + : typeInfo.size * data.size; + const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array, + asFloat: new Float32Array(array), // for debugging + asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer + buffer, + uniforms, + setters, + offset: options.bufferOffset ?? offset, + size: blockSpec.size, + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName, options = {}) { + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + const bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + const setters = uniformBlockInfo.setters; + for (const name in values) { + const setter = setters[name]; + if (setter) { + const value = values[name]; + setter(value); + } + } +} + +function setUniformTree(tree, values) { + for (const name in values) { + const prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters, ...args) { // eslint-disable-line + const actualSetters = setters.uniformSetters || setters; + const numArgs = args.length; + for (let aNdx = 0; aNdx < numArgs; ++aNdx) { + const values = args[aNdx]; + if (Array.isArray(values)) { + const numValues = values.length; + for (let ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (const name in values) { + const setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +const setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + const attribSetters = { + }; + + const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (let ii = 0; ii < numAttribs; ++ii) { + const attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + const index = gl.getAttribLocation(program, attribInfo.name); + const typeInfo = attrTypeMap[attribInfo.type]; + const setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (const name in buffers) { + const setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER$1, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + const uniformSetters = createUniformSetters(gl, program); + const attribSetters = createAttributeSetters(gl, program); + const programInfo = { + program, + uniformSetters, + attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])), + }; + + if (isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + + return programInfo; +} + +const notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const errors = []; + shaderSources = shaderSources.map(function(source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + const script = getElementById(source); + if (!script) { + const err = `no element with id: ${source}`; + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + + if (errors.length) { + return reportError(progOptions, ''); + } + + const origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = (err, program) => { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + + const program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + + return createProgramInfoFromProgram(gl, program); +} + +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (const [name, program] of Object.entries(programs)) { + const options = {...programOptions}; + const spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + const errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (const program of Object.values(programs)) { + const shaders = gl.getAttachedShaders(program); + gl.deleteProgram(program); + for (const shader of shaders) { + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } + return errors; + } + } + + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs, programOptions = {}) { + // Remember existing shaders so that if there is an error we don't delete them + const noDeleteShadersSet = new Set(); + + // compile and link everything + const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => { + const options = {...programOptions}; + const shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => { + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(([name, program]) => + [name, createProgramInfoFromProgram(gl, program)] + )); + } + + const origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = (err, programs) => { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + + const programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +const createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +const createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +var programs = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttributeSetters: createAttributeSetters, + createProgram: createProgram, + createProgramAsync: createProgramAsync, + createPrograms: createPrograms, + createProgramsAsync: createProgramsAsync, + createProgramFromScripts: createProgramFromScripts, + createProgramFromSources: createProgramFromSources, + createProgramInfo: createProgramInfo, + createProgramInfoAsync: createProgramInfoAsync, + createProgramInfos: createProgramInfos, + createProgramInfosAsync: createProgramInfosAsync, + createProgramInfoFromProgram: createProgramInfoFromProgram, + createUniformSetters: createUniformSetters, + createUniformBlockSpecFromProgram: createUniformBlockSpecFromProgram, + createUniformBlockInfoFromProgram: createUniformBlockInfoFromProgram, + createUniformBlockInfo: createUniformBlockInfo, + createTransformFeedback: createTransformFeedback, + createTransformFeedbackInfo: createTransformFeedbackInfo, + bindTransformFeedbackInfo: bindTransformFeedbackInfo, + setAttributes: setAttributes, + setBuffersAndAttributes: setBuffersAndAttributes, + setUniforms: setUniforms, + setUniformsAndBindTextures: setUniformsAndBindTextures, + setUniformBlock: setUniformBlock, + setBlockUniforms: setBlockUniforms, + bindUniformBlock: bindUniformBlock +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const TRIANGLES = 0x0004; +const UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + const indices = bufferInfo.indices; + const elementType = bufferInfo.elementType; + const numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + let lastUsedProgramInfo = null; + let lastUsedBufferInfo = null; + + objectsToDraw.forEach(function(object) { + if (object.active === false) { + return; + } + + const programInfo = object.programInfo; + const bufferInfo = object.vertexArrayInfo || object.bufferInfo; + let bindBuffers = false; + const type = object.type === undefined ? TRIANGLES : object.type; + + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +var draw = /*#__PURE__*/Object.freeze({ + __proto__: null, + drawBufferInfo: drawBufferInfo, + drawObjectList: drawObjectList +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const FRAMEBUFFER = 0x8d40; +const RENDERBUFFER = 0x8d41; +const TEXTURE_2D = 0x0de1; + +const UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +const DEPTH_COMPONENT = 0x1902; +const RGBA = 0x1908; +const DEPTH_COMPONENT24 = 0x81a6; +const DEPTH_COMPONENT32F = 0x8cac; +const DEPTH24_STENCIL8 = 0x88f0; +const DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +const RGBA4 = 0x8056; +const RGB5_A1 = 0x8057; +const RGB565 = 0x8D62; +const DEPTH_COMPONENT16 = 0x81A5; +const STENCIL_INDEX = 0x1901; +const STENCIL_INDEX8 = 0x8D48; +const DEPTH_STENCIL = 0x84F9; +const COLOR_ATTACHMENT0 = 0x8CE0; +const DEPTH_ATTACHMENT = 0x8D00; +const STENCIL_ATTACHMENT = 0x8D20; +const DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +const CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +const LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +const defaultAttachments = [ + { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, }, + { format: DEPTH_STENCIL, }, +]; + +const attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; + +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} + +const renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; + +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} + +const MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + const target = FRAMEBUFFER; + const fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + const usedColorAttachmentsPoints = []; + const framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height, + }; + + attachments.forEach(function(attachmentOptions, i) { + let attachment = attachmentOptions.attachment; + const samples = attachmentOptions.samples; + const format = attachmentOptions.format; + let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + const textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = createTexture(gl, textureOptions); + } + } + if (isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer( + target, + attachmentPoint, + attachment, + attachmentOptions.level || 0, + attachmentOptions.layer); + } else { + gl.framebufferTexture2D( + target, + attachmentPoint, + attachmentOptions.target || TEXTURE_2D, + attachment, + attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function(attachmentOptions, ndx) { + const attachment = framebufferInfo.attachments[ndx]; + const format = attachmentOptions.format; + const samples = attachmentOptions.samples; + if (samples !== undefined || isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (isTexture(gl, attachment)) { + resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +var framebuffers = /*#__PURE__*/Object.freeze({ + __proto__: null, + bindFramebufferInfo: bindFramebufferInfo, + createFramebufferInfo: createFramebufferInfo, + resizeFramebufferInfo: resizeFramebufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +const ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function(programInfo) { + setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao, + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +var vertexArrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + createVertexArrayInfo: createVertexArrayInfo, + createVAOAndSetAttributes: createVAOAndSetAttributes, + createVAOFromBufferInfo: createVAOFromBufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults = { + addExtensionsToContext: true, +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + copyExistingProperties(newDefaults, defaults); + setDefaults$2(newDefaults); // eslint-disable-line + setDefaults$1(newDefaults); // eslint-disable-line +} + +const prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + glEnumToString(gl, 0); + const ext = gl.getExtension(extensionName); + if (ext) { + const enums = {}; + const fnSuffix = prefixRE.exec(extensionName)[1]; + const enumSuffix = '_' + fnSuffix; + for (const key in ext) { + const value = ext[key]; + const isFunc = typeof (value) === 'function'; + const suffix = isFunc ? fnSuffix : enumSuffix; + let name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + warn$1(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function(origFn) { + return function() { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name, + }; + glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +const supportedExtensions = [ + 'ANGLE_instanced_arrays', + 'EXT_blend_minmax', + 'EXT_color_buffer_float', + 'EXT_color_buffer_half_float', + 'EXT_disjoint_timer_query', + 'EXT_disjoint_timer_query_webgl2', + 'EXT_frag_depth', + 'EXT_sRGB', + 'EXT_shader_texture_lod', + 'EXT_texture_filter_anisotropic', + 'OES_element_index_uint', + 'OES_standard_derivatives', + 'OES_texture_float', + 'OES_texture_float_linear', + 'OES_texture_half_float', + 'OES_texture_half_float_linear', + 'OES_vertex_array_object', + 'WEBGL_color_buffer_float', + 'WEBGL_compressed_texture_atc', + 'WEBGL_compressed_texture_etc1', + 'WEBGL_compressed_texture_pvrtc', + 'WEBGL_compressed_texture_s3tc', + 'WEBGL_compressed_texture_s3tc_srgb', + 'WEBGL_depth_texture', + 'WEBGL_draw_buffers', +]; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (let ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + const names = ["webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + const gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + const names = ["webgl2", "webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + const gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + const width = canvas.clientWidth * multiplier | 0; + const height = canvas.clientHeight * multiplier | 0; + if (canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + return true; + } + return false; +} + +export { addExtensionsToContext, attributes, bindFramebufferInfo, bindTransformFeedbackInfo, bindUniformBlock, canFilter, canGenerateMipmap, createAttribsFromArrays, createAttributeSetters, createBufferFromArray, createBufferFromTypedArray, createBufferInfoFromArrays, createBuffersFromArrays, createFramebufferInfo, createProgram, createProgramAsync, createProgramFromScripts, createProgramFromSources, createProgramInfo, createProgramInfoAsync, createProgramInfoFromProgram, createProgramInfos, createProgramInfosAsync, createPrograms, createProgramsAsync, createSampler, createSamplers, createTexture, createTextures, createTransformFeedback, createTransformFeedbackInfo, createUniformBlockInfo, createUniformBlockInfoFromProgram, createUniformBlockSpecFromProgram, createUniformSetters, createVAOAndSetAttributes, createVAOFromBufferInfo, createVertexArrayInfo, draw, drawBufferInfo, drawObjectList, framebuffers, getArray$1 as getArray_, getBytesPerElementForInternalFormat, getContext, getFormatAndTypeForInternalFormat, getGLTypeForTypedArray, getGLTypeForTypedArrayType, getNumComponentsForFormat, getNumComponents$1 as getNumComponents_, getTypedArrayTypeForGLType, getWebGLContext, glEnumToString, isArrayBuffer$1 as isArrayBuffer, isWebGL1, isWebGL2, loadTextureFromUrl, m4, primitives, programs, resizeCanvasToDisplaySize, resizeFramebufferInfo, resizeTexture, setAttribInfoBufferFromArray, setDefaults$2 as setAttributeDefaults_, setAttributePrefix, setAttributes, setBlockUniforms, setBuffersAndAttributes, setDefaultTextureColor, setDefaults, setEmptyTexture, setSamplerParameters, setDefaults$1 as setTextureDefaults_, setTextureFilteringForSize, setTextureFromArray, setTextureFromElement, setTextureParameters, setUniformBlock, setUniforms, setUniformsAndBindTextures, textures, typedarrays, utils, v3, vertexArrays }; diff --git a/dist/6.x/twgl.d.ts b/dist/6.x/twgl.d.ts new file mode 100644 index 00000000..a8063b02 --- /dev/null +++ b/dist/6.x/twgl.d.ts @@ -0,0 +1,3172 @@ + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ +export type Defaults = { + attribPrefix?: string; + textureColor?: number[]; + crossOrigin?: string; + addExtensionsToContext?: boolean; +}; +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +export function setDefaults(newDefaults: Defaults): void; +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +export function addExtensionsToContext(gl: WebGLRenderingContext): void; +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +export function createContext(canvas: HTMLCanvasElement): WebGLRenderingContext; +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +export function getContext(canvas: HTMLCanvasElement, opt_attribs?: WebGLContextAttributes): WebGLRenderingContext; +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +export function resizeCanvasToDisplaySize(canvas: HTMLCanvasElement, multiplier?: number): boolean; +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type AttribInfo = { + value?: number[] | ArrayBufferView; + numComponents?: number; + size?: number; + type?: number; + normalize?: boolean; + offset?: number; + stride?: number; + divisor?: number; + buffer: WebGLBuffer; + drawType?: number; +}; +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type FullArraySpec = { + value?: number[] | ArrayBufferView; + data?: number | number[] | ArrayBufferView; + numComponents?: number; + type?: number | TypedArrayConstructor; + size?: number; + normalize?: boolean; + stride?: number; + offset?: number; + divisor?: number; + attrib?: string; + name?: string; + attribName?: string; + buffer?: WebGLBuffer; + drawType?: number; +}; +/** + * An individual array in {@link Arrays} + * + * When passed to {@link createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ +export type ArraySpec = number | number[] | ArrayBufferView | FullArraySpec; +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ +export type Arrays = { + [key: string]: ArraySpec; +}; +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ +export type BufferInfo = { + numElements: number; + elementType?: number; + indices?: WebGLBuffer; + attribs?: { + [key: string]: AttribInfo; + }; +}; +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @property {BufferInfo} [bufferInfo] A BufferInfo as returned from {@link createBufferInfoFromArrays} + * @property {VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ +export type DrawObject = { + active?: boolean; + type?: number; + programInfo: ProgramInfo; + bufferInfo?: BufferInfo; + vertexArrayInfo?: VertexArrayInfo; + uniforms: { + [key: string]: any; + }; + offset?: number; + count?: number; + instanceCount?: number; +}; +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes TextureOptions + */ +export type AttachmentOptions = TextureOptions & { + attachmentPoint?: number; + format?: number; + type?: number; + target?: number; + samples?: number; + level?: number; + layer?: number; + attachment?: WebGLRenderbuffer | WebGLTexture; +}; +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ +export type FramebufferInfo = { + framebuffer: WebGLFramebuffer; + attachments: (WebGLRenderbuffer | WebGLTexture)[]; + width: number; + height: number; +}; +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ +export type ErrorCallback = (msg: string, lineOffset?: number) => void; +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type FullProgramSpec = { + shaders: string[]; + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {string[]|FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ +export type ProgramSpec = string[] | FullProgramSpec; +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type ProgramOptions = { + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ +export type TransformFeedbackInfo = { + index: number; + type: number; + size: number; +}; +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +export function createTransformFeedbackInfo(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: TransformFeedbackInfo; +}; +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +export function bindTransformFeedbackInfo(gl: WebGLRenderingContext, transformFeedbackInfo: ProgramInfo | { + [key: string]: TransformFeedbackInfo; +}, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): void; +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +export function createTransformFeedback(gl: WebGLRenderingContext, programInfo: ProgramInfo, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): WebGLTransformFeedback; +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ +export type UniformData = { + name: string; + type: number; + size: number; + blockNdx: number; + offset: number; +}; +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ +export type BlockSpec = { + index: number; + size: number; + uniformIndices: number[]; + usedByVertexShader: boolean; + usedByFragmentShader: boolean; + used: boolean; +}; +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ +export type UniformBlockSpec = { + blockSpecs: { + [key: string]: BlockSpec; + }; + uniformData: UniformData[]; +}; +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link setBlockUniforms} + * @memberOf module:twgl + */ +export type UniformBlockInfo = { + name: string; + array: ArrayBuffer; + asFloat: Float32Array; + asUint8t: Uint8Array; + buffer: WebGLBuffer; + offset?: number; + uniforms: { + [key: string]: ArrayBufferView; + }; + setters: { + [key: string]: (...params: any[]) => any; + }; +}; +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ +export type ProgramInfo = { + program: WebGLProgram; + uniformLocations: { + [key: string]: WebGLUniformLocation; + }; + attribLocations: { + [key: string]: number; + }; + uniformSetters: { + [key: string]: (...params: any[]) => any; + }; + attribSetters: { + [key: string]: (...params: any[]) => any; + }; + uniformBlockSpec?: UniformBlockSpec; + transformFeedbackInfo?: { + [key: string]: TransformFeedbackInfo; + }; +}; +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link TextureOptions}. + * @memberOf module:twgl + */ +export type TextureFunc = (gl: WebGLRenderingContext, options: TextureOptions) => any; +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link setDefaults}. + * + * @memberOf module:twgl + */ +export type TextureOptions = { + target?: number; + level?: number; + width?: number; + height?: number; + depth?: number; + min?: number; + mag?: number; + minMag?: number; + internalFormat?: number; + format?: number; + type?: number; + wrap?: number; + wrapS?: number; + wrapT?: number; + wrapR?: number; + minLod?: number; + maxLod?: number; + baseLevel?: number; + maxLevel?: number; + compareFunc?: number; + compareMode?: number; + unpackAlignment?: number; + color?: number[] | ArrayBufferView; + premultiplyAlpha?: number; + flipY?: number; + colorspaceConversion?: number; + auto?: boolean; + cubeFaceOrder?: number[]; + src?: number[] | ArrayBufferView | TexImageSource | TexImageSource[] | string | string[] | TextureFunc; + crossOrigin?: string; +}; +/** + * The src image(s) used to create a texture. + * + * When you call {@link createTexture} or {@link createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ +export type TextureSrc = HTMLImageElement | HTMLImageElement[]; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ +export type TextureReadyCallback = (err: any, texture: WebGLTexture, source: TextureSrc) => void; +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ +export type TexturesReadyCallback = (err: any, textures: { + [key: string]: WebGLTexture; +}, sources: { + [key: string]: TextureSrc; +}) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ +export type CubemapReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ +export type ThreeDReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +export function isWebGL2(gl: WebGLRenderingContext): boolean; +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +export function isWebGL1(gl: WebGLRenderingContext): boolean; +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +export function glEnumToString(gl: WebGLRenderingContext, value: number): string; +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ +export type VertexArrayInfo = { + numElements: number; + elementType?: number; + vertexArrayObject?: WebGLVertexArrayObject; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +export function setAttributePrefix(prefix: string): void; +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +export function createBufferFromTypedArray(gl: WebGLRenderingContext, typedArray: ArrayBuffer | SharedArrayBuffer | ArrayBufferView | WebGLBuffer, type?: number, drawType?: number): WebGLBuffer; +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ +export type TypedArrayConstructor = Int8ArrayConstructor | Uint8ArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor; +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {Arrays} arrays The arrays + * @param {BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +export function createAttribsFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): { + [key: string]: AttribInfo; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +export function createBufferFromArray(gl: WebGLRenderingContext, array: ArraySpec, arrayName: string): WebGLBuffer; +/** + * Creates buffers from arrays or 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 {Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +export function createBuffersFromArrays(gl: WebGLRenderingContext, arrays: Arrays): { + [key: string]: WebGLBuffer; +}; + + +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; + + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; + + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|ProgramInfo} [result] the program or programInfo + */ +export type ProgramCallback = (err?: string, result?: WebGLProgram | ProgramInfo) => void; +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgram(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created program + * @memberOf module:twgl/programs + */ +export function createProgramAsync(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +export function createProgramInfoAsync(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromScripts(gl: WebGLRenderingContext, shaderScriptIds: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromSources(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +export function createUniformSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +export function createUniformBlockSpecFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram): UniformBlockSpec; +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ +export type UniformBlockInfoOptions = { + array?: ArrayBuffer; + offset?: number; + buffer?: WebGLBuffer; + bufferOffset?: number; +}; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfoFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Alias for `setUniforms` + * @function + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +export function setUniformsAndBindTextures(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +export function createAttributeSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +export function createProgramInfoFromProgram(gl: WebGLRenderingContext, program: WebGLProgram): ProgramInfo; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createPrograms(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramInfos(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: ProgramInfo; +}; +/** + * Creates multiple programs asynchronously + * + * @see {@link createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramsAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos asynchronously + * + * @see {@link createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +export function createProgramInfosAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): Promise<{ + [key: string]: ProgramInfo; +}>; + + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +export function getBytesPerElementForInternalFormat(internalFormat: number, type: number): number; +/** + * Info related to a specific texture internalFormat as returned + * from {@link getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ +export type TextureFormatInfo = { + format: number; + type: number; +}; +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +export function getFormatAndTypeForInternalFormat(internalFormat: number): TextureFormatInfo; +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canGenerateMipmap(gl: WebGLRenderingContext, width: number, height: number, internalFormat: number): boolean; +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canFilter(internalFormat: number): boolean; +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +export function getNumComponentsForFormat(format: number): number; +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link setDefaults} + * @memberOf module:twgl/textures + */ +export function setDefaultTextureColor(color: number[]): void; +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureParameters(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setSamplerParameters(gl: WebGLRenderingContext, sampler: WebGLSampler, options: TextureOptions): void; +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +export function setTextureFilteringForSize(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, width?: number, height?: number, internalFormat?: number): void; +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +export function setTextureFromElement(gl: WebGLRenderingContext, tex: WebGLTexture, element: HTMLElement, options?: TextureOptions): void; +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +export function loadTextureFromUrl(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, callback?: TextureReadyCallback): HTMLImageElement; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setEmptyTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArray(typedArray: ArrayBufferView): number; +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArrayType(typedArrayType: ArrayBufferView): number; +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +export function getTypedArrayTypeForGLType(type: number): (...params: any[]) => any; + + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ProgramInfo|ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +export function createVertexArrayInfo(gl: WebGLRenderingContext, programInfo: ProgramInfo | ProgramInfo[], bufferInfo: BufferInfo): VertexArrayInfo; +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOAndSetAttributes(gl: WebGLRenderingContext, setters: { + [key: string]: (...params: any[]) => any; +}, attribs: { + [key: string]: AttribInfo; +}, indices?: WebGLBuffer): WebGLVertexArrayObject | null; +/** + * Creates a vertex array object and then sets the attributes + * on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {Object.| ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOFromBufferInfo(gl: WebGLRenderingContext, programInfo: { + [key: string]: (...params: any[]) => any; +} | ProgramInfo, bufferInfo: BufferInfo, indices?: WebGLBuffer): WebGLVertexArrayObject | null; diff --git a/dist/6.x/twgl.js b/dist/6.x/twgl.js new file mode 100644 index 00000000..9a4cc6f9 --- /dev/null +++ b/dist/6.x/twgl.js @@ -0,0 +1,7263 @@ +/*! + * @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. + * Available via the MIT license. + * see: http://github.com/greggman/twgl.js for details + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["twgl"] = factory(); + else + root["twgl"] = factory(); +})(typeof self !== 'undefined' ? self : this, () => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/attributes.js": +/*!***************************!*\ + !*** ./src/attributes.js ***! + \***************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createAttribsFromArrays = createAttribsFromArrays; +exports.createBufferFromArray = createBufferFromArray; +exports.createBufferFromTypedArray = createBufferFromTypedArray; +exports.createBufferInfoFromArrays = createBufferInfoFromArrays; +exports.createBuffersFromArrays = createBuffersFromArrays; +exports.getArray_ = getArray; +exports.getNumComponents_ = getNumComponents; +exports.setAttribInfoBufferFromArray = setAttribInfoBufferFromArray; +exports.setAttributeDefaults_ = setDefaults; +exports.setAttributePrefix = setAttributePrefix; +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var STATIC_DRAW = 0x88e4; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var BUFFER_SIZE = 0x8764; +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; + +/** + * Low level attribute and buffer related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/attributes + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + attribPrefix: "" +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults.attribPrefix = prefix; +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); +} +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (helper.isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER; + var buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return true; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return true; + } // eslint-disable-line + return false; +} +function getArray(array) { + return array.length ? array : array.data; +} +var texcoordRE = /coord|texture/i; +var colorRE = /color|colour/i; +function guessNumComponentsFromName(name, length) { + var numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + if (length % numComponents > 0) { + throw new Error("Can not guess numComponents for attribute '".concat(name, "'. Tried ").concat(numComponents, " but ").concat(length, " values is not evenly divisible by ").concat(numComponents, ". You should specify it.")); + } + return numComponents; +} +function getNumComponents(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length); +} +function makeTypedArray(array, name) { + if (typedArrays.isArrayBuffer(array)) { + return array; + } + if (typedArrays.isArrayBuffer(array.data)) { + return array.data; + } + if (Array.isArray(array)) { + array = { + data: array + }; + } + var Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? glTypeOrTypedArrayCtor : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT; +} +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) : glTypeOrTypedArrayCtor || Float32Array; +} +function attribBufferFromBuffer(gl, array /*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, + // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) + }; +} +function attribBufferFromSize(gl, array /*, arrayName*/) { + var numValues = array.data || array; + var arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + var numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + var buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER, buffer); + gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW); + return { + buffer: buffer, + numValues: numValues, + type: typedArrays.getGLTypeForTypedArrayType(arrayType), + arrayType: arrayType + }; +} +function attribBufferFromArrayLike(gl, array, arrayName) { + var typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: typedArrays.getGLTypeForTypedArray(typedArray), + numValues: 0 + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + var attribs = {}; + Object.keys(arrays).forEach(function (arrayName) { + if (!isIndices(arrayName)) { + var array = arrays[arrayName]; + var attribName = array.attrib || array.name || array.attribName || defaults.attribPrefix + arrayName; + if (array.value) { + if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value + }; + } else { + var fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + var _fn = fn(gl, array, arrayName), + buffer = _fn.buffer, + type = _fn.type, + numValues = _fn.numValues, + arrayType = _fn.arrayType; + var normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + var numComponents = getNumComponents(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType); + } +} +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line + if (type === SHORT) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line + if (type === INT) return 4; // eslint-disable-line + if (type === UNSIGNED_INT) return 4; // eslint-disable-line + if (type === FLOAT) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +var positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + var array = arrays[key]; + var length = getArray(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + var numComponents = getNumComponents(array, key); + var numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} +function getNumElementsFromAttributes(gl, attribs) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + var attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER, attrib.buffer); + var numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER, null); + var bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + var totalElements = numBytes / bytesPerValue; + var numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + var numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + var newAttribs = createAttribsFromArrays(gl, arrays); + var bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + var indices = arrays.indices; + if (indices) { + var newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + var type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER; + var typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + var buffers = {}; + Object.keys(arrays).forEach(function (key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices'); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + return buffers; +} + +/***/ }), + +/***/ "./src/draw.js": +/*!*********************!*\ + !*** ./src/draw.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.drawBufferInfo = drawBufferInfo; +exports.drawObjectList = drawObjectList; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var TRIANGLES = 0x0004; +var UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + var indices = bufferInfo.indices; + var elementType = bufferInfo.elementType; + var numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + var lastUsedProgramInfo = null; + var lastUsedBufferInfo = null; + objectsToDraw.forEach(function (object) { + if (object.active === false) { + return; + } + var programInfo = object.programInfo; + var bufferInfo = object.vertexArrayInfo || object.bufferInfo; + var bindBuffers = false; + var type = object.type === undefined ? TRIANGLES : object.type; + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + programs.setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +/***/ }), + +/***/ "./src/framebuffers.js": +/*!*****************************!*\ + !*** ./src/framebuffers.js ***! + \*****************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindFramebufferInfo = bindFramebufferInfo; +exports.createFramebufferInfo = createFramebufferInfo; +exports.resizeFramebufferInfo = resizeFramebufferInfo; +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Framebuffer related functions + * + * For backward compatibility they are available at both `twgl.framebuffer` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/framebuffers + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var FRAMEBUFFER = 0x8d40; +var RENDERBUFFER = 0x8d41; +var TEXTURE_2D = 0x0de1; +var UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +var DEPTH_COMPONENT = 0x1902; +var RGBA = 0x1908; +var DEPTH_COMPONENT24 = 0x81a6; +var DEPTH_COMPONENT32F = 0x8cac; +var DEPTH24_STENCIL8 = 0x88f0; +var DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +var RGBA4 = 0x8056; +var RGB5_A1 = 0x8057; +var RGB565 = 0x8D62; +var DEPTH_COMPONENT16 = 0x81A5; +var STENCIL_INDEX = 0x1901; +var STENCIL_INDEX8 = 0x8D48; +var DEPTH_STENCIL = 0x84F9; +var COLOR_ATTACHMENT0 = 0x8CE0; +var DEPTH_ATTACHMENT = 0x8D00; +var STENCIL_ATTACHMENT = 0x8D20; +var DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +var CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +var LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +var defaultAttachments = [{ + format: RGBA, + type: UNSIGNED_BYTE, + min: LINEAR, + wrap: CLAMP_TO_EDGE +}, { + format: DEPTH_STENCIL +}]; +var attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} +var renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} +var MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + var target = FRAMEBUFFER; + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + var usedColorAttachmentsPoints = []; + var framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height + }; + attachments.forEach(function (attachmentOptions, i) { + var attachment = attachmentOptions.attachment; + var samples = attachmentOptions.samples; + var format = attachmentOptions.format; + var attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + var textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = textures.createTexture(gl, textureOptions); + } + } + if (helper.isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (helper.isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer(target, attachmentPoint, attachment, attachmentOptions.level || 0, attachmentOptions.layer); + } else { + gl.framebufferTexture2D(target, attachmentPoint, attachmentOptions.target || TEXTURE_2D, attachment, attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function (attachmentOptions, ndx) { + var attachment = framebufferInfo.attachments[ndx]; + var format = attachmentOptions.format; + var samples = attachmentOptions.samples; + if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (helper.isTexture(gl, attachment)) { + textures.resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +/***/ }), + +/***/ "./src/helper.js": +/*!***********************!*\ + !*** ./src/helper.js ***! + \***********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.copyExistingProperties = copyExistingProperties; +exports.copyNamedProperties = copyNamedProperties; +exports.error = error; +exports.isBuffer = isBuffer; +exports.isRenderbuffer = isRenderbuffer; +exports.isSampler = isSampler; +exports.isShader = isShader; +exports.isTexture = isTexture; +exports.warn = warn; +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* eslint no-console: "off" */ + +/** + * Copy named properties + * + * @param {string[]} names names of properties to copy + * @param {object} src object to copy properties from + * @param {object} dst object to copy properties to + * @private + */ +function copyNamedProperties(names, src, dst) { + names.forEach(function (name) { + var value = src[name]; + if (value !== undefined) { + dst[name] = value; + } + }); +} + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function (key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { + /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} +function error() { + var _console; + (_console = console).error.apply(_console, arguments); +} +function warn() { + var _console2; + (_console2 = console).warn.apply(_console2, arguments); +} +var isTypeWeakMaps = new Map(); +function isType(object, type) { + if (!object || _typeof(object) !== 'object') { + return false; + } + var weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + var isOfType = weakMap.get(object); + if (isOfType === undefined) { + var s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} +function isShader(gl, t) { + return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader'); +} +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/***/ }), + +/***/ "./src/programs.js": +/*!*************************!*\ + !*** ./src/programs.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindTransformFeedbackInfo = bindTransformFeedbackInfo; +exports.bindUniformBlock = bindUniformBlock; +exports.createAttributeSetters = createAttributeSetters; +exports.createProgram = createProgram; +exports.createProgramAsync = void 0; +exports.createProgramFromScripts = createProgramFromScripts; +exports.createProgramFromSources = createProgramFromSources; +exports.createProgramInfo = createProgramInfo; +exports.createProgramInfoAsync = void 0; +exports.createProgramInfoFromProgram = createProgramInfoFromProgram; +exports.createProgramInfos = createProgramInfos; +exports.createProgramInfosAsync = void 0; +exports.createPrograms = createPrograms; +exports.createProgramsAsync = void 0; +exports.createTransformFeedback = createTransformFeedback; +exports.createTransformFeedbackInfo = createTransformFeedbackInfo; +exports.createUniformBlockInfo = createUniformBlockInfo; +exports.createUniformBlockInfoFromProgram = createUniformBlockInfoFromProgram; +exports.createUniformBlockSpecFromProgram = createUniformBlockSpecFromProgram; +exports.createUniformSetters = createUniformSetters; +exports.setAttributes = setAttributes; +exports.setBlockUniforms = setBlockUniforms; +exports.setBuffersAndAttributes = setBuffersAndAttributes; +exports.setUniformBlock = setUniformBlock; +exports.setUniforms = setUniforms; +exports.setUniformsAndBindTextures = void 0; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } +function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } /* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +var error = helper.error; +var warn = helper.warn; +function getElementById(id) { + return typeof document !== 'undefined' && document.getElementById ? document.getElementById(id) : null; +} +var TEXTURE0 = 0x84c0; +var DYNAMIC_DRAW = 0x88e8; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var UNIFORM_BUFFER = 0x8a11; +var TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; +var TRANSFORM_FEEDBACK = 0x8e22; +var COMPILE_STATUS = 0x8b81; +var LINK_STATUS = 0x8b82; +var FRAGMENT_SHADER = 0x8b30; +var VERTEX_SHADER = 0x8b31; +var SEPARATE_ATTRIBS = 0x8c8d; +var ACTIVE_UNIFORMS = 0x8b86; +var ACTIVE_ATTRIBUTES = 0x8b89; +var TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +var ACTIVE_UNIFORM_BLOCKS = 0x8a36; +var UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +var UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +var UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +var UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; +var FLOAT = 0x1406; +var FLOAT_VEC2 = 0x8B50; +var FLOAT_VEC3 = 0x8B51; +var FLOAT_VEC4 = 0x8B52; +var INT = 0x1404; +var INT_VEC2 = 0x8B53; +var INT_VEC3 = 0x8B54; +var INT_VEC4 = 0x8B55; +var BOOL = 0x8B56; +var BOOL_VEC2 = 0x8B57; +var BOOL_VEC3 = 0x8B58; +var BOOL_VEC4 = 0x8B59; +var FLOAT_MAT2 = 0x8B5A; +var FLOAT_MAT3 = 0x8B5B; +var FLOAT_MAT4 = 0x8B5C; +var SAMPLER_2D = 0x8B5E; +var SAMPLER_CUBE = 0x8B60; +var SAMPLER_3D = 0x8B5F; +var SAMPLER_2D_SHADOW = 0x8B62; +var FLOAT_MAT2x3 = 0x8B65; +var FLOAT_MAT2x4 = 0x8B66; +var FLOAT_MAT3x2 = 0x8B67; +var FLOAT_MAT3x4 = 0x8B68; +var FLOAT_MAT4x2 = 0x8B69; +var FLOAT_MAT4x3 = 0x8B6A; +var SAMPLER_2D_ARRAY = 0x8DC1; +var SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +var SAMPLER_CUBE_SHADOW = 0x8DC5; +var UNSIGNED_INT = 0x1405; +var UNSIGNED_INT_VEC2 = 0x8DC6; +var UNSIGNED_INT_VEC3 = 0x8DC7; +var UNSIGNED_INT_VEC4 = 0x8DC8; +var INT_SAMPLER_2D = 0x8DCA; +var INT_SAMPLER_3D = 0x8DCB; +var INT_SAMPLER_CUBE = 0x8DCC; +var INT_SAMPLER_2D_ARRAY = 0x8DCF; +var UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +var UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +var UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +var UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; +var TEXTURE_2D = 0x0DE1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806F; +var TEXTURE_2D_ARRAY = 0x8C1A; +var typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function (v) { + gl.uniform1f(location, v); + }; +} +function floatArraySetter(gl, location) { + return function (v) { + gl.uniform1fv(location, v); + }; +} +function floatVec2Setter(gl, location) { + return function (v) { + gl.uniform2fv(location, v); + }; +} +function floatVec3Setter(gl, location) { + return function (v) { + gl.uniform3fv(location, v); + }; +} +function floatVec4Setter(gl, location) { + return function (v) { + gl.uniform4fv(location, v); + }; +} +function intSetter(gl, location) { + return function (v) { + gl.uniform1i(location, v); + }; +} +function intArraySetter(gl, location) { + return function (v) { + gl.uniform1iv(location, v); + }; +} +function intVec2Setter(gl, location) { + return function (v) { + gl.uniform2iv(location, v); + }; +} +function intVec3Setter(gl, location) { + return function (v) { + gl.uniform3iv(location, v); + }; +} +function intVec4Setter(gl, location) { + return function (v) { + gl.uniform4iv(location, v); + }; +} +function uintSetter(gl, location) { + return function (v) { + gl.uniform1ui(location, v); + }; +} +function uintArraySetter(gl, location) { + return function (v) { + gl.uniform1uiv(location, v); + }; +} +function uintVec2Setter(gl, location) { + return function (v) { + gl.uniform2uiv(location, v); + }; +} +function uintVec3Setter(gl, location) { + return function (v) { + gl.uniform3uiv(location, v); + }; +} +function uintVec4Setter(gl, location) { + return function (v) { + gl.uniform4uiv(location, v); + }; +} +function floatMat2Setter(gl, location) { + return function (v) { + gl.uniformMatrix2fv(location, false, v); + }; +} +function floatMat3Setter(gl, location) { + return function (v) { + gl.uniformMatrix3fv(location, false, v); + }; +} +function floatMat4Setter(gl, location) { + return function (v) { + gl.uniformMatrix4fv(location, false, v); + }; +} +function floatMat23Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} +function floatMat32Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} +function floatMat24Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} +function floatMat42Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} +function floatMat34Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} +function floatMat43Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} +function samplerSetter(gl, type, unit, location) { + var bindPoint = getBindPointForSamplerType(gl, type); + return utils.isWebGL2(gl) ? function (textureOrPair) { + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function (texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} +function samplerArraySetter(gl, type, unit, location, size) { + var bindPoint = getBindPointForSamplerType(gl, type); + var units = new Int32Array(size); + for (var ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + return utils.isWebGL2(gl) ? function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} +typeMap[FLOAT] = { + Type: Float32Array, + size: 4, + setter: floatSetter, + arraySetter: floatArraySetter +}; +typeMap[FLOAT_VEC2] = { + Type: Float32Array, + size: 8, + setter: floatVec2Setter, + cols: 2 +}; +typeMap[FLOAT_VEC3] = { + Type: Float32Array, + size: 12, + setter: floatVec3Setter, + cols: 3 +}; +typeMap[FLOAT_VEC4] = { + Type: Float32Array, + size: 16, + setter: floatVec4Setter, + cols: 4 +}; +typeMap[INT] = { + Type: Int32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[INT_VEC2] = { + Type: Int32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[INT_VEC3] = { + Type: Int32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[INT_VEC4] = { + Type: Int32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[UNSIGNED_INT] = { + Type: Uint32Array, + size: 4, + setter: uintSetter, + arraySetter: uintArraySetter +}; +typeMap[UNSIGNED_INT_VEC2] = { + Type: Uint32Array, + size: 8, + setter: uintVec2Setter, + cols: 2 +}; +typeMap[UNSIGNED_INT_VEC3] = { + Type: Uint32Array, + size: 12, + setter: uintVec3Setter, + cols: 3 +}; +typeMap[UNSIGNED_INT_VEC4] = { + Type: Uint32Array, + size: 16, + setter: uintVec4Setter, + cols: 4 +}; +typeMap[BOOL] = { + Type: Uint32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[BOOL_VEC2] = { + Type: Uint32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[BOOL_VEC3] = { + Type: Uint32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[BOOL_VEC4] = { + Type: Uint32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[FLOAT_MAT2] = { + Type: Float32Array, + size: 32, + setter: floatMat2Setter, + rows: 2, + cols: 2 +}; +typeMap[FLOAT_MAT3] = { + Type: Float32Array, + size: 48, + setter: floatMat3Setter, + rows: 3, + cols: 3 +}; +typeMap[FLOAT_MAT4] = { + Type: Float32Array, + size: 64, + setter: floatMat4Setter, + rows: 4, + cols: 4 +}; +typeMap[FLOAT_MAT2x3] = { + Type: Float32Array, + size: 32, + setter: floatMat23Setter, + rows: 2, + cols: 3 +}; +typeMap[FLOAT_MAT2x4] = { + Type: Float32Array, + size: 32, + setter: floatMat24Setter, + rows: 2, + cols: 4 +}; +typeMap[FLOAT_MAT3x2] = { + Type: Float32Array, + size: 48, + setter: floatMat32Setter, + rows: 3, + cols: 2 +}; +typeMap[FLOAT_MAT3x4] = { + Type: Float32Array, + size: 48, + setter: floatMat34Setter, + rows: 3, + cols: 4 +}; +typeMap[FLOAT_MAT4x2] = { + Type: Float32Array, + size: 64, + setter: floatMat42Setter, + rows: 4, + cols: 2 +}; +typeMap[FLOAT_MAT4x3] = { + Type: Float32Array, + size: 64, + setter: floatMat43Setter, + rows: 4, + cols: 3 +}; +typeMap[SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[SAMPLER_2D_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_CUBE_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +function floatAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer(index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function intAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function uintAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function matAttribSetter(gl, index, typeInfo) { + var defaultSize = typeInfo.size; + var count = typeInfo.count; + return function (b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + var numComponents = b.size || b.numComponents || defaultSize; + var size = numComponents / count; + var type = b.type || FLOAT; + var typeInfo = typeMap[type]; + var stride = typeInfo.size * numComponents; + var normalize = b.normalize || false; + var offset = b.offset || 0; + var rowOffset = stride / count; + for (var i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer(index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} +var attrTypeMap = {}; +attrTypeMap[FLOAT] = { + size: 4, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC2] = { + size: 8, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC3] = { + size: 12, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC4] = { + size: 16, + setter: floatAttribSetter +}; +attrTypeMap[INT] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[UNSIGNED_INT] = { + size: 4, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC2] = { + size: 8, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC3] = { + size: 12, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC4] = { + size: 16, + setter: uintAttribSetter +}; +attrTypeMap[BOOL] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[FLOAT_MAT2] = { + size: 4, + setter: matAttribSetter, + count: 2 +}; +attrTypeMap[FLOAT_MAT3] = { + size: 9, + setter: matAttribSetter, + count: 3 +}; +attrTypeMap[FLOAT_MAT4] = { + size: 16, + setter: matAttribSetter, + count: 4 +}; + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src) { + var log = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var lineOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + // Note: Error message formats are not defined by any spec so this may or may not work. + var matches = _toConsumableArray(log.matchAll(errorRE)); + var lineNoToErrorMap = new Map(matches.map(function (m, ndx) { + var lineNo = parseInt(m[1]); + var next = matches[ndx + 1]; + var end = next ? next.index : log.length; + var msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map(function (line, lineNo) { + var err = lineNoToErrorMap.get(lineNo); + return "".concat(lineNo + 1 + lineOffset, ": ").concat(line).concat(err ? "\n\n^^^ ".concat(err) : ''); + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +var spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + var lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return { + lineOffset: lineOffset, + shaderSource: shaderSource + }; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(function () { + progOptions.callback("".concat(msg, "\n").concat(progOptions.errors.join('\n'))); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + var compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var lastError = gl.getShaderInfoLog(shader); + var _prepShaderSource = prepShaderSource(gl.getShaderSource(shader)), + lineOffset = _prepShaderSource.lineOffset, + shaderSource = _prepShaderSource.shaderSource; + var _error = "".concat(addLineNumbersWithError(shaderSource, lastError, lineOffset), "\nError compiling ").concat(utils.glEnumToString(gl, shaderType), ": ").concat(lastError); + errFn(_error); + return _error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + var transformFeedbackVaryings; + var transformFeedbackMode; + var callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + var opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + var _errorCallback = opt_errorCallback || error; + var errors = []; + var options = { + errorCallback: function errorCallback(msg) { + errors.push(msg); + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + _errorCallback.apply(void 0, [msg].concat(args)); + }, + transformFeedbackVaryings: transformFeedbackVaryings, + transformFeedbackMode: transformFeedbackMode, + callback: callback, + errors: errors + }; + { + var attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function (attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + return options; +} +var defaultShaderType = ["VERTEX_SHADER", "FRAGMENT_SHADER"]; +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} +function deleteProgramAndShaders(gl, program, notThese) { + var shaders = gl.getAttachedShaders(program); + var _iterator = _createForOfIteratorHelper(shaders), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var shader = _step.value; + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + gl.deleteProgram(program); +} +var wait = function wait() { + var ms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + return new Promise(function (resolve) { + return setTimeout(resolve, ms); + }); +}; +function createProgramNoCheck(gl, shaders, programOptions) { + var program = gl.createProgram(); + var _getProgramOptions = getProgramOptions(programOptions), + attribLocations = _getProgramOptions.attribLocations, + transformFeedbackVaryings = _getProgramOptions.transformFeedbackVaryings, + transformFeedbackMode = _getProgramOptions.transformFeedbackMode; + for (var ndx = 0; ndx < shaders.length; ++ndx) { + var shader = shaders[ndx]; + if (typeof shader === 'string') { + var elem = getElementById(shader); + var src = elem ? elem.text : shader; + var type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + Object.entries(attribLocations).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + attrib = _ref2[0], + loc = _ref2[1]; + return gl.bindAttribLocation(program, loc, attrib); + }); + { + var varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaderSet = new Set(shaders); + var program = createProgramNoCheck(gl, shaders, progOptions); + function hasErrors(gl, program) { + var errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(function () { + var errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function (gl, arg1) { + for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + return new Promise(function (resolve, reject) { + var programOptions = getProgramOptions.apply(void 0, args); + programOptions.callback = function (err, program) { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +var createProgramAsync = exports.createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +var createProgramInfoAsync = exports.createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); +function waitForProgramLinkCompletionAsync(_x, _x2) { + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function _waitForProgramLinkCompletionAsync() { + _waitForProgramLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(gl, program) { + var ext, checkFn, waitTime; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + ext = gl.getExtension('KHR_parallel_shader_compile'); + checkFn = ext ? function (gl, program) { + return gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR); + } : function () { + return true; + }; + waitTime = 0; + case 3: + _context.next = 5; + return wait(waitTime); + case 5: + // must wait at least once + waitTime = 1000 / 60; + case 6: + if (!checkFn(gl, program)) { + _context.next = 3; + break; + } + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function waitForAllProgramsLinkCompletionAsync(_x3, _x4) { + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function _waitForAllProgramsLinkCompletionAsync() { + _waitForAllProgramsLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(gl, programs) { + var _i3, _Object$values2, program; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + _i3 = 0, _Object$values2 = Object.values(programs); + case 1: + if (!(_i3 < _Object$values2.length)) { + _context2.next = 8; + break; + } + program = _Object$values2[_i3]; + _context2.next = 5; + return waitForProgramLinkCompletionAsync(gl, program); + case 5: + _i3++; + _context2.next = 1; + break; + case 8: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + var linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + var lastError = gl.getProgramInfoLog(program); + errFn("Error in program linking: ".concat(lastError)); + // print any errors from these shaders + var shaders = gl.getAttachedShaders(program); + var errors = shaders.map(function (shader) { + return checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn); + }); + return "".concat(lastError, "\n").concat(errors.filter(function (_) { + return _; + }).join('\n')); + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts(gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaders = []; + var _iterator2 = _createForOfIteratorHelper(shaderScriptIds), + _step2; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var scriptId = _step2.value; + var shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, "unknown script element: ".concat(scriptId)); + } + shaders.push(shaderScript.text); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + var name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} +var tokenRE = /(\.|\[|]|\w+)/g; +var isDigit = function isDigit(s) { + return s >= '0' && s <= '9'; +}; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + var tokens = fullPath.split(tokenRE).filter(function (s) { + return s !== ''; + }); + var tokenNdx = 0; + var path = ''; + for (;;) { + var token = tokens[tokenNdx++]; // has to be name or number + path += token; + var isArrayIndex = isDigit(token[0]); + var accessor = isArrayIndex ? parseInt(token) : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + var isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + var _token = tokens[tokenNdx++]; // has to be . or [ + var isArray = _token === '['; + var child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function (node) { + return function (value) { + setUniformTree(node, value); + }; + }(child); + path += _token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +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, location) { + var isArray = uniformInfo.name.endsWith("[0]"); + var type = uniformInfo.type; + var typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error("unknown type: 0x".concat(type.toString(16))); // we should never get here. + } + var setter; + if (typeInfo.bindPoint) { + // it's a sampler + var unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + var uniformSetters = {}; + var uniformTree = {}; + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + for (var ii = 0; ii < numUniforms; ++ii) { + var uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + var name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + var location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + var setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + var info = {}; + var numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (var ii = 0; ii < numVaryings; ++ii) { + var varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (var name in bufferInfo) { + var varying = transformFeedbackInfo[name]; + if (varying) { + var buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + var tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + var uniformData = []; + var uniformIndices = []; + for (var ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + var uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + [["UNIFORM_TYPE", "type"], ["UNIFORM_SIZE", "size"], + // num elements + ["UNIFORM_BLOCK_INDEX", "blockNdx"], ["UNIFORM_OFFSET", "offset"]].forEach(function (pair) { + var pname = pair[0]; + var key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function (value, ndx) { + uniformData[ndx][key] = value; + }); + }); + var blockSpecs = {}; + var numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (var _ii = 0; _ii < numUniformBlocks; ++_ii) { + var name = gl.getActiveUniformBlockName(program, _ii); + var blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + return { + blockSpecs: blockSpecs, + uniformData: uniformData + }; +} +var arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +var pad = function pad(v, padding) { + return ((v + (padding - 1)) / padding | 0) * padding; +}; +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + var numElements = view.length; + var totalRows = numElements / 4; + return function (value) { + var dst = 0; + var src = 0; + for (var row = 0; row < totalRows; ++row) { + for (var col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function (value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName) { + var _options$offset, _options$array, _options$buffer, _options$bufferOffset; + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + var blockSpecs = uniformBlockSpec.blockSpecs; + var uniformData = uniformBlockSpec.uniformData; + var blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {} + }; + } + var offset = (_options$offset = options.offset) !== null && _options$offset !== void 0 ? _options$offset : 0; + var array = (_options$array = options.array) !== null && _options$array !== void 0 ? _options$array : new ArrayBuffer(blockSpec.size); + var buffer = (_options$buffer = options.buffer) !== null && _options$buffer !== void 0 ? _options$buffer : gl.createBuffer(); + var uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + var prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + var uniforms = {}; + var setters = {}; + var setterTree = {}; + blockSpec.uniformIndices.forEach(function (uniformNdx) { + var data = uniformData[uniformNdx]; + var name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + var isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + var typeInfo = typeMap[data.type]; + var Type = typeInfo.Type; + var byteLength = isArray ? pad(typeInfo.size, 16) * data.size : typeInfo.size * data.size; + var uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + var setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array: array, + asFloat: new Float32Array(array), + // for debugging + asUint8: new Uint8Array(array), + // needed for gl.bufferSubData because it doesn't take an array buffer + buffer: buffer, + uniforms: uniforms, + setters: setters, + offset: (_options$bufferOffset = options.bufferOffset) !== null && _options$bufferOffset !== void 0 ? _options$bufferOffset : offset, + size: blockSpec.size + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + var uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + var blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + var _uniformBlockInfo$siz; + var bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, (_uniformBlockInfo$siz = uniformBlockInfo.size) !== null && _uniformBlockInfo$siz !== void 0 ? _uniformBlockInfo$siz : uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + var setters = uniformBlockInfo.setters; + for (var name in values) { + var setter = setters[name]; + if (setter) { + var value = values[name]; + setter(value); + } + } +} +function setUniformTree(tree, values) { + for (var name in values) { + var prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters) { + // eslint-disable-line + var actualSetters = setters.uniformSetters || setters; + var numArgs = arguments.length <= 1 ? 0 : arguments.length - 1; + for (var aNdx = 0; aNdx < numArgs; ++aNdx) { + var values = aNdx + 1 < 1 || arguments.length <= aNdx + 1 ? undefined : arguments[aNdx + 1]; + if (Array.isArray(values)) { + var numValues = values.length; + for (var ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (var name in values) { + var setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +var setUniformsAndBindTextures = exports.setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + var attribSetters = {}; + var numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (var ii = 0; ii < numAttribs; ++ii) { + var attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + var index = gl.getAttribLocation(program, attribInfo.name); + var typeInfo = attrTypeMap[attribInfo.type]; + var setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (var name in buffers) { + var setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + var uniformSetters = createUniformSetters(gl, program); + var attribSetters = createAttributeSetters(gl, program); + var programInfo = { + program: program, + uniformSetters: uniformSetters, + attribSetters: attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + k = _ref4[0], + v = _ref4[1]; + return [k, v.location]; + })), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + k = _ref6[0], + v = _ref6[1]; + return [k, v.location]; + })) + }; + if (utils.isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + return programInfo; +} +var notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var errors = []; + shaderSources = shaderSources.map(function (source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + var script = getElementById(source); + if (!script) { + var err = "no element with id: ".concat(source); + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + if (errors.length) { + return reportError(progOptions, ''); + } + var origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = function (err, program) { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + var program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + return createProgramInfoFromProgram(gl, program); +} +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (var _i = 0, _Object$entries = Object.entries(programs); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), + name = _Object$entries$_i[0], + program = _Object$entries$_i[1]; + var options = _objectSpread({}, programOptions); + var spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + var errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (var _i2 = 0, _Object$values = Object.values(programs); _i2 < _Object$values.length; _i2++) { + var _program = _Object$values[_i2]; + var shaders = gl.getAttachedShaders(_program); + gl.deleteProgram(_program); + var _iterator3 = _createForOfIteratorHelper(shaders), + _step3; + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var shader = _step3.value; + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + } + return errors; + } + } + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs) { + var programOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // Remember existing shaders so that if there is an error we don't delete them + var noDeleteShadersSet = new Set(); + + // compile and link everything + var programs = Object.fromEntries(Object.entries(programSpecs).map(function (_ref7) { + var _ref8 = _slicedToArray(_ref7, 2), + name = _ref8[0], + spec = _ref8[1]; + var options = _objectSpread({}, programOptions); + var shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(function () { + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + name = _ref10[0], + program = _ref10[1]; + return [name, createProgramInfoFromProgram(gl, program)]; + })); + } + var origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = function (err, programs) { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + var programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +var createProgramsAsync = exports.createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +var createProgramInfosAsync = exports.createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +/***/ }), + +/***/ "./src/textures.js": +/*!*************************!*\ + !*** ./src/textures.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.canFilter = canFilter; +exports.canGenerateMipmap = canGenerateMipmap; +exports.createSampler = createSampler; +exports.createSamplers = createSamplers; +exports.createTexture = createTexture; +exports.createTextures = createTextures; +exports.getBytesPerElementForInternalFormat = getBytesPerElementForInternalFormat; +exports.getFormatAndTypeForInternalFormat = getFormatAndTypeForInternalFormat; +exports.getNumComponentsForFormat = getNumComponentsForFormat; +exports.loadTextureFromUrl = loadTextureFromUrl; +exports.resizeTexture = resizeTexture; +exports.setDefaultTextureColor = setDefaultTextureColor; +exports.setEmptyTexture = setEmptyTexture; +exports.setSamplerParameters = setSamplerParameters; +exports.setTextureDefaults_ = setDefaults; +exports.setTextureFilteringForSize = setTextureFilteringForSize; +exports.setTextureFromArray = setTextureFromArray; +exports.setTextureFromElement = setTextureFromElement; +exports.setTextureParameters = setTextureParameters; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level texture related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.textures` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/textures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined +}; +var isArrayBuffer = typedArrays.isArrayBuffer; + +// Should we make this on demand? +var getShared2DContext = function () { + var s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || (typeof document !== 'undefined' && document.createElement ? document.createElement("canvas").getContext("2d") : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +var ALPHA = 0x1906; +var RGB = 0x1907; +var RGBA = 0x1908; +var LUMINANCE = 0x1909; +var LUMINANCE_ALPHA = 0x190A; +var DEPTH_COMPONENT = 0x1902; +var DEPTH_STENCIL = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +var CLAMP_TO_EDGE = 0x812f; + +/* TextureMagFilter */ +var NEAREST = 0x2600; +var LINEAR = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +var TEXTURE_2D = 0x0de1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806f; +var TEXTURE_2D_ARRAY = 0x8c1a; + +/* Cubemap Targets */ +var TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +var TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +var TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +var TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +var TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +var TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +var TEXTURE_MIN_FILTER = 0x2801; +var TEXTURE_MAG_FILTER = 0x2800; +var TEXTURE_WRAP_S = 0x2802; +var TEXTURE_WRAP_T = 0x2803; +var TEXTURE_WRAP_R = 0x8072; +var TEXTURE_MIN_LOD = 0x813a; +var TEXTURE_MAX_LOD = 0x813b; +var TEXTURE_BASE_LEVEL = 0x813c; +var TEXTURE_MAX_LEVEL = 0x813d; +var TEXTURE_COMPARE_MODE = 0x884C; +var TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +var UNPACK_ALIGNMENT = 0x0cf5; +var UNPACK_ROW_LENGTH = 0x0cf2; +var UNPACK_IMAGE_HEIGHT = 0x806e; +var UNPACK_SKIP_PIXELS = 0x0cf4; +var UNPACK_SKIP_ROWS = 0x0cf3; +var UNPACK_SKIP_IMAGES = 0x806d; +var UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +var UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +var UNPACK_FLIP_Y_WEBGL = 0x9240; +var R8 = 0x8229; +var R8_SNORM = 0x8F94; +var R16F = 0x822D; +var R32F = 0x822E; +var R8UI = 0x8232; +var R8I = 0x8231; +var RG16UI = 0x823A; +var RG16I = 0x8239; +var RG32UI = 0x823C; +var RG32I = 0x823B; +var RG8 = 0x822B; +var RG8_SNORM = 0x8F95; +var RG16F = 0x822F; +var RG32F = 0x8230; +var RG8UI = 0x8238; +var RG8I = 0x8237; +var R16UI = 0x8234; +var R16I = 0x8233; +var R32UI = 0x8236; +var R32I = 0x8235; +var RGB8 = 0x8051; +var SRGB8 = 0x8C41; +var RGB565 = 0x8D62; +var RGB8_SNORM = 0x8F96; +var R11F_G11F_B10F = 0x8C3A; +var RGB9_E5 = 0x8C3D; +var RGB16F = 0x881B; +var RGB32F = 0x8815; +var RGB8UI = 0x8D7D; +var RGB8I = 0x8D8F; +var RGB16UI = 0x8D77; +var RGB16I = 0x8D89; +var RGB32UI = 0x8D71; +var RGB32I = 0x8D83; +var RGBA8 = 0x8058; +var SRGB8_ALPHA8 = 0x8C43; +var RGBA8_SNORM = 0x8F97; +var RGB5_A1 = 0x8057; +var RGBA4 = 0x8056; +var RGB10_A2 = 0x8059; +var RGBA16F = 0x881A; +var RGBA32F = 0x8814; +var RGBA8UI = 0x8D7C; +var RGBA8I = 0x8D8E; +var RGB10_A2UI = 0x906F; +var RGBA16UI = 0x8D76; +var RGBA16I = 0x8D88; +var RGBA32I = 0x8D82; +var RGBA32UI = 0x8D70; +var DEPTH_COMPONENT16 = 0x81A5; +var DEPTH_COMPONENT24 = 0x81A6; +var DEPTH_COMPONENT32F = 0x8CAC; +var DEPTH32F_STENCIL8 = 0x8CAD; +var DEPTH24_STENCIL8 = 0x88F0; + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var RG = 0x8227; +var RG_INTEGER = 0x8228; +var RED = 0x1903; +var RED_INTEGER = 0x8D94; +var RGB_INTEGER = 0x8D98; +var RGBA_INTEGER = 0x8D99; +var formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + var f = formatInfo; + f[ALPHA] = { + numColorComponents: 1 + }; + f[LUMINANCE] = { + numColorComponents: 1 + }; + f[LUMINANCE_ALPHA] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RED] = { + numColorComponents: 1 + }; + f[RED_INTEGER] = { + numColorComponents: 1 + }; + f[RG] = { + numColorComponents: 2 + }; + f[RG_INTEGER] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGB_INTEGER] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RGBA_INTEGER] = { + numColorComponents: 4 + }; + f[DEPTH_COMPONENT] = { + numColorComponents: 1 + }; + f[DEPTH_STENCIL] = { + numColorComponents: 2 + }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +var s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + var t = {}; + // unsized formats + t[ALPHA] = { + textureFormat: ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE] = { + textureFormat: LUMINANCE, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE_ALPHA] = { + textureFormat: LUMINANCE_ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2, 4, 4, 8], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[RGB] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 6, 6, 12, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5] + }; + t[RGBA] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 8, 8, 16, 2, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1] + }; + t[DEPTH_COMPONENT] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_INT, UNSIGNED_SHORT] + }; + + // sized formats + t[R8] = { + textureFormat: RED, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8_SNORM] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [FLOAT, HALF_FLOAT] + }; + t[R32F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[R8UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_SHORT] + }; + t[R16I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [SHORT] + }; + t[R32UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[R32I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [INT] + }; + t[RG8] = { + textureFormat: RG, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8_SNORM] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [8, 4], + type: [FLOAT, HALF_FLOAT] + }; + t[RG32F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [8], + type: [FLOAT] + }; + t[RG8UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_SHORT] + }; + t[RG16I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [SHORT] + }; + t[RG32UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_INT] + }; + t[RG32I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [INT] + }; + t[RGB8] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[SRGB8] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB565] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5] + }; + t[RGB8_SNORM] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [BYTE] + }; + t[R11F_G11F_B10F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV] + }; + t[RGB9_E5] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV] + }; + t[RGB16F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6], + type: [FLOAT, HALF_FLOAT] + }; + t[RGB32F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [FLOAT] + }; + t[RGB8UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB8I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [BYTE] + }; + t[RGB16UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [UNSIGNED_SHORT] + }; + t[RGB16I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [SHORT] + }; + t[RGB32UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [UNSIGNED_INT] + }; + t[RGB32I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [INT] + }; + t[RGBA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[SRGB8_ALPHA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8_SNORM] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB5_A1] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2, 4], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA4] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4] + }; + t[RGB10_A2] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [16, 8], + type: [FLOAT, HALF_FLOAT] + }; + t[RGBA32F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [16], + type: [FLOAT] + }; + t[RGBA8UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB10_A2UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_SHORT] + }; + t[RGBA16I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [SHORT] + }; + t[RGBA32I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [INT] + }; + t[RGBA32UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [UNSIGNED_INT] + }; + // Sized Internal + t[DEPTH_COMPONENT16] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_SHORT, UNSIGNED_INT] + }; + t[DEPTH_COMPONENT24] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[DEPTH_COMPONENT32F] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[DEPTH24_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_24_8] + }; + t[DEPTH32F_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT_32_UNSIGNED_INT_24_8_REV] + }; + Object.keys(t).forEach(function (internalFormat) { + var info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function (bytesPerElement, ndx) { + var type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + var bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0] + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & value - 1) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!utils.isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + var info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return typedArrays.getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE; +} +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + var size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + var colorspaceConversion; + var premultiplyAlpha; + var flipY; + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + fn(); + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (utils.isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D || helper.isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + var sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + var samplers = {}; + Object.keys(samplerOptions).forEach(function (name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults.textureOptions; + internalFormat = internalFormat || RGBA; + var target = options.target || TEXTURE_2D; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + var filtering = canFilter(internalFormat) ? LINEAR : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } +} +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || options.auto === undefined && options.level === undefined; +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_Z]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + var faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + var facesWithNdx = faces.map(function (face, ndx) { + return { + face: face, + ndx: ndx + }; + }); + facesWithNdx.sort(function (a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + var level = options.level || 0; + var width = element.width; + var height = element.height; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // guess the parts + var imgWidth = element.width; + var imgHeight = element.height; + var size; + var slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + var ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, function () { + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }).then(function (imageBitmap) { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + scopedSetPackState(gl, options, function () { + var smallest = Math.min(element.width, element.height); + var largest = Math.max(element.width, element.height); + var depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + var xMult = element.width === largest ? 1 : 0; + var yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (var d = 0; d < depth; ++d) { + var srcX = d * smallest * xMult; + var srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, function () { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} +function noop() {} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + var a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && a.port === location.port && a.protocol === location.protocol; + } else { + var localOrigin = new URL(location.href).origin; + var urlOrigin = new URL(url, location.href).origin; + return urlOrigin === localOrigin; + } +} +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) ? 'anonymous' : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + var img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + var clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + var onError = function onError() { + var msg = "couldn't load image: " + url; + helper.error(msg); + callback(msg, img); + clearEventHandlers(); + }; + var onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + var err; + var bm; + var cb = function cb() { + callback(err, bm); + }; + var options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function (response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function (blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }); + }).then(function (bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + })["catch"](function (e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap || typeof ImageData !== 'undefined' && obj instanceof ImageData || typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement; +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function () { + callback(null, obj); + }); + return obj; + } + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + var color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } else { + gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var img = loadAndUseImage(options.src, options.crossOrigin, function (err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D; + if (target !== TEXTURE_CUBE_MAP) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = 6; + var errors = []; + var faces = getCubeFaceOrder(gl, options); + var imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder(gl).forEach(function (otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D_ARRAY; + if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = urls.length; + var errors = []; + var imgs; // eslint-disable-line + var level = options.level || 0; + var width = options.width; + var height = options.height; + var depth = urls.length; + var firstImage = true; + function uploadImg(slice) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (var s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + var src = img; + var ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var width = options.width; + var height = options.height; + var depth = options.depth; + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + var Type = typedArrays.getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + var bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + var numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + utils.glEnumToString(gl, format); + } + var dimensions; + if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + if (!width && !height && !depth) { + var size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + var elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + var faceSize = numElements / 6 * elementsPerElement; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var offset = faceSize * f.ndx; + var data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + var tex = gl.createTexture(); + var target = options.target || TEXTURE_2D; + var width = options.width || 1; + var height = options.height || 1; + var internalFormat = options.internalFormat || RGBA; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } + var src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof src === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || Array.isArray(src) && (typeof src[0] === 'number' || Array.isArray(src[0]) || isArrayBuffer(src[0]))) { + var dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof src[0] === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { + // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type; + var src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || Array.isArray(src) && typeof src[0] === 'number') { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || Array.isArray(src) && typeof src[0] === 'string'; +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + var numDownloading = 0; + var errors = []; + var textures = {}; + var images = {}; + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function () { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + Object.keys(textureOptions).forEach(function (name) { + var options = textureOptions[name]; + var onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function onLoadFn(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + return textures; +} + +/***/ }), + +/***/ "./src/twgl-base.js": +/*!**************************!*\ + !*** ./src/twgl-base.js ***! + \**************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +exports.__esModule = true; +var _twgl = __webpack_require__(/*! ./twgl.js */ "./src/twgl.js"); +Object.keys(_twgl).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _twgl[key]) return; + exports[key] = _twgl[key]; +}); + +/***/ }), + +/***/ "./src/twgl.js": +/*!*********************!*\ + !*** ./src/twgl.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +var _exportNames = { + addExtensionsToContext: true, + getContext: true, + getWebGLContext: true, + resizeCanvasToDisplaySize: true, + setDefaults: true, + attributes: true, + textures: true, + utils: true, + draw: true, + framebuffers: true, + programs: true, + typedarrays: true, + vertexArrays: true +}; +exports.addExtensionsToContext = addExtensionsToContext; +exports.framebuffers = exports.draw = exports.attributes = void 0; +exports.getContext = getContext; +exports.getWebGLContext = getWebGLContext; +exports.programs = void 0; +exports.resizeCanvasToDisplaySize = resizeCanvasToDisplaySize; +exports.setDefaults = setDefaults; +exports.vertexArrays = exports.utils = exports.typedarrays = exports.textures = void 0; +var attributes = _interopRequireWildcard(__webpack_require__(/*! ./attributes.js */ "./src/attributes.js")); +exports.attributes = attributes; +Object.keys(attributes).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === attributes[key]) return; + exports[key] = attributes[key]; +}); +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +exports.textures = textures; +Object.keys(textures).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === textures[key]) return; + exports[key] = textures[key]; +}); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +exports.utils = utils; +Object.keys(utils).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === utils[key]) return; + exports[key] = utils[key]; +}); +var draw = _interopRequireWildcard(__webpack_require__(/*! ./draw.js */ "./src/draw.js")); +exports.draw = draw; +Object.keys(draw).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === draw[key]) return; + exports[key] = draw[key]; +}); +var framebuffers = _interopRequireWildcard(__webpack_require__(/*! ./framebuffers.js */ "./src/framebuffers.js")); +exports.framebuffers = framebuffers; +Object.keys(framebuffers).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === framebuffers[key]) return; + exports[key] = framebuffers[key]; +}); +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +exports.programs = programs; +Object.keys(programs).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === programs[key]) return; + exports[key] = programs[key]; +}); +var typedarrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +exports.typedarrays = typedarrays; +Object.keys(typedarrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === typedarrays[key]) return; + exports[key] = typedarrays[key]; +}); +var vertexArrays = _interopRequireWildcard(__webpack_require__(/*! ./vertex-arrays.js */ "./src/vertex-arrays.js")); +exports.vertexArrays = vertexArrays; +Object.keys(vertexArrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === vertexArrays[key]) return; + exports[key] = vertexArrays[key]; +}); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * The main TWGL module. + * + * For most use cases you shouldn't need anything outside this module. + * Exceptions between the stuff added to twgl-full (v3, m4, primitives) + * + * @module twgl + * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray + * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays + * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo + * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo + * @borrows module:twgl/draw.drawObjectList as drawObjectList + * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo + * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo + * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo + * @borrows module:twgl/programs.createProgramInfo as createProgramInfo + * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo + * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock + * @borrows module:twgl/programs.setUniformBlock as setUniformBlock + * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms + * @borrows module:twgl/programs.setUniforms as setUniforms + * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes + * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray + * @borrows module:twgl/textures.createTexture as createTexture + * @borrows module:twgl/textures.resizeTexture as resizeTexture + * @borrows module:twgl/textures.createTextures as createTextures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + addExtensionsToContext: true +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line + textures.setTextureDefaults_(newDefaults); // eslint-disable-line +} +var prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + utils.glEnumToString(gl, 0); + var ext = gl.getExtension(extensionName); + if (ext) { + var enums = {}; + var fnSuffix = prefixRE.exec(extensionName)[1]; + var enumSuffix = '_' + fnSuffix; + for (var key in ext) { + var value = ext[key]; + var isFunc = typeof value === 'function'; + var suffix = isFunc ? fnSuffix : enumSuffix; + var name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + helper.warn(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function (origFn) { + return function () { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name + }; + utils.glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +var supportedExtensions = ['ANGLE_instanced_arrays', 'EXT_blend_minmax', 'EXT_color_buffer_float', 'EXT_color_buffer_half_float', 'EXT_disjoint_timer_query', 'EXT_disjoint_timer_query_webgl2', 'EXT_frag_depth', 'EXT_sRGB', 'EXT_shader_texture_lod', 'EXT_texture_filter_anisotropic', 'OES_element_index_uint', 'OES_standard_derivatives', 'OES_texture_float', 'OES_texture_float_linear', 'OES_texture_half_float', 'OES_texture_half_float_linear', 'OES_vertex_array_object', 'WEBGL_color_buffer_float', 'WEBGL_compressed_texture_atc', 'WEBGL_compressed_texture_etc1', 'WEBGL_compressed_texture_pvrtc', 'WEBGL_compressed_texture_s3tc', 'WEBGL_compressed_texture_s3tc_srgb', 'WEBGL_depth_texture', 'WEBGL_draw_buffers']; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (var ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + var gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + var names = ["webgl2", "webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + var gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + 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; +} + +// function notPrivate(name) { +// return name[name.length - 1] !== '_'; +// } +// +// function copyPublicProperties(src, dst) { +// Object.keys(src).filter(notPrivate).forEach(function(key) { +// dst[key] = src[key]; +// }); +// return dst; +// } + +/***/ }), + +/***/ "./src/typedarrays.js": +/*!****************************!*\ + !*** ./src/typedarrays.js ***! + \****************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.getGLTypeForTypedArray = getGLTypeForTypedArray; +exports.getGLTypeForTypedArrayType = getGLTypeForTypedArrayType; +exports.getTypedArrayTypeForGLType = getTypedArrayTypeForGLType; +exports.isArrayBuffer = void 0; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader typed array related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.typedArray` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/typedArray + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var glTypeToTypedArray = {}; +{ + var tt = glTypeToTypedArray; + tt[BYTE] = Int8Array; + tt[UNSIGNED_BYTE] = Uint8Array; + tt[SHORT] = Int16Array; + tt[UNSIGNED_SHORT] = Uint16Array; + tt[INT] = Int32Array; + tt[UNSIGNED_INT] = Uint32Array; + tt[FLOAT] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5] = Uint16Array; + tt[HALF_FLOAT] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array; + tt[UNSIGNED_INT_24_8] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArray instanceof Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArray instanceof Int32Array) { + return INT; + } // eslint-disable-line + if (typedArray instanceof Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArray instanceof Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArrayType === Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArrayType === Int32Array) { + return INT; + } // eslint-disable-line + if (typedArrayType === Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArrayType === Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + var CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} +var isArrayBuffer = exports.isArrayBuffer = typeof SharedArrayBuffer !== 'undefined' ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); +} : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; +}; + +/***/ }), + +/***/ "./src/utils.js": +/*!**********************!*\ + !*** ./src/utils.js ***! + \**********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.glEnumToString = void 0; +exports.isWebGL1 = isWebGL1; +exports.isWebGL2 = isWebGL2; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +var glEnumToString = exports.glEnumToString = function () { + var haveEnumsForType = {}; + var enums = {}; + function addEnums(gl) { + var type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (var key in gl) { + if (typeof gl[key] === 'number') { + var existing = enums[gl[key]]; + enums[gl[key]] = existing ? "".concat(existing, " | ").concat(key) : key; + } + } + haveEnumsForType[type] = true; + } + } + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? "0x".concat(value.toString(16)) : value); + }; +}(); + +/***/ }), + +/***/ "./src/vertex-arrays.js": +/*!******************************!*\ + !*** ./src/vertex-arrays.js ***! + \******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createVAOAndSetAttributes = createVAOAndSetAttributes; +exports.createVAOFromBufferInfo = createVAOFromBufferInfo; +exports.createVertexArrayInfo = createVertexArrayInfo; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +var ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function (programInfo) { + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + programs.setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__("./src/twgl-base.js"); +/******/ +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=twgl.js.map \ No newline at end of file diff --git a/dist/6.x/twgl.js.map b/dist/6.x/twgl.js.map new file mode 100644 index 00000000..e037e65d --- /dev/null +++ b/dist/6.x/twgl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"twgl.js","mappings":"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AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASsB,uBAAuBA,CAAC5D,EAAE,EAAE6D,MAAM,EAAE;EAC3C,IAAMC,OAAO,GAAG,CAAC,CAAC;EAClBlF,MAAM,CAACmF,IAAI,CAACF,MAAM,CAAC,CAACG,OAAO,CAAC,UAAS3B,SAAS,EAAE;IAC9C,IAAI,CAACjB,SAAS,CAACiB,SAAS,CAAC,EAAE;MACzB,IAAMzB,KAAK,GAAGiD,MAAM,CAACxB,SAAS,CAAC;MAC/B,IAAM4B,UAAU,GAAGrD,KAAK,CAACsD,MAAM,IAAItD,KAAK,CAACS,IAAI,IAAIT,KAAK,CAACqD,UAAU,IAAK/D,QAAQ,CAACC,YAAY,GAAGkC,SAAU;MACxG,IAAIzB,KAAK,CAACuD,KAAK,EAAE;QACf,IAAI,CAACzB,KAAK,CAACC,OAAO,CAAC/B,KAAK,CAACuD,KAAK,CAAC,IAAI,CAACvG,WAAW,CAAC6E,aAAa,CAAC7B,KAAK,CAACuD,KAAK,CAAC,EAAE;UAC1E,MAAM,IAAIjC,KAAK,CAAC,wCAAwC,CAAC;QAC3D;QACA4B,OAAO,CAACG,UAAU,CAAC,GAAG;UACpBE,KAAK,EAAEvD,KAAK,CAACuD;QACf,CAAC;MACH,CAAC,MAAM;QACL,IAAIC,EAAE;QA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,IAAM4C,QAAQ,GAAGvD,EAAE,CAACsF,kBAAkB,CAAChG,YAAY,EAAEE,WAAW,CAAC;EACjEQ,EAAE,CAACc,UAAU,CAACxB,YAAY,EAAE,IAAI,CAAC;EAEjC,IAAMiG,aAAa,GAAGR,yBAAyB,CAAC/E,EAAE,EAAEkE,MAAM,CAACxD,IAAI,CAAC;EAChE,IAAM8E,aAAa,GAAGjC,QAAQ,GAAGgC,aAAa;EAC9C,IAAMvD,aAAa,GAAGkC,MAAM,CAAClC,aAAa,IAAIkC,MAAM,CAAC3B,IAAI;EACzD;EACA,IAAM6C,WAAW,GAAGI,aAAa,GAAGxD,aAAa;EACjD,IAAIoD,WAAW,GAAG,CAAC,KAAK,CAAC,EAAE;IACzB,MAAM,IAAIlD,KAAK,kBAAAC,MAAA,CAAkBH,aAAa,8BAAAG,MAAA,CAA2BR,MAAM,CAAE,CAAC;EACpF;EACA,OAAOyD,WAAW;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASK,0BAA0BA,CAACzF,EAAE,EAAE6D,MAAM,EAAE6B,aAAa,EAAE;EAC7D,IAAMC,UAAU,GAAG/B,uBAAuB,CAAC5D,EAAE,EAAE6D,MAAM,CAAC;EACtD,IAAM+B,UAAU,GAAGhH,MAAM,CAACiH,MAAM,CAAC,CAAC,CAAC,EAAEH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AAMijB,SAAS,GAAGe,gBAAgB,CAAClB,UAAU,CAACqC,gBAAgB,CAACjrB,IAAI,CAAC;EACpE,IAAI+oB,SAAS,EAAE;IAAA,IAAAmC,qBAAA;IACb,IAAMC,eAAe,GAAGpC,SAAS,CAACtM,KAAK;IACvC9d,EAAE,CAACspB,eAAe,CAAChT,cAAc,EAAEkW,eAAe,EAAEF,gBAAgB,CAAC3rB,MAAM,EAAE2rB,gBAAgB,CAAC5nB,MAAM,IAAI,CAAC,GAAA6nB,qBAAA,GAAED,gBAAgB,CAAC/pB,IAAI,cAAAgqB,qBAAA,cAAAA,qBAAA,GAAID,gBAAgB,CAAC1rB,KAAK,CAAC+qB,UAAU,CAAC;IACtK,OAAO,IAAI;EACb;EACA,OAAO,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASc,eAAeA,CAACzsB,EAAE,EAAEmH,WAAW,EAAEmlB,gBAAgB,EAAE;EAC1D,IAAID,gBAAgB,CAACrsB,EAAE,EAAEmH,WAAW,EAAEmlB,gBAAgB,CAAC,EAAE;IACvDtsB,EAAE,CAAC8E,aAAa,CAACwR,cAAc,EAAE,CAAC,EAAEgW,gBAAgB,CAACJ,OAAO,EAAEI,gBAAgB,CAAC5nB,MAAM,IAAI,CAAC,EAAE4nB,gBAAgB,CAAC/pB,IAAI,IAAI,CAAC,CAAC;EACzH;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASmqB,gBAAgBA,CAACJ,gBAAgB,EAAExc,MAAM,EAAE;EAClD,IAAM+b,OAAO,GAAGS,gBAAgB,CAACT,OAAO;EACxC,KAAK,IAAMxqB,IAAI,IAAIyO,MAAM,EAAE;IACzB,IAAMiO,MAAM,GAAG8N,OAAO,CAACxqB,IAAI,CAAC;IAC5B,IAAI0c,MAAM,EAAE;MACV,IAAM5Z,KAAK,GAAG2L,MAAM,CAACzO,IAAI,CAAC;MAC1B0c,MAAM,CAAC5Z,KAAK,CAAC;IACf;EACF;AACF;AAEA,SAASikB,cAAcA,CAACuE,IAAI,EAAE7c,MAAM,EAAE;EACpC,KAAK,IAAMzO,IAAI,IAAIyO,MAAM,EAAE;IACzB,IAAM8c,IAAI,GAAGD,IAAI,CAACtrB,IAAI,CAAC;IACvB,IAAI,OAAOurB,IAAI,KAAK,UAAU,EAAE;MAC9BA,IAAI,CAAC9c,MAAM,CAACzO,IAAI,CAAC,CAAC;IACpB,CAAC,MAAM;MACL+mB,cAAc,CAACuE,IAAI,CAACtrB,IAAI,CAAC,EAAEyO,MAAM,CAACzO,IAAI,CAAC,CAAC;IAC1C;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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","sources":["webpack://twgl/webpack/universalModuleDefinition","webpack://twgl/./src/attributes.js","webpack://twgl/./src/draw.js","webpack://twgl/./src/framebuffers.js","webpack://twgl/./src/helper.js","webpack://twgl/./src/programs.js","webpack://twgl/./src/textures.js","webpack://twgl/./src/twgl-base.js","webpack://twgl/./src/twgl.js","webpack://twgl/./src/typedarrays.js","webpack://twgl/./src/utils.js","webpack://twgl/./src/vertex-arrays.js","webpack://twgl/webpack/bootstrap","webpack://twgl/webpack/before-startup","webpack://twgl/webpack/startup","webpack://twgl/webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"twgl\"] = factory();\n\telse\n\t\troot[\"twgl\"] = factory();\n})(typeof self !== 'undefined' ? self : this, () => {\nreturn ","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\nconst STATIC_DRAW = 0x88e4;\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst BUFFER_SIZE = 0x8764;\n\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\n\n/**\n * Low level attribute and buffer related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/attributes\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n attribPrefix: \"\",\n};\n\n/**\n * Sets the default attrib prefix\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * var arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * @deprecated see {@link module:twgl.setDefaults}\n * @param {string} prefix prefix for attribs\n * @memberOf module:twgl/attributes\n */\nfunction setAttributePrefix(prefix) {\n defaults.attribPrefix = prefix;\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n}\n\nfunction setBufferFromTypedArray(gl, type, buffer, array, drawType) {\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, array, drawType || STATIC_DRAW);\n}\n\n/**\n * Given typed array creates a WebGLBuffer and copies the typed array\n * into it.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken\n * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`.\n * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`.\n * @return {WebGLBuffer} the created WebGLBuffer\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromTypedArray(gl, typedArray, type, drawType) {\n if (helper.isBuffer(gl, typedArray)) {\n return typedArray;\n }\n type = type || ARRAY_BUFFER;\n const buffer = gl.createBuffer();\n setBufferFromTypedArray(gl, type, buffer, typedArray, drawType);\n return buffer;\n}\n\nfunction isIndices(name) {\n return name === \"indices\";\n}\n\n// This is really just a guess. Though I can't really imagine using\n// anything else? Maybe for some compression?\nfunction getNormalizationForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return true; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line\n return false;\n}\n\nfunction getArray(array) {\n return array.length ? array : array.data;\n}\n\nconst texcoordRE = /coord|texture/i;\nconst colorRE = /color|colour/i;\n\nfunction guessNumComponentsFromName(name, length) {\n let numComponents;\n if (texcoordRE.test(name)) {\n numComponents = 2;\n } else if (colorRE.test(name)) {\n numComponents = 4;\n } else {\n numComponents = 3; // position, normals, indices ...\n }\n\n if (length % numComponents > 0) {\n throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`);\n }\n\n return numComponents;\n}\n\nfunction getNumComponents(array, arrayName, numValues) {\n return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length);\n}\n\nfunction makeTypedArray(array, name) {\n if (typedArrays.isArrayBuffer(array)) {\n return array;\n }\n\n if (typedArrays.isArrayBuffer(array.data)) {\n return array.data;\n }\n\n if (Array.isArray(array)) {\n array = {\n data: array,\n };\n }\n\n let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined;\n if (!Type) {\n if (isIndices(name)) {\n Type = Uint16Array;\n } else {\n Type = Float32Array;\n }\n }\n return new Type(array.data);\n}\n\nfunction glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? glTypeOrTypedArrayCtor\n : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT;\n}\n\nfunction typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor)\n : glTypeOrTypedArrayCtor || Float32Array;\n}\n\nfunction attribBufferFromBuffer(gl, array/*, arrayName */) {\n return {\n buffer: array.buffer,\n numValues: 2 * 3 * 4, // safely divided by 2, 3, 4\n type: glTypeFromGLTypeOrTypedArrayType(array.type),\n arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type),\n };\n}\n\nfunction attribBufferFromSize(gl, array/*, arrayName*/) {\n const numValues = array.data || array;\n const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type);\n const numBytes = numValues * arrayType.BYTES_PER_ELEMENT;\n const buffer = gl.createBuffer();\n gl.bindBuffer(ARRAY_BUFFER, buffer);\n gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW);\n return {\n buffer,\n numValues,\n type: typedArrays.getGLTypeForTypedArrayType(arrayType),\n arrayType,\n };\n}\n\nfunction attribBufferFromArrayLike(gl, array, arrayName) {\n const typedArray = makeTypedArray(array, arrayName);\n return {\n arrayType: typedArray.constructor,\n buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType),\n type: typedArrays.getGLTypeForTypedArray(typedArray),\n numValues: 0,\n };\n}\n\n/**\n * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer\n * for the attribute.\n *\n * @typedef {Object} AttribInfo\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {number} [numComponents] the number of components for this attribute.\n * @property {number} [size] synonym for `numComponents`.\n * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT`\n * @property {boolean} [normalize] whether or not to normalize the data. Default = false\n * @property {number} [offset] offset into buffer in bytes. Default = 0\n * @property {number} [stride] the stride in bytes per element. Default = 0\n * @property {number} [divisor] the divisor in instances. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor\n */\n\n/**\n * Use this type of array spec when TWGL can't guess the type or number of components of an array\n * @typedef {Object} FullArraySpec\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type.\n * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array.\n * If `coord` is in the name assumes `numComponents = 2`.\n * If `color` is in the name assumes `numComponents = 4`.\n * otherwise assumes `numComponents = 3`\n * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number.\n * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`).\n * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`.\n * @property {number} [size] synonym for `numComponents`.\n * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false.\n * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0\n * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0\n * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix.\n * @property {string} [name] synonym for `attrib`.\n * @property {string} [attribName] synonym for `attrib`.\n * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer\n * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo`\n * to provide this. Example:\n *\n * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, {\n * position: [1, 2, 3, ... ],\n * });\n * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, {\n * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1\n * });\n *\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * An individual array in {@link module:twgl.Arrays}\n *\n * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView`\n * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will\n * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer.\n *\n * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec\n * @memberOf module:twgl\n */\n\n/**\n * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your\n * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}.\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * Objects with various fields. See {@link module:twgl.FullArraySpec}.\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * @typedef {Object.} Arrays\n * @memberOf module:twgl\n */\n\n\n/**\n * Creates a set of attribute data and WebGLBuffers from set of arrays\n *\n * Given\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * returns something like\n *\n * var attribs = {\n * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, },\n * };\n *\n * notes:\n *\n * * Arrays can take various forms\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * @param {WebGLRenderingContext} gl The webgl rendering context.\n * @param {module:twgl.Arrays} arrays The arrays\n * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from\n * This lets you share buffers. Any arrays you supply will override\n * the buffers from srcBufferInfo.\n * @return {Object.} the attribs\n * @memberOf module:twgl/attributes\n */\nfunction createAttribsFromArrays(gl, arrays) {\n const attribs = {};\n Object.keys(arrays).forEach(function(arrayName) {\n if (!isIndices(arrayName)) {\n const array = arrays[arrayName];\n const attribName = array.attrib || array.name || array.attribName || (defaults.attribPrefix + arrayName);\n if (array.value) {\n if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) {\n throw new Error('array.value is not array or typedarray');\n }\n attribs[attribName] = {\n value: array.value,\n };\n } else {\n let fn;\n if (array.buffer && array.buffer instanceof WebGLBuffer) {\n fn = attribBufferFromBuffer;\n } else if (typeof array === \"number\" || typeof array.data === \"number\") {\n fn = attribBufferFromSize;\n } else {\n fn = attribBufferFromArrayLike;\n }\n const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName);\n const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType);\n const numComponents = getNumComponents(array, arrayName, numValues);\n attribs[attribName] = {\n buffer: buffer,\n numComponents: numComponents,\n type: type,\n normalize: normalization,\n stride: array.stride || 0,\n offset: array.offset || 0,\n divisor: array.divisor === undefined ? undefined : array.divisor,\n drawType: array.drawType,\n };\n }\n }\n });\n gl.bindBuffer(ARRAY_BUFFER, null);\n return attribs;\n}\n\n/**\n * Sets the contents of a buffer attached to an attribInfo\n *\n * This is helper function to dynamically update a buffer.\n *\n * Let's say you make a bufferInfo\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * And you want to dynamically update the positions. You could do this\n *\n * // assuming arrays.position has already been updated with new data.\n * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position);\n *\n * @param {WebGLRenderingContext} gl\n * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix\n * the name of the attribute will include the prefix.\n * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything\n * else will have to be converted to a typed array before it can be used by WebGL. During init time that\n * inefficiency is usually not important but if you're updating data dynamically best to be efficient.\n * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer\n * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView`\n * for the portion of the array you want to use.\n *\n * var someArray = new Float32Array(1000); // an array with 1000 floats\n * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray\n *\n * Now you can pass `someSubArray` into setAttribInfoBufferFromArray`\n * @memberOf module:twgl/attributes\n */\nfunction setAttribInfoBufferFromArray(gl, attribInfo, array, offset) {\n array = makeTypedArray(array);\n if (offset !== undefined) {\n gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer);\n gl.bufferSubData(ARRAY_BUFFER, offset, array);\n } else {\n setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType);\n }\n}\n\nfunction getBytesPerValueForGLType(gl, type) {\n if (type === BYTE) return 1; // eslint-disable-line\n if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line\n if (type === SHORT) return 2; // eslint-disable-line\n if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line\n if (type === INT) return 4; // eslint-disable-line\n if (type === UNSIGNED_INT) return 4; // eslint-disable-line\n if (type === FLOAT) return 4; // eslint-disable-line\n return 0;\n}\n\n// Tries to get the number of elements from a set of arrays.\nconst positionKeys = ['position', 'positions', 'a_position'];\nfunction getNumElementsFromNonIndexedArrays(arrays) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in arrays) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(arrays)[0];\n }\n const array = arrays[key];\n const length = getArray(array).length;\n if (length === undefined) {\n return 1; // There's no arrays\n }\n const numComponents = getNumComponents(array, key);\n const numElements = length / numComponents;\n if (length % numComponents > 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\nfunction getNumElementsFromAttributes(gl, attribs) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in attribs) {\n break;\n }\n key = defaults.attribPrefix + key;\n if (key in attribs) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(attribs)[0];\n }\n const attrib = attribs[key];\n if (!attrib.buffer) {\n return 1; // There's no buffer\n }\n gl.bindBuffer(ARRAY_BUFFER, attrib.buffer);\n const numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE);\n gl.bindBuffer(ARRAY_BUFFER, null);\n\n const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type);\n const totalElements = numBytes / bytesPerValue;\n const numComponents = attrib.numComponents || attrib.size;\n // TODO: check stride\n const numElements = totalElements / numComponents;\n if (numElements % 1 !== 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\n/**\n * @typedef {Object} BufferInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist.\n * @property {Object.} [attribs] The attribs appropriate to call `setAttributes`\n * @memberOf module:twgl\n */\n\n/**\n * Creates a BufferInfo from an object of arrays.\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * Given an object like\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * Creates an BufferInfo like this\n *\n * bufferInfo = {\n * numElements: 4, // or whatever the number of elements is\n * indices: WebGLBuffer, // this property will not exist if there are no indices\n * attribs: {\n * position: { buffer: WebGLBuffer, numComponents: 3, },\n * normal: { buffer: WebGLBuffer, numComponents: 3, },\n * texcoord: { buffer: WebGLBuffer, numComponents: 2, },\n * },\n * };\n *\n * The properties of arrays can be JavaScript arrays in which case the number of components\n * will be guessed.\n *\n * var arrays = {\n * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0],\n * texcoord: [0, 0, 0, 1, 1, 0, 1, 1],\n * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],\n * indices: [0, 1, 2, 1, 2, 3],\n * };\n *\n * They can also be TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n *\n * Or AugmentedTypedArrays\n *\n * var positions = createAugmentedTypedArray(3, 4);\n * var texcoords = createAugmentedTypedArray(2, 4);\n * var normals = createAugmentedTypedArray(3, 4);\n * var indices = createAugmentedTypedArray(3, 2, Uint16Array);\n *\n * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]);\n * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]);\n * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\n * indices.push([0, 1, 2, 1, 2, 3]);\n *\n * var arrays = {\n * position: positions,\n * texcoord: texcoords,\n * normal: normals,\n * indices: indices,\n * };\n *\n * For the last example it is equivalent to\n *\n * var bufferInfo = {\n * attribs: {\n * position: { numComponents: 3, buffer: gl.createBuffer(), },\n * texcoord: { numComponents: 2, buffer: gl.createBuffer(), },\n * normal: { numComponents: 3, buffer: gl.createBuffer(), },\n * },\n * indices: gl.createBuffer(),\n * numElements: 6,\n * };\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.normal.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices);\n * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.Arrays} arrays Your data\n * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing\n * buffer info to start from. WebGLBuffers etc specified\n * in the srcBufferInfo will be used in a new BufferInfo\n * with any arrays specified overriding the ones in\n * srcBufferInfo.\n * @return {module:twgl.BufferInfo} A BufferInfo\n * @memberOf module:twgl/attributes\n */\nfunction createBufferInfoFromArrays(gl, arrays, srcBufferInfo) {\n const newAttribs = createAttribsFromArrays(gl, arrays);\n const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {});\n bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs);\n const indices = arrays.indices;\n if (indices) {\n const newIndices = makeTypedArray(indices, \"indices\");\n bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER);\n bufferInfo.numElements = newIndices.length;\n bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices);\n } else if (!bufferInfo.numElements) {\n bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs);\n }\n\n return bufferInfo;\n}\n\n/**\n * Creates a buffer from an array, typed array, or array spec\n *\n * Given something like this\n *\n * [1, 2, 3],\n *\n * or\n *\n * new Uint16Array([1,2,3]);\n *\n * or\n *\n * {\n * data: [1, 2, 3],\n * type: Uint8Array,\n * }\n *\n * returns a WebGLBuffer that contains the given data.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.ArraySpec} array an array, typed array, or array spec.\n * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise.\n * @return {WebGLBuffer} a WebGLBuffer containing the data in array.\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromArray(gl, array, arrayName) {\n const type = arrayName === \"indices\" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER;\n const typedArray = makeTypedArray(array, arrayName);\n return createBufferFromTypedArray(gl, typedArray, type);\n}\n\n/**\n * Creates buffers from arrays or typed arrays\n *\n * Given something like this\n *\n * var arrays = {\n * positions: [1, 2, 3],\n * normals: [0, 0, 1],\n * }\n *\n * returns something like\n *\n * buffers = {\n * positions: WebGLBuffer,\n * normals: WebGLBuffer,\n * }\n *\n * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.Arrays} arrays\n * @return {Object} returns an object with one WebGLBuffer per array\n * @memberOf module:twgl/attributes\n */\nfunction createBuffersFromArrays(gl, arrays) {\n const buffers = { };\n Object.keys(arrays).forEach(function(key) {\n buffers[key] = createBufferFromArray(gl, arrays[key], key);\n });\n\n // Ugh!\n if (arrays.indices) {\n buffers.numElements = arrays.indices.length;\n buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices');\n } else {\n buffers.numElements = getNumElementsFromNonIndexedArrays(arrays);\n }\n\n return buffers;\n}\n\nexport {\n createAttribsFromArrays,\n createBuffersFromArrays,\n createBufferFromArray,\n createBufferFromTypedArray,\n createBufferInfoFromArrays,\n setAttribInfoBufferFromArray,\n\n setAttributePrefix,\n\n setDefaults as setAttributeDefaults_,\n getNumComponents as getNumComponents_,\n getArray as getArray_,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\nconst TRIANGLES = 0x0004;\nconst UNSIGNED_SHORT = 0x1403;\n\n/**\n * Drawing related functions\n *\n * For backward compatibility they are available at both `twgl.draw` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/draw\n */\n\n/**\n * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate\n *\n * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself\n * but calling this means if you switch from indexed data to non-indexed\n * data you don't have to remember to update your draw call.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or\n * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES`\n * @param {number} [count] An optional count. Defaults to bufferInfo.numElements\n * @param {number} [offset] An optional offset. Defaults to 0.\n * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called\n * @memberOf module:twgl/draw\n */\nfunction drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) {\n type = type === undefined ? TRIANGLES : type;\n const indices = bufferInfo.indices;\n const elementType = bufferInfo.elementType;\n const numElements = count === undefined ? bufferInfo.numElements : count;\n offset = offset === undefined ? 0 : offset;\n if (elementType || indices) {\n if (instanceCount !== undefined) {\n gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount);\n } else {\n gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset);\n }\n } else {\n if (instanceCount !== undefined) {\n gl.drawArraysInstanced(type, offset, numElements, instanceCount);\n } else {\n gl.drawArrays(type, offset, numElements);\n }\n }\n}\n\n/**\n * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}.\n *\n * You need either a `BufferInfo` or a `VertexArrayInfo`.\n *\n * @typedef {Object} DrawObject\n * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true`\n * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc...\n * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays}\n * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @property {Object} uniforms The values for the uniforms.\n * You can pass multiple objects by putting them in an array. For example\n *\n * var sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * var localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * var drawObj = {\n * ...\n * uniforms: [sharedUniforms, localUniforms],\n * };\n *\n * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0.\n * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements.\n * @property {number} [instanceCount] the number of instances. Defaults to undefined.\n * @memberOf module:twgl\n */\n\n/**\n * Draws a list of objects\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {DrawObject[]} objectsToDraw an array of objects to draw.\n * @memberOf module:twgl/draw\n */\nfunction drawObjectList(gl, objectsToDraw) {\n let lastUsedProgramInfo = null;\n let lastUsedBufferInfo = null;\n\n objectsToDraw.forEach(function(object) {\n if (object.active === false) {\n return;\n }\n\n const programInfo = object.programInfo;\n const bufferInfo = object.vertexArrayInfo || object.bufferInfo;\n let bindBuffers = false;\n const type = object.type === undefined ? TRIANGLES : object.type;\n\n if (programInfo !== lastUsedProgramInfo) {\n lastUsedProgramInfo = programInfo;\n gl.useProgram(programInfo.program);\n\n // We have to rebind buffers when changing programs because we\n // only bind buffers the program uses. So if 2 programs use the same\n // bufferInfo but the 1st one uses only positions the when the\n // we switch to the 2nd one some of the attributes will not be on.\n bindBuffers = true;\n }\n\n // Setup all the needed attributes.\n if (bindBuffers || bufferInfo !== lastUsedBufferInfo) {\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n lastUsedBufferInfo = bufferInfo;\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n }\n\n // Set the uniforms.\n programs.setUniforms(programInfo, object.uniforms);\n\n // Draw\n drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount);\n });\n\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n}\n\nexport {\n drawBufferInfo,\n drawObjectList,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\n\n/**\n * Framebuffer related functions\n *\n * For backward compatibility they are available at both `twgl.framebuffer` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/framebuffers\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst FRAMEBUFFER = 0x8d40;\nconst RENDERBUFFER = 0x8d41;\nconst TEXTURE_2D = 0x0de1;\n\nconst UNSIGNED_BYTE = 0x1401;\n\n/* PixelFormat */\nconst DEPTH_COMPONENT = 0x1902;\nconst RGBA = 0x1908;\nconst DEPTH_COMPONENT24 = 0x81a6;\nconst DEPTH_COMPONENT32F = 0x8cac;\nconst DEPTH24_STENCIL8 = 0x88f0;\nconst DEPTH32F_STENCIL8 = 0x8cad;\n\n/* Framebuffer Object. */\nconst RGBA4 = 0x8056;\nconst RGB5_A1 = 0x8057;\nconst RGB565 = 0x8D62;\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst STENCIL_INDEX = 0x1901;\nconst STENCIL_INDEX8 = 0x8D48;\nconst DEPTH_STENCIL = 0x84F9;\nconst COLOR_ATTACHMENT0 = 0x8CE0;\nconst DEPTH_ATTACHMENT = 0x8D00;\nconst STENCIL_ATTACHMENT = 0x8D20;\nconst DEPTH_STENCIL_ATTACHMENT = 0x821A;\n\n/* TextureWrapMode */\nconst CLAMP_TO_EDGE = 0x812F;\n\n/* TextureMagFilter */\nconst LINEAR = 0x2601;\n\n/**\n * The options for a framebuffer attachment.\n *\n * Note: For a `format` that is a texture include all the texture\n * options from {@link module:twgl.TextureOptions} for example\n * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions}\n * `auto` defaults to `false` for attachment textures but `min` and `mag` default\n * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE`\n *\n * @typedef {Object} AttachmentOptions\n * @property {number} [attachmentPoint] The attachment point. Defaults\n * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type\n * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending\n * on the format or attachment type.\n * @property {number} [format] The format. If one of `gl.RGBA4`,\n * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`,\n * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a\n * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA`\n * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`.\n * @property {number} [target] The texture target for `gl.framebufferTexture2D`.\n * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps.\n * @property {number} [samples] The number of samples. Default = 1\n * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0.\n * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined.\n * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D`\n * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture.\n * If provided will attach this Object. This allows you to share\n * attachments across framebuffers.\n * @memberOf module:twgl\n * @mixes module:twgl.TextureOptions\n */\n\nconst defaultAttachments = [\n { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, },\n { format: DEPTH_STENCIL, },\n];\n\nconst attachmentsByFormat = {};\nattachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\n\nfunction getAttachmentPointForFormat(format, internalFormat) {\n return attachmentsByFormat[format] || attachmentsByFormat[internalFormat];\n}\n\nconst renderbufferFormats = {};\nrenderbufferFormats[RGBA4] = true;\nrenderbufferFormats[RGB5_A1] = true;\nrenderbufferFormats[RGB565] = true;\nrenderbufferFormats[DEPTH_STENCIL] = true;\nrenderbufferFormats[DEPTH_COMPONENT16] = true;\nrenderbufferFormats[STENCIL_INDEX] = true;\nrenderbufferFormats[STENCIL_INDEX8] = true;\n\nfunction isRenderbufferFormat(format) {\n return renderbufferFormats[format];\n}\n\nconst MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32\n\nfunction isColorAttachmentPoint(attachmentPoint) {\n return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS;\n}\n\n/**\n * @typedef {Object} FramebufferInfo\n * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo\n * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}.\n * @property {number} width The width of the framebuffer and its attachments\n * @property {number} height The width of the framebuffer and its attachments\n * @memberOf module:twgl\n */\n\n/**\n * Creates a framebuffer and attachments.\n *\n * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer.\n * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`.\n * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers\n * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * Passing in a specific size\n *\n * const width = 256;\n * const height = 256;\n * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height);\n *\n * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`.\n * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6).\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an\n * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @return {module:twgl.FramebufferInfo} the framebuffer and attachments.\n * @memberOf module:twgl/framebuffers\n */\nfunction createFramebufferInfo(gl, attachments, width, height) {\n const target = FRAMEBUFFER;\n const fb = gl.createFramebuffer();\n gl.bindFramebuffer(target, fb);\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n attachments = attachments || defaultAttachments;\n const usedColorAttachmentsPoints = [];\n const framebufferInfo = {\n framebuffer: fb,\n attachments: [],\n width: width,\n height: height,\n };\n\n attachments.forEach(function(attachmentOptions, i) {\n let attachment = attachmentOptions.attachment;\n const samples = attachmentOptions.samples;\n const format = attachmentOptions.format;\n let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat);\n if (!attachmentPoint) {\n attachmentPoint = COLOR_ATTACHMENT0 + i;\n }\n if (isColorAttachmentPoint(attachmentPoint)) {\n usedColorAttachmentsPoints.push(attachmentPoint);\n }\n if (!attachment) {\n if (samples !== undefined || isRenderbufferFormat(format)) {\n attachment = gl.createRenderbuffer();\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else {\n const textureOptions = Object.assign({}, attachmentOptions);\n textureOptions.width = width;\n textureOptions.height = height;\n if (textureOptions.auto === undefined) {\n textureOptions.auto = false;\n textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR;\n textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR;\n textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE;\n textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE;\n }\n attachment = textures.createTexture(gl, textureOptions);\n }\n }\n if (helper.isRenderbuffer(gl, attachment)) {\n gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment);\n } else if (helper.isTexture(gl, attachment)) {\n if (attachmentOptions.layer !== undefined) {\n gl.framebufferTextureLayer(\n target,\n attachmentPoint,\n attachment,\n attachmentOptions.level || 0,\n attachmentOptions.layer);\n } else {\n gl.framebufferTexture2D(\n target,\n attachmentPoint,\n attachmentOptions.target || TEXTURE_2D,\n attachment,\n attachmentOptions.level || 0);\n }\n } else {\n throw new Error('unknown attachment type');\n }\n framebufferInfo.attachments.push(attachment);\n });\n if (gl.drawBuffers) {\n gl.drawBuffers(usedColorAttachmentsPoints);\n }\n return framebufferInfo;\n}\n\n/**\n * Resizes the attachments of a framebuffer.\n *\n * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo}\n * because TWGL has no idea the format/type of each attachment.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments\n * twgl.resizeFramebufferInfo(gl, fbi);\n * }\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments to match\n * twgl.resizeFramebufferInfo(gl, fbi, attachments);\n * }\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @memberOf module:twgl/framebuffers\n */\nfunction resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) {\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n framebufferInfo.width = width;\n framebufferInfo.height = height;\n attachments = attachments || defaultAttachments;\n attachments.forEach(function(attachmentOptions, ndx) {\n const attachment = framebufferInfo.attachments[ndx];\n const format = attachmentOptions.format;\n const samples = attachmentOptions.samples;\n if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) {\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else if (helper.isTexture(gl, attachment)) {\n textures.resizeTexture(gl, attachment, attachmentOptions, width, height);\n } else {\n throw new Error('unknown attachment type');\n }\n });\n}\n\n/**\n * Binds a framebuffer\n *\n * This function pretty much solely exists because I spent hours\n * trying to figure out why something I wrote wasn't working only\n * to realize I forget to set the viewport dimensions.\n * My hope is this function will fix that.\n *\n * It is effectively the same as\n *\n * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer);\n * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height);\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * If falsy will bind the canvas.\n * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used.\n * @memberOf module:twgl/framebuffers\n */\n\nfunction bindFramebufferInfo(gl, framebufferInfo, target) {\n target = target || FRAMEBUFFER;\n if (framebufferInfo) {\n gl.bindFramebuffer(target, framebufferInfo.framebuffer);\n gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height);\n } else {\n gl.bindFramebuffer(target, null);\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n}\n\nexport {\n bindFramebufferInfo,\n createFramebufferInfo,\n resizeFramebufferInfo,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/* eslint no-console: \"off\" */\n\n/**\n * Copy named properties\n *\n * @param {string[]} names names of properties to copy\n * @param {object} src object to copy properties from\n * @param {object} dst object to copy properties to\n * @private\n */\nfunction copyNamedProperties(names, src, dst) {\n names.forEach(function(name) {\n const value = src[name];\n if (value !== undefined) {\n dst[name] = value;\n }\n });\n}\n\n/**\n * Copies properties from source to dest only if a matching key is in dest\n *\n * @param {Object.} src the source\n * @param {Object.} dst the dest\n * @private\n */\nfunction copyExistingProperties(src, dst) {\n Object.keys(dst).forEach(function(key) {\n if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */\n dst[key] = src[key];\n }\n });\n}\n\nfunction error(...args) {\n console.error(...args);\n}\n\nfunction warn(...args) {\n console.warn(...args);\n}\n\nconst isTypeWeakMaps = new Map();\n\nfunction isType(object, type) {\n if (!object || typeof object !== 'object') {\n return false;\n }\n let weakMap = isTypeWeakMaps.get(type);\n if (!weakMap) {\n weakMap = new WeakMap();\n isTypeWeakMaps.set(type, weakMap);\n }\n let isOfType = weakMap.get(object);\n if (isOfType === undefined) {\n const s = Object.prototype.toString.call(object);\n isOfType = s.substring(8, s.length - 1) === type;\n weakMap.set(object, isOfType);\n }\n return isOfType;\n}\n\nfunction isBuffer(gl, t) {\n return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer');\n}\n\nfunction isRenderbuffer(gl, t) {\n return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer');\n}\n\nfunction isShader(gl, t) {\n return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader');\n}\n\nfunction isTexture(gl, t) {\n return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture');\n}\n\nfunction isSampler(gl, t) {\n return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler');\n}\n\nexport {\n copyExistingProperties,\n copyNamedProperties,\n error,\n warn,\n isBuffer,\n isRenderbuffer,\n isShader,\n isTexture,\n isSampler,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level shader program related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.programs` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/programs\n */\n\nconst error = helper.error;\nconst warn = helper.warn;\nfunction getElementById(id) {\n return (typeof document !== 'undefined' && document.getElementById)\n ? document.getElementById(id)\n : null;\n}\n\nconst TEXTURE0 = 0x84c0;\nconst DYNAMIC_DRAW = 0x88e8;\n\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst UNIFORM_BUFFER = 0x8a11;\nconst TRANSFORM_FEEDBACK_BUFFER = 0x8c8e;\n\nconst TRANSFORM_FEEDBACK = 0x8e22;\n\nconst COMPILE_STATUS = 0x8b81;\nconst LINK_STATUS = 0x8b82;\nconst FRAGMENT_SHADER = 0x8b30;\nconst VERTEX_SHADER = 0x8b31;\nconst SEPARATE_ATTRIBS = 0x8c8d;\n\nconst ACTIVE_UNIFORMS = 0x8b86;\nconst ACTIVE_ATTRIBUTES = 0x8b89;\nconst TRANSFORM_FEEDBACK_VARYINGS = 0x8c83;\nconst ACTIVE_UNIFORM_BLOCKS = 0x8a36;\nconst UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44;\nconst UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46;\nconst UNIFORM_BLOCK_DATA_SIZE = 0x8a40;\nconst UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43;\n\nconst FLOAT = 0x1406;\nconst FLOAT_VEC2 = 0x8B50;\nconst FLOAT_VEC3 = 0x8B51;\nconst FLOAT_VEC4 = 0x8B52;\nconst INT = 0x1404;\nconst INT_VEC2 = 0x8B53;\nconst INT_VEC3 = 0x8B54;\nconst INT_VEC4 = 0x8B55;\nconst BOOL = 0x8B56;\nconst BOOL_VEC2 = 0x8B57;\nconst BOOL_VEC3 = 0x8B58;\nconst BOOL_VEC4 = 0x8B59;\nconst FLOAT_MAT2 = 0x8B5A;\nconst FLOAT_MAT3 = 0x8B5B;\nconst FLOAT_MAT4 = 0x8B5C;\nconst SAMPLER_2D = 0x8B5E;\nconst SAMPLER_CUBE = 0x8B60;\nconst SAMPLER_3D = 0x8B5F;\nconst SAMPLER_2D_SHADOW = 0x8B62;\nconst FLOAT_MAT2x3 = 0x8B65;\nconst FLOAT_MAT2x4 = 0x8B66;\nconst FLOAT_MAT3x2 = 0x8B67;\nconst FLOAT_MAT3x4 = 0x8B68;\nconst FLOAT_MAT4x2 = 0x8B69;\nconst FLOAT_MAT4x3 = 0x8B6A;\nconst SAMPLER_2D_ARRAY = 0x8DC1;\nconst SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;\nconst SAMPLER_CUBE_SHADOW = 0x8DC5;\nconst UNSIGNED_INT = 0x1405;\nconst UNSIGNED_INT_VEC2 = 0x8DC6;\nconst UNSIGNED_INT_VEC3 = 0x8DC7;\nconst UNSIGNED_INT_VEC4 = 0x8DC8;\nconst INT_SAMPLER_2D = 0x8DCA;\nconst INT_SAMPLER_3D = 0x8DCB;\nconst INT_SAMPLER_CUBE = 0x8DCC;\nconst INT_SAMPLER_2D_ARRAY = 0x8DCF;\nconst UNSIGNED_INT_SAMPLER_2D = 0x8DD2;\nconst UNSIGNED_INT_SAMPLER_3D = 0x8DD3;\nconst UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;\nconst UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;\n\nconst TEXTURE_2D = 0x0DE1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806F;\nconst TEXTURE_2D_ARRAY = 0x8C1A;\n\nconst typeMap = {};\n\n/**\n * Returns the corresponding bind point for a given sampler type\n * @private\n */\nfunction getBindPointForSamplerType(gl, type) {\n return typeMap[type].bindPoint;\n}\n\n// This kind of sucks! If you could compose functions as in `var fn = gl[name];`\n// this code could be a lot smaller but that is sadly really slow (T_T)\n\nfunction floatSetter(gl, location) {\n return function(v) {\n gl.uniform1f(location, v);\n };\n}\n\nfunction floatArraySetter(gl, location) {\n return function(v) {\n gl.uniform1fv(location, v);\n };\n}\n\nfunction floatVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2fv(location, v);\n };\n}\n\nfunction floatVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3fv(location, v);\n };\n}\n\nfunction floatVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4fv(location, v);\n };\n}\n\nfunction intSetter(gl, location) {\n return function(v) {\n gl.uniform1i(location, v);\n };\n}\n\nfunction intArraySetter(gl, location) {\n return function(v) {\n gl.uniform1iv(location, v);\n };\n}\n\nfunction intVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2iv(location, v);\n };\n}\n\nfunction intVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3iv(location, v);\n };\n}\n\nfunction intVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4iv(location, v);\n };\n}\n\nfunction uintSetter(gl, location) {\n return function(v) {\n gl.uniform1ui(location, v);\n };\n}\n\nfunction uintArraySetter(gl, location) {\n return function(v) {\n gl.uniform1uiv(location, v);\n };\n}\n\nfunction uintVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2uiv(location, v);\n };\n}\n\nfunction uintVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3uiv(location, v);\n };\n}\n\nfunction uintVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4uiv(location, v);\n };\n}\n\nfunction floatMat2Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2fv(location, false, v);\n };\n}\n\nfunction floatMat3Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3fv(location, false, v);\n };\n}\n\nfunction floatMat4Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4fv(location, false, v);\n };\n}\n\nfunction floatMat23Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x3fv(location, false, v);\n };\n}\n\nfunction floatMat32Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x2fv(location, false, v);\n };\n}\n\nfunction floatMat24Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x4fv(location, false, v);\n };\n}\n\nfunction floatMat42Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x2fv(location, false, v);\n };\n}\n\nfunction floatMat34Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x4fv(location, false, v);\n };\n}\n\nfunction floatMat43Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x3fv(location, false, v);\n };\n}\n\nfunction samplerSetter(gl, type, unit, location) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n return utils.isWebGL2(gl) ? function(textureOrPair) {\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n gl.bindSampler(unit, sampler);\n } : function(texture) {\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n };\n}\n\nfunction samplerArraySetter(gl, type, unit, location, size) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n const units = new Int32Array(size);\n for (let ii = 0; ii < size; ++ii) {\n units[ii] = unit + ii;\n }\n\n return utils.isWebGL2(gl) ? function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(textureOrPair, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.bindSampler(unit, sampler);\n gl.bindTexture(bindPoint, texture);\n });\n } : function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(texture, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n gl.bindTexture(bindPoint, texture);\n });\n };\n}\n\ntypeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, };\ntypeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, };\ntypeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, };\ntypeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, };\ntypeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, };\ntypeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, };\ntypeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, };\ntypeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, };\ntypeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, };\ntypeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, };\ntypeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, };\ntypeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, };\ntypeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, };\ntypeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, };\ntypeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, };\ntypeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, };\ntypeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, };\ntypeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\n\nfunction floatAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n switch (b.value.length) {\n case 4:\n gl.vertexAttrib4fv(index, b.value);\n break;\n case 3:\n gl.vertexAttrib3fv(index, b.value);\n break;\n case 2:\n gl.vertexAttrib2fv(index, b.value);\n break;\n case 1:\n gl.vertexAttrib1fv(index, b.value);\n break;\n default:\n throw new Error('the length of a float constant value must be between 1 and 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribPointer(\n index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction intAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4iv(index, b.value);\n } else {\n throw new Error('The length of an integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction uintAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4uiv(index, b.value);\n } else {\n throw new Error('The length of an unsigned integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction matAttribSetter(gl, index, typeInfo) {\n const defaultSize = typeInfo.size;\n const count = typeInfo.count;\n\n return function(b) {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n const numComponents = b.size || b.numComponents || defaultSize;\n const size = numComponents / count;\n const type = b.type || FLOAT;\n const typeInfo = typeMap[type];\n const stride = typeInfo.size * numComponents;\n const normalize = b.normalize || false;\n const offset = b.offset || 0;\n const rowOffset = stride / count;\n for (let i = 0; i < count; ++i) {\n gl.enableVertexAttribArray(index + i);\n gl.vertexAttribPointer(\n index + i, size, type, normalize, stride, offset + rowOffset * i);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index + i, b.divisor || 0);\n }\n }\n };\n}\n\n\n\nconst attrTypeMap = {};\nattrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, };\nattrTypeMap[INT] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, };\nattrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, };\nattrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, };\nattrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, };\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst errorRE = /ERROR:\\s*\\d+:(\\d+)/gi;\nfunction addLineNumbersWithError(src, log = '', lineOffset = 0) {\n // Note: Error message formats are not defined by any spec so this may or may not work.\n const matches = [...log.matchAll(errorRE)];\n const lineNoToErrorMap = new Map(matches.map((m, ndx) => {\n const lineNo = parseInt(m[1]);\n const next = matches[ndx + 1];\n const end = next ? next.index : log.length;\n const msg = log.substring(m.index, end);\n return [lineNo - 1, msg];\n }));\n return src.split('\\n').map((line, lineNo) => {\n const err = lineNoToErrorMap.get(lineNo);\n return `${lineNo + 1 + lineOffset}: ${line}${err ? `\\n\\n^^^ ${err}` : ''}`;\n }).join('\\n');\n}\n\n/**\n * Error Callback\n * @callback ErrorCallback\n * @param {string} msg error message.\n * @param {number} [lineOffset] amount to add to line number\n * @memberOf module:twgl\n */\n\n/**\n * Program Callback\n * @callback ProgramCallback\n * @param {string} [err] error message, falsy if no error\n * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo\n */\n\nconst spaceRE = /^[ \\t]*\\n/;\n\n/**\n * Remove the first end of line because WebGL 2.0 requires\n * #version 300 es\n * as the first line. No whitespace allowed before that line\n * so\n *\n * \n *\n * Has one line before it which is invalid according to GLSL ES 3.00\n *\n * @param {string} shaderSource The source of the shader\n * @returns {{shaderSource: string, lineOffset: number}}\n * @private\n */\nfunction prepShaderSource(shaderSource) {\n let lineOffset = 0;\n if (spaceRE.test(shaderSource)) {\n lineOffset = 1;\n shaderSource = shaderSource.replace(spaceRE, '');\n }\n return {lineOffset, shaderSource};\n}\n\n/**\n * @param {module:twgl.ProgramOptions} progOptions\n * @param {string} msg\n * @return null\n * @private\n */\nfunction reportError(progOptions, msg) {\n progOptions.errorCallback(msg);\n if (progOptions.callback) {\n setTimeout(() => {\n progOptions.callback(`${msg}\\n${progOptions.errors.join('\\n')}`);\n });\n }\n return null;\n}\n\n/**\n * Check Shader status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {number} shaderType The shader type\n * @param {WebGLShader} shader The shader\n * @param {ErrorCallback} [errFn] function to receive error message.\n * @return {string} errors or empty string\n * @private\n */\nfunction checkShaderStatus(gl, shaderType, shader, errFn) {\n errFn = errFn || error;\n // Check the compile status\n const compiled = gl.getShaderParameter(shader, COMPILE_STATUS);\n if (!compiled) {\n // Something went wrong during compilation; get the error\n const lastError = gl.getShaderInfoLog(shader);\n const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader));\n const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\\nError compiling ${utils.glEnumToString(gl, shaderType)}: ${lastError}`;\n errFn(error);\n return error;\n }\n return '';\n}\n\n/**\n * @typedef {Object} FullProgramSpec\n * @property {string[]} shaders the shader source or element ids.\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {Object} ProgramOptions\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * Gets the program options based on all these optional arguments\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in\n * @private\n */\nfunction getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) {\n let transformFeedbackVaryings;\n let transformFeedbackMode;\n let callback;\n if (typeof opt_locations === 'function') {\n opt_errorCallback = opt_locations;\n opt_locations = undefined;\n }\n if (typeof opt_attribs === 'function') {\n opt_errorCallback = opt_attribs;\n opt_attribs = undefined;\n } else if (opt_attribs && !Array.isArray(opt_attribs)) {\n const opt = opt_attribs;\n opt_errorCallback = opt.errorCallback;\n opt_attribs = opt.attribLocations;\n transformFeedbackVaryings = opt.transformFeedbackVaryings;\n transformFeedbackMode = opt.transformFeedbackMode;\n callback = opt.callback;\n }\n\n const errorCallback = opt_errorCallback || error;\n const errors = [];\n const options = {\n errorCallback(msg, ...args) {\n errors.push(msg);\n errorCallback(msg, ...args);\n },\n transformFeedbackVaryings,\n transformFeedbackMode,\n callback,\n errors,\n };\n\n {\n let attribLocations = {};\n if (Array.isArray(opt_attribs)) {\n opt_attribs.forEach(function(attrib, ndx) {\n attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx;\n });\n } else {\n attribLocations = opt_attribs || {};\n }\n options.attribLocations = attribLocations;\n }\n\n return options;\n}\n\nconst defaultShaderType = [\n \"VERTEX_SHADER\",\n \"FRAGMENT_SHADER\",\n];\n\nfunction getShaderTypeFromScriptType(gl, scriptType) {\n if (scriptType.indexOf(\"frag\") >= 0) {\n return FRAGMENT_SHADER;\n } else if (scriptType.indexOf(\"vert\") >= 0) {\n return VERTEX_SHADER;\n }\n return undefined;\n}\n\nfunction deleteProgramAndShaders(gl, program, notThese) {\n const shaders = gl.getAttachedShaders(program);\n for (const shader of shaders) {\n if (notThese.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n gl.deleteProgram(program);\n}\n\nconst wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));\n\nfunction createProgramNoCheck(gl, shaders, programOptions) {\n const program = gl.createProgram();\n const {\n attribLocations,\n transformFeedbackVaryings,\n transformFeedbackMode,\n } = getProgramOptions(programOptions);\n\n for (let ndx = 0; ndx < shaders.length; ++ndx) {\n let shader = shaders[ndx];\n if (typeof shader === 'string') {\n const elem = getElementById(shader);\n const src = elem ? elem.text : shader;\n let type = gl[defaultShaderType[ndx]];\n if (elem && elem.type) {\n type = getShaderTypeFromScriptType(gl, elem.type) || type;\n }\n shader = gl.createShader(type);\n gl.shaderSource(shader, prepShaderSource(src).shaderSource);\n gl.compileShader(shader);\n gl.attachShader(program, shader);\n }\n }\n\n Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib));\n\n {\n let varyings = transformFeedbackVaryings;\n if (varyings) {\n if (varyings.attribs) {\n varyings = varyings.attribs;\n }\n if (!Array.isArray(varyings)) {\n varyings = Object.keys(varyings);\n }\n gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS);\n }\n }\n\n gl.linkProgram(program);\n return program;\n}\n\n/**\n * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the\n * program.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgram(gl, [vs, fs], options);\n * twgl.createProgram(gl, [vs, fs], opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error of a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgram(\n gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {\n // This code is really convoluted, because it may or may not be async\n // Maybe it would be better to have a separate function\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaderSet = new Set(shaders);\n const program = createProgramNoCheck(gl, shaders, progOptions);\n\n function hasErrors(gl, program) {\n const errors = getProgramErrors(gl, program, progOptions.errorCallback);\n if (errors) {\n deleteProgramAndShaders(gl, program, shaderSet);\n }\n return errors;\n }\n\n if (progOptions.callback) {\n waitForProgramLinkCompletionAsync(gl, program).then(() => {\n const errors = hasErrors(gl, program);\n progOptions.callback(errors, errors ? undefined : program);\n });\n return undefined;\n }\n\n return hasErrors(gl, program) ? undefined : program;\n}\n\n/**\n * This only works because the functions it wraps the first 2 arguments\n * are gl and any, followed by things that become programOptions\n * @private\n */\nfunction wrapCallbackFnToAsyncFn(fn) {\n return function(gl, arg1, ...args) {\n return new Promise((resolve, reject) => {\n const programOptions = getProgramOptions(...args);\n programOptions.callback = (err, program) => {\n if (err) {\n reject(err);\n } else {\n resolve(program);\n }\n };\n fn(gl, arg1, programOptions);\n });\n };\n}\n\n/**\n * Same as createProgram but returns a promise\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramAsync(gl, [vs, fs], options);\n * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created program\n * @memberOf module:twgl/programs\n */\nconst createProgramAsync = wrapCallbackFnToAsyncFn(createProgram);\n\n/**\n * Same as createProgramInfo but returns a promise\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created ProgramInfo\n * @memberOf module:twgl/programs\n */\nconst createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo);\n\nasync function waitForProgramLinkCompletionAsync(gl, program) {\n const ext = gl.getExtension('KHR_parallel_shader_compile');\n const checkFn = ext\n ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR)\n : () => true;\n\n let waitTime = 0;\n do {\n await wait(waitTime); // must wait at least once\n waitTime = 1000 / 60;\n } while (!checkFn(gl, program));\n}\n\nasync function waitForAllProgramsLinkCompletionAsync(gl, programs) {\n for (const program of Object.values(programs)) {\n await waitForProgramLinkCompletionAsync(gl, program);\n }\n}\n\n/**\n * Check a program's link status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program Program to check\n * @param {ErrorCallback} [errFn] func for errors\n * @return {string?} errors if program is failed, else undefined\n * @private\n */\nfunction getProgramErrors(gl, program, errFn) {\n errFn = errFn || error;\n // Check the link status\n const linked = gl.getProgramParameter(program, LINK_STATUS);\n if (!linked) {\n // something went wrong with the link\n const lastError = gl.getProgramInfoLog(program);\n errFn(`Error in program linking: ${lastError}`);\n // print any errors from these shaders\n const shaders = gl.getAttachedShaders(program);\n const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn));\n return `${lastError}\\n${errors.filter(_ => _).join('\\n')}`;\n }\n return undefined;\n}\n\n/**\n * Creates a program from 2 script tags.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_options);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderScriptIds Array of ids of the script\n * tags for the shaders. The first is assumed to be the\n * vertex shader, the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromScripts(\n gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaders = [];\n for (const scriptId of shaderScriptIds) {\n const shaderScript = getElementById(scriptId);\n if (!shaderScript) {\n return reportError(progOptions, `unknown script element: ${scriptId}`);\n }\n shaders.push(shaderScript.text);\n }\n return createProgram(gl, shaders, progOptions);\n}\n\n/**\n * Creates a program from 2 sources.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromSource(gl, [vs, fs], opt_options);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromSources(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback);\n}\n\n/**\n * Returns true if attribute/uniform is a reserved/built in\n *\n * It makes no sense to me why GL returns these because it's\n * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation`\n * with names that start with `gl_` (and `webgl_` in WebGL)\n *\n * I can only assume they are there because they might count\n * when computing the number of uniforms/attributes used when you want to\n * know if you are near the limit. That doesn't really make sense\n * to me but the fact that these get returned are in the spec.\n *\n * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or\n * `gl.getActiveAttrib`.\n * @return {bool} true if it's reserved\n * @private\n */\nfunction isBuiltIn(info) {\n const name = info.name;\n return name.startsWith(\"gl_\") || name.startsWith(\"webgl_\");\n}\n\nconst tokenRE = /(\\.|\\[|]|\\w+)/g;\nconst isDigit = s => s >= '0' && s <= '9';\nfunction addSetterToUniformTree(fullPath, setter, node, uniformSetters) {\n const tokens = fullPath.split(tokenRE).filter(s => s !== '');\n let tokenNdx = 0;\n let path = '';\n\n for (;;) {\n const token = tokens[tokenNdx++]; // has to be name or number\n path += token;\n const isArrayIndex = isDigit(token[0]);\n const accessor = isArrayIndex\n ? parseInt(token)\n : token;\n if (isArrayIndex) {\n path += tokens[tokenNdx++]; // skip ']'\n }\n const isLastToken = tokenNdx === tokens.length;\n if (isLastToken) {\n node[accessor] = setter;\n break;\n } else {\n const token = tokens[tokenNdx++]; // has to be . or [\n const isArray = token === '[';\n const child = node[accessor] || (isArray ? [] : {});\n node[accessor] = child;\n node = child;\n uniformSetters[path] = uniformSetters[path] || function(node) {\n return function(value) {\n setUniformTree(node, value);\n };\n }(child);\n path += token;\n }\n }\n}\n\n/**\n * Creates setter functions for all uniforms of a shader\n * program.\n *\n * @see {@link module:twgl.setUniforms}\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @returns {Object.} an object with a setter by name for each uniform\n * @memberOf module:twgl/programs\n */\nfunction createUniformSetters(gl, program) {\n let textureUnit = 0;\n\n /**\n * Creates a setter for a uniform of the given program with it's\n * location embedded in the setter.\n * @param {WebGLProgram} program\n * @param {WebGLUniformInfo} uniformInfo\n * @returns {function} the created setter.\n */\n function createUniformSetter(program, uniformInfo, location) {\n const isArray = uniformInfo.name.endsWith(\"[0]\");\n const type = uniformInfo.type;\n const typeInfo = typeMap[type];\n if (!typeInfo) {\n throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here.\n }\n let setter;\n if (typeInfo.bindPoint) {\n // it's a sampler\n const unit = textureUnit;\n textureUnit += uniformInfo.size;\n if (isArray) {\n setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size);\n } else {\n setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size);\n }\n } else {\n if (typeInfo.arraySetter && isArray) {\n setter = typeInfo.arraySetter(gl, location);\n } else {\n setter = typeInfo.setter(gl, location);\n }\n }\n setter.location = location;\n return setter;\n }\n\n const uniformSetters = {};\n const uniformTree = {};\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n const uniformInfo = gl.getActiveUniform(program, ii);\n if (isBuiltIn(uniformInfo)) {\n continue;\n }\n let name = uniformInfo.name;\n // remove the array suffix.\n if (name.endsWith(\"[0]\")) {\n name = name.substr(0, name.length - 3);\n }\n const location = gl.getUniformLocation(program, uniformInfo.name);\n // the uniform will have no location if it's in a uniform block\n if (location) {\n const setter = createUniformSetter(program, uniformInfo, location);\n uniformSetters[name] = setter;\n addSetterToUniformTree(name, setter, uniformTree, uniformSetters);\n }\n }\n\n return uniformSetters;\n}\n\n/**\n * @typedef {Object} TransformFeedbackInfo\n * @property {number} index index of transform feedback\n * @property {number} type GL type\n * @property {number} size 1 - 4\n * @memberOf module:twgl\n */\n\n/**\n * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo.\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {Object}\n * @memberOf module:twgl\n */\nfunction createTransformFeedbackInfo(gl, program) {\n const info = {};\n const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS);\n for (let ii = 0; ii < numVaryings; ++ii) {\n const varying = gl.getTransformFeedbackVarying(program, ii);\n info[varying.name] = {\n index: ii,\n type: varying.type,\n size: varying.size,\n };\n }\n return info;\n}\n\n/**\n * Binds buffers for transform feedback.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo.\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @memberOf module:twgl\n */\nfunction bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) {\n if (transformFeedbackInfo.transformFeedbackInfo) {\n transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo;\n }\n if (bufferInfo.attribs) {\n bufferInfo = bufferInfo.attribs;\n }\n for (const name in bufferInfo) {\n const varying = transformFeedbackInfo[name];\n if (varying) {\n const buf = bufferInfo[name];\n if (buf.offset) {\n gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size);\n } else {\n gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer);\n }\n }\n }\n}\n\n/**\n * Creates a transform feedback and sets the buffers\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @return {WebGLTransformFeedback} the created transform feedback\n * @memberOf module:twgl\n */\nfunction createTransformFeedback(gl, programInfo, bufferInfo) {\n const tf = gl.createTransformFeedback();\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf);\n gl.useProgram(programInfo.program);\n bindTransformFeedbackInfo(gl, programInfo, bufferInfo);\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null);\n return tf;\n}\n\n/**\n * @typedef {Object} UniformData\n * @property {string} name The name of the uniform\n * @property {number} type The WebGL type enum for this uniform\n * @property {number} size The number of elements for this uniform\n * @property {number} blockNdx The block index this uniform appears in\n * @property {number} offset The byte offset in the block for this uniform's value\n * @memberOf module:twgl\n */\n\n/**\n * The specification for one UniformBlockObject\n *\n * @typedef {Object} BlockSpec\n * @property {number} index The index of the block.\n * @property {number} size The size in bytes needed for the block\n * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices\n * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}.\n * @property {bool} usedByVertexShader Self explanatory\n * @property {bool} usedByFragmentShader Self explanatory\n * @property {bool} used Self explanatory\n * @memberOf module:twgl\n */\n\n/**\n * A `UniformBlockSpec` represents the data needed to create and bind\n * UniformBlockObjects for a given program\n *\n * @typedef {Object} UniformBlockSpec\n * @property {Object.} blockSpecs The BlockSpec for each block by block name\n * @property {UniformData[]} uniformData An array of data for each uniform by uniform index.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a UniformBlockSpec for the given program.\n *\n * A UniformBlockSpec represents the data needed to create and bind\n * UniformBlockObjects\n *\n * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context\n * @param {WebGLProgram} program A WebGLProgram for a successfully linked program\n * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockSpecFromProgram(gl, program) {\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n const uniformData = [];\n const uniformIndices = [];\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n uniformIndices.push(ii);\n uniformData.push({});\n const uniformInfo = gl.getActiveUniform(program, ii);\n uniformData[ii].name = uniformInfo.name;\n }\n\n [\n [ \"UNIFORM_TYPE\", \"type\" ],\n [ \"UNIFORM_SIZE\", \"size\" ], // num elements\n [ \"UNIFORM_BLOCK_INDEX\", \"blockNdx\" ],\n [ \"UNIFORM_OFFSET\", \"offset\", ],\n ].forEach(function(pair) {\n const pname = pair[0];\n const key = pair[1];\n gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) {\n uniformData[ndx][key] = value;\n });\n });\n\n const blockSpecs = {};\n\n const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS);\n for (let ii = 0; ii < numUniformBlocks; ++ii) {\n const name = gl.getActiveUniformBlockName(program, ii);\n const blockSpec = {\n index: gl.getUniformBlockIndex(program, name),\n usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER),\n usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER),\n size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE),\n uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES),\n };\n blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader;\n blockSpecs[name] = blockSpec;\n }\n\n return {\n blockSpecs: blockSpecs,\n uniformData: uniformData,\n };\n}\n\nconst arraySuffixRE = /\\[\\d+\\]\\.$/; // better way to check?\n\nconst pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding;\n\nfunction createUniformBlockUniformSetter(view, isArray, rows, cols) {\n if (isArray || rows) {\n cols = cols || 1;\n const numElements = view.length;\n const totalRows = numElements / 4;\n return function(value) {\n let dst = 0;\n let src = 0;\n for (let row = 0; row < totalRows; ++row) {\n for (let col = 0; col < cols; ++col) {\n view[dst++] = value[src++];\n }\n dst += 4 - cols;\n }\n };\n } else {\n return function(value) {\n if (value.length) {\n view.set(value);\n } else {\n view[0] = value;\n }\n };\n }\n}\n\n/**\n * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values\n * and a corresponding WebGLBuffer to hold those values on the GPU\n *\n * @typedef {Object} UniformBlockInfo\n * @property {string} name The name of the block\n * @property {ArrayBuffer} array The array buffer that contains the uniform values\n * @property {Float32Array} asFloat A float view on the array buffer. This is useful\n * inspecting the contents of the buffer in the debugger.\n * @property {Uint8Array} asUint8t A uint8 view on the array buffer.\n * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering.\n * @property {number} [offset] offset into buffer\n * @property {Object} uniforms A uniform name to ArrayBufferView map.\n * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset\n * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array`\n * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an\n * `Int32Array` view, etc.\n * @property {Object} setters A setter for this uniform.\n * The reason to use setters is elements of arrays are padded to vec4 sizes which\n * means if you want to set an array of 4 floats you'd need to set 16 values\n * (or set elements 0, 4, 8, 12). In other words\n * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])`\n * where as the setter handles just passing in [0, 1, 2, 3] either directly as in\n * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended)\n * or via {@link module:twgl.setBlockUniforms}\n * @memberOf module:twgl\n */\n\n/**\n * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset\n * @typedef {Object} UniformBlockInfoOptions\n * @property {ArrayBuffer} [array] an existing array buffer to use for values\n * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0)\n * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info\n * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above)\n */\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {WebGLProgram} program A WebGLProgram\n * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned\n * from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) {\n const blockSpecs = uniformBlockSpec.blockSpecs;\n const uniformData = uniformBlockSpec.uniformData;\n const blockSpec = blockSpecs[blockName];\n if (!blockSpec) {\n warn(\"no uniform block object named:\", blockName);\n return {\n name: blockName,\n uniforms: {},\n };\n }\n const offset = options.offset ?? 0;\n const array = options.array ?? new ArrayBuffer(blockSpec.size);\n const buffer = options.buffer ?? gl.createBuffer();\n const uniformBufferIndex = blockSpec.index;\n gl.bindBuffer(UNIFORM_BUFFER, buffer);\n if (!options.buffer) {\n gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW);\n }\n gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex);\n\n let prefix = blockName + \".\";\n if (arraySuffixRE.test(prefix)) {\n prefix = prefix.replace(arraySuffixRE, \".\");\n }\n const uniforms = {};\n const setters = {};\n const setterTree = {};\n blockSpec.uniformIndices.forEach(function(uniformNdx) {\n const data = uniformData[uniformNdx];\n let name = data.name;\n if (name.startsWith(prefix)) {\n name = name.substr(prefix.length);\n }\n const isArray = name.endsWith('[0]');\n if (isArray) {\n name = name.substr(0, name.length - 3);\n }\n const typeInfo = typeMap[data.type];\n const Type = typeInfo.Type;\n const byteLength = isArray\n ? pad(typeInfo.size, 16) * data.size\n : typeInfo.size * data.size;\n const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT);\n uniforms[name] = uniformView;\n // Note: I'm not sure what to do here. The original\n // idea was to create TypedArray views into each part\n // of the block. This is useful, for example if you have\n // a block with { mat4: model; mat4 view; mat4 projection; }\n // you'll get a Float32Array for each one suitable for\n // passing to most JS math libraries including twgl's and glMatrix.js.\n //\n // But, if you have a an array of structures, especially if that\n // array is large, you get a whole bunch of TypedArray views.\n // Every one of them has overhead and switching between them all\n // is probably a cache miss. In that case it would really be better\n // to just have one view (asFloat) and have all the setters\n // just reference the correct portion. But, then you can't easily\n // treat a matrix, or a vec4, as a standalone thing like you can\n // with all the views.\n //\n // Another problem with the views is they are not shared. With\n // uniforms you have one set of setters. With UniformBlockInfo\n // you have a set of setters *pre block instance*. That's because\n // TypedArray views can't be mapped to different buffers.\n //\n // My gut right now is if you really want the speed and compactness\n // then you should probably roll your own solution. TWGL's goal\n // here is ease of use as AFAICT there is no simple generic efficient\n // solution.\n const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols);\n setters[name] = setter;\n addSetterToUniformTree(name, setter, setterTree, setters);\n });\n return {\n name: blockName,\n array,\n asFloat: new Float32Array(array), // for debugging\n asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer\n buffer,\n uniforms,\n setters,\n offset: options.bufferOffset ?? offset,\n size: blockSpec.size,\n };\n}\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo}\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfo(gl, programInfo, blockName, options = {}) {\n return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options);\n}\n\n/**\n * Binds a uniform block to the matching uniform block point.\n * Matches by blocks by name so blocks must have the same name not just the same\n * structure.\n *\n * If you have changed any values and you upload the values into the corresponding WebGLBuffer\n * call {@link module:twgl.setUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name\n * no buffer is bound.\n * @memberOf module:twgl/programs\n */\nfunction bindUniformBlock(gl, programInfo, uniformBlockInfo) {\n const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo;\n const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name];\n if (blockSpec) {\n const bufferBindIndex = blockSpec.index;\n gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength);\n return true;\n }\n return false;\n}\n\n/**\n * Uploads the current uniform values to the corresponding WebGLBuffer\n * and binds that buffer to the program's corresponding bind point for the uniform block object.\n *\n * If you haven't changed any values and you only need to bind the uniform block object\n * call {@link module:twgl.bindUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @memberOf module:twgl/programs\n */\nfunction setUniformBlock(gl, programInfo, uniformBlockInfo) {\n if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) {\n gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0);\n }\n}\n\n/**\n * Sets values of a uniform block object\n *\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}.\n * @param {Object.} values A uniform name to value map where the value is correct for the given\n * type of uniform. So for example given a block like\n *\n * uniform SomeBlock {\n * float someFloat;\n * vec2 someVec2;\n * vec3 someVec3Array[2];\n * int someInt;\n * }\n *\n * You can set the values of the uniform block with\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * someFloat: 12.3,\n * someVec2: [1, 2],\n * someVec3Array: [1, 2, 3, 4, 5, 6],\n * someInt: 5,\n * }\n *\n * Arrays can be JavaScript arrays or typed arrays\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Lights {\n * Light lights[2];\n * };\n *\n * // in JavaScript\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices.\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * **IMPORTANT!**, packing in a UniformBlock is unintuitive.\n * For example the actual layout of `someVec3Array` above in memory\n * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values\n * as shown about and copies them, skipping the padding. This might\n * be confusing if you're already familiar with Uniform blocks.\n *\n * If you want to deal with the padding yourself you can access the array\n * buffer views directly. eg:\n *\n * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]);\n *\n * Any name that doesn't match will be ignored\n * @memberOf module:twgl/programs\n */\nfunction setBlockUniforms(uniformBlockInfo, values) {\n const setters = uniformBlockInfo.setters;\n for (const name in values) {\n const setter = setters[name];\n if (setter) {\n const value = values[name];\n setter(value);\n }\n }\n}\n\nfunction setUniformTree(tree, values) {\n for (const name in values) {\n const prop = tree[name];\n if (typeof prop === 'function') {\n prop(values[name]);\n } else {\n setUniformTree(tree[name], values[name]);\n }\n }\n}\n\n/**\n * Set uniforms and binds related textures.\n *\n * example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\"]);\n *\n * const tex1 = gl.createTexture();\n * const tex2 = gl.createTexture();\n *\n * ... assume we setup the textures with data ...\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the textures AND set the\n * uniforms.\n *\n * twgl.setUniforms(programInfo, uniforms);\n *\n * For the example above it is equivalent to\n *\n * let texUnit = 0;\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex1);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex2);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);\n * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);\n * gl.uniformMatrix4fv(u_someMatrix, false, [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ]);\n *\n * Note it is perfectly reasonable to call `setUniforms` multiple times. For example\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * };\n *\n * const moreUniforms {\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * twgl.setUniforms(programInfo, uniforms);\n * twgl.setUniforms(programInfo, moreUniforms);\n *\n * You can also add WebGLSamplers to uniform samplers as in\n *\n * const uniforms = {\n * u_someSampler: {\n * texture: someWebGLTexture,\n * sampler: someWebGLSampler,\n * },\n * };\n *\n * In which case both the sampler and texture will be bound to the\n * same unit.\n *\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * uniforms.\n * You can pass multiple objects by putting them in an array or by calling with more arguments.For example\n *\n * const sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * const localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * twgl.setUniforms(programInfo, sharedUniforms, localUniforms);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, sharedUniforms);\n * twgl.setUniforms(programInfo, localUniforms};\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Light lights[2];\n *\n * // in JavaScript\n *\n * twgl.setUniforms(programInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setUniforms(programInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * @memberOf module:twgl/programs\n */\nfunction setUniforms(setters, ...args) { // eslint-disable-line\n const actualSetters = setters.uniformSetters || setters;\n const numArgs = args.length;\n for (let aNdx = 0; aNdx < numArgs; ++aNdx) {\n const values = args[aNdx];\n if (Array.isArray(values)) {\n const numValues = values.length;\n for (let ii = 0; ii < numValues; ++ii) {\n setUniforms(actualSetters, values[ii]);\n }\n } else {\n for (const name in values) {\n const setter = actualSetters[name];\n if (setter) {\n setter(values[name]);\n }\n }\n }\n }\n}\n\n/**\n * Alias for `setUniforms`\n * @function\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * @memberOf module:twgl/programs\n */\nconst setUniformsAndBindTextures = setUniforms;\n\n/**\n * Creates setter functions for all attributes of a shader\n * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes.\n *\n * @see {@link module:twgl.setAttributes} for example\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @return {Object.} an object with a setter for each attribute by name.\n * @memberOf module:twgl/programs\n */\nfunction createAttributeSetters(gl, program) {\n const attribSetters = {\n };\n\n const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES);\n for (let ii = 0; ii < numAttribs; ++ii) {\n const attribInfo = gl.getActiveAttrib(program, ii);\n if (isBuiltIn(attribInfo)) {\n continue;\n }\n const index = gl.getAttribLocation(program, attribInfo.name);\n const typeInfo = attrTypeMap[attribInfo.type];\n const setter = typeInfo.setter(gl, index, typeInfo);\n setter.location = index;\n attribSetters[attribInfo.name] = setter;\n }\n\n return attribSetters;\n}\n\n/**\n * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes})\n *\n * Example:\n *\n * const program = createProgramFromScripts(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const attribSetters = createAttributeSetters(program);\n *\n * const positionBuffer = gl.createBuffer();\n * const texcoordBuffer = gl.createBuffer();\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * };\n *\n * gl.useProgram(program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setAttributes(attribSetters, attribs);\n *\n * Properties of attribs. For each attrib you can add\n * properties:\n *\n * * type: the type of data in the buffer. Default = gl.FLOAT\n * * normalize: whether or not to normalize the data. Default = false\n * * stride: the stride. Default = 0\n * * offset: offset into the buffer. Default = 0\n * * divisor: the divisor for instances. Default = undefined\n *\n * For example if you had 3 value float positions, 2 value\n * float texcoord and 4 value uint8 colors you'd setup your\n * attribs like this\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * a_color: {\n * buffer: colorBuffer,\n * numComponents: 4,\n * type: gl.UNSIGNED_BYTE,\n * normalize: true,\n * },\n * };\n *\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} buffers AttribInfos mapped by attribute name.\n * @memberOf module:twgl/programs\n * @deprecated use {@link module:twgl.setBuffersAndAttributes}\n * @private\n */\nfunction setAttributes(setters, buffers) {\n for (const name in buffers) {\n const setter = setters[name];\n if (setter) {\n setter(buffers[name]);\n }\n }\n}\n\n/**\n * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate\n *\n * Example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * };\n *\n * const bufferInfo = createBufferInfoFromArrays(gl, arrays);\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setBuffersAndAttributes(gl, programInfo, bufferInfo);\n *\n * For the example above it is equivalent to\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n * gl.enableVertexAttribArray(a_positionLocation);\n * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0);\n * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);\n * gl.enableVertexAttribArray(a_texcoordLocation);\n * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters}\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}.\n * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo}\n * @memberOf module:twgl/programs\n */\nfunction setBuffersAndAttributes(gl, programInfo, buffers) {\n if (buffers.vertexArrayObject) {\n gl.bindVertexArray(buffers.vertexArrayObject);\n } else {\n setAttributes(programInfo.attribSetters || programInfo, buffers.attribs);\n if (buffers.indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices);\n }\n }\n}\n\n/**\n * @typedef {Object} ProgramInfo\n * @property {WebGLProgram} program A shader program\n * @property {Object} uniformLocations The uniform locations of each uniform\n * @property {Object} attribLocations The locations of each attribute\n * @property {Object} uniformSetters object of setters as returned from createUniformSetters,\n * @property {Object} attribSetters object of setters as returned from createAttribSetters,\n * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc..\n * @property {Object} [transformFeedbackInfo] info for transform feedbacks\n * @memberOf module:twgl\n */\n\n/**\n * Creates a ProgramInfo from an existing program.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {module:twgl.ProgramInfo} The created ProgramInfo.\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfoFromProgram(gl, program) {\n const uniformSetters = createUniformSetters(gl, program);\n const attribSetters = createAttributeSetters(gl, program);\n const programInfo = {\n program,\n uniformSetters,\n attribSetters,\n uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])),\n attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])),\n };\n\n if (utils.isWebGL2(gl)) {\n programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program);\n programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program);\n }\n\n return programInfo;\n}\n\nconst notIdRE = /\\s|{|}|;/;\n\n/**\n * Creates a ProgramInfo from 2 sources.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramInfo(gl, [vs, fs], options);\n * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfo(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const errors = [];\n shaderSources = shaderSources.map(function(source) {\n // Lets assume if there is no \\n it's an id\n if (!notIdRE.test(source)) {\n const script = getElementById(source);\n if (!script) {\n const err = `no element with id: ${source}`;\n progOptions.errorCallback(err);\n errors.push(err);\n } else {\n source = script.text;\n }\n }\n return source;\n });\n\n if (errors.length) {\n return reportError(progOptions, '');\n }\n\n const origCallback = progOptions.callback;\n if (origCallback) {\n progOptions.callback = (err, program) => {\n origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program));\n };\n }\n\n const program = createProgramFromSources(gl, shaderSources, progOptions);\n if (!program) {\n return null;\n }\n\n return createProgramInfoFromProgram(gl, program);\n}\n\nfunction checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) {\n // check errors for everything.\n for (const [name, program] of Object.entries(programs)) {\n const options = {...programOptions};\n const spec = programSpecs[name];\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n const errors = getProgramErrors(gl, program, options.errorCallback);\n if (errors) {\n // delete everything we created\n for (const program of Object.values(programs)) {\n const shaders = gl.getAttachedShaders(program);\n gl.deleteProgram(program);\n for (const shader of shaders) {\n // Don't delete it if we didn't create it.\n if (!noDeleteShadersSet.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n }\n return errors;\n }\n }\n\n return undefined;\n}\n\n/**\n * Creates multiple programs\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgram}\n *\n * Example:\n *\n * const programs = twgl.createPrograms(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createPrograms(gl, programSpecs, programOptions = {}) {\n // Remember existing shaders so that if there is an error we don't delete them\n const noDeleteShadersSet = new Set();\n\n // compile and link everything\n const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => {\n const options = {...programOptions};\n const shaders = Array.isArray(spec) ? spec : spec.shaders;\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet);\n return [name, createProgramNoCheck(gl, shaders, options)];\n }));\n\n if (programOptions.callback) {\n waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => {\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n programOptions.callback(errors, errors ? undefined : programs);\n });\n return undefined;\n }\n\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n return errors ? undefined : programs;\n}\n\n/**\n * Creates multiple programInfos\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgramInfo}\n *\n * Examples:\n *\n * const programInfos = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * or\n *\n * const {lambert, phong, particles} = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createProgramInfos(gl, programSpecs, programOptions) {\n programOptions = getProgramOptions(programOptions);\n\n function createProgramInfosForPrograms(gl, programs) {\n return Object.fromEntries(Object.entries(programs).map(([name, program]) =>\n [name, createProgramInfoFromProgram(gl, program)]\n ));\n }\n\n const origCallback = programOptions.callback;\n if (origCallback) {\n programOptions.callback = (err, programs) => {\n origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs));\n };\n }\n\n const programs = createPrograms(gl, programSpecs, programOptions);\n if (origCallback || !programs) {\n return undefined;\n }\n\n return createProgramInfosForPrograms(gl, programs);\n}\n\n/**\n * Creates multiple programs asynchronously\n *\n * @see {@link module:twgl.createProgramAsync}\n *\n * Example:\n *\n * const programs = await twgl.createProgramsAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nconst createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms);\n\n/**\n * Creates multiple programInfos asynchronously\n *\n * @see {@link module:twgl.createProgramInfoAsync}\n *\n * Example:\n *\n * const programInfos = await twgl.createProgramInfosAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Promise>} the created programInfos by name\n */\nconst createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos);\n\nexport {\n createAttributeSetters,\n\n createProgram,\n createProgramAsync,\n createPrograms,\n createProgramsAsync,\n createProgramFromScripts,\n createProgramFromSources,\n createProgramInfo,\n createProgramInfoAsync,\n createProgramInfos,\n createProgramInfosAsync,\n createProgramInfoFromProgram,\n createUniformSetters,\n createUniformBlockSpecFromProgram,\n createUniformBlockInfoFromProgram,\n createUniformBlockInfo,\n\n createTransformFeedback,\n createTransformFeedbackInfo,\n bindTransformFeedbackInfo,\n\n setAttributes,\n setBuffersAndAttributes,\n setUniforms,\n setUniformsAndBindTextures,\n setUniformBlock,\n setBlockUniforms,\n bindUniformBlock,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level texture related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.textures` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/textures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n textureColor: new Uint8Array([128, 192, 255, 255]),\n textureOptions: {},\n crossOrigin: undefined,\n};\nconst isArrayBuffer = typedArrays.isArrayBuffer;\n\n// Should we make this on demand?\nconst getShared2DContext = function() {\n let s_ctx;\n return function getShared2DContext() {\n s_ctx = s_ctx ||\n ((typeof document !== 'undefined' && document.createElement)\n ? document.createElement(\"canvas\").getContext(\"2d\")\n : null);\n return s_ctx;\n };\n}();\n\n// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but\n// not only does Firefox NOT support it but Firefox freezes immediately\n// if you try to create one instead of just returning null and continuing.\n// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext(\"2d\")); // OffscreenCanvas may not support 2d\n\n// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2\n// we can use the various unpack settings. Otherwise we could try using\n// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap\n// is async and the current TWGL code expects a non-Async result though that\n// might not be a problem. ImageBitmap though is not available in Edge or Safari\n// as of 2018-01-02\n\n/* PixelFormat */\nconst ALPHA = 0x1906;\nconst RGB = 0x1907;\nconst RGBA = 0x1908;\nconst LUMINANCE = 0x1909;\nconst LUMINANCE_ALPHA = 0x190A;\nconst DEPTH_COMPONENT = 0x1902;\nconst DEPTH_STENCIL = 0x84F9;\n\n/* TextureWrapMode */\n// const REPEAT = 0x2901;\n// const MIRRORED_REPEAT = 0x8370;\nconst CLAMP_TO_EDGE = 0x812f;\n\n/* TextureMagFilter */\nconst NEAREST = 0x2600;\nconst LINEAR = 0x2601;\n\n/* TextureMinFilter */\n// const NEAREST_MIPMAP_NEAREST = 0x2700;\n// const LINEAR_MIPMAP_NEAREST = 0x2701;\n// const NEAREST_MIPMAP_LINEAR = 0x2702;\n// const LINEAR_MIPMAP_LINEAR = 0x2703;\n\n/* Texture Target */\nconst TEXTURE_2D = 0x0de1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806f;\nconst TEXTURE_2D_ARRAY = 0x8c1a;\n\n/* Cubemap Targets */\nconst TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;\nconst TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;\nconst TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;\nconst TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a;\n\n/* Texture Parameters */\nconst TEXTURE_MIN_FILTER = 0x2801;\nconst TEXTURE_MAG_FILTER = 0x2800;\nconst TEXTURE_WRAP_S = 0x2802;\nconst TEXTURE_WRAP_T = 0x2803;\nconst TEXTURE_WRAP_R = 0x8072;\nconst TEXTURE_MIN_LOD = 0x813a;\nconst TEXTURE_MAX_LOD = 0x813b;\nconst TEXTURE_BASE_LEVEL = 0x813c;\nconst TEXTURE_MAX_LEVEL = 0x813d;\nconst TEXTURE_COMPARE_MODE = 0x884C;\nconst TEXTURE_COMPARE_FUNC = 0x884D;\n\n/* Pixel store */\nconst UNPACK_ALIGNMENT = 0x0cf5;\nconst UNPACK_ROW_LENGTH = 0x0cf2;\nconst UNPACK_IMAGE_HEIGHT = 0x806e;\nconst UNPACK_SKIP_PIXELS = 0x0cf4;\nconst UNPACK_SKIP_ROWS = 0x0cf3;\nconst UNPACK_SKIP_IMAGES = 0x806d;\nconst UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;\nconst UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;\nconst UNPACK_FLIP_Y_WEBGL = 0x9240;\n\nconst R8 = 0x8229;\nconst R8_SNORM = 0x8F94;\nconst R16F = 0x822D;\nconst R32F = 0x822E;\nconst R8UI = 0x8232;\nconst R8I = 0x8231;\nconst RG16UI = 0x823A;\nconst RG16I = 0x8239;\nconst RG32UI = 0x823C;\nconst RG32I = 0x823B;\nconst RG8 = 0x822B;\nconst RG8_SNORM = 0x8F95;\nconst RG16F = 0x822F;\nconst RG32F = 0x8230;\nconst RG8UI = 0x8238;\nconst RG8I = 0x8237;\nconst R16UI = 0x8234;\nconst R16I = 0x8233;\nconst R32UI = 0x8236;\nconst R32I = 0x8235;\nconst RGB8 = 0x8051;\nconst SRGB8 = 0x8C41;\nconst RGB565 = 0x8D62;\nconst RGB8_SNORM = 0x8F96;\nconst R11F_G11F_B10F = 0x8C3A;\nconst RGB9_E5 = 0x8C3D;\nconst RGB16F = 0x881B;\nconst RGB32F = 0x8815;\nconst RGB8UI = 0x8D7D;\nconst RGB8I = 0x8D8F;\nconst RGB16UI = 0x8D77;\nconst RGB16I = 0x8D89;\nconst RGB32UI = 0x8D71;\nconst RGB32I = 0x8D83;\nconst RGBA8 = 0x8058;\nconst SRGB8_ALPHA8 = 0x8C43;\nconst RGBA8_SNORM = 0x8F97;\nconst RGB5_A1 = 0x8057;\nconst RGBA4 = 0x8056;\nconst RGB10_A2 = 0x8059;\nconst RGBA16F = 0x881A;\nconst RGBA32F = 0x8814;\nconst RGBA8UI = 0x8D7C;\nconst RGBA8I = 0x8D8E;\nconst RGB10_A2UI = 0x906F;\nconst RGBA16UI = 0x8D76;\nconst RGBA16I = 0x8D88;\nconst RGBA32I = 0x8D82;\nconst RGBA32UI = 0x8D70;\n\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst DEPTH_COMPONENT24 = 0x81A6;\nconst DEPTH_COMPONENT32F = 0x8CAC;\nconst DEPTH32F_STENCIL8 = 0x8CAD;\nconst DEPTH24_STENCIL8 = 0x88F0;\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:(\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst RG = 0x8227;\nconst RG_INTEGER = 0x8228;\nconst RED = 0x1903;\nconst RED_INTEGER = 0x8D94;\nconst RGB_INTEGER = 0x8D98;\nconst RGBA_INTEGER = 0x8D99;\n\nconst formatInfo = {};\n{\n // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle\n // the name.\n const f = formatInfo;\n f[ALPHA] = { numColorComponents: 1, };\n f[LUMINANCE] = { numColorComponents: 1, };\n f[LUMINANCE_ALPHA] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RED] = { numColorComponents: 1, };\n f[RED_INTEGER] = { numColorComponents: 1, };\n f[RG] = { numColorComponents: 2, };\n f[RG_INTEGER] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGB_INTEGER] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RGBA_INTEGER] = { numColorComponents: 4, };\n f[DEPTH_COMPONENT] = { numColorComponents: 1, };\n f[DEPTH_STENCIL] = { numColorComponents: 2, };\n}\n\n/**\n * @typedef {Object} TextureFormatDetails\n * @property {number} textureFormat format to pass texImage2D and similar functions.\n * @property {boolean} colorRenderable true if you can render to this format of texture.\n * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`.\n * @property {number[]} type Array of possible types you can pass to texImage2D and similar function\n * @property {Object.} bytesPerElementMap A map of types to bytes per element\n * @private\n */\n\nlet s_textureInternalFormatInfo;\nfunction getTextureInternalFormatInfo(internalFormat) {\n if (!s_textureInternalFormatInfo) {\n // NOTE: these properties need unique names so we can let Uglify mangle the name.\n const t = {};\n // unsized formats\n t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5], };\n t[RGBA] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], };\n t[DEPTH_COMPONENT] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT, UNSIGNED_SHORT], };\n\n // sized formats\n t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], };\n t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT, HALF_FLOAT], };\n t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], };\n t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT], };\n t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], };\n t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT], };\n t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], };\n t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT, HALF_FLOAT], };\n t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT], };\n t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], };\n t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT], };\n t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], };\n t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT], };\n t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT], };\n t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB565] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5], };\n t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], };\n t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], };\n t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], };\n t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT, HALF_FLOAT], };\n t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT], };\n t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], };\n t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT], };\n t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], };\n t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT], };\n t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT], };\n t[RGBA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[SRGB8_ALPHA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8_SNORM] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], };\n t[RGB5_A1] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA4] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4], };\n t[RGB10_A2] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT, HALF_FLOAT], };\n t[RGBA32F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT], };\n t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], };\n t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT], };\n t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], };\n t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT], };\n t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT], };\n // Sized Internal\n t[DEPTH_COMPONENT16] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT, UNSIGNED_INT], };\n t[DEPTH_COMPONENT24] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[DEPTH_COMPONENT32F] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[DEPTH24_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], };\n t[DEPTH32F_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], };\n\n Object.keys(t).forEach(function(internalFormat) {\n const info = t[internalFormat];\n info.bytesPerElementMap = {};\n info.bytesPerElement.forEach(function(bytesPerElement, ndx) {\n const type = info.type[ndx];\n info.bytesPerElementMap[type] = bytesPerElement;\n });\n });\n s_textureInternalFormatInfo = t;\n }\n return s_textureInternalFormatInfo[internalFormat];\n}\n\n/**\n * Gets the number of bytes per element for a given internalFormat / type\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {number} the number of bytes per element for the given internalFormat, type combo\n * @memberOf module:twgl/textures\n */\nfunction getBytesPerElementForInternalFormat(internalFormat, type) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n const bytesPerElement = info.bytesPerElementMap[type];\n if (bytesPerElement === undefined) {\n throw \"unknown internal format\";\n }\n return bytesPerElement;\n}\n\n/**\n * Info related to a specific texture internalFormat as returned\n * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}.\n *\n * @typedef {Object} TextureFormatInfo\n * @property {number} format Format to pass to texImage2D and related functions\n * @property {number} type Type to pass to texImage2D and related functions\n * @memberOf module:twgl/textures\n */\n\n/**\n * Gets the format and type for a given internalFormat\n *\n * @param {number} internalFormat The internal format\n * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type,\n * @memberOf module:twgl/textures\n */\nfunction getFormatAndTypeForInternalFormat(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return {\n format: info.textureFormat,\n type: info.type[0],\n };\n}\n\n/**\n * Returns true if value is power of 2\n * @param {number} value number to check.\n * @return true if value is power of 2\n * @private\n */\nfunction isPowerOf2(value) {\n return (value & (value - 1)) === 0;\n}\n\n/**\n * Gets whether or not we can generate mips for the given\n * internal format.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number} width The width parameter from texImage2D etc..\n * @param {number} height The height parameter from texImage2D etc..\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canGenerateMipmap(gl, width, height, internalFormat) {\n if (!utils.isWebGL2(gl)) {\n return isPowerOf2(width) && isPowerOf2(height);\n }\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.colorRenderable && info.textureFilterable;\n}\n\n/**\n * Gets whether or not we can generate mips for the given format\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canFilter(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.textureFilterable;\n}\n\n/**\n * Gets the number of components for a given image format.\n * @param {number} format the format.\n * @return {number} the number of components for the format.\n * @memberOf module:twgl/textures\n */\nfunction getNumComponentsForFormat(format) {\n const info = formatInfo[format];\n if (!info) {\n throw \"unknown format: \" + format;\n }\n return info.numColorComponents;\n}\n\n/**\n * Gets the texture type for a given array type.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @return {number} the gl texture type\n * @private\n */\nfunction getTextureTypeForArrayType(gl, src, defaultType) {\n if (isArrayBuffer(src)) {\n return typedArrays.getGLTypeForTypedArray(src);\n }\n return defaultType || UNSIGNED_BYTE;\n}\n\nfunction guessDimensions(gl, target, width, height, numElements) {\n if (numElements % 1 !== 0) {\n throw \"can't guess dimensions\";\n }\n if (!width && !height) {\n const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1));\n if (size % 1 === 0) {\n width = size;\n height = size;\n } else {\n width = numElements;\n height = 1;\n }\n } else if (!height) {\n height = numElements / width;\n if (height % 1) {\n throw \"can't guess dimensions\";\n }\n } else if (!width) {\n width = numElements / height;\n if (width % 1) {\n throw \"can't guess dimensions\";\n }\n }\n return {\n width: width,\n height: height,\n };\n}\n\n/**\n * Sets the default texture color.\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * @param {number[]} color Array of 4 values in the range 0 to 1\n * @deprecated see {@link module:twgl.setDefaults}\n * @memberOf module:twgl/textures\n */\nfunction setDefaultTextureColor(color) {\n defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n if (newDefaults.textureColor) {\n setDefaultTextureColor(newDefaults.textureColor);\n }\n}\n\n/**\n * A function to generate the source for a texture.\n * @callback TextureFunc\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options the texture options\n * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}.\n * @memberOf module:twgl\n */\n\n/**\n * Texture options passed to most texture functions. Each function will use whatever options\n * are appropriate for its needs. This lets you pass the same options to all functions.\n *\n * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`,\n * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`.\n *\n * @typedef {Object} TextureOptions\n * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`.\n * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true.\n * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null.\n * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null.\n * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` .\n * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR`\n * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`.\n * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR`\n * @property {number} [minMag] both the min and mag filter settings.\n * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA`\n * @property {number} [format] format for texture. Defaults to `gl.RGBA`.\n * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src`\n * is ArrayBufferView defaults to type that matches ArrayBufferView type.\n * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube\n * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [minLod] TEXTURE_MIN_LOD setting\n * @property {number} [maxLod] TEXTURE_MAX_LOD setting\n * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting\n * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting\n * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting\n * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting\n * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1.\n * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously.\n * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults`\n * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink\n * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and\n * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above\n * then then `auto` is assumed to be `false` unless explicity set to `true`.\n * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is\n *\n * [gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]\n *\n * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture\n *\n * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable\n * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded.\n * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3.\n * The pieces will be uploaded in `cubeFaceOrder`\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map.\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture\n * and will be scaled to the specified width and height OR to the size of the first image that loads.\n *\n * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`,\n * `HTMLCanvasElement`, `HTMLVideoElement`.\n *\n * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is\n * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents`\n * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided\n * by 6. Then\n *\n * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height\n * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`.\n *\n * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`.\n *\n * If `number[]` will be converted to `type`.\n *\n * If `src` is a function it will be called with a `WebGLRenderingContext` and these options.\n * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement`\n * an array etc...\n *\n * If `src` is undefined then an empty texture will be created of size `width` by `height`.\n *\n * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded.\n * default: undefined. Also see {@link module:twgl.setDefaults}.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Saves the current packing state, sets the packing state as specified\n * then calls a function, after which the packing state will be restored.\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {function():void} [fn] A function to call, after which the packing state will be restored.\n * @private\n */\nfunction scopedSetPackState(gl, options, fn) {\n let colorspaceConversion;\n let premultiplyAlpha;\n let flipY;\n\n if (options.colorspaceConversion !== undefined) {\n colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL);\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion);\n }\n if (options.premultiplyAlpha !== undefined) {\n premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha);\n }\n if (options.flipY !== undefined) {\n flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL);\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY);\n }\n\n fn();\n\n if (colorspaceConversion !== undefined) {\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion);\n }\n if (premultiplyAlpha !== undefined) {\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha);\n }\n if (flipY !== undefined) {\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY);\n }\n}\n\n/**\n * Set skip state to defaults\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @private\n */\nfunction setSkipStateToDefault(gl) {\n gl.pixelStorei(UNPACK_ALIGNMENT, 4);\n if (utils.isWebGL2(gl)) {\n gl.pixelStorei(UNPACK_ROW_LENGTH, 0);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_PIXELS, 0);\n gl.pixelStorei(UNPACK_SKIP_ROWS, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n }\n}\n\n/**\n * Sets the parameters of a texture or sampler\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number|WebGLSampler} target texture target or sampler\n * @param {function()} parameteriFn texParameteri or samplerParameteri fn\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @private\n */\nfunction setTextureSamplerParameters(gl, target, parameteriFn, options) {\n if (options.minMag) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag);\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag);\n }\n if (options.min) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min);\n }\n if (options.mag) {\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag);\n }\n if (options.wrap) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap);\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap);\n if (target === TEXTURE_3D || helper.isSampler(gl, target)) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap);\n }\n }\n if (options.wrapR) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR);\n }\n if (options.wrapS) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS);\n }\n if (options.wrapT) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT);\n }\n if (options.minLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod);\n }\n if (options.maxLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod);\n }\n if (options.baseLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel);\n }\n if (options.maxLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel);\n }\n if (options.compareFunc !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc);\n }\n if (options.compareMode !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode);\n }\n}\n\n/**\n * Sets the texture parameters of a texture.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureParameters(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n setTextureSamplerParameters(gl, target, gl.texParameteri, options);\n}\n\n/**\n * Sets the sampler parameters of a sampler.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLSampler} sampler the WebGLSampler to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setSamplerParameters(gl, sampler, options) {\n setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options);\n}\n\n/**\n * Creates a new sampler object and sets parameters.\n *\n * Example:\n *\n * const sampler = twgl.createSampler(gl, {\n * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER\n * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per sampler.\n * @return {Object.} the created samplers by name\n * @private\n */\nfunction createSampler(gl, options) {\n const sampler = gl.createSampler();\n setSamplerParameters(gl, sampler, options);\n return sampler;\n}\n\n/**\n * Creates a multiple sampler objects and sets parameters on each.\n *\n * Example:\n *\n * const samplers = twgl.createSamplers(gl, {\n * nearest: {\n * minMag: gl.NEAREST,\n * },\n * nearestClampS: {\n * minMag: gl.NEAREST,\n * wrapS: gl.CLAMP_TO_NEAREST,\n * },\n * linear: {\n * minMag: gl.LINEAR,\n * },\n * nearestClamp: {\n * minMag: gl.NEAREST,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClamp: {\n * minMag: gl.LINEAR,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClampT: {\n * minMag: gl.LINEAR,\n * wrapT: gl.CLAMP_TO_EDGE,\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler\n * @private\n */\nfunction createSamplers(gl, samplerOptions) {\n const samplers = {};\n Object.keys(samplerOptions).forEach(function(name) {\n samplers[name] = createSampler(gl, samplerOptions[name]);\n });\n return samplers;\n}\n\n/**\n * Makes a 1x1 pixel\n * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`.\n * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values\n * @return {Uint8Array} Unit8Array with color.\n * @private\n */\nfunction make1Pixel(color) {\n color = color || defaults.textureColor;\n if (isArrayBuffer(color)) {\n return color;\n }\n return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\n/**\n * Sets filtering or generates mips for texture based on width or height\n * If width or height is not passed in uses `options.width` and//or `options.height`\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @param {number} [width] width of texture\n * @param {number} [height] height of texture\n * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc..\n * @memberOf module:twgl/textures\n */\nfunction setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) {\n options = options || defaults.textureOptions;\n internalFormat = internalFormat || RGBA;\n const target = options.target || TEXTURE_2D;\n width = width || options.width;\n height = height || options.height;\n gl.bindTexture(target, tex);\n if (canGenerateMipmap(gl, width, height, internalFormat)) {\n gl.generateMipmap(target);\n } else {\n const filtering = canFilter(internalFormat) ? LINEAR : NEAREST;\n gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n}\n\nfunction shouldAutomaticallySetTextureFilteringForSize(options) {\n return options.auto === true || (options.auto === undefined && options.level === undefined);\n}\n\n/**\n * Gets an array of cubemap face enums\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @return {number[]} cubemap face enums\n * @private\n */\nfunction getCubeFaceOrder(gl, options) {\n options = options || {};\n return options.cubeFaceOrder || [\n TEXTURE_CUBE_MAP_POSITIVE_X,\n TEXTURE_CUBE_MAP_NEGATIVE_X,\n TEXTURE_CUBE_MAP_POSITIVE_Y,\n TEXTURE_CUBE_MAP_NEGATIVE_Y,\n TEXTURE_CUBE_MAP_POSITIVE_Z,\n TEXTURE_CUBE_MAP_NEGATIVE_Z,\n ];\n}\n\n/**\n * @typedef {Object} FaceInfo\n * @property {number} face gl enum for texImage2D\n * @property {number} ndx face index (0 - 5) into source data\n * @ignore\n */\n\n/**\n * Gets an array of FaceInfos\n * There's a bug in some NVidia drivers that will crash the driver if\n * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take\n * the user's desired order from his faces to WebGL and make sure we\n * do the faces in WebGL order\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but\n * it's needed internally to sort the array of `ndx` properties by `face`.\n * @private\n */\nfunction getCubeFacesWithNdx(gl, options) {\n const faces = getCubeFaceOrder(gl, options);\n // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :(\n const facesWithNdx = faces.map(function(face, ndx) {\n return { face: face, ndx: ndx };\n });\n facesWithNdx.sort(function(a, b) {\n return a.face - b.face;\n });\n return facesWithNdx;\n}\n\n/**\n * Set a texture from the contents of an element. Will also set\n * texture filtering or generate mips based on the dimensions of the element\n * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will\n * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {HTMLElement} element a canvas, img, or video element.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @kind function\n */\nfunction setTextureFromElement(gl, tex, element, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n const level = options.level || 0;\n let width = element.width;\n let height = element.height;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // guess the parts\n const imgWidth = element.width;\n const imgHeight = element.height;\n let size;\n let slices;\n if (imgWidth / 6 === imgHeight) {\n // It's 6x1\n size = imgHeight;\n slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0];\n } else if (imgHeight / 6 === imgWidth) {\n // It's 1x6\n size = imgWidth;\n slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5];\n } else if (imgWidth / 3 === imgHeight / 2) {\n // It's 3x2\n size = imgWidth / 3;\n slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1];\n } else if (imgWidth / 2 === imgHeight / 3) {\n // It's 2x3\n size = imgWidth / 2;\n slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2];\n } else {\n throw \"can't figure out cube map from element: \" + (element.src ? element.src : element.nodeName);\n }\n const ctx = getShared2DContext();\n if (ctx) {\n ctx.canvas.width = size;\n ctx.canvas.height = size;\n width = size;\n height = size;\n scopedSetPackState(gl, options, () => {\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size);\n gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas);\n });\n // Free up the canvas memory\n ctx.canvas.width = 1;\n ctx.canvas.height = 1;\n });\n } else if (typeof createImageBitmap !== 'undefined') {\n // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's\n // note lossy? (alpha is not premultiplied? although I'm not sure what\n width = size;\n height = size;\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n // We can't easily use a default texture color here as it would have to match\n // the type across all faces where as with a 2D one there's only one face\n // so we're replacing everything all at once. It also has to be the correct size.\n // On the other hand we need all faces to be the same size so as one face loads\n // the rest match else the texture will be un-renderable.\n gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null);\n createImageBitmap(element, xOffset, yOffset, size, size, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n })\n .then(function(imageBitmap) {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap);\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n });\n });\n });\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n scopedSetPackState(gl, options, () => {\n const smallest = Math.min(element.width, element.height);\n const largest = Math.max(element.width, element.height);\n const depth = largest / smallest;\n if (depth % 1 !== 0) {\n throw \"can not compute 3D dimensions of element\";\n }\n const xMult = element.width === largest ? 1 : 0;\n const yMult = element.height === largest ? 1 : 0;\n gl.pixelStorei(UNPACK_ALIGNMENT, 1);\n gl.pixelStorei(UNPACK_ROW_LENGTH, element.width);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null);\n for (let d = 0; d < depth; ++d) {\n const srcX = d * smallest * xMult;\n const srcY = d * smallest * yMult;\n gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX);\n gl.pixelStorei(UNPACK_SKIP_ROWS, srcY);\n gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element);\n }\n setSkipStateToDefault(gl);\n });\n } else {\n scopedSetPackState(gl, options, () => {\n gl.texImage2D(target, level, internalFormat, format, type, element);\n });\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n}\n\nfunction noop() {\n}\n\n/**\n * Checks whether the url's origin is the same so that we can set the `crossOrigin`\n * @param {string} url url to image\n * @returns {boolean} true if the window's origin is the same as image's url\n * @private\n */\nfunction urlIsSameOrigin(url) {\n if (typeof document !== 'undefined') {\n // for IE really\n const a = document.createElement('a');\n a.href = url;\n return a.hostname === location.hostname &&\n a.port === location.port &&\n a.protocol === location.protocol;\n } else {\n const localOrigin = (new URL(location.href)).origin;\n const urlOrigin = (new URL(url, location.href)).origin;\n return urlOrigin === localOrigin;\n }\n}\n\nfunction setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) {\n return crossOrigin === undefined && !urlIsSameOrigin(url)\n ? 'anonymous'\n : crossOrigin;\n}\n\n/**\n * Loads an image\n * @param {string} url url to image\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @return {HTMLImageElement} the image being loaded.\n * @private\n */\nfunction loadImage(url, crossOrigin, callback) {\n callback = callback || noop;\n let img;\n crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin;\n crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin);\n if (typeof Image !== 'undefined') {\n img = new Image();\n if (crossOrigin !== undefined) {\n img.crossOrigin = crossOrigin;\n }\n\n const clearEventHandlers = function clearEventHandlers() {\n img.removeEventListener('error', onError); // eslint-disable-line\n img.removeEventListener('load', onLoad); // eslint-disable-line\n img = null;\n };\n\n const onError = function onError() {\n const msg = \"couldn't load image: \" + url;\n helper.error(msg);\n callback(msg, img);\n clearEventHandlers();\n };\n\n const onLoad = function onLoad() {\n callback(null, img);\n clearEventHandlers();\n };\n\n img.addEventListener('error', onError);\n img.addEventListener('load', onLoad);\n img.src = url;\n return img;\n } else if (typeof ImageBitmap !== 'undefined') {\n let err;\n let bm;\n const cb = function cb() {\n callback(err, bm);\n };\n\n const options = {};\n if (crossOrigin) {\n options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin\n }\n fetch(url, options).then(function(response) {\n if (!response.ok) {\n throw response;\n }\n return response.blob();\n }).then(function(blob) {\n return createImageBitmap(blob, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n });\n }).then(function(bitmap) {\n // not sure if this works. We don't want\n // to catch the user's error. So, call\n // the callback in a timeout so we're\n // not in this scope inside the promise.\n bm = bitmap;\n setTimeout(cb);\n }).catch(function(e) {\n err = e;\n setTimeout(cb);\n });\n img = null;\n }\n return img;\n}\n\n/**\n * check if object is a TexImageSource\n *\n * @param {Object} obj Object to test\n * @return {boolean} true if object is a TexImageSource\n * @private\n */\nfunction isTexImageSource(obj) {\n return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) ||\n (typeof ImageData !== 'undefined' && obj instanceof ImageData) ||\n (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement);\n}\n\n/**\n * if obj is an TexImageSource then just\n * uses it otherwise if obj is a string\n * then load it first.\n *\n * @param {string|TexImageSource} obj\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @private\n */\nfunction loadAndUseImage(obj, crossOrigin, callback) {\n if (isTexImageSource(obj)) {\n setTimeout(function() {\n callback(null, obj);\n });\n return obj;\n }\n\n return loadImage(obj, crossOrigin, callback);\n}\n\n/**\n * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set\n * the default texture color is used which can be set by calling `setDefaultTextureColor`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction setTextureTo1PixelColor(gl, tex, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n if (options.color === false) {\n return;\n }\n // Assume it's a URL\n // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering.\n const color = make1Pixel(options.color);\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n } else {\n gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n}\n\n/**\n * The src image(s) used to create a texture.\n *\n * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures}\n * you can pass in urls for images to load into the textures. If it's a single url\n * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap\n * this will be a corresponding array of images for the cubemap.\n *\n * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback TextureReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} texture the texture.\n * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when all images have finished downloading and been uploaded into their respective textures\n * @callback TexturesReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}.\n * @param {Object.} sources the image(s) used for the texture by name.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback CubemapReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each face.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback ThreeDReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each slice.\n * @memberOf module:twgl\n */\n\n/**\n * Loads a texture from an image from a Url as specified in `options.src`\n * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is\n * immediately useable. It will be updated with the contents of the image once the image has finished\n * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will\n * be non null if there was an error.\n * @return {HTMLImageElement} the image being downloaded.\n * @memberOf module:twgl/textures\n */\nfunction loadTextureFromUrl(gl, tex, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) {\n if (err) {\n callback(err, tex, img);\n } else {\n setTextureFromElement(gl, tex, img, options);\n callback(null, tex, img);\n }\n });\n return img;\n}\n\n/**\n * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadCubemapFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n if (urls.length !== 6) {\n throw \"there must be 6 urls for a cubemap\";\n }\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D;\n if (target !== TEXTURE_CUBE_MAP) {\n throw \"target must be TEXTURE_CUBE_MAP\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = 6;\n const errors = [];\n const faces = getCubeFaceOrder(gl, options);\n let imgs; // eslint-disable-line\n\n function uploadImg(faceTarget) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n if (img.width !== img.height) {\n errors.push(\"cubemap face img is not a square: \" + img.src);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n // So assuming this is the first image we now have one face that's img sized\n // and 5 faces that are 1x1 pixel so size the other faces\n if (numToLoad === 5) {\n // use the default order\n getCubeFaceOrder(gl).forEach(function(otherTarget) {\n // Should we re-use the same face or a color?\n gl.texImage2D(otherTarget, level, internalFormat, format, type, img);\n });\n } else {\n gl.texImage2D(faceTarget, level, internalFormat, format, type, img);\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx]));\n });\n}\n\n/**\n * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`.\n * Will set the texture to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n *\n * If the width and height is not specified the width and height of the first\n * image loaded will be used. Note that since images are loaded async\n * which image downloads first is unknown.\n *\n * If an image is not the same size as the width and height it will be scaled\n * to that width and height.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadSlicesFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D_ARRAY;\n if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) {\n throw \"target must be TEXTURE_3D or TEXTURE_2D_ARRAY\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = urls.length;\n const errors = [];\n let imgs; // eslint-disable-line\n const level = options.level || 0;\n let width = options.width;\n let height = options.height;\n const depth = urls.length;\n let firstImage = true;\n\n function uploadImg(slice) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n if (firstImage) {\n firstImage = false;\n width = options.width || img.width;\n height = options.height || img.height;\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n\n // put it in every slice otherwise some slices will be 0,0,0,0\n for (let s = 0; s < depth; ++s) {\n gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img);\n }\n } else {\n let src = img;\n let ctx;\n if (img.width !== width || img.height !== height) {\n // Size the image to fix\n ctx = getShared2DContext();\n src = ctx.canvas;\n ctx.canvas.width = width;\n ctx.canvas.height = height;\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src);\n\n // free the canvas memory\n if (ctx && src === ctx.canvas) {\n ctx.canvas.width = 0;\n ctx.canvas.height = 0;\n }\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx));\n });\n}\n\n/**\n * Sets a texture from an array or typed array. If the width or height is not provided will attempt to\n * guess the size. See {@link module:twgl.TextureOptions}.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureFromArray(gl, tex, src, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n let width = options.width;\n let height = options.height;\n let depth = options.depth;\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n if (!isArrayBuffer(src)) {\n const Type = typedArrays.getTypedArrayTypeForGLType(type);\n src = new Type(src);\n } else if (src instanceof Uint8ClampedArray) {\n src = new Uint8Array(src.buffer);\n }\n\n const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type);\n const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT?\n if (numElements % 1) {\n throw \"length wrong size for format: \" + utils.glEnumToString(gl, format);\n }\n let dimensions;\n if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n if (!width && !height && !depth) {\n const size = Math.cbrt(numElements);\n if (size % 1 !== 0) {\n throw \"can't guess cube size of array of numElements: \" + numElements;\n }\n width = size;\n height = size;\n depth = size;\n } else if (width && (!height || !depth)) {\n dimensions = guessDimensions(gl, target, height, depth, numElements / width);\n height = dimensions.width;\n depth = dimensions.height;\n } else if (height && (!width || !depth)) {\n dimensions = guessDimensions(gl, target, width, depth, numElements / height);\n width = dimensions.width;\n depth = dimensions.height;\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements / depth);\n width = dimensions.width;\n height = dimensions.height;\n }\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements);\n width = dimensions.width;\n height = dimensions.height;\n }\n setSkipStateToDefault(gl);\n gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1);\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT;\n const faceSize = numElements / 6 * elementsPerElement;\n\n getCubeFacesWithNdx(gl, options).forEach(f => {\n const offset = faceSize * f.ndx;\n const data = src.subarray(offset, offset + faceSize);\n gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data);\n });\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src);\n }\n });\n return {\n width: width,\n height: height,\n depth: depth,\n type: type,\n };\n}\n\n/**\n * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`.\n * You must set `options.width` and `options.height`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setEmptyTexture(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n });\n}\n\n/**\n * Creates a texture based on the options passed in.\n *\n * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES\n * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture.\n * @return {WebGLTexture} the created texture.\n * @memberOf module:twgl/textures\n */\nfunction createTexture(gl, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n const tex = gl.createTexture();\n const target = options.target || TEXTURE_2D;\n let width = options.width || 1;\n let height = options.height || 1;\n const internalFormat = options.internalFormat || RGBA;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // this should have been the default for cubemaps :(\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n let src = options.src;\n if (src) {\n if (typeof src === \"function\") {\n src = src(gl, options);\n }\n if (typeof (src) === \"string\") {\n loadTextureFromUrl(gl, tex, options, callback);\n } else if (isArrayBuffer(src) ||\n (Array.isArray(src) && (\n typeof src[0] === 'number' ||\n Array.isArray(src[0]) ||\n isArrayBuffer(src[0]))\n )\n ) {\n const dimensions = setTextureFromArray(gl, tex, src, options);\n width = dimensions.width;\n height = dimensions.height;\n } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) {\n if (target === TEXTURE_CUBE_MAP) {\n loadCubemapFromUrls(gl, tex, options, callback);\n } else {\n loadSlicesFromUrls(gl, tex, options, callback);\n }\n } else { // if (isTexImageSource(src))\n setTextureFromElement(gl, tex, src, options);\n width = src.width;\n height = src.height;\n }\n } else {\n setEmptyTexture(gl, tex, options);\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n return tex;\n}\n\n/**\n * Resizes a texture based on the options passed in.\n *\n * Note: This is not a generic resize anything function.\n * It's mostly used by {@link module:twgl.resizeFramebufferInfo}\n * It will use `options.src` if it exists to try to determine a `type`\n * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided\n * for the texture. Texture parameters will be set accordingly\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the texture to resize\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {number} [width] the new width. If not passed in will use `options.width`\n * @param {number} [height] the new height. If not passed in will use `options.height`\n * @param {number} [depth] the new depth. If not passed in will use `options.depth`\n * @memberOf module:twgl/textures\n */\nfunction resizeTexture(gl, tex, options, width, height, depth) {\n width = width || options.width;\n height = height || options.height;\n depth = depth || options.depth;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n let type;\n const src = options.src;\n if (!src) {\n type = options.type || formatType.type;\n } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) {\n type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n } else {\n type = options.type || formatType.type;\n }\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null);\n }\n}\n\n/**\n * Check if a src is an async request.\n * if src is a string we're going to download an image\n * if src is an array of strings we're going to download cubemap images\n * @param {*} src The src from a TextureOptions\n * @returns {bool} true if src is async.\n * @private\n */\nfunction isAsyncSrc(src) {\n return typeof src === 'string' ||\n (Array.isArray(src) && typeof src[0] === 'string');\n}\n\n/**\n * Creates a bunch of textures based on the passed in options.\n *\n * Example:\n *\n * const textures = twgl.createTextures(gl, {\n * // a power of 2 image\n * hftIcon: { src: \"images/hft-icon-16.png\", mag: gl.NEAREST },\n * // a non-power of 2 image\n * clover: { src: \"images/clover.jpg\" },\n * // From a canvas\n * fromCanvas: { src: ctx.canvas },\n * // A cubemap from 6 images\n * yokohama: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: [\n * 'images/yokohama/posx.jpg',\n * 'images/yokohama/negx.jpg',\n * 'images/yokohama/posy.jpg',\n * 'images/yokohama/negy.jpg',\n * 'images/yokohama/posz.jpg',\n * 'images/yokohama/negz.jpg',\n * ],\n * },\n * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)\n * goldengate: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: 'images/goldengate.jpg',\n * },\n * // A 2x2 pixel texture from a JavaScript array\n * checker: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * src: [\n * 255,255,255,255,\n * 192,192,192,255,\n * 192,192,192,255,\n * 255,255,255,255,\n * ],\n * },\n * // a 1x2 pixel texture from a typed array.\n * stripe: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * format: gl.LUMINANCE,\n * src: new Uint8Array([\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * ]),\n * width: 1,\n * },\n * });\n *\n * Now\n *\n * * `textures.hftIcon` will be a 2d texture\n * * `textures.clover` will be a 2d texture\n * * `textures.fromCanvas` will be a 2d texture\n * * `textures.yohohama` will be a cubemap texture\n * * `textures.goldengate` will be a cubemap texture\n * * `textures.checker` will be a 2d texture\n * * `textures.stripe` will be a 2d texture\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per texture.\n * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded.\n * @return {Object.} the created textures by name\n * @memberOf module:twgl/textures\n */\nfunction createTextures(gl, textureOptions, callback) {\n callback = callback || noop;\n let numDownloading = 0;\n const errors = [];\n const textures = {};\n const images = {};\n\n function callCallbackIfReady() {\n if (numDownloading === 0) {\n setTimeout(function() {\n callback(errors.length ? errors : undefined, textures, images);\n }, 0);\n }\n }\n\n Object.keys(textureOptions).forEach(function(name) {\n const options = textureOptions[name];\n let onLoadFn;\n if (isAsyncSrc(options.src)) {\n onLoadFn = function(err, tex, img) {\n images[name] = img;\n --numDownloading;\n if (err) {\n errors.push(err);\n }\n callCallbackIfReady();\n };\n ++numDownloading;\n }\n textures[name] = createTexture(gl, options, onLoadFn);\n });\n\n // queue the callback if there are no images to download.\n // We do this because if your code is structured to wait for\n // images to download but then you comment out all the async\n // images your code would break.\n callCallbackIfReady();\n\n return textures;\n}\n\nexport {\n setDefaults as setTextureDefaults_,\n\n createSampler,\n createSamplers,\n setSamplerParameters,\n\n createTexture,\n setEmptyTexture,\n setTextureFromArray,\n loadTextureFromUrl,\n setTextureFromElement,\n setTextureFilteringForSize,\n setTextureParameters,\n setDefaultTextureColor,\n createTextures,\n resizeTexture,\n\n canGenerateMipmap,\n canFilter,\n getNumComponentsForFormat,\n getBytesPerElementForInternalFormat,\n getFormatAndTypeForInternalFormat,\n};\n\n","export * from './twgl.js';\n\n\n\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as attributes from './attributes.js';\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\nimport * as utils from './utils.js';\n\nimport * as draw from './draw.js';\nimport * as framebuffers from './framebuffers.js';\nimport * as programs from './programs.js';\nimport * as typedarrays from './typedarrays.js';\nimport * as vertexArrays from './vertex-arrays.js';\n\n/**\n * The main TWGL module.\n *\n * For most use cases you shouldn't need anything outside this module.\n * Exceptions between the stuff added to twgl-full (v3, m4, primitives)\n *\n * @module twgl\n * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray\n * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays\n * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo\n * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo\n * @borrows module:twgl/draw.drawObjectList as drawObjectList\n * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo\n * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo\n * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo\n * @borrows module:twgl/programs.createProgramInfo as createProgramInfo\n * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo\n * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock\n * @borrows module:twgl/programs.setUniformBlock as setUniformBlock\n * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms\n * @borrows module:twgl/programs.setUniforms as setUniforms\n * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes\n * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray\n * @borrows module:twgl/textures.createTexture as createTexture\n * @borrows module:twgl/textures.resizeTexture as resizeTexture\n * @borrows module:twgl/textures.createTextures as createTextures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n addExtensionsToContext: true,\n};\n\n/**\n * Various default settings for twgl.\n *\n * Note: You can call this any number of times. Example:\n *\n * twgl.setDefaults({ textureColor: [1, 0, 0, 1] });\n * twgl.setDefaults({ attribPrefix: 'a_' });\n *\n * is equivalent to\n *\n * twgl.setDefaults({\n * textureColor: [1, 0, 0, 1],\n * attribPrefix: 'a_',\n * });\n *\n * @typedef {Object} Defaults\n * @property {string} [attribPrefix] The prefix to stick on attributes\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * const arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * Default: `\"\"`\n *\n * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * Default: `[0.5, 0.75, 1, 1]`\n *\n * @property {string} [crossOrigin]\n *\n * If not undefined sets the crossOrigin attribute on images\n * that twgl creates when downloading images for textures.\n *\n * Also see {@link module:twgl.TextureOptions}.\n *\n * @property {bool} [addExtensionsToContext]\n *\n * If true, then, when twgl will try to add any supported WebGL extensions\n * directly to the context under their normal GL names. For example\n * if ANGLE_instances_arrays exists then twgl would enable it,\n * add the functions `vertexAttribDivisor`, `drawArraysInstanced`,\n * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR`\n * to the `WebGLRenderingContext`.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Sets various defaults for twgl.\n *\n * In the interest of terseness which is kind of the point\n * of twgl I've integrated a few of the older functions here\n *\n * @param {module:twgl.Defaults} newDefaults The default settings.\n * @memberOf module:twgl\n */\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line\n textures.setTextureDefaults_(newDefaults); // eslint-disable-line\n}\n\nconst prefixRE = /^(.*?)_/;\nfunction addExtensionToContext(gl, extensionName) {\n utils.glEnumToString(gl, 0);\n const ext = gl.getExtension(extensionName);\n if (ext) {\n const enums = {};\n const fnSuffix = prefixRE.exec(extensionName)[1];\n const enumSuffix = '_' + fnSuffix;\n for (const key in ext) {\n const value = ext[key];\n const isFunc = typeof (value) === 'function';\n const suffix = isFunc ? fnSuffix : enumSuffix;\n let name = key;\n // examples of where this is not true are WEBGL_compressed_texture_s3tc\n // and WEBGL_compressed_texture_pvrtc\n if (key.endsWith(suffix)) {\n name = key.substring(0, key.length - suffix.length);\n }\n if (gl[name] !== undefined) {\n if (!isFunc && gl[name] !== value) {\n helper.warn(name, gl[name], value, key);\n }\n } else {\n if (isFunc) {\n gl[name] = function(origFn) {\n return function() {\n return origFn.apply(ext, arguments);\n };\n }(value);\n } else {\n gl[name] = value;\n enums[name] = value;\n }\n }\n }\n // pass the modified enums to glEnumToString\n enums.constructor = {\n name: ext.constructor.name,\n };\n utils.glEnumToString(enums, 0);\n }\n return ext;\n}\n\n/*\n * If you're wondering why the code doesn't just iterate\n * over all extensions using `gl.getExtensions` is that it's possible\n * some future extension is incompatible with this code. Rather than\n * have thing suddenly break it seems better to manually add to this\n * list.\n *\n */\nconst supportedExtensions = [\n 'ANGLE_instanced_arrays',\n 'EXT_blend_minmax',\n 'EXT_color_buffer_float',\n 'EXT_color_buffer_half_float',\n 'EXT_disjoint_timer_query',\n 'EXT_disjoint_timer_query_webgl2',\n 'EXT_frag_depth',\n 'EXT_sRGB',\n 'EXT_shader_texture_lod',\n 'EXT_texture_filter_anisotropic',\n 'OES_element_index_uint',\n 'OES_standard_derivatives',\n 'OES_texture_float',\n 'OES_texture_float_linear',\n 'OES_texture_half_float',\n 'OES_texture_half_float_linear',\n 'OES_vertex_array_object',\n 'WEBGL_color_buffer_float',\n 'WEBGL_compressed_texture_atc',\n 'WEBGL_compressed_texture_etc1',\n 'WEBGL_compressed_texture_pvrtc',\n 'WEBGL_compressed_texture_s3tc',\n 'WEBGL_compressed_texture_s3tc_srgb',\n 'WEBGL_depth_texture',\n 'WEBGL_draw_buffers',\n];\n\n/**\n * Attempts to enable all of the following extensions\n * and add their functions and constants to the\n * `WebGLRenderingContext` using their normal non-extension like names.\n *\n * ANGLE_instanced_arrays\n * EXT_blend_minmax\n * EXT_color_buffer_float\n * EXT_color_buffer_half_float\n * EXT_disjoint_timer_query\n * EXT_disjoint_timer_query_webgl2\n * EXT_frag_depth\n * EXT_sRGB\n * EXT_shader_texture_lod\n * EXT_texture_filter_anisotropic\n * OES_element_index_uint\n * OES_standard_derivatives\n * OES_texture_float\n * OES_texture_float_linear\n * OES_texture_half_float\n * OES_texture_half_float_linear\n * OES_vertex_array_object\n * WEBGL_color_buffer_float\n * WEBGL_compressed_texture_atc\n * WEBGL_compressed_texture_etc1\n * WEBGL_compressed_texture_pvrtc\n * WEBGL_compressed_texture_s3tc\n * WEBGL_compressed_texture_s3tc_srgb\n * WEBGL_depth_texture\n * WEBGL_draw_buffers\n *\n * For example if `ANGLE_instanced_arrays` exists then the functions\n * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor`\n * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the\n * `WebGLRenderingContext`.\n *\n * Note that if you want to know if the extension exists you should\n * probably call `gl.getExtension` for each extension. Alternatively\n * you can check for the existence of the functions or constants that\n * are expected to be added. For example\n *\n * if (gl.drawBuffers) {\n * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2\n * ....\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @memberOf module:twgl\n */\nfunction addExtensionsToContext(gl) {\n for (let ii = 0; ii < supportedExtensions.length; ++ii) {\n addExtensionToContext(gl, supportedExtensions[ii]);\n }\n}\n\n/**\n * Creates a webgl context.\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n * @private\n */\nfunction create3DContext(canvas, opt_attribs) {\n const names = [\"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL1 context.\n *\n * Note: Will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n * @deprecated\n * @private\n */\nfunction getWebGLContext(canvas, opt_attribs) {\n const gl = create3DContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Creates a webgl context.\n *\n * Will return a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * twgl.isWebGL2(gl);\n *\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n */\nfunction createContext(canvas, opt_attribs) {\n const names = [\"webgl2\", \"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL context. Will create a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * function isWebGL2(gl) {\n * return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0 \") == 0;\n * }\n *\n * Note: For a WebGL1 context will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n */\nfunction getContext(canvas, opt_attribs) {\n const gl = createContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Resize a canvas to match the size it's displayed.\n * @param {HTMLCanvasElement} canvas The canvas to resize.\n * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to.\n * @return {boolean} true if the canvas was resized.\n * @memberOf module:twgl\n */\nfunction resizeCanvasToDisplaySize(canvas, multiplier) {\n multiplier = multiplier || 1;\n multiplier = Math.max(0, multiplier);\n const width = canvas.clientWidth * multiplier | 0;\n const height = canvas.clientHeight * multiplier | 0;\n if (canvas.width !== width || canvas.height !== height) {\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n return false;\n}\n\nexport {\n addExtensionsToContext,\n getContext,\n getWebGLContext,\n resizeCanvasToDisplaySize,\n setDefaults,\n\n attributes,\n draw,\n framebuffers,\n programs,\n textures,\n typedarrays,\n utils,\n vertexArrays,\n};\n\n// function notPrivate(name) {\n// return name[name.length - 1] !== '_';\n// }\n//\n// function copyPublicProperties(src, dst) {\n// Object.keys(src).filter(notPrivate).forEach(function(key) {\n// dst[key] = src[key];\n// });\n// return dst;\n// }\n\nexport * from './attributes.js';\nexport * from './draw.js';\nexport * from './framebuffers.js';\nexport * from './programs.js';\nexport * from './textures.js';\nexport * from './typedarrays.js';\nexport * from './utils.js';\nexport * from './vertex-arrays.js';\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Low level shader typed array related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.typedArray` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/typedArray\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst glTypeToTypedArray = {};\n{\n const tt = glTypeToTypedArray;\n tt[BYTE] = Int8Array;\n tt[UNSIGNED_BYTE] = Uint8Array;\n tt[SHORT] = Int16Array;\n tt[UNSIGNED_SHORT] = Uint16Array;\n tt[INT] = Int32Array;\n tt[UNSIGNED_INT] = Uint32Array;\n tt[FLOAT] = Float32Array;\n tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array;\n tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array;\n tt[UNSIGNED_SHORT_5_6_5] = Uint16Array;\n tt[HALF_FLOAT] = Uint16Array;\n tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array;\n tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array;\n tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array;\n tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array;\n tt[UNSIGNED_INT_24_8] = Uint32Array;\n}\n\n/**\n * Get the GL type for a typedArray\n * @param {ArrayBufferView} typedArray a typedArray\n * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will\n * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArray(typedArray) {\n if (typedArray instanceof Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArray instanceof Int32Array) { return INT; } // eslint-disable-line\n if (typedArray instanceof Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArray instanceof Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the GL type for a typedArray type\n * @param {ArrayBufferView} typedArrayType a typedArray constructor\n * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will\n * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArrayType === Int32Array) { return INT; } // eslint-disable-line\n if (typedArrayType === Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArrayType === Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the typed array constructor for a given GL type\n * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`)\n * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`).\n * @memberOf module:twgl/typedArray\n */\nfunction getTypedArrayTypeForGLType(type) {\n const CTOR = glTypeToTypedArray[type];\n if (!CTOR) {\n throw new Error('unknown gl type');\n }\n return CTOR;\n}\n\nconst isArrayBuffer = typeof SharedArrayBuffer !== 'undefined'\n ? function isArrayBufferOrSharedArrayBuffer(a) {\n return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer);\n }\n : function isArrayBuffer(a) {\n return a && a.buffer && a.buffer instanceof ArrayBuffer;\n };\n\nexport {\n getGLTypeForTypedArray,\n getGLTypeForTypedArrayType,\n getTypedArrayTypeForGLType,\n isArrayBuffer,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Gets the gl version as a number\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {number} version of gl\n * @private\n */\n//function getVersionAsNumber(gl) {\n// return parseFloat(gl.getParameter(gl.VERSION).substr(6));\n//}\n\n/**\n * Check if context is WebGL 2.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 2.0\n * @memberOf module:twgl\n */\nfunction isWebGL2(gl) {\n // This is the correct check but it's slow\n // return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0\") === 0;\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGL2RenderingContext;\n return !!gl.texStorage2D;\n}\n\n/**\n * Check if context is WebGL 1.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 1.0\n * @memberOf module:twgl\n */\nfunction isWebGL1(gl) {\n // This is the correct check but it's slow\n // const version = getVersionAsNumber(gl);\n // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGLRenderingContext;\n return !gl.texStorage2D;\n}\n\n/**\n * Gets a string for WebGL enum\n *\n * Note: Several enums are the same. Without more\n * context (which function) it's impossible to always\n * give the correct enum. As it is, for matching values\n * it gives all enums. Checking the WebGL2RenderingContext\n * that means\n *\n * 0 = ZERO | POINT | NONE | NO_ERROR\n * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT\n * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB\n * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING\n * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING\n * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING\n *\n * It's also not useful for bits really unless you pass in individual bits.\n * In other words\n *\n * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT;\n * twgl.glEnumToString(gl, bits); // not going to work\n *\n * Note that some enums only exist on extensions. If you\n * want them to show up you need to pass the extension at least\n * once. For example\n *\n * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc');\n * if (ext) {\n * twgl.glEnumToString(ext, 0); // just prime the function\n *\n * ..later..\n *\n * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT;\n * console.log(twgl.glEnumToString(gl, internalFormat));\n *\n * Notice I didn't have to pass the extension the second time. This means\n * you can have place that generically gets an enum for texture formats for example.\n * and as long as you primed the function with the extensions\n *\n * If you're using `twgl.addExtensionsToContext` to enable your extensions\n * then twgl will automatically get the extension's enums.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object\n * @param {number} value the value of the enum you want to look up.\n * @return {string} enum string or hex value\n * @memberOf module:twgl\n * @function glEnumToString\n */\nconst glEnumToString = (function() {\n const haveEnumsForType = {};\n const enums = {};\n\n function addEnums(gl) {\n const type = gl.constructor.name;\n if (!haveEnumsForType[type]) {\n for (const key in gl) {\n if (typeof gl[key] === 'number') {\n const existing = enums[gl[key]];\n enums[gl[key]] = existing ? `${existing} | ${key}` : key;\n }\n }\n haveEnumsForType[type] = true;\n }\n }\n\n return function glEnumToString(gl, value) {\n addEnums(gl);\n return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value);\n };\n}());\n\nexport {\n glEnumToString,\n isWebGL1,\n isWebGL2,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\n/**\n * vertex array object related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/vertexArrays\n */\n\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\n\n/**\n * @typedef {Object} VertexArrayInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object\n * @memberOf module:twgl\n */\n\n/**\n * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects\n * assign buffers to specific attributes at creation time. That means they can only be used with programs\n * who's attributes use the same attribute locations for the same purposes.\n *\n * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo}\n * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match.\n *\n * also\n *\n * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object\n * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES**\n * will affect the Vertex Array Object state.\n *\n * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n *\n * You need to make sure every attribute that will be used is bound. So for example assume shader 1\n * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo\n * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't\n * now attribute D's location.\n *\n * So, you can pass in both shader 1 and shader 2's programInfo\n *\n * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVertexArrayInfo(gl, programInfos, bufferInfo) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n if (!programInfos.length) {\n programInfos = [programInfos];\n }\n programInfos.forEach(function(programInfo) {\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n });\n gl.bindVertexArray(null);\n return {\n numElements: bufferInfo.numElements,\n elementType: bufferInfo.elementType,\n vertexArrayObject: vao,\n };\n}\n\n/**\n * Creates a vertex array object and then sets the attributes on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} attribs AttribInfos mapped by attribute name.\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOAndSetAttributes(gl, setters, attribs, indices) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n programs.setAttributes(setters, attribs);\n if (indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, indices);\n }\n // We unbind this because otherwise any change to ELEMENT_ARRAY_BUFFER\n // like when creating buffers for other stuff will mess up this VAO's binding\n gl.bindVertexArray(null);\n return vao;\n}\n\n/**\n * Creates a vertex array object and then sets the attributes\n * on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {Object.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOFromBufferInfo(gl, programInfo, bufferInfo) {\n return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices);\n}\n\nexport {\n createVertexArrayInfo,\n createVAOAndSetAttributes,\n createVAOFromBufferInfo,\n};\n\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/twgl-base.js\");\n",""],"names":["typedArrays","_interopRequireWildcard","require","helper","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","_typeof","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","STATIC_DRAW","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","BUFFER_SIZE","BYTE","UNSIGNED_BYTE","SHORT","UNSIGNED_SHORT","INT","UNSIGNED_INT","FLOAT","gl","undefined","defaults","attribPrefix","setAttributePrefix","prefix","setDefaults","newDefaults","copyExistingProperties","setBufferFromTypedArray","type","buffer","array","drawType","bindBuffer","bufferData","createBufferFromTypedArray","typedArray","isBuffer","createBuffer","isIndices","name","getNormalizationForTypedArrayType","typedArrayType","Int8Array","Uint8Array","getArray","length","data","texcoordRE","colorRE","guessNumComponentsFromName","numComponents","test","Error","concat","getNumComponents","arrayName","numValues","size","makeTypedArray","isArrayBuffer","Array","isArray","Type","typedArrayTypeFromGLTypeOrTypedArrayCtor","Uint16Array","Float32Array","glTypeFromGLTypeOrTypedArrayType","glTypeOrTypedArrayCtor","getGLTypeForTypedArrayType","getTypedArrayTypeForGLType","attribBufferFromBuffer","arrayType","attribBufferFromSize","numBytes","BYTES_PER_ELEMENT","attribBufferFromArrayLike","constructor","getGLTypeForTypedArray","createAttribsFromArrays","arrays","attribs","keys","forEach","attribName","attrib","value","fn","WebGLBuffer","_fn","normalization","normalize","stride","offset","divisor","setAttribInfoBufferFromArray","attribInfo","bufferSubData","getBytesPerValueForGLType","positionKeys","getNumElementsFromNonIndexedArrays","key","ii","numElements","getNumElementsFromAttributes","getBufferParameter","bytesPerValue","totalElements","createBufferInfoFromArrays","srcBufferInfo","newAttribs","bufferInfo","assign","indices","newIndices","elementType","createBufferFromArray","createBuffersFromArrays","buffers","programs","TRIANGLES","drawBufferInfo","count","instanceCount","drawElementsInstanced","drawElements","drawArraysInstanced","drawArrays","drawObjectList","objectsToDraw","lastUsedProgramInfo","lastUsedBufferInfo","object","active","programInfo","vertexArrayInfo","bindBuffers","useProgram","program","vertexArrayObject","bindVertexArray","setBuffersAndAttributes","setUniforms","uniforms","textures","FRAMEBUFFER","RENDERBUFFER","TEXTURE_2D","DEPTH_COMPONENT","RGBA","DEPTH_COMPONENT24","DEPTH_COMPONENT32F","DEPTH24_STENCIL8","DEPTH32F_STENCIL8","RGBA4","RGB5_A1","RGB565","DEPTH_COMPONENT16","STENCIL_INDEX","STENCIL_INDEX8","DEPTH_STENCIL","COLOR_ATTACHMENT0","DEPTH_ATTACHMENT","STENCIL_ATTACHMENT","DEPTH_STENCIL_ATTACHMENT","CLAMP_TO_EDGE","LINEAR","defaultAttachments","format","min","wrap","attachmentsByFormat","getAttachmentPointForFormat","internalFormat","renderbufferFormats","isRenderbufferFormat","MAX_COLOR_ATTACHMENT_POINTS","isColorAttachmentPoint","attachmentPoint","createFramebufferInfo","attachments","width","height","target","fb","createFramebuffer","bindFramebuffer","drawingBufferWidth","drawingBufferHeight","usedColorAttachmentsPoints","framebufferInfo","framebuffer","attachmentOptions","attachment","samples","push","createRenderbuffer","bindRenderbuffer","renderbufferStorageMultisample","renderbufferStorage","textureOptions","auto","minMag","mag","wrapS","wrapT","createTexture","isRenderbuffer","framebufferRenderbuffer","isTexture","layer","framebufferTextureLayer","level","framebufferTexture2D","drawBuffers","resizeFramebufferInfo","ndx","resizeTexture","bindFramebufferInfo","viewport","copyNamedProperties","names","src","dst","error","_console","console","apply","arguments","warn","_console2","isTypeWeakMaps","Map","isType","weakMap","isOfType","s","toString","substring","WebGLRenderbuffer","isShader","WebGLShader","WebGLTexture","isSampler","WebGLSampler","utils","_regeneratorRuntime","o","Symbol","iterator","c","asyncIterator","toStringTag","define","enumerable","configurable","writable","Generator","create","Context","makeInvokeMethod","tryCatch","arg","h","l","f","y","GeneratorFunction","GeneratorFunctionPrototype","p","d","getPrototypeOf","v","values","g","defineIteratorMethods","_invoke","AsyncIterator","invoke","resolve","__await","then","callInvokeWithMethodAndArg","done","method","delegate","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","TypeError","resultName","next","nextLoc","pushTryEntry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","isNaN","displayName","isGeneratorFunction","mark","setPrototypeOf","awrap","async","Promise","reverse","pop","prev","charAt","slice","stop","rval","handle","complete","finish","_catch","delegateYield","ownKeys","getOwnPropertySymbols","filter","_objectSpread","_defineProperty","getOwnPropertyDescriptors","defineProperties","obj","_toPropertyKey","_toPrimitive","String","toPrimitive","Number","asyncGeneratorStep","gen","reject","_next","_throw","info","_asyncToGenerator","self","args","err","_slicedToArray","arr","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","_createForOfIteratorHelper","allowArrayLike","it","F","_e","normalCompletion","didErr","step","_e2","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","minLen","_arrayLikeToArray","from","iter","len","arr2","getElementById","id","document","TEXTURE0","DYNAMIC_DRAW","UNIFORM_BUFFER","TRANSFORM_FEEDBACK_BUFFER","TRANSFORM_FEEDBACK","COMPILE_STATUS","LINK_STATUS","FRAGMENT_SHADER","VERTEX_SHADER","SEPARATE_ATTRIBS","ACTIVE_UNIFORMS","ACTIVE_ATTRIBUTES","TRANSFORM_FEEDBACK_VARYINGS","ACTIVE_UNIFORM_BLOCKS","UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER","UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER","UNIFORM_BLOCK_DATA_SIZE","UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES","FLOAT_VEC2","FLOAT_VEC3","FLOAT_VEC4","INT_VEC2","INT_VEC3","INT_VEC4","BOOL","BOOL_VEC2","BOOL_VEC3","BOOL_VEC4","FLOAT_MAT2","FLOAT_MAT3","FLOAT_MAT4","SAMPLER_2D","SAMPLER_CUBE","SAMPLER_3D","SAMPLER_2D_SHADOW","FLOAT_MAT2x3","FLOAT_MAT2x4","FLOAT_MAT3x2","FLOAT_MAT3x4","FLOAT_MAT4x2","FLOAT_MAT4x3","SAMPLER_2D_ARRAY","SAMPLER_2D_ARRAY_SHADOW","SAMPLER_CUBE_SHADOW","UNSIGNED_INT_VEC2","UNSIGNED_INT_VEC3","UNSIGNED_INT_VEC4","INT_SAMPLER_2D","INT_SAMPLER_3D","INT_SAMPLER_CUBE","INT_SAMPLER_2D_ARRAY","UNSIGNED_INT_SAMPLER_2D","UNSIGNED_INT_SAMPLER_3D","UNSIGNED_INT_SAMPLER_CUBE","UNSIGNED_INT_SAMPLER_2D_ARRAY","TEXTURE_CUBE_MAP","TEXTURE_3D","TEXTURE_2D_ARRAY","typeMap","getBindPointForSamplerType","bindPoint","floatSetter","location","uniform1f","floatArraySetter","uniform1fv","floatVec2Setter","uniform2fv","floatVec3Setter","uniform3fv","floatVec4Setter","uniform4fv","intSetter","uniform1i","intArraySetter","uniform1iv","intVec2Setter","uniform2iv","intVec3Setter","uniform3iv","intVec4Setter","uniform4iv","uintSetter","uniform1ui","uintArraySetter","uniform1uiv","uintVec2Setter","uniform2uiv","uintVec3Setter","uniform3uiv","uintVec4Setter","uniform4uiv","floatMat2Setter","uniformMatrix2fv","floatMat3Setter","uniformMatrix3fv","floatMat4Setter","uniformMatrix4fv","floatMat23Setter","uniformMatrix2x3fv","floatMat32Setter","uniformMatrix3x2fv","floatMat24Setter","uniformMatrix2x4fv","floatMat42Setter","uniformMatrix4x2fv","floatMat34Setter","uniformMatrix3x4fv","floatMat43Setter","uniformMatrix4x3fv","samplerSetter","unit","isWebGL2","textureOrPair","texture","sampler","activeTexture","bindTexture","bindSampler","samplerArraySetter","units","Int32Array","index","setter","arraySetter","cols","Uint32Array","rows","floatAttribSetter","b","disableVertexAttribArray","vertexAttrib4fv","vertexAttrib3fv","vertexAttrib2fv","vertexAttrib1fv","enableVertexAttribArray","vertexAttribPointer","vertexAttribDivisor","intAttribSetter","vertexAttrib4iv","vertexAttribIPointer","uintAttribSetter","vertexAttrib4uiv","matAttribSetter","typeInfo","defaultSize","rowOffset","attrTypeMap","errorRE","addLineNumbersWithError","log","lineOffset","matches","matchAll","lineNoToErrorMap","map","m","lineNo","parseInt","end","msg","split","line","join","spaceRE","prepShaderSource","shaderSource","replace","reportError","progOptions","errorCallback","callback","setTimeout","errors","checkShaderStatus","shaderType","shader","errFn","compiled","getShaderParameter","lastError","getShaderInfoLog","_prepShaderSource","getShaderSource","glEnumToString","getProgramOptions","opt_attribs","opt_locations","opt_errorCallback","transformFeedbackVaryings","transformFeedbackMode","opt","attribLocations","options","_len","_key","defaultShaderType","getShaderTypeFromScriptType","scriptType","indexOf","deleteProgramAndShaders","notThese","shaders","getAttachedShaders","_iterator","_step","deleteShader","deleteProgram","wait","ms","createProgramNoCheck","programOptions","createProgram","_getProgramOptions","elem","text","createShader","compileShader","attachShader","entries","_ref","_ref2","loc","bindAttribLocation","varyings","linkProgram","shaderSet","Set","hasErrors","getProgramErrors","waitForProgramLinkCompletionAsync","wrapCallbackFnToAsyncFn","arg1","_len2","_key2","createProgramAsync","exports","createProgramInfoAsync","createProgramInfo","_x","_x2","_waitForProgramLinkCompletionAsync","_callee","ext","checkFn","waitTime","_callee$","_context","getExtension","getProgramParameter","COMPLETION_STATUS_KHR","waitForAllProgramsLinkCompletionAsync","_x3","_x4","_waitForAllProgramsLinkCompletionAsync","_callee2","_i3","_Object$values2","_callee2$","_context2","linked","getProgramInfoLog","SHADER_TYPE","_","createProgramFromScripts","shaderScriptIds","_iterator2","_step2","scriptId","shaderScript","createProgramFromSources","shaderSources","isBuiltIn","startsWith","tokenRE","isDigit","addSetterToUniformTree","fullPath","node","uniformSetters","tokens","tokenNdx","path","token","isArrayIndex","accessor","isLastToken","child","setUniformTree","createUniformSetters","textureUnit","createUniformSetter","uniformInfo","endsWith","uniformTree","numUniforms","getActiveUniform","substr","getUniformLocation","createTransformFeedbackInfo","numVaryings","varying","getTransformFeedbackVarying","bindTransformFeedbackInfo","transformFeedbackInfo","buf","bindBufferRange","bindBufferBase","createTransformFeedback","tf","bindTransformFeedback","createUniformBlockSpecFromProgram","uniformData","uniformIndices","pair","pname","getActiveUniforms","blockSpecs","numUniformBlocks","getActiveUniformBlockName","blockSpec","getUniformBlockIndex","usedByVertexShader","getActiveUniformBlockParameter","usedByFragmentShader","used","arraySuffixRE","pad","padding","createUniformBlockUniformSetter","view","totalRows","row","col","createUniformBlockInfoFromProgram","uniformBlockSpec","blockName","_options$offset","_options$array","_options$buffer","_options$bufferOffset","ArrayBuffer","uniformBufferIndex","byteLength","uniformBlockBinding","setters","setterTree","uniformNdx","uniformView","asFloat","asUint8","bufferOffset","createUniformBlockInfo","bindUniformBlock","uniformBlockInfo","_uniformBlockInfo$siz","bufferBindIndex","setUniformBlock","setBlockUniforms","tree","prop","actualSetters","numArgs","aNdx","setUniformsAndBindTextures","createAttributeSetters","attribSetters","numAttribs","getActiveAttrib","getAttribLocation","setAttributes","createProgramInfoFromProgram","uniformLocations","fromEntries","_ref3","_ref4","k","_ref5","_ref6","notIdRE","source","script","origCallback","checkAllPrograms","programSpecs","noDeleteShadersSet","_i","_Object$entries","_Object$entries$_i","spec","_i2","_Object$values","_iterator3","_step3","createPrograms","_ref7","_ref8","add","createProgramInfos","createProgramInfosForPrograms","_ref9","_ref10","createProgramsAsync","createProgramInfosAsync","textureColor","crossOrigin","getShared2DContext","s_ctx","createElement","getContext","ALPHA","RGB","LUMINANCE","LUMINANCE_ALPHA","NEAREST","TEXTURE_CUBE_MAP_POSITIVE_X","TEXTURE_CUBE_MAP_NEGATIVE_X","TEXTURE_CUBE_MAP_POSITIVE_Y","TEXTURE_CUBE_MAP_NEGATIVE_Y","TEXTURE_CUBE_MAP_POSITIVE_Z","TEXTURE_CUBE_MAP_NEGATIVE_Z","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","TEXTURE_WRAP_R","TEXTURE_MIN_LOD","TEXTURE_MAX_LOD","TEXTURE_BASE_LEVEL","TEXTURE_MAX_LEVEL","TEXTURE_COMPARE_MODE","TEXTURE_COMPARE_FUNC","UNPACK_ALIGNMENT","UNPACK_ROW_LENGTH","UNPACK_IMAGE_HEIGHT","UNPACK_SKIP_PIXELS","UNPACK_SKIP_ROWS","UNPACK_SKIP_IMAGES","UNPACK_COLORSPACE_CONVERSION_WEBGL","UNPACK_PREMULTIPLY_ALPHA_WEBGL","UNPACK_FLIP_Y_WEBGL","R8","R8_SNORM","R16F","R32F","R8UI","R8I","RG16UI","RG16I","RG32UI","RG32I","RG8","RG8_SNORM","RG16F","RG32F","RG8UI","RG8I","R16UI","R16I","R32UI","R32I","RGB8","SRGB8","RGB8_SNORM","R11F_G11F_B10F","RGB9_E5","RGB16F","RGB32F","RGB8UI","RGB8I","RGB16UI","RGB16I","RGB32UI","RGB32I","RGBA8","SRGB8_ALPHA8","RGBA8_SNORM","RGB10_A2","RGBA16F","RGBA32F","RGBA8UI","RGBA8I","RGB10_A2UI","RGBA16UI","RGBA16I","RGBA32I","RGBA32UI","UNSIGNED_SHORT_4_4_4_4","UNSIGNED_SHORT_5_5_5_1","UNSIGNED_SHORT_5_6_5","HALF_FLOAT","HALF_FLOAT_OES","UNSIGNED_INT_2_10_10_10_REV","UNSIGNED_INT_10F_11F_11F_REV","UNSIGNED_INT_5_9_9_9_REV","FLOAT_32_UNSIGNED_INT_24_8_REV","UNSIGNED_INT_24_8","RG","RG_INTEGER","RED","RED_INTEGER","RGB_INTEGER","RGBA_INTEGER","formatInfo","numColorComponents","s_textureInternalFormatInfo","getTextureInternalFormatInfo","textureFormat","colorRenderable","textureFilterable","bytesPerElement","bytesPerElementMap","getBytesPerElementForInternalFormat","getFormatAndTypeForInternalFormat","isPowerOf2","canGenerateMipmap","canFilter","getNumComponentsForFormat","getTextureTypeForArrayType","defaultType","guessDimensions","Math","sqrt","setDefaultTextureColor","color","scopedSetPackState","colorspaceConversion","premultiplyAlpha","flipY","getParameter","pixelStorei","setSkipStateToDefault","setTextureSamplerParameters","parameteriFn","wrapR","minLod","maxLod","baseLevel","maxLevel","compareFunc","compareMode","setTextureParameters","tex","texParameteri","setSamplerParameters","samplerParameteri","createSampler","createSamplers","samplerOptions","samplers","make1Pixel","setTextureFilteringForSize","generateMipmap","filtering","shouldAutomaticallySetTextureFilteringForSize","getCubeFaceOrder","cubeFaceOrder","getCubeFacesWithNdx","faces","facesWithNdx","face","sort","setTextureFromElement","element","formatType","imgWidth","imgHeight","slices","nodeName","ctx","canvas","xOffset","yOffset","drawImage","texImage2D","createImageBitmap","colorSpaceConversion","imageBitmap","smallest","largest","max","depth","xMult","yMult","texImage3D","srcX","srcY","texSubImage3D","noop","urlIsSameOrigin","url","href","hostname","port","protocol","localOrigin","URL","origin","urlOrigin","setToAnonymousIfUndefinedAndURLIsNotSameOrigin","loadImage","img","Image","clearEventHandlers","removeEventListener","onError","onLoad","addEventListener","ImageBitmap","bm","cb","mode","fetch","response","ok","blob","bitmap","isTexImageSource","ImageData","HTMLElement","loadAndUseImage","setTextureTo1PixelColor","loadTextureFromUrl","loadCubemapFromUrls","urls","numToLoad","imgs","uploadImg","faceTarget","otherTarget","loadSlicesFromUrls","firstImage","setTextureFromArray","Uint8ClampedArray","dimensions","cbrt","unpackAlignment","elementsPerElement","faceSize","subarray","setEmptyTexture","isAsyncSrc","createTextures","numDownloading","images","callCallbackIfReady","onLoadFn","_twgl","attributes","_exportNames","draw","framebuffers","typedarrays","vertexArrays","addExtensionsToContext","setAttributeDefaults_","setTextureDefaults_","prefixRE","addExtensionToContext","extensionName","enums","fnSuffix","exec","enumSuffix","isFunc","suffix","origFn","supportedExtensions","create3DContext","context","getWebGLContext","createContext","resizeCanvasToDisplaySize","multiplier","clientWidth","clientHeight","glTypeToTypedArray","tt","Int16Array","CTOR","SharedArrayBuffer","isArrayBufferOrSharedArrayBuffer","texStorage2D","isWebGL1","haveEnumsForType","addEnums","existing","createVertexArrayInfo","programInfos","vao","createVertexArray","createVAOAndSetAttributes","createVAOFromBufferInfo"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/6.x/twgl.min.js b/dist/6.x/twgl.min.js new file mode 100644 index 00000000..a290d1b8 --- /dev/null +++ b/dist/6.x/twgl.min.js @@ -0,0 +1,6 @@ +/*! + * @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. + * Available via the MIT license. + * see: http://github.com/greggman/twgl.js for details + */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.twgl=t():e.twgl=t()}("undefined"!=typeof self?self:this,(()=>(()=>{"use strict";var e={650:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.createAttribsFromArrays=z,t.createBufferFromArray=C,t.createBufferFromTypedArray=F,t.createBufferInfoFromArrays=function(e,t,r){var n=z(e,t),i=Object.assign({},r||{});i.attribs=Object.assign({},r?r.attribs:{},n);var u=t.indices;if(u){var a=S(u,"indices");i.indices=F(e,a,c),i.numElements=a.length,i.elementType=o.getGLTypeForTypedArray(a)}else i.numElements||(i.numElements=function(e,t){var r,n;for(n=0;n0)throw new Error("numComponents ".concat(i," not correct for length ").concat(o));return u}(t);return r},t.getArray_=E,t.getNumComponents_=A,t.setAttribInfoBufferFromArray=function(e,t,r,n){r=S(r),void 0!==n?(e.bindBuffer(l,t.buffer),e.bufferSubData(l,n,r)):x(e,l,t.buffer,r,t.drawType)},t.setAttributeDefaults_=function(e){i.copyExistingProperties(e,w)},t.setAttributePrefix=function(e){w.attribPrefix=e};var o=a(r(801)),i=a(r(303));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(u=function(e){return e?r:t})(e)}function a(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=u(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var f=i?Object.getOwnPropertyDescriptor(e,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=e[a]}return o.default=e,r&&r.set(e,o),o}var f=35044,l=34962,c=34963,s=34660,y=5120,b=5121,v=5122,m=5123,d=5124,p=5125,h=5126,w={attribPrefix:""};function x(e,t,r,n,o){e.bindBuffer(t,r),e.bufferData(t,n,o||f)}function F(e,t,r,n){if(i.isBuffer(e,t))return t;r=r||l;var o=e.createBuffer();return x(e,r,o,t,n),o}function _(e){return"indices"===e}function E(e){return e.length?e:e.data}var j=/coord|texture/i,O=/color|colour/i;function A(e,t,r){return e.numComponents||e.size||function(e,t){var r;if(t%(r=j.test(e)?2:O.test(e)?4:3)>0)throw new Error("Can not guess numComponents for attribute '".concat(e,"'. Tried ").concat(r," but ").concat(t," values is not evenly divisible by ").concat(r,". You should specify it."));return r}(t,r||E(e).length)}function S(e,t){if(o.isArrayBuffer(e))return e;if(o.isArrayBuffer(e.data))return e.data;Array.isArray(e)&&(e={data:e});var r=e.type?T(e.type):void 0;return r||(r=_(t)?Uint16Array:Float32Array),new r(e.data)}function T(e){return"number"==typeof e?o.getTypedArrayTypeForGLType(e):e||Float32Array}function P(e,t){return{buffer:t.buffer,numValues:24,type:(r=t.type,"number"==typeof r?r:r?o.getGLTypeForTypedArrayType(r):h),arrayType:T(t.type)};var r}function g(e,t){var r=t.data||t,n=T(t.type),i=r*n.BYTES_PER_ELEMENT,u=e.createBuffer();return e.bindBuffer(l,u),e.bufferData(l,i,t.drawType||f),{buffer:u,numValues:r,type:o.getGLTypeForTypedArrayType(n),arrayType:n}}function R(e,t,r){var n=S(t,r);return{arrayType:n.constructor,buffer:F(e,n,void 0,t.drawType),type:o.getGLTypeForTypedArray(n),numValues:0}}function z(e,t){var r={};return Object.keys(t).forEach((function(n){if(!_(n)){var i=t[n],u=i.attrib||i.name||i.attribName||w.attribPrefix+n;if(i.value){if(!Array.isArray(i.value)&&!o.isArrayBuffer(i.value))throw new Error("array.value is not array or typedarray");r[u]={value:i.value}}else{var a=(i.buffer&&i.buffer instanceof WebGLBuffer?P:"number"==typeof i||"number"==typeof i.data?g:R)(e,i,n),f=a.buffer,l=a.type,c=a.numValues,s=a.arrayType,y=void 0!==i.normalize?i.normalize:(v=s)===Int8Array||v===Uint8Array,b=A(i,n,c);r[u]={buffer:f,numComponents:b,type:l,normalize:y,stride:i.stride||0,offset:i.offset||0,divisor:void 0===i.divisor?void 0:i.divisor,drawType:i.drawType}}}var v})),e.bindBuffer(l,null),r}var k=["position","positions","a_position"];function C(e,t,r){var n="indices"===r?c:l;return F(e,S(t,r),n)}},341:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.drawBufferInfo=f,t.drawObjectList=function(e,t){var r=null,n=null;t.forEach((function(t){if(!1!==t.active){var i=t.programInfo,a=t.vertexArrayInfo||t.bufferInfo,l=!1,c=void 0===t.type?u:t.type;i!==r&&(r=i,e.useProgram(i.program),l=!0),(l||a!==n)&&(n&&n.vertexArrayObject&&!a.vertexArrayObject&&e.bindVertexArray(null),n=a,o.setBuffersAndAttributes(e,i,a)),o.setUniforms(i,t.uniforms),f(e,a,c,t.count,t.offset,t.instanceCount)}})),n&&n.vertexArrayObject&&e.bindVertexArray(null)};var o=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=i(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},u=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var f=u?Object.getOwnPropertyDescriptor(e,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=e[a]}return o.default=e,r&&r.set(e,o),o}(r(38));function i(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(i=function(e){return e?r:t})(e)}var u=4,a=5123;function f(e,t,r,n,o,i){r=void 0===r?u:r;var f=t.indices,l=t.elementType,c=void 0===n?t.numElements:n;o=void 0===o?0:o,l||f?void 0!==i?e.drawElementsInstanced(r,c,void 0===l?a:t.elementType,o,i):e.drawElements(r,c,void 0===l?a:t.elementType,o):void 0!==i?e.drawArraysInstanced(r,o,c,i):e.drawArrays(r,o,c)}},167:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.bindFramebufferInfo=function(e,t,r){r=r||f,t?(e.bindFramebuffer(r,t.framebuffer),e.viewport(0,0,t.width,t.height)):(e.bindFramebuffer(r,null),e.viewport(0,0,e.drawingBufferWidth,e.drawingBufferHeight))},t.createFramebufferInfo=function(e,t,r,n){var u=f,a=e.createFramebuffer();e.bindFramebuffer(u,a),r=r||e.drawingBufferWidth,n=n||e.drawingBufferHeight;var s=[],b={framebuffer:a,attachments:[],width:r,height:n};(t=t||p).forEach((function(t,a){var f=t.attachment,v=t.samples,p=t.format,F=t.attachmentPoint||function(e,t){return h[e]||h[t]}(p,t.internalFormat);if(F||(F=y+a),function(e){return e>=y&&e1?e.renderbufferStorageMultisample(l,v,p,r,n):e.renderbufferStorage(l,p,r,n);else{var _=Object.assign({},t);_.width=r,_.height=n,void 0===_.auto&&(_.auto=!1,_.min=_.min||_.minMag||d,_.mag=_.mag||_.minMag||d,_.wrapS=_.wrapS||_.wrap||m,_.wrapT=_.wrapT||_.wrap||m),f=o.createTexture(e,_)}if(i.isRenderbuffer(e,f))e.framebufferRenderbuffer(u,F,l,f);else{if(!i.isTexture(e,f))throw new Error("unknown attachment type");void 0!==t.layer?e.framebufferTextureLayer(u,F,f,t.level||0,t.layer):e.framebufferTexture2D(u,F,t.target||c,f,t.level||0)}b.attachments.push(f)})),e.drawBuffers&&e.drawBuffers(s);return b},t.resizeFramebufferInfo=function(e,t,r,n,u){n=n||e.drawingBufferWidth,u=u||e.drawingBufferHeight,t.width=n,t.height=u,(r=r||p).forEach((function(r,a){var f=t.attachments[a],c=r.format,s=r.samples;if(void 0!==s||i.isRenderbuffer(e,f))e.bindRenderbuffer(l,f),s>1?e.renderbufferStorageMultisample(l,s,c,n,u):e.renderbufferStorage(l,c,n,u);else{if(!i.isTexture(e,f))throw new Error("unknown attachment type");o.resizeTexture(e,f,r,n,u)}}))};var o=a(r(175)),i=a(r(303));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(u=function(e){return e?r:t})(e)}function a(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=u(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var f=i?Object.getOwnPropertyDescriptor(e,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=e[a]}return o.default=e,r&&r.set(e,o),o}var f=36160,l=36161,c=3553,s=34041,y=36064,b=36096,v=33306,m=33071,d=9729,p=[{format:6408,type:5121,min:d,wrap:m},{format:s}],h={};h[34041]=v,h[6401]=36128,h[36168]=36128,h[6402]=b,h[33189]=b,h[33190]=b,h[36012]=b,h[35056]=v,h[36013]=v;var w={};w[32854]=!0,w[32855]=!0,w[36194]=!0,w[34041]=!0,w[33189]=!0,w[6401]=!0,w[36168]=!0;var x=32},303:(e,t)=>{function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}t.__esModule=!0,t.copyExistingProperties=function(e,t){Object.keys(t).forEach((function(r){t.hasOwnProperty(r)&&e.hasOwnProperty(r)&&(t[r]=e[r])}))},t.copyNamedProperties=function(e,t,r){e.forEach((function(e){var n=t[e];void 0!==n&&(r[e]=n)}))},t.error=function(){var e;(e=console).error.apply(e,arguments)},t.isBuffer=function(e,t){return"undefined"!=typeof WebGLBuffer&&o(t,"WebGLBuffer")},t.isRenderbuffer=function(e,t){return"undefined"!=typeof WebGLRenderbuffer&&o(t,"WebGLRenderbuffer")},t.isSampler=function(e,t){return"undefined"!=typeof WebGLSampler&&o(t,"WebGLSampler")},t.isShader=function(e,t){return"undefined"!=typeof WebGLShader&&o(t,"WebGLShader")},t.isTexture=function(e,t){return"undefined"!=typeof WebGLTexture&&o(t,"WebGLTexture")},t.warn=function(){var e;(e=console).warn.apply(e,arguments)};var n=new Map;function o(e,t){if(!e||"object"!==r(e))return!1;var o=n.get(t);o||(o=new WeakMap,n.set(t,o));var i=o.get(e);if(void 0===i){var u=Object.prototype.toString.call(e);i=u.substring(8,u.length-1)===t,o.set(e,i)}return i}},38:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.bindTransformFeedbackInfo=Re,t.bindUniformBlock=Ue,t.createAttributeSetters=Le,t.createProgram=he,t.createProgramAsync=void 0,t.createProgramFromScripts=function(e,t,r,n,o){var i,u=ve(r,n,o),a=[],f=m(t);try{for(f.s();!(i=f.n()).done;){var l=i.value,c=F(l);if(!c)return ye(u,"unknown script element: ".concat(l));a.push(c.text)}}catch(e){f.e(e)}finally{f.f()}return he(e,a,u)},t.createProgramFromSources=je,t.createProgramInfo=Xe,t.createProgramInfoAsync=void 0,t.createProgramInfoFromProgram=Be,t.createProgramInfos=He,t.createProgramInfosAsync=void 0,t.createPrograms=Ve,t.createProgramsAsync=void 0,t.createTransformFeedback=function(e,t,r){var n=e.createTransformFeedback();return e.bindTransformFeedback(T,n),e.useProgram(t.program),Re(e,t,r),e.bindTransformFeedback(T,null),n},t.createTransformFeedbackInfo=ge,t.createUniformBlockInfo=function(e,t,r){var n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};return Me(e,t.program,t.uniformBlockSpec,r,n)},t.createUniformBlockInfoFromProgram=Me,t.createUniformBlockSpecFromProgram=ze,t.createUniformSetters=Pe,t.setAttributes=Ge,t.setBlockUniforms=function(e,t){var r=e.setters;for(var n in t){var o=r[n];if(o)o(t[n])}},t.setBuffersAndAttributes=function(e,t,r){r.vertexArrayObject?e.bindVertexArray(r.vertexArrayObject):(Ge(t.attribSetters||t,r.attribs),r.indices&&e.bindBuffer(O,r.indices))},t.setUniformBlock=function(e,t,r){Ue(e,t,r)&&e.bufferSubData(A,0,r.asUint8,r.offset||0,r.size||0)},t.setUniforms=We,t.setUniformsAndBindTextures=void 0;var o=a(r(854)),i=a(r(303));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(u=function(e){return e?r:t})(e)}function a(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=u(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var f=i?Object.getOwnPropertyDescriptor(e,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=e[a]}return o.default=e,r&&r.set(e,o),o}function f(){f=function(){return t};var e,t={},r=Object.prototype,o=r.hasOwnProperty,i=Object.defineProperty||function(e,t,r){e[t]=r.value},u="function"==typeof Symbol?Symbol:{},a=u.iterator||"@@iterator",l=u.asyncIterator||"@@asyncIterator",c=u.toStringTag||"@@toStringTag";function s(e,t,r){return Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{s({},"")}catch(e){s=function(e,t,r){return e[t]=r}}function y(e,t,r,n){var o=t&&t.prototype instanceof w?t:w,u=Object.create(o.prototype),a=new z(n||[]);return i(u,"_invoke",{value:T(e,r,a)}),u}function b(e,t,r){try{return{type:"normal",arg:e.call(t,r)}}catch(e){return{type:"throw",arg:e}}}t.wrap=y;var v="suspendedStart",m="suspendedYield",d="executing",p="completed",h={};function w(){}function x(){}function F(){}var _={};s(_,a,(function(){return this}));var E=Object.getPrototypeOf,j=E&&E(E(k([])));j&&j!==r&&o.call(j,a)&&(_=j);var O=F.prototype=w.prototype=Object.create(_);function A(e){["next","throw","return"].forEach((function(t){s(e,t,(function(e){return this._invoke(t,e)}))}))}function S(e,t){function r(i,u,a,f){var l=b(e[i],e,u);if("throw"!==l.type){var c=l.arg,s=c.value;return s&&"object"==n(s)&&o.call(s,"__await")?t.resolve(s.__await).then((function(e){r("next",e,a,f)}),(function(e){r("throw",e,a,f)})):t.resolve(s).then((function(e){c.value=e,a(c)}),(function(e){return r("throw",e,a,f)}))}f(l.arg)}var u;i(this,"_invoke",{value:function(e,n){function o(){return new t((function(t,o){r(e,n,t,o)}))}return u=u?u.then(o,o):o()}})}function T(t,r,n){var o=v;return function(i,u){if(o===d)throw new Error("Generator is already running");if(o===p){if("throw"===i)throw u;return{value:e,done:!0}}for(n.method=i,n.arg=u;;){var a=n.delegate;if(a){var f=P(a,n);if(f){if(f===h)continue;return f}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===v)throw o=p,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=d;var l=b(t,r,n);if("normal"===l.type){if(o=n.done?p:m,l.arg===h)continue;return{value:l.arg,done:n.done}}"throw"===l.type&&(o=p,n.method="throw",n.arg=l.arg)}}}function P(t,r){var n=r.method,o=t.iterator[n];if(o===e)return r.delegate=null,"throw"===n&&t.iterator.return&&(r.method="return",r.arg=e,P(t,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),h;var i=b(o,t.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,h;var u=i.arg;return u?u.done?(r[t.resultName]=u.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=e),r.delegate=null,h):u:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,h)}function g(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function R(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function z(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(g,this),this.reset(!0)}function k(t){if(t||""===t){var r=t[a];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var i=-1,u=function r(){for(;++i=0;--i){var u=this.tryEntries[i],a=u.completion;if("root"===u.tryLoc)return n("end");if(u.tryLoc<=this.prev){var f=o.call(u,"catchLoc"),l=o.call(u,"finallyLoc");if(f&&l){if(this.prev=0;--r){var n=this.tryEntries[r];if(n.tryLoc<=this.prev&&o.call(n,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),R(r),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;R(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:k(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),h}},t}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,u=!0,a=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return u=e.done,e},e:function(e){a=!0,i=e},f:function(){try{u||null==r.return||r.return()}finally{if(a)throw i}}}}function d(e){return function(e){if(Array.isArray(e))return h(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||p(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function p(e,t){if(e){if("string"==typeof e)return h(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?h(e,t):void 0}}function h(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r1&&void 0!==arguments[1]?arguments[1]:"",r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,n=d(t.matchAll(le)),o=new Map(n.map((function(e,r){var o=parseInt(e[1]),i=n[r+1],u=i?i.index:t.length;return[o-1,t.substring(e.index,u)]})));return e.split("\n").map((function(e,t){var n=o.get(t);return"".concat(t+1+r,": ").concat(e).concat(n?"\n\n^^^ ".concat(n):"")})).join("\n")}(f,i,a),"\nError compiling ").concat(o.glEnumToString(e,t),": ").concat(i);return n(l),l}return""}function ve(e,t,r){var n,o,i;if("function"==typeof t&&(r=t,t=void 0),"function"==typeof e)r=e,e=void 0;else if(e&&!Array.isArray(e)){var u=e;r=u.errorCallback,e=u.attribLocations,n=u.transformFeedbackVaryings,o=u.transformFeedbackMode,i=u.callback}var a=r||w,f=[],l={errorCallback:function(e){f.push(e);for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n0&&void 0!==arguments[0]?arguments[0]:0;return new Promise((function(t){return setTimeout(t,e)}))};function pe(e,t,r){for(var n,o=e.createProgram(),i=ve(r),u=i.attribLocations,a=i.transformFeedbackVaryings,f=i.transformFeedbackMode,l=0;l=0?R:n.indexOf("vert")>=0?z:void 0)||b),c=e.createShader(b),e.shaderSource(c,se(y).shaderSource),e.compileShader(c),e.attachShader(o,c)}}Object.entries(u).forEach((function(t){var r=v(t,2),n=r[0],i=r[1];return e.bindAttribLocation(o,i,n)}));var m=a;return m&&(m.attribs&&(m=m.attribs),Array.isArray(m)||(m=Object.keys(m)),e.transformFeedbackVaryings(o,m,f||k)),e.linkProgram(o),o}function he(e,t,r,n,o){var i=ve(r,n,o),u=new Set(t),a=pe(e,t,i);function f(e,t){var r=Ee(e,t,i.errorCallback);return r&&function(e,t,r){var n,o=m(e.getAttachedShaders(t));try{for(o.s();!(n=o.n()).done;){var i=n.value;r.has(i)&&e.deleteShader(i)}}catch(e){o.e(e)}finally{o.f()}e.deleteProgram(t)}(e,t,u),r}if(!i.callback)return f(e,a)?void 0:a;xe(e,a).then((function(){var t=f(e,a);i.callback(t,t?void 0:a)}))}function we(e){return function(t,r){for(var n=arguments.length,o=new Array(n>2?n-2:0),i=2;i="0"&&e<="9"};function Te(e,t,r,n){for(var o=e.split(Ae).filter((function(e){return""!==e})),i=0,u="";;){var a=o[i++];u+=a;var f=Se(a[0]),l=f?parseInt(a):a;if(f&&(u+=o[i++]),i===o.length){r[l]=t;break}var c=o[i++],s="["===c,y=r[l]||(s?[]:{});r[l]=y,r=y,n[u]=n[u]||function(e){return function(t){Ie(e,t)}}(y),u+=c}}function Pe(e,t){var r=0;function n(t,n,o){var i,u=n.name.endsWith("[0]"),a=n.type,f=K[a];if(!f)throw new Error("unknown type: 0x".concat(a.toString(16)));if(f.bindPoint){var l=r;r+=n.size,i=u?f.arraySetter(e,a,l,o,n.size):f.setter(e,a,l,o,n.size)}else i=f.arraySetter&&u?f.arraySetter(e,o):f.setter(e,o);return i.location=o,i}for(var o={},i={},u=e.getProgramParameter(t,C),a=0;a4&&void 0!==arguments[4]?arguments[4]:{},l=r.blockSpecs,c=r.uniformData,s=l[n];if(!s)return x("no uniform block object named:",n),{name:n,uniforms:{}};var y=null!==(o=f.offset)&&void 0!==o?o:0,b=null!==(i=f.array)&&void 0!==i?i:new ArrayBuffer(s.size),v=null!==(u=f.buffer)&&void 0!==u?u:e.createBuffer(),m=s.index;e.bindBuffer(A,v),f.buffer||e.bufferData(A,b.byteLength,E),e.uniformBlockBinding(t,s.index,m);var d=n+".";ke.test(d)&&(d=d.replace(ke,"."));var p={},h={},w={};return s.uniformIndices.forEach((function(e){var t=c[e],r=t.name;r.startsWith(d)&&(r=r.substr(d.length));var n=r.endsWith("[0]");n&&(r=r.substr(0,r.length-3));var o=K[t.type],i=o.Type,u=n?Ce(o.size,16)*t.size:o.size*t.size,a=new i(b,y+t.offset,u/i.BYTES_PER_ELEMENT);p[r]=a;var f=function(e,t,r,n){if(t||r){n=n||1;var o=e.length/4;return function(t){for(var r=0,i=0,u=0;u2&&void 0!==arguments[2]?arguments[2]:{},n=new Set,o=Object.fromEntries(Object.entries(t).map((function(t){var o=v(t,2),i=o[0],u=o[1],a=c({},r),f=Array.isArray(u)?u:u.shaders;return Array.isArray(u)||Object.assign(a,u),f.forEach(n.add,n),[i,pe(e,f,a)]})));if(!r.callback)return De(e,o,t,n,r)?void 0:o;(function(e,t){return _e.apply(this,arguments)})(e,o).then((function(){var i=De(e,o,t,n,r);r.callback(i,i?void 0:o)}))}function He(e,t,r){function n(e,t){return Object.fromEntries(Object.entries(t).map((function(t){var r=v(t,2),n=r[0],o=r[1];return[n,Be(e,o)]})))}var o=(r=ve(r)).callback;o&&(r.callback=function(t,r){o(t,t?void 0:n(e,r))});var i=Ve(e,t,r);if(!o&&i)return n(e,i)}t.createProgramsAsync=we(Ve),t.createProgramInfosAsync=we(He)},175:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.canFilter=gt,t.canGenerateMipmap=Pt,t.createSampler=Lt,t.createSamplers=function(e,t){var r={};return Object.keys(t).forEach((function(n){r[n]=Lt(e,t[n])})),r},t.createTexture=tr,t.createTextures=function(e,t,r){r=r||Vt;var n=0,o=[],i={},u={};function a(){0===n&&setTimeout((function(){r(o.length?o:void 0,i,u)}),0)}return Object.keys(t).forEach((function(r){var f,l,c=t[r];("string"==typeof(l=c.src)||Array.isArray(l)&&"string"==typeof l[0])&&(f=function(e,t,i){u[r]=i,--n,e&&o.push(e),a()},++n),i[r]=tr(e,c,f)})),a(),i},t.getBytesPerElementForInternalFormat=At,t.getFormatAndTypeForInternalFormat=St,t.getNumComponentsForFormat=function(e){var t=Et[e];if(!t)throw"unknown format: "+e;return t.t},t.loadTextureFromUrl=$t,t.resizeTexture=function(e,t,r,n,o,i){n=n||r.width,o=o||r.height,i=i||r.depth;var u=r.target||j;e.bindTexture(u,t);var a,f=r.level||0,l=r.internalFormat||r.format||d,c=St(l),s=r.format||c.format,b=r.src;a=b&&(y(b)||Array.isArray(b)&&"number"==typeof b[0])?r.type||Rt(e,b,c.type):r.type||c.type;if(u===O)for(var v=0;v<6;++v)e.texImage2D(T+v,f,l,n,o,0,s,a,null);else u===A||u===S?e.texImage3D(u,f,l,n,o,i,0,s,a,null):e.texImage2D(u,f,l,n,o,0,s,a,null)},t.setDefaultTextureColor=kt,t.setEmptyTexture=er,t.setSamplerParameters=Wt,t.setTextureDefaults_=function(e){u.copyExistingProperties(e,s),e.textureColor&&kt(e.textureColor)},t.setTextureFilteringForSize=Gt,t.setTextureFromArray=Qt,t.setTextureFromElement=Dt,t.setTextureParameters=It;var o=f(r(854)),i=f(r(801)),u=f(r(303));function a(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(a=function(e){return e?r:t})(e)}function f(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=a(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var u in e)if("default"!==u&&Object.prototype.hasOwnProperty.call(e,u)){var f=i?Object.getOwnPropertyDescriptor(e,u):null;f&&(f.get||f.set)?Object.defineProperty(o,u,f):o[u]=e[u]}return o.default=e,r&&r.set(e,o),o}var l,c,s={textureColor:new Uint8Array([128,192,255,255]),textureOptions:{},crossOrigin:void 0},y=i.isArrayBuffer,b=function(){return l=l||("undefined"!=typeof document&&document.createElement?document.createElement("canvas").getContext("2d"):null)},v=6406,m=6407,d=6408,p=6409,h=6410,w=6402,x=34041,F=33071,_=9728,E=9729,j=3553,O=34067,A=32879,S=35866,T=34069,P=34070,g=34071,R=34072,z=34073,k=34074,C=10241,M=10240,U=10242,I=10243,W=32882,L=33082,G=33083,B=33084,N=33085,X=34892,D=34893,V=3317,H=3314,Y=32878,q=3316,K=3315,$=32877,Z=37443,J=37441,Q=37440,ee=33321,te=36756,re=33325,ne=33326,oe=33330,ie=33329,ue=33338,ae=33337,fe=33340,le=33339,ce=33323,se=36757,ye=33327,be=33328,ve=33336,me=33335,de=33332,pe=33331,he=33334,we=33333,xe=32849,Fe=35905,_e=36194,Ee=36758,je=35898,Oe=35901,Ae=34843,Se=34837,Te=36221,Pe=36239,ge=36215,Re=36233,ze=36209,ke=36227,Ce=32856,Me=35907,Ue=36759,Ie=32855,We=32854,Le=32857,Ge=34842,Be=34836,Ne=36220,Xe=36238,De=36975,Ve=36214,He=36232,Ye=36226,qe=36208,Ke=33189,$e=33190,Ze=36012,Je=36013,Qe=35056,et=5120,tt=5121,rt=5122,nt=5123,ot=5124,it=5125,ut=5126,at=32819,ft=32820,lt=33635,ct=5131,st=36193,yt=33640,bt=35899,vt=35902,mt=36269,dt=34042,pt=33319,ht=33320,wt=6403,xt=36244,Ft=36248,_t=36249,Et={},jt=Et;function Ot(e){if(!c){var t={};t[v]={o:v,i:!0,u:!0,l:[1,2,2,4],type:[tt,ct,st,ut]},t[p]={o:p,i:!0,u:!0,l:[1,2,2,4],type:[tt,ct,st,ut]},t[h]={o:h,i:!0,u:!0,l:[2,4,4,8],type:[tt,ct,st,ut]},t[m]={o:m,i:!0,u:!0,l:[3,6,6,12,2],type:[tt,ct,st,ut,lt]},t[d]={o:d,i:!0,u:!0,l:[4,8,8,16,2,2],type:[tt,ct,st,ut,at,ft]},t[w]={o:w,i:!0,u:!1,l:[2,4],type:[it,nt]},t[ee]={o:wt,i:!0,u:!0,l:[1],type:[tt]},t[te]={o:wt,i:!1,u:!0,l:[1],type:[et]},t[re]={o:wt,i:!1,u:!0,l:[4,2],type:[ut,ct]},t[ne]={o:wt,i:!1,u:!1,l:[4],type:[ut]},t[oe]={o:xt,i:!0,u:!1,l:[1],type:[tt]},t[ie]={o:xt,i:!0,u:!1,l:[1],type:[et]},t[de]={o:xt,i:!0,u:!1,l:[2],type:[nt]},t[pe]={o:xt,i:!0,u:!1,l:[2],type:[rt]},t[he]={o:xt,i:!0,u:!1,l:[4],type:[it]},t[we]={o:xt,i:!0,u:!1,l:[4],type:[ot]},t[ce]={o:pt,i:!0,u:!0,l:[2],type:[tt]},t[se]={o:pt,i:!1,u:!0,l:[2],type:[et]},t[ye]={o:pt,i:!1,u:!0,l:[8,4],type:[ut,ct]},t[be]={o:pt,i:!1,u:!1,l:[8],type:[ut]},t[ve]={o:ht,i:!0,u:!1,l:[2],type:[tt]},t[me]={o:ht,i:!0,u:!1,l:[2],type:[et]},t[ue]={o:ht,i:!0,u:!1,l:[4],type:[nt]},t[ae]={o:ht,i:!0,u:!1,l:[4],type:[rt]},t[fe]={o:ht,i:!0,u:!1,l:[8],type:[it]},t[le]={o:ht,i:!0,u:!1,l:[8],type:[ot]},t[xe]={o:m,i:!0,u:!0,l:[3],type:[tt]},t[Fe]={o:m,i:!1,u:!0,l:[3],type:[tt]},t[_e]={o:m,i:!0,u:!0,l:[3,2],type:[tt,lt]},t[Ee]={o:m,i:!1,u:!0,l:[3],type:[et]},t[je]={o:m,i:!1,u:!0,l:[12,6,4],type:[ut,ct,bt]},t[Oe]={o:m,i:!1,u:!0,l:[12,6,4],type:[ut,ct,vt]},t[Ae]={o:m,i:!1,u:!0,l:[12,6],type:[ut,ct]},t[Se]={o:m,i:!1,u:!1,l:[12],type:[ut]},t[Te]={o:Ft,i:!1,u:!1,l:[3],type:[tt]},t[Pe]={o:Ft,i:!1,u:!1,l:[3],type:[et]},t[ge]={o:Ft,i:!1,u:!1,l:[6],type:[nt]},t[Re]={o:Ft,i:!1,u:!1,l:[6],type:[rt]},t[ze]={o:Ft,i:!1,u:!1,l:[12],type:[it]},t[ke]={o:Ft,i:!1,u:!1,l:[12],type:[ot]},t[Ce]={o:d,i:!0,u:!0,l:[4],type:[tt]},t[Me]={o:d,i:!0,u:!0,l:[4],type:[tt]},t[Ue]={o:d,i:!1,u:!0,l:[4],type:[et]},t[Ie]={o:d,i:!0,u:!0,l:[4,2,4],type:[tt,ft,yt]},t[We]={o:d,i:!0,u:!0,l:[4,2],type:[tt,at]},t[Le]={o:d,i:!0,u:!0,l:[4],type:[yt]},t[Ge]={o:d,i:!1,u:!0,l:[16,8],type:[ut,ct]},t[Be]={o:d,i:!1,u:!1,l:[16],type:[ut]},t[Ne]={o:_t,i:!0,u:!1,l:[4],type:[tt]},t[Xe]={o:_t,i:!0,u:!1,l:[4],type:[et]},t[De]={o:_t,i:!0,u:!1,l:[4],type:[yt]},t[Ve]={o:_t,i:!0,u:!1,l:[8],type:[nt]},t[He]={o:_t,i:!0,u:!1,l:[8],type:[rt]},t[Ye]={o:_t,i:!0,u:!1,l:[16],type:[ot]},t[qe]={o:_t,i:!0,u:!1,l:[16],type:[it]},t[Ke]={o:w,i:!0,u:!1,l:[2,4],type:[nt,it]},t[$e]={o:w,i:!0,u:!1,l:[4],type:[it]},t[Ze]={o:w,i:!0,u:!1,l:[4],type:[ut]},t[Qe]={o:x,i:!0,u:!1,l:[4],type:[dt]},t[Je]={o:x,i:!0,u:!1,l:[4],type:[mt]},Object.keys(t).forEach((function(e){var r=t[e];r.bytesPerElementMap={},r.l.forEach((function(e,t){var n=r.type[t];r.bytesPerElementMap[n]=e}))})),c=t}return c[e]}function At(e,t){var r=Ot(e);if(!r)throw"unknown internal format";var n=r.bytesPerElementMap[t];if(void 0===n)throw"unknown internal format";return n}function St(e){var t=Ot(e);if(!t)throw"unknown internal format";return{format:t.o,type:t.type[0]}}function Tt(e){return 0==(e&e-1)}function Pt(e,t,r,n){if(!o.isWebGL2(e))return Tt(t)&&Tt(r);var i=Ot(n);if(!i)throw"unknown internal format";return i.i&&i.u}function gt(e){var t=Ot(e);if(!t)throw"unknown internal format";return t.u}function Rt(e,t,r){return y(t)?i.getGLTypeForTypedArray(t):r||tt}function zt(e,t,r,n,o){if(o%1!=0)throw"can't guess dimensions";if(r||n){if(n){if(!r&&(r=o/n)%1)throw"can't guess dimensions"}else if((n=o/r)%1)throw"can't guess dimensions"}else{var i=Math.sqrt(o/(t===O?6:1));i%1==0?(r=i,n=i):(r=o,n=1)}return{width:r,height:n}}function kt(e){s.textureColor=new Uint8Array([255*e[0],255*e[1],255*e[2],255*e[3]])}function Ct(e,t,r){var n,o,i;void 0!==t.colorspaceConversion&&(n=e.getParameter(Z),e.pixelStorei(Z,t.colorspaceConversion)),void 0!==t.premultiplyAlpha&&(o=e.getParameter(J),e.pixelStorei(J,t.premultiplyAlpha)),void 0!==t.flipY&&(i=e.getParameter(Q),e.pixelStorei(Q,t.flipY)),r(),void 0!==n&&e.pixelStorei(Z,n),void 0!==o&&e.pixelStorei(J,o),void 0!==i&&e.pixelStorei(Q,i)}function Mt(e){e.pixelStorei(V,4),o.isWebGL2(e)&&(e.pixelStorei(H,0),e.pixelStorei(Y,0),e.pixelStorei(q,0),e.pixelStorei(K,0),e.pixelStorei($,0))}function Ut(e,t,r,n){n.minMag&&(r.call(e,t,C,n.minMag),r.call(e,t,M,n.minMag)),n.min&&r.call(e,t,C,n.min),n.mag&&r.call(e,t,M,n.mag),n.wrap&&(r.call(e,t,U,n.wrap),r.call(e,t,I,n.wrap),(t===A||u.isSampler(e,t))&&r.call(e,t,W,n.wrap)),n.wrapR&&r.call(e,t,W,n.wrapR),n.wrapS&&r.call(e,t,U,n.wrapS),n.wrapT&&r.call(e,t,I,n.wrapT),void 0!==n.minLod&&r.call(e,t,L,n.minLod),void 0!==n.maxLod&&r.call(e,t,G,n.maxLod),void 0!==n.baseLevel&&r.call(e,t,B,n.baseLevel),void 0!==n.maxLevel&&r.call(e,t,N,n.maxLevel),void 0!==n.compareFunc&&r.call(e,t,D,n.compareFunc),void 0!==n.compareMode&&r.call(e,t,X,n.compareMode)}function It(e,t,r){var n=r.target||j;e.bindTexture(n,t),Ut(e,n,e.texParameteri,r)}function Wt(e,t,r){Ut(e,t,e.samplerParameteri,r)}function Lt(e,t){var r=e.createSampler();return Wt(e,r,t),r}function Gt(e,t,r,n,o,i){r=r||s.textureOptions,i=i||d;var u=r.target||j;if(n=n||r.width,o=o||r.height,e.bindTexture(u,t),Pt(e,n,o,i))e.generateMipmap(u);else{var a=gt(i)?E:_;e.texParameteri(u,C,a),e.texParameteri(u,M,a),e.texParameteri(u,U,F),e.texParameteri(u,I,F)}}function Bt(e){return!0===e.auto||void 0===e.auto&&void 0===e.level}function Nt(e,t){return(t=t||{}).cubeFaceOrder||[T,P,g,R,z,k]}function Xt(e,t){var r=Nt(0,t).map((function(e,t){return{face:e,ndx:t}}));return r.sort((function(e,t){return e.face-t.face})),r}function Dt(e,t,r,n){var o=(n=n||s.textureOptions).target||j,i=n.level||0,u=r.width,a=r.height,f=n.internalFormat||n.format||d,l=St(f),c=n.format||l.format,y=n.type||l.type;if(e.bindTexture(o,t),o===O){var v,m,p=r.width,h=r.height;if(p/6===h)v=h,m=[0,0,1,0,2,0,3,0,4,0,5,0];else if(h/6===p)v=p,m=[0,0,0,1,0,2,0,3,0,4,0,5];else if(p/3==h/2)v=p/3,m=[0,0,1,0,2,0,0,1,1,1,2,1];else{if(p/2!=h/3)throw"can't figure out cube map from element: "+(r.src?r.src:r.nodeName);v=p/2,m=[0,0,1,0,0,1,1,1,0,2,1,2]}var w=b();w?(w.canvas.width=v,w.canvas.height=v,u=v,a=v,Ct(e,n,(function(){Xt(0,n).forEach((function(t){var n=m[2*t.ndx+0]*v,o=m[2*t.ndx+1]*v;w.drawImage(r,n,o,v,v,0,0,v,v),e.texImage2D(t.face,i,f,c,y,w.canvas)})),w.canvas.width=1,w.canvas.height=1}))):"undefined"!=typeof createImageBitmap&&(u=v,a=v,Xt(0,n).forEach((function(l){var s=m[2*l.ndx+0]*v,b=m[2*l.ndx+1]*v;e.texImage2D(l.face,i,f,v,v,0,c,y,null),createImageBitmap(r,s,b,v,v,{premultiplyAlpha:"none",colorSpaceConversion:"none"}).then((function(r){Ct(e,n,(function(){e.bindTexture(o,t),e.texImage2D(l.face,i,f,c,y,r),Bt(n)&&Gt(e,t,n,u,a,f)}))}))})))}else Ct(e,n,o===A||o===S?function(){var t=Math.min(r.width,r.height),n=Math.max(r.width,r.height),u=n/t;if(u%1!=0)throw"can not compute 3D dimensions of element";var a=r.width===n?1:0,l=r.height===n?1:0;e.pixelStorei(V,1),e.pixelStorei(H,r.width),e.pixelStorei(Y,0),e.pixelStorei($,0),e.texImage3D(o,i,f,t,t,t,0,c,y,null);for(var s=0;s{t.__esModule=!0;var n=r(373);Object.keys(n).forEach((function(e){"default"!==e&&"__esModule"!==e&&(e in t&&t[e]===n[e]||(t[e]=n[e]))}))},373:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0;var o={addExtensionsToContext:!0,getContext:!0,getWebGLContext:!0,resizeCanvasToDisplaySize:!0,setDefaults:!0,attributes:!0,textures:!0,utils:!0,draw:!0,framebuffers:!0,programs:!0,typedarrays:!0,vertexArrays:!0};t.addExtensionsToContext=x,t.framebuffers=t.draw=t.attributes=void 0,t.getContext=function(e,t){var r=function(e,t){for(var r=["webgl2","webgl","experimental-webgl"],n=null,o=0;o{t.__esModule=!0,t.getGLTypeForTypedArray=function(e){if(e instanceof Int8Array)return r;if(e instanceof Uint8Array)return n;if(e instanceof Uint8ClampedArray)return n;if(e instanceof Int16Array)return o;if(e instanceof Uint16Array)return i;if(e instanceof Int32Array)return u;if(e instanceof Uint32Array)return a;if(e instanceof Float32Array)return f;throw new Error("unsupported typed array type")},t.getGLTypeForTypedArrayType=function(e){if(e===Int8Array)return r;if(e===Uint8Array)return n;if(e===Uint8ClampedArray)return n;if(e===Int16Array)return o;if(e===Uint16Array)return i;if(e===Int32Array)return u;if(e===Uint32Array)return a;if(e===Float32Array)return f;throw new Error("unsupported typed array type")},t.getTypedArrayTypeForGLType=function(e){var t=l[e];if(!t)throw new Error("unknown gl type");return t},t.isArrayBuffer=void 0;var r=5120,n=5121,o=5122,i=5123,u=5124,a=5125,f=5126,l={},c=l;c[r]=Int8Array,c[n]=Uint8Array,c[o]=Int16Array,c[i]=Uint16Array,c[u]=Int32Array,c[a]=Uint32Array,c[f]=Float32Array,c[32819]=Uint16Array,c[32820]=Uint16Array,c[33635]=Uint16Array,c[5131]=Uint16Array,c[33640]=Uint32Array,c[35899]=Uint32Array,c[35902]=Uint32Array,c[36269]=Uint32Array,c[34042]=Uint32Array;t.isArrayBuffer="undefined"!=typeof SharedArrayBuffer?function(e){return e&&e.buffer&&(e.buffer instanceof ArrayBuffer||e.buffer instanceof SharedArrayBuffer)}:function(e){return e&&e.buffer&&e.buffer instanceof ArrayBuffer}},854:(e,t)=>{t.__esModule=!0,t.glEnumToString=void 0,t.isWebGL1=function(e){return!e.texStorage2D},t.isWebGL2=function(e){return!!e.texStorage2D};var r,n;t.glEnumToString=(r={},n={},function(e,t){return function(e){var t=e.constructor.name;if(!r[t]){for(var o in e)if("number"==typeof e[o]){var i=n[e[o]];n[e[o]]=i?"".concat(i," | ").concat(o):o}r[t]=!0}}(e),n[t]||("number"==typeof t?"0x".concat(t.toString(16)):t)})},496:(e,t,r)=>{function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}t.__esModule=!0,t.createVAOAndSetAttributes=a,t.createVAOFromBufferInfo=function(e,t,r){return a(e,t.attribSetters||t,r.attribs,r.indices)},t.createVertexArrayInfo=function(e,t,r){var n=e.createVertexArray();e.bindVertexArray(n),t.length||(t=[t]);return t.forEach((function(t){o.setBuffersAndAttributes(e,t,r)})),e.bindVertexArray(null),{numElements:r.numElements,elementType:r.elementType,vertexArrayObject:n}};var o=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=n(e)&&"function"!=typeof e)return{default:e};var r=i(t);if(r&&r.has(e))return r.get(e);var o={__proto__:null},u=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var a in e)if("default"!==a&&Object.prototype.hasOwnProperty.call(e,a)){var f=u?Object.getOwnPropertyDescriptor(e,a):null;f&&(f.get||f.set)?Object.defineProperty(o,a,f):o[a]=e[a]}return o.default=e,r&&r.set(e,o),o}(r(38));function i(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,r=new WeakMap;return(i=function(e){return e?r:t})(e)}var u=34963;function a(e,t,r,n){var i=e.createVertexArray();return e.bindVertexArray(i),o.setAttributes(t,r),n&&e.bindBuffer(u,n),e.bindVertexArray(null),i}}},t={};var r=function r(n){var o=t[n];if(void 0!==o)return o.exports;var i=t[n]={exports:{}};return e[n](i,i.exports,r),i.exports}(599);return r})())); \ No newline at end of file diff --git a/dist/6.x/twgl.module.js b/dist/6.x/twgl.module.js new file mode 100644 index 00000000..9f68e597 --- /dev/null +++ b/dist/6.x/twgl.module.js @@ -0,0 +1,6233 @@ +/* @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. +Available via the MIT license. +see: http://github.com/greggman/twgl.js for details */ +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* DataType */ +const BYTE$2 = 0x1400; +const UNSIGNED_BYTE$3 = 0x1401; +const SHORT$2 = 0x1402; +const UNSIGNED_SHORT$3 = 0x1403; +const INT$3 = 0x1404; +const UNSIGNED_INT$3 = 0x1405; +const FLOAT$3 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4$1 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1$1 = 0x8034; +const UNSIGNED_SHORT_5_6_5$1 = 0x8363; +const HALF_FLOAT$1 = 0x140B; +const UNSIGNED_INT_2_10_10_10_REV$1 = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV$1 = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV$1 = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV$1 = 0x8DAD; +const UNSIGNED_INT_24_8$1 = 0x84FA; + +const glTypeToTypedArray = {}; +{ + const tt = glTypeToTypedArray; + tt[BYTE$2] = Int8Array; + tt[UNSIGNED_BYTE$3] = Uint8Array; + tt[SHORT$2] = Int16Array; + tt[UNSIGNED_SHORT$3] = Uint16Array; + tt[INT$3] = Int32Array; + tt[UNSIGNED_INT$3] = Uint32Array; + tt[FLOAT$3] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5$1] = Uint16Array; + tt[HALF_FLOAT$1] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV$1] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV$1] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV$1] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV$1] = Uint32Array; + tt[UNSIGNED_INT_24_8$1] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArray instanceof Int32Array) { return INT$3; } // eslint-disable-line + if (typedArray instanceof Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArray instanceof Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArrayType === Int32Array) { return INT$3; } // eslint-disable-line + if (typedArrayType === Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArrayType === Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + const CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} + +const isArrayBuffer$1 = typeof SharedArrayBuffer !== 'undefined' + ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); + } + : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; + }; + +var typedarrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + getGLTypeForTypedArray: getGLTypeForTypedArray, + getGLTypeForTypedArrayType: getGLTypeForTypedArrayType, + getTypedArrayTypeForGLType: getTypedArrayTypeForGLType, + isArrayBuffer: isArrayBuffer$1 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function(key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} + +function error$1(...args) { + console.error(...args); +} + +function warn$1(...args) { + console.warn(...args); +} + +const isTypeWeakMaps = new Map(); + +function isType(object, type) { + if (!object || typeof object !== 'object') { + return false; + } + let weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + let isOfType = weakMap.get(object); + if (isOfType === undefined) { + const s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} + +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} + +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} + +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} + +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const STATIC_DRAW = 0x88e4; +const ARRAY_BUFFER$1 = 0x8892; +const ELEMENT_ARRAY_BUFFER$2 = 0x8893; +const BUFFER_SIZE = 0x8764; + +const BYTE$1 = 0x1400; +const UNSIGNED_BYTE$2 = 0x1401; +const SHORT$1 = 0x1402; +const UNSIGNED_SHORT$2 = 0x1403; +const INT$2 = 0x1404; +const UNSIGNED_INT$2 = 0x1405; +const FLOAT$2 = 0x1406; +const defaults$2 = { + attribPrefix: "", +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults$2.attribPrefix = prefix; +} + +function setDefaults$2(newDefaults) { + copyExistingProperties(newDefaults, defaults$2); +} + +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER$1; + const buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} + +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return true; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line + return false; +} + +function getArray(array) { + return array.length ? array : array.data; +} + +const texcoordRE = /coord|texture/i; +const colorRE = /color|colour/i; + +function guessNumComponentsFromName(name, length) { + let numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + + if (length % numComponents > 0) { + throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`); + } + + return numComponents; +} + +function getNumComponents(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length); +} + +function makeTypedArray(array, name) { + if (isArrayBuffer$1(array)) { + return array; + } + + if (isArrayBuffer$1(array.data)) { + return array.data; + } + + if (Array.isArray(array)) { + array = { + data: array, + }; + } + + let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} + +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? glTypeOrTypedArrayCtor + : glTypeOrTypedArrayCtor ? getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT$2; +} + +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) + : glTypeOrTypedArrayCtor || Float32Array; +} + +function attribBufferFromBuffer(gl, array/*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type), + }; +} + +function attribBufferFromSize(gl, array/*, arrayName*/) { + const numValues = array.data || array; + const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + const numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + const buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER$1, buffer); + gl.bufferData(ARRAY_BUFFER$1, numBytes, array.drawType || STATIC_DRAW); + return { + buffer, + numValues, + type: getGLTypeForTypedArrayType(arrayType), + arrayType, + }; +} + +function attribBufferFromArrayLike(gl, array, arrayName) { + const typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: getGLTypeForTypedArray(typedArray), + numValues: 0, + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + const attribs = {}; + Object.keys(arrays).forEach(function(arrayName) { + if (!isIndices(arrayName)) { + const array = arrays[arrayName]; + const attribName = array.attrib || array.name || array.attribName || (defaults$2.attribPrefix + arrayName); + if (array.value) { + if (!Array.isArray(array.value) && !isArrayBuffer$1(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value, + }; + } else { + let fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName); + const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + const numComponents = getNumComponents(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType, + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER$1, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER$1, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER$1, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER$1, attribInfo.buffer, array, attribInfo.drawType); + } +} + +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE$1) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE$2) return 1; // eslint-disable-line + if (type === SHORT$1) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT$2) return 2; // eslint-disable-line + if (type === INT$2) return 4; // eslint-disable-line + if (type === UNSIGNED_INT$2) return 4; // eslint-disable-line + if (type === FLOAT$2) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +const positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + const array = arrays[key]; + const length = getArray(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + const numComponents = getNumComponents(array, key); + const numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +function getNumElementsFromAttributes(gl, attribs) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults$2.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + const attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER$1, attrib.buffer); + const numBytes = gl.getBufferParameter(ARRAY_BUFFER$1, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER$1, null); + + const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + const totalElements = numBytes / bytesPerValue; + const numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + const numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + const newAttribs = createAttribsFromArrays(gl, arrays); + const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + const indices = arrays.indices; + if (indices) { + const newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER$2); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + const type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER$2 : ARRAY_BUFFER$1; + const typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + const buffers = { }; + Object.keys(arrays).forEach(function(key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = getGLTypeForTypedArray(makeTypedArray(arrays.indices)); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + + return buffers; +} + +var attributes = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttribsFromArrays: createAttribsFromArrays, + createBuffersFromArrays: createBuffersFromArrays, + createBufferFromArray: createBufferFromArray, + createBufferFromTypedArray: createBufferFromTypedArray, + createBufferInfoFromArrays: createBufferInfoFromArrays, + setAttribInfoBufferFromArray: setAttribInfoBufferFromArray, + setAttributePrefix: setAttributePrefix, + setAttributeDefaults_: setDefaults$2, + getNumComponents_: getNumComponents, + getArray_: getArray +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +const glEnumToString = (function() { + const haveEnumsForType = {}; + const enums = {}; + + function addEnums(gl) { + const type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (const key in gl) { + if (typeof gl[key] === 'number') { + const existing = enums[gl[key]]; + enums[gl[key]] = existing ? `${existing} | ${key}` : key; + } + } + haveEnumsForType[type] = true; + } + } + + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value); + }; +}()); + +var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + glEnumToString: glEnumToString, + isWebGL1: isWebGL1, + isWebGL2: isWebGL2 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults$1 = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined, +}; +const isArrayBuffer = isArrayBuffer$1; + +// Should we make this on demand? +const getShared2DContext = function() { + let s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || + ((typeof document !== 'undefined' && document.createElement) + ? document.createElement("canvas").getContext("2d") + : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +const ALPHA = 0x1906; +const RGB = 0x1907; +const RGBA$1 = 0x1908; +const LUMINANCE = 0x1909; +const LUMINANCE_ALPHA = 0x190A; +const DEPTH_COMPONENT$1 = 0x1902; +const DEPTH_STENCIL$1 = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +const CLAMP_TO_EDGE$1 = 0x812f; + +/* TextureMagFilter */ +const NEAREST = 0x2600; +const LINEAR$1 = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +const TEXTURE_2D$2 = 0x0de1; +const TEXTURE_CUBE_MAP$1 = 0x8513; +const TEXTURE_3D$1 = 0x806f; +const TEXTURE_2D_ARRAY$1 = 0x8c1a; + +/* Cubemap Targets */ +const TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +const TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +const TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +const TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +const TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +const TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +const TEXTURE_MIN_FILTER = 0x2801; +const TEXTURE_MAG_FILTER = 0x2800; +const TEXTURE_WRAP_S = 0x2802; +const TEXTURE_WRAP_T = 0x2803; +const TEXTURE_WRAP_R = 0x8072; +const TEXTURE_MIN_LOD = 0x813a; +const TEXTURE_MAX_LOD = 0x813b; +const TEXTURE_BASE_LEVEL = 0x813c; +const TEXTURE_MAX_LEVEL = 0x813d; +const TEXTURE_COMPARE_MODE = 0x884C; +const TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +const UNPACK_ALIGNMENT = 0x0cf5; +const UNPACK_ROW_LENGTH = 0x0cf2; +const UNPACK_IMAGE_HEIGHT = 0x806e; +const UNPACK_SKIP_PIXELS = 0x0cf4; +const UNPACK_SKIP_ROWS = 0x0cf3; +const UNPACK_SKIP_IMAGES = 0x806d; +const UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +const UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +const UNPACK_FLIP_Y_WEBGL = 0x9240; + +const R8 = 0x8229; +const R8_SNORM = 0x8F94; +const R16F = 0x822D; +const R32F = 0x822E; +const R8UI = 0x8232; +const R8I = 0x8231; +const RG16UI = 0x823A; +const RG16I = 0x8239; +const RG32UI = 0x823C; +const RG32I = 0x823B; +const RG8 = 0x822B; +const RG8_SNORM = 0x8F95; +const RG16F = 0x822F; +const RG32F = 0x8230; +const RG8UI = 0x8238; +const RG8I = 0x8237; +const R16UI = 0x8234; +const R16I = 0x8233; +const R32UI = 0x8236; +const R32I = 0x8235; +const RGB8 = 0x8051; +const SRGB8 = 0x8C41; +const RGB565$1 = 0x8D62; +const RGB8_SNORM = 0x8F96; +const R11F_G11F_B10F = 0x8C3A; +const RGB9_E5 = 0x8C3D; +const RGB16F = 0x881B; +const RGB32F = 0x8815; +const RGB8UI = 0x8D7D; +const RGB8I = 0x8D8F; +const RGB16UI = 0x8D77; +const RGB16I = 0x8D89; +const RGB32UI = 0x8D71; +const RGB32I = 0x8D83; +const RGBA8 = 0x8058; +const SRGB8_ALPHA8 = 0x8C43; +const RGBA8_SNORM = 0x8F97; +const RGB5_A1$1 = 0x8057; +const RGBA4$1 = 0x8056; +const RGB10_A2 = 0x8059; +const RGBA16F = 0x881A; +const RGBA32F = 0x8814; +const RGBA8UI = 0x8D7C; +const RGBA8I = 0x8D8E; +const RGB10_A2UI = 0x906F; +const RGBA16UI = 0x8D76; +const RGBA16I = 0x8D88; +const RGBA32I = 0x8D82; +const RGBA32UI = 0x8D70; + +const DEPTH_COMPONENT16$1 = 0x81A5; +const DEPTH_COMPONENT24$1 = 0x81A6; +const DEPTH_COMPONENT32F$1 = 0x8CAC; +const DEPTH32F_STENCIL8$1 = 0x8CAD; +const DEPTH24_STENCIL8$1 = 0x88F0; + +/* DataType */ +const BYTE = 0x1400; +const UNSIGNED_BYTE$1 = 0x1401; +const SHORT = 0x1402; +const UNSIGNED_SHORT$1 = 0x1403; +const INT$1 = 0x1404; +const UNSIGNED_INT$1 = 0x1405; +const FLOAT$1 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1 = 0x8034; +const UNSIGNED_SHORT_5_6_5 = 0x8363; +const HALF_FLOAT = 0x140B; +const HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +const UNSIGNED_INT_2_10_10_10_REV = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +const UNSIGNED_INT_24_8 = 0x84FA; + +const RG = 0x8227; +const RG_INTEGER = 0x8228; +const RED = 0x1903; +const RED_INTEGER = 0x8D94; +const RGB_INTEGER = 0x8D98; +const RGBA_INTEGER = 0x8D99; + +const formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + const f = formatInfo; + f[ALPHA] = { numColorComponents: 1, }; + f[LUMINANCE] = { numColorComponents: 1, }; + f[LUMINANCE_ALPHA] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RED] = { numColorComponents: 1, }; + f[RED_INTEGER] = { numColorComponents: 1, }; + f[RG] = { numColorComponents: 2, }; + f[RG_INTEGER] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGB_INTEGER] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RGBA_INTEGER] = { numColorComponents: 4, }; + f[DEPTH_COMPONENT$1] = { numColorComponents: 1, }; + f[DEPTH_STENCIL$1] = { numColorComponents: 2, }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +let s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + const t = {}; + // unsized formats + t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_5_6_5], }; + t[RGBA$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], }; + t[DEPTH_COMPONENT$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT$1, UNSIGNED_SHORT$1], }; + + // sized formats + t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], }; + t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT$1, HALF_FLOAT], }; + t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], }; + t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT$1], }; + t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], }; + t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT$1], }; + t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], }; + t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT$1, HALF_FLOAT], }; + t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT$1], }; + t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], }; + t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT$1], }; + t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], }; + t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT$1], }; + t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT$1], }; + t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB565$1] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_6_5], }; + t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], }; + t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], }; + t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], }; + t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT$1, HALF_FLOAT], }; + t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT$1], }; + t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], }; + t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT$1], }; + t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], }; + t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT$1], }; + t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT$1], }; + t[RGBA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[SRGB8_ALPHA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8_SNORM] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], }; + t[RGB5_A1$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA4$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_4_4_4_4], }; + t[RGB10_A2] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT$1, HALF_FLOAT], }; + t[RGBA32F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT$1], }; + t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], }; + t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT$1], }; + t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], }; + t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT$1], }; + t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT$1], }; + // Sized Internal + t[DEPTH_COMPONENT16$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT$1, UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT24$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT32F$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[DEPTH24_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], }; + t[DEPTH32F_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], }; + + Object.keys(t).forEach(function(internalFormat) { + const info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function(bytesPerElement, ndx) { + const type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + const bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0], + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & (value - 1)) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + const info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE$1; +} + +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP$1 ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height, + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults$1.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +function setDefaults$1(newDefaults) { + copyExistingProperties(newDefaults, defaults$1); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + let colorspaceConversion; + let premultiplyAlpha; + let flipY; + + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + + fn(); + + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D$1 || isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + const sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + const samplers = {}; + Object.keys(samplerOptions).forEach(function(name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults$1.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults$1.textureOptions; + internalFormat = internalFormat || RGBA$1; + const target = options.target || TEXTURE_2D$2; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + const filtering = canFilter(internalFormat) ? LINEAR$1 : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } +} + +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || (options.auto === undefined && options.level === undefined); +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [ + TEXTURE_CUBE_MAP_POSITIVE_X, + TEXTURE_CUBE_MAP_NEGATIVE_X, + TEXTURE_CUBE_MAP_POSITIVE_Y, + TEXTURE_CUBE_MAP_NEGATIVE_Y, + TEXTURE_CUBE_MAP_POSITIVE_Z, + TEXTURE_CUBE_MAP_NEGATIVE_Z, + ]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + const faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + const facesWithNdx = faces.map(function(face, ndx) { + return { face: face, ndx: ndx }; + }); + facesWithNdx.sort(function(a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + const level = options.level || 0; + let width = element.width; + let height = element.height; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // guess the parts + const imgWidth = element.width; + const imgHeight = element.height; + let size; + let slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + const ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, () => { + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }) + .then(function(imageBitmap) { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + scopedSetPackState(gl, options, () => { + const smallest = Math.min(element.width, element.height); + const largest = Math.max(element.width, element.height); + const depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + const xMult = element.width === largest ? 1 : 0; + const yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (let d = 0; d < depth; ++d) { + const srcX = d * smallest * xMult; + const srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, () => { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} + +function noop() { +} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + const a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && + a.port === location.port && + a.protocol === location.protocol; + } else { + const localOrigin = (new URL(location.href)).origin; + const urlOrigin = (new URL(url, location.href)).origin; + return urlOrigin === localOrigin; + } +} + +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) + ? 'anonymous' + : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + let img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults$1.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + + const clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + + const onError = function onError() { + const msg = "couldn't load image: " + url; + error$1(msg); + callback(msg, img); + clearEventHandlers(); + }; + + const onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + let err; + let bm; + const cb = function cb() { + callback(err, bm); + }; + + const options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function(response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function(blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }); + }).then(function(bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + }).catch(function(e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) || + (typeof ImageData !== 'undefined' && obj instanceof ImageData) || + (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement); +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function() { + callback(null, obj); + }); + return obj; + } + + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + const color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, 0, RGBA$1, 1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } else { + gl.texImage2D(target, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D$2; + if (target !== TEXTURE_CUBE_MAP$1) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = 6; + const errors = []; + const faces = getCubeFaceOrder(gl, options); + let imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder().forEach(function(otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D_ARRAY$1; + if (target !== TEXTURE_3D$1 && target !== TEXTURE_2D_ARRAY$1) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = urls.length; + const errors = []; + let imgs; // eslint-disable-line + const level = options.level || 0; + let width = options.width; + let height = options.height; + const depth = urls.length; + let firstImage = true; + + function uploadImg(slice) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (let s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + let src = img; + let ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + let width = options.width; + let height = options.height; + let depth = options.depth; + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + const Type = getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + + const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + glEnumToString(gl, format); + } + let dimensions; + if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + if (!width && !height && !depth) { + const size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + const faceSize = numElements / 6 * elementsPerElement; + + getCubeFacesWithNdx(gl, options).forEach(f => { + const offset = faceSize * f.ndx; + const data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type, + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + const tex = gl.createTexture(); + const target = options.target || TEXTURE_2D$2; + let width = options.width || 1; + let height = options.height || 1; + const internalFormat = options.internalFormat || RGBA$1; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } + let src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof (src) === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || + (Array.isArray(src) && ( + typeof src[0] === 'number' || + Array.isArray(src[0]) || + isArrayBuffer(src[0])) + ) + ) { + const dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP$1) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + let type; + const src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || + (Array.isArray(src) && typeof src[0] === 'string'); +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + let numDownloading = 0; + const errors = []; + const textures = {}; + const images = {}; + + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function() { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + + Object.keys(textureOptions).forEach(function(name) { + const options = textureOptions[name]; + let onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + + return textures; +} + +var textures = /*#__PURE__*/Object.freeze({ + __proto__: null, + setTextureDefaults_: setDefaults$1, + createSampler: createSampler, + createSamplers: createSamplers, + setSamplerParameters: setSamplerParameters, + createTexture: createTexture, + setEmptyTexture: setEmptyTexture, + setTextureFromArray: setTextureFromArray, + loadTextureFromUrl: loadTextureFromUrl, + setTextureFromElement: setTextureFromElement, + setTextureFilteringForSize: setTextureFilteringForSize, + setTextureParameters: setTextureParameters, + setDefaultTextureColor: setDefaultTextureColor, + createTextures: createTextures, + resizeTexture: resizeTexture, + canGenerateMipmap: canGenerateMipmap, + canFilter: canFilter, + getNumComponentsForFormat: getNumComponentsForFormat, + getBytesPerElementForInternalFormat: getBytesPerElementForInternalFormat, + getFormatAndTypeForInternalFormat: getFormatAndTypeForInternalFormat +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +const error = error$1; +const warn = warn$1; +function getElementById(id) { + return (typeof document !== 'undefined' && document.getElementById) + ? document.getElementById(id) + : null; +} + +const TEXTURE0 = 0x84c0; +const DYNAMIC_DRAW = 0x88e8; + +const ARRAY_BUFFER = 0x8892; +const ELEMENT_ARRAY_BUFFER$1 = 0x8893; +const UNIFORM_BUFFER = 0x8a11; +const TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; + +const TRANSFORM_FEEDBACK = 0x8e22; + +const COMPILE_STATUS = 0x8b81; +const LINK_STATUS = 0x8b82; +const FRAGMENT_SHADER = 0x8b30; +const VERTEX_SHADER = 0x8b31; +const SEPARATE_ATTRIBS = 0x8c8d; + +const ACTIVE_UNIFORMS = 0x8b86; +const ACTIVE_ATTRIBUTES = 0x8b89; +const TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +const ACTIVE_UNIFORM_BLOCKS = 0x8a36; +const UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +const UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +const UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +const UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; + +const FLOAT = 0x1406; +const FLOAT_VEC2 = 0x8B50; +const FLOAT_VEC3 = 0x8B51; +const FLOAT_VEC4 = 0x8B52; +const INT = 0x1404; +const INT_VEC2 = 0x8B53; +const INT_VEC3 = 0x8B54; +const INT_VEC4 = 0x8B55; +const BOOL = 0x8B56; +const BOOL_VEC2 = 0x8B57; +const BOOL_VEC3 = 0x8B58; +const BOOL_VEC4 = 0x8B59; +const FLOAT_MAT2 = 0x8B5A; +const FLOAT_MAT3 = 0x8B5B; +const FLOAT_MAT4 = 0x8B5C; +const SAMPLER_2D = 0x8B5E; +const SAMPLER_CUBE = 0x8B60; +const SAMPLER_3D = 0x8B5F; +const SAMPLER_2D_SHADOW = 0x8B62; +const FLOAT_MAT2x3 = 0x8B65; +const FLOAT_MAT2x4 = 0x8B66; +const FLOAT_MAT3x2 = 0x8B67; +const FLOAT_MAT3x4 = 0x8B68; +const FLOAT_MAT4x2 = 0x8B69; +const FLOAT_MAT4x3 = 0x8B6A; +const SAMPLER_2D_ARRAY = 0x8DC1; +const SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +const SAMPLER_CUBE_SHADOW = 0x8DC5; +const UNSIGNED_INT = 0x1405; +const UNSIGNED_INT_VEC2 = 0x8DC6; +const UNSIGNED_INT_VEC3 = 0x8DC7; +const UNSIGNED_INT_VEC4 = 0x8DC8; +const INT_SAMPLER_2D = 0x8DCA; +const INT_SAMPLER_3D = 0x8DCB; +const INT_SAMPLER_CUBE = 0x8DCC; +const INT_SAMPLER_2D_ARRAY = 0x8DCF; +const UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +const UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +const UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +const UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; + +const TEXTURE_2D$1 = 0x0DE1; +const TEXTURE_CUBE_MAP = 0x8513; +const TEXTURE_3D = 0x806F; +const TEXTURE_2D_ARRAY = 0x8C1A; + +const typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function(v) { + gl.uniform1f(location, v); + }; +} + +function floatArraySetter(gl, location) { + return function(v) { + gl.uniform1fv(location, v); + }; +} + +function floatVec2Setter(gl, location) { + return function(v) { + gl.uniform2fv(location, v); + }; +} + +function floatVec3Setter(gl, location) { + return function(v) { + gl.uniform3fv(location, v); + }; +} + +function floatVec4Setter(gl, location) { + return function(v) { + gl.uniform4fv(location, v); + }; +} + +function intSetter(gl, location) { + return function(v) { + gl.uniform1i(location, v); + }; +} + +function intArraySetter(gl, location) { + return function(v) { + gl.uniform1iv(location, v); + }; +} + +function intVec2Setter(gl, location) { + return function(v) { + gl.uniform2iv(location, v); + }; +} + +function intVec3Setter(gl, location) { + return function(v) { + gl.uniform3iv(location, v); + }; +} + +function intVec4Setter(gl, location) { + return function(v) { + gl.uniform4iv(location, v); + }; +} + +function uintSetter(gl, location) { + return function(v) { + gl.uniform1ui(location, v); + }; +} + +function uintArraySetter(gl, location) { + return function(v) { + gl.uniform1uiv(location, v); + }; +} + +function uintVec2Setter(gl, location) { + return function(v) { + gl.uniform2uiv(location, v); + }; +} + +function uintVec3Setter(gl, location) { + return function(v) { + gl.uniform3uiv(location, v); + }; +} + +function uintVec4Setter(gl, location) { + return function(v) { + gl.uniform4uiv(location, v); + }; +} + +function floatMat2Setter(gl, location) { + return function(v) { + gl.uniformMatrix2fv(location, false, v); + }; +} + +function floatMat3Setter(gl, location) { + return function(v) { + gl.uniformMatrix3fv(location, false, v); + }; +} + +function floatMat4Setter(gl, location) { + return function(v) { + gl.uniformMatrix4fv(location, false, v); + }; +} + +function floatMat23Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} + +function floatMat32Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} + +function floatMat24Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} + +function floatMat42Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} + +function floatMat34Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} + +function floatMat43Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} + +function samplerSetter(gl, type, unit, location) { + const bindPoint = getBindPointForSamplerType(gl, type); + return isWebGL2(gl) ? function(textureOrPair) { + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function(texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} + +function samplerArraySetter(gl, type, unit, location, size) { + const bindPoint = getBindPointForSamplerType(gl, type); + const units = new Int32Array(size); + for (let ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + + return isWebGL2(gl) ? function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} + +typeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, }; +typeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, }; +typeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, }; +typeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, }; +typeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, }; +typeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, }; +typeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, }; +typeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, }; +typeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, }; +typeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, }; +typeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, }; +typeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, }; +typeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, }; +typeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, }; +typeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, }; +typeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, }; +typeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, }; +typeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; + +function floatAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer( + index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function intAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function uintAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function matAttribSetter(gl, index, typeInfo) { + const defaultSize = typeInfo.size; + const count = typeInfo.count; + + return function(b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + const numComponents = b.size || b.numComponents || defaultSize; + const size = numComponents / count; + const type = b.type || FLOAT; + const typeInfo = typeMap[type]; + const stride = typeInfo.size * numComponents; + const normalize = b.normalize || false; + const offset = b.offset || 0; + const rowOffset = stride / count; + for (let i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer( + index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} + + + +const attrTypeMap = {}; +attrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, }; +attrTypeMap[INT] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, }; +attrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, }; +attrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, }; +attrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, }; + +const errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src, log = '', lineOffset = 0) { + // Note: Error message formats are not defined by any spec so this may or may not work. + const matches = [...log.matchAll(errorRE)]; + const lineNoToErrorMap = new Map(matches.map((m, ndx) => { + const lineNo = parseInt(m[1]); + const next = matches[ndx + 1]; + const end = next ? next.index : log.length; + const msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map((line, lineNo) => { + const err = lineNoToErrorMap.get(lineNo); + return `${lineNo + 1 + lineOffset}: ${line}${err ? `\n\n^^^ ${err}` : ''}`; + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +const spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + let lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return {lineOffset, shaderSource}; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(() => { + progOptions.callback(`${msg}\n${progOptions.errors.join('\n')}`); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + const compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + const lastError = gl.getShaderInfoLog(shader); + const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader)); + const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\nError compiling ${glEnumToString(gl, shaderType)}: ${lastError}`; + errFn(error); + return error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + let transformFeedbackVaryings; + let transformFeedbackMode; + let callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + const opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + + const errorCallback = opt_errorCallback || error; + const errors = []; + const options = { + errorCallback(msg, ...args) { + errors.push(msg); + errorCallback(msg, ...args); + }, + transformFeedbackVaryings, + transformFeedbackMode, + callback, + errors, + }; + + { + let attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function(attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + + return options; +} + +const defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER", +]; + +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} + +function deleteProgramAndShaders(gl, program, notThese) { + const shaders = gl.getAttachedShaders(program); + for (const shader of shaders) { + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + gl.deleteProgram(program); +} + +const wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms)); + +function createProgramNoCheck(gl, shaders, programOptions) { + const program = gl.createProgram(); + const { + attribLocations, + transformFeedbackVaryings, + transformFeedbackMode, + } = getProgramOptions(programOptions); + + for (let ndx = 0; ndx < shaders.length; ++ndx) { + let shader = shaders[ndx]; + if (typeof shader === 'string') { + const elem = getElementById(shader); + const src = elem ? elem.text : shader; + let type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + + Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib)); + + { + let varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram( + gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaderSet = new Set(shaders); + const program = createProgramNoCheck(gl, shaders, progOptions); + + function hasErrors(gl, program) { + const errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(() => { + const errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function(gl, arg1, ...args) { + return new Promise((resolve, reject) => { + const programOptions = getProgramOptions(...args); + programOptions.callback = (err, program) => { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +const createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +const createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); + +async function waitForProgramLinkCompletionAsync(gl, program) { + const ext = gl.getExtension('KHR_parallel_shader_compile'); + const checkFn = ext + ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR) + : () => true; + + let waitTime = 0; + do { + await wait(waitTime); // must wait at least once + waitTime = 1000 / 60; + } while (!checkFn(gl, program)); +} + +async function waitForAllProgramsLinkCompletionAsync(gl, programs) { + for (const program of Object.values(programs)) { + await waitForProgramLinkCompletionAsync(gl, program); + } +} + +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + const linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + const lastError = gl.getProgramInfoLog(program); + errFn(`Error in program linking: ${lastError}`); + // print any errors from these shaders + const shaders = gl.getAttachedShaders(program); + const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn)); + return `${lastError}\n${errors.filter(_ => _).join('\n')}`; + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts( + gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaders = []; + for (const scriptId of shaderScriptIds) { + const shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, `unknown script element: ${scriptId}`); + } + shaders.push(shaderScript.text); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + const name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} + +const tokenRE = /(\.|\[|]|\w+)/g; +const isDigit = s => s >= '0' && s <= '9'; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + const tokens = fullPath.split(tokenRE).filter(s => s !== ''); + let tokenNdx = 0; + let path = ''; + + for (;;) { + const token = tokens[tokenNdx++]; // has to be name or number + path += token; + const isArrayIndex = isDigit(token[0]); + const accessor = isArrayIndex + ? parseInt(token) + : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + const isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + const token = tokens[tokenNdx++]; // has to be . or [ + const isArray = token === '['; + const child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function(node) { + return function(value) { + setUniformTree(node, value); + }; + }(child); + path += token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +function createUniformSetters(gl, program) { + let 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, location) { + const isArray = uniformInfo.name.endsWith("[0]"); + const type = uniformInfo.type; + const typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here. + } + let setter; + if (typeInfo.bindPoint) { + // it's a sampler + const unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + + const uniformSetters = {}; + const uniformTree = {}; + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + + for (let ii = 0; ii < numUniforms; ++ii) { + const uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + let name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + const location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + const setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + const info = {}; + const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (let ii = 0; ii < numVaryings; ++ii) { + const varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size, + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (const name in bufferInfo) { + const varying = transformFeedbackInfo[name]; + if (varying) { + const buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + const tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + const uniformData = []; + const uniformIndices = []; + + for (let ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + const uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + + [ + [ "UNIFORM_TYPE", "type" ], + [ "UNIFORM_SIZE", "size" ], // num elements + [ "UNIFORM_BLOCK_INDEX", "blockNdx" ], + [ "UNIFORM_OFFSET", "offset", ], + ].forEach(function(pair) { + const pname = pair[0]; + const key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) { + uniformData[ndx][key] = value; + }); + }); + + const blockSpecs = {}; + + const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (let ii = 0; ii < numUniformBlocks; ++ii) { + const name = gl.getActiveUniformBlockName(program, ii); + const blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES), + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + + return { + blockSpecs: blockSpecs, + uniformData: uniformData, + }; +} + +const arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +const pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding; + +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + const numElements = view.length; + const totalRows = numElements / 4; + return function(value) { + let dst = 0; + let src = 0; + for (let row = 0; row < totalRows; ++row) { + for (let col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function(value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) { + const blockSpecs = uniformBlockSpec.blockSpecs; + const uniformData = uniformBlockSpec.uniformData; + const blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {}, + }; + } + const offset = options.offset ?? 0; + const array = options.array ?? new ArrayBuffer(blockSpec.size); + const buffer = options.buffer ?? gl.createBuffer(); + const uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + + let prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + const uniforms = {}; + const setters = {}; + const setterTree = {}; + blockSpec.uniformIndices.forEach(function(uniformNdx) { + const data = uniformData[uniformNdx]; + let name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + const isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + const typeInfo = typeMap[data.type]; + const Type = typeInfo.Type; + const byteLength = isArray + ? pad(typeInfo.size, 16) * data.size + : typeInfo.size * data.size; + const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array, + asFloat: new Float32Array(array), // for debugging + asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer + buffer, + uniforms, + setters, + offset: options.bufferOffset ?? offset, + size: blockSpec.size, + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName, options = {}) { + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + const bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + const setters = uniformBlockInfo.setters; + for (const name in values) { + const setter = setters[name]; + if (setter) { + const value = values[name]; + setter(value); + } + } +} + +function setUniformTree(tree, values) { + for (const name in values) { + const prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters, ...args) { // eslint-disable-line + const actualSetters = setters.uniformSetters || setters; + const numArgs = args.length; + for (let aNdx = 0; aNdx < numArgs; ++aNdx) { + const values = args[aNdx]; + if (Array.isArray(values)) { + const numValues = values.length; + for (let ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (const name in values) { + const setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +const setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + const attribSetters = { + }; + + const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (let ii = 0; ii < numAttribs; ++ii) { + const attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + const index = gl.getAttribLocation(program, attribInfo.name); + const typeInfo = attrTypeMap[attribInfo.type]; + const setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (const name in buffers) { + const setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER$1, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + const uniformSetters = createUniformSetters(gl, program); + const attribSetters = createAttributeSetters(gl, program); + const programInfo = { + program, + uniformSetters, + attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])), + }; + + if (isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + + return programInfo; +} + +const notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const errors = []; + shaderSources = shaderSources.map(function(source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + const script = getElementById(source); + if (!script) { + const err = `no element with id: ${source}`; + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + + if (errors.length) { + return reportError(progOptions, ''); + } + + const origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = (err, program) => { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + + const program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + + return createProgramInfoFromProgram(gl, program); +} + +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (const [name, program] of Object.entries(programs)) { + const options = {...programOptions}; + const spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + const errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (const program of Object.values(programs)) { + const shaders = gl.getAttachedShaders(program); + gl.deleteProgram(program); + for (const shader of shaders) { + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } + return errors; + } + } + + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs, programOptions = {}) { + // Remember existing shaders so that if there is an error we don't delete them + const noDeleteShadersSet = new Set(); + + // compile and link everything + const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => { + const options = {...programOptions}; + const shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => { + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(([name, program]) => + [name, createProgramInfoFromProgram(gl, program)] + )); + } + + const origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = (err, programs) => { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + + const programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +const createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +const createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +var programs = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttributeSetters: createAttributeSetters, + createProgram: createProgram, + createProgramAsync: createProgramAsync, + createPrograms: createPrograms, + createProgramsAsync: createProgramsAsync, + createProgramFromScripts: createProgramFromScripts, + createProgramFromSources: createProgramFromSources, + createProgramInfo: createProgramInfo, + createProgramInfoAsync: createProgramInfoAsync, + createProgramInfos: createProgramInfos, + createProgramInfosAsync: createProgramInfosAsync, + createProgramInfoFromProgram: createProgramInfoFromProgram, + createUniformSetters: createUniformSetters, + createUniformBlockSpecFromProgram: createUniformBlockSpecFromProgram, + createUniformBlockInfoFromProgram: createUniformBlockInfoFromProgram, + createUniformBlockInfo: createUniformBlockInfo, + createTransformFeedback: createTransformFeedback, + createTransformFeedbackInfo: createTransformFeedbackInfo, + bindTransformFeedbackInfo: bindTransformFeedbackInfo, + setAttributes: setAttributes, + setBuffersAndAttributes: setBuffersAndAttributes, + setUniforms: setUniforms, + setUniformsAndBindTextures: setUniformsAndBindTextures, + setUniformBlock: setUniformBlock, + setBlockUniforms: setBlockUniforms, + bindUniformBlock: bindUniformBlock +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const TRIANGLES = 0x0004; +const UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + const indices = bufferInfo.indices; + const elementType = bufferInfo.elementType; + const numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + let lastUsedProgramInfo = null; + let lastUsedBufferInfo = null; + + objectsToDraw.forEach(function(object) { + if (object.active === false) { + return; + } + + const programInfo = object.programInfo; + const bufferInfo = object.vertexArrayInfo || object.bufferInfo; + let bindBuffers = false; + const type = object.type === undefined ? TRIANGLES : object.type; + + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +var draw = /*#__PURE__*/Object.freeze({ + __proto__: null, + drawBufferInfo: drawBufferInfo, + drawObjectList: drawObjectList +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const FRAMEBUFFER = 0x8d40; +const RENDERBUFFER = 0x8d41; +const TEXTURE_2D = 0x0de1; + +const UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +const DEPTH_COMPONENT = 0x1902; +const RGBA = 0x1908; +const DEPTH_COMPONENT24 = 0x81a6; +const DEPTH_COMPONENT32F = 0x8cac; +const DEPTH24_STENCIL8 = 0x88f0; +const DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +const RGBA4 = 0x8056; +const RGB5_A1 = 0x8057; +const RGB565 = 0x8D62; +const DEPTH_COMPONENT16 = 0x81A5; +const STENCIL_INDEX = 0x1901; +const STENCIL_INDEX8 = 0x8D48; +const DEPTH_STENCIL = 0x84F9; +const COLOR_ATTACHMENT0 = 0x8CE0; +const DEPTH_ATTACHMENT = 0x8D00; +const STENCIL_ATTACHMENT = 0x8D20; +const DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +const CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +const LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +const defaultAttachments = [ + { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, }, + { format: DEPTH_STENCIL, }, +]; + +const attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; + +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} + +const renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; + +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} + +const MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + const target = FRAMEBUFFER; + const fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + const usedColorAttachmentsPoints = []; + const framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height, + }; + + attachments.forEach(function(attachmentOptions, i) { + let attachment = attachmentOptions.attachment; + const samples = attachmentOptions.samples; + const format = attachmentOptions.format; + let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + const textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = createTexture(gl, textureOptions); + } + } + if (isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer( + target, + attachmentPoint, + attachment, + attachmentOptions.level || 0, + attachmentOptions.layer); + } else { + gl.framebufferTexture2D( + target, + attachmentPoint, + attachmentOptions.target || TEXTURE_2D, + attachment, + attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function(attachmentOptions, ndx) { + const attachment = framebufferInfo.attachments[ndx]; + const format = attachmentOptions.format; + const samples = attachmentOptions.samples; + if (samples !== undefined || isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (isTexture(gl, attachment)) { + resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +var framebuffers = /*#__PURE__*/Object.freeze({ + __proto__: null, + bindFramebufferInfo: bindFramebufferInfo, + createFramebufferInfo: createFramebufferInfo, + resizeFramebufferInfo: resizeFramebufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +const ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function(programInfo) { + setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao, + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +var vertexArrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + createVertexArrayInfo: createVertexArrayInfo, + createVAOAndSetAttributes: createVAOAndSetAttributes, + createVAOFromBufferInfo: createVAOFromBufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults = { + addExtensionsToContext: true, +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + copyExistingProperties(newDefaults, defaults); + setDefaults$2(newDefaults); // eslint-disable-line + setDefaults$1(newDefaults); // eslint-disable-line +} + +const prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + glEnumToString(gl, 0); + const ext = gl.getExtension(extensionName); + if (ext) { + const enums = {}; + const fnSuffix = prefixRE.exec(extensionName)[1]; + const enumSuffix = '_' + fnSuffix; + for (const key in ext) { + const value = ext[key]; + const isFunc = typeof (value) === 'function'; + const suffix = isFunc ? fnSuffix : enumSuffix; + let name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + warn$1(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function(origFn) { + return function() { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name, + }; + glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +const supportedExtensions = [ + 'ANGLE_instanced_arrays', + 'EXT_blend_minmax', + 'EXT_color_buffer_float', + 'EXT_color_buffer_half_float', + 'EXT_disjoint_timer_query', + 'EXT_disjoint_timer_query_webgl2', + 'EXT_frag_depth', + 'EXT_sRGB', + 'EXT_shader_texture_lod', + 'EXT_texture_filter_anisotropic', + 'OES_element_index_uint', + 'OES_standard_derivatives', + 'OES_texture_float', + 'OES_texture_float_linear', + 'OES_texture_half_float', + 'OES_texture_half_float_linear', + 'OES_vertex_array_object', + 'WEBGL_color_buffer_float', + 'WEBGL_compressed_texture_atc', + 'WEBGL_compressed_texture_etc1', + 'WEBGL_compressed_texture_pvrtc', + 'WEBGL_compressed_texture_s3tc', + 'WEBGL_compressed_texture_s3tc_srgb', + 'WEBGL_depth_texture', + 'WEBGL_draw_buffers', +]; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (let ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + const names = ["webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + const gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + const names = ["webgl2", "webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + const gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + const width = canvas.clientWidth * multiplier | 0; + const height = canvas.clientHeight * multiplier | 0; + if (canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + return true; + } + return false; +} + +export { addExtensionsToContext, attributes, bindFramebufferInfo, bindTransformFeedbackInfo, bindUniformBlock, canFilter, canGenerateMipmap, createAttribsFromArrays, createAttributeSetters, createBufferFromArray, createBufferFromTypedArray, createBufferInfoFromArrays, createBuffersFromArrays, createFramebufferInfo, createProgram, createProgramAsync, createProgramFromScripts, createProgramFromSources, createProgramInfo, createProgramInfoAsync, createProgramInfoFromProgram, createProgramInfos, createProgramInfosAsync, createPrograms, createProgramsAsync, createSampler, createSamplers, createTexture, createTextures, createTransformFeedback, createTransformFeedbackInfo, createUniformBlockInfo, createUniformBlockInfoFromProgram, createUniformBlockSpecFromProgram, createUniformSetters, createVAOAndSetAttributes, createVAOFromBufferInfo, createVertexArrayInfo, draw, drawBufferInfo, drawObjectList, framebuffers, getArray as getArray_, getBytesPerElementForInternalFormat, getContext, getFormatAndTypeForInternalFormat, getGLTypeForTypedArray, getGLTypeForTypedArrayType, getNumComponentsForFormat, getNumComponents as getNumComponents_, getTypedArrayTypeForGLType, getWebGLContext, glEnumToString, isArrayBuffer$1 as isArrayBuffer, isWebGL1, isWebGL2, loadTextureFromUrl, programs, resizeCanvasToDisplaySize, resizeFramebufferInfo, resizeTexture, setAttribInfoBufferFromArray, setDefaults$2 as setAttributeDefaults_, setAttributePrefix, setAttributes, setBlockUniforms, setBuffersAndAttributes, setDefaultTextureColor, setDefaults, setEmptyTexture, setSamplerParameters, setDefaults$1 as setTextureDefaults_, setTextureFilteringForSize, setTextureFromArray, setTextureFromElement, setTextureParameters, setUniformBlock, setUniforms, setUniformsAndBindTextures, textures, typedarrays, utils, vertexArrays }; diff --git a/index.html b/index.html index 237afc59..6f115c10 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ diff --git a/npm/base/dist/6.x/twgl.d.ts b/npm/base/dist/6.x/twgl.d.ts new file mode 100644 index 00000000..a8063b02 --- /dev/null +++ b/npm/base/dist/6.x/twgl.d.ts @@ -0,0 +1,3172 @@ + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ +export type Defaults = { + attribPrefix?: string; + textureColor?: number[]; + crossOrigin?: string; + addExtensionsToContext?: boolean; +}; +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +export function setDefaults(newDefaults: Defaults): void; +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +export function addExtensionsToContext(gl: WebGLRenderingContext): void; +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +export function createContext(canvas: HTMLCanvasElement): WebGLRenderingContext; +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +export function getContext(canvas: HTMLCanvasElement, opt_attribs?: WebGLContextAttributes): WebGLRenderingContext; +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +export function resizeCanvasToDisplaySize(canvas: HTMLCanvasElement, multiplier?: number): boolean; +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type AttribInfo = { + value?: number[] | ArrayBufferView; + numComponents?: number; + size?: number; + type?: number; + normalize?: boolean; + offset?: number; + stride?: number; + divisor?: number; + buffer: WebGLBuffer; + drawType?: number; +}; +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ +export type FullArraySpec = { + value?: number[] | ArrayBufferView; + data?: number | number[] | ArrayBufferView; + numComponents?: number; + type?: number | TypedArrayConstructor; + size?: number; + normalize?: boolean; + stride?: number; + offset?: number; + divisor?: number; + attrib?: string; + name?: string; + attribName?: string; + buffer?: WebGLBuffer; + drawType?: number; +}; +/** + * An individual array in {@link Arrays} + * + * When passed to {@link createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ +export type ArraySpec = number | number[] | ArrayBufferView | FullArraySpec; +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ +export type Arrays = { + [key: string]: ArraySpec; +}; +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ +export type BufferInfo = { + numElements: number; + elementType?: number; + indices?: WebGLBuffer; + attribs?: { + [key: string]: AttribInfo; + }; +}; +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @property {BufferInfo} [bufferInfo] A BufferInfo as returned from {@link createBufferInfoFromArrays} + * @property {VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ +export type DrawObject = { + active?: boolean; + type?: number; + programInfo: ProgramInfo; + bufferInfo?: BufferInfo; + vertexArrayInfo?: VertexArrayInfo; + uniforms: { + [key: string]: any; + }; + offset?: number; + count?: number; + instanceCount?: number; +}; +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes TextureOptions + */ +export type AttachmentOptions = TextureOptions & { + attachmentPoint?: number; + format?: number; + type?: number; + target?: number; + samples?: number; + level?: number; + layer?: number; + attachment?: WebGLRenderbuffer | WebGLTexture; +}; +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ +export type FramebufferInfo = { + framebuffer: WebGLFramebuffer; + attachments: (WebGLRenderbuffer | WebGLTexture)[]; + width: number; + height: number; +}; +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ +export type ErrorCallback = (msg: string, lineOffset?: number) => void; +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type FullProgramSpec = { + shaders: string[]; + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {string[]|FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ +export type ProgramSpec = string[] | FullProgramSpec; +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ +export type ProgramOptions = { + errorCallback?: (...params: any[]) => any; + attribLocations?: { + [key: string]: number; + } | string[]; + transformFeedbackVaryings?: BufferInfo | { + [key: string]: AttribInfo; + } | string[]; + transformFeedbackMode?: number; + callback?: ProgramCallback; +}; +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ +export type TransformFeedbackInfo = { + index: number; + type: number; + size: number; +}; +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +export function createTransformFeedbackInfo(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: TransformFeedbackInfo; +}; +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +export function bindTransformFeedbackInfo(gl: WebGLRenderingContext, transformFeedbackInfo: ProgramInfo | { + [key: string]: TransformFeedbackInfo; +}, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): void; +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {ProgramInfo} programInfo A ProgramInfo as returned from {@link createProgramInfo} + * @param {(BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +export function createTransformFeedback(gl: WebGLRenderingContext, programInfo: ProgramInfo, bufferInfo?: BufferInfo | { + [key: string]: AttribInfo; +}): WebGLTransformFeedback; +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ +export type UniformData = { + name: string; + type: number; + size: number; + blockNdx: number; + offset: number; +}; +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ +export type BlockSpec = { + index: number; + size: number; + uniformIndices: number[]; + usedByVertexShader: boolean; + usedByFragmentShader: boolean; + used: boolean; +}; +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ +export type UniformBlockSpec = { + blockSpecs: { + [key: string]: BlockSpec; + }; + uniformData: UniformData[]; +}; +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link setBlockUniforms} + * @memberOf module:twgl + */ +export type UniformBlockInfo = { + name: string; + array: ArrayBuffer; + asFloat: Float32Array; + asUint8t: Uint8Array; + buffer: WebGLBuffer; + offset?: number; + uniforms: { + [key: string]: ArrayBufferView; + }; + setters: { + [key: string]: (...params: any[]) => any; + }; +}; +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ +export type ProgramInfo = { + program: WebGLProgram; + uniformLocations: { + [key: string]: WebGLUniformLocation; + }; + attribLocations: { + [key: string]: number; + }; + uniformSetters: { + [key: string]: (...params: any[]) => any; + }; + attribSetters: { + [key: string]: (...params: any[]) => any; + }; + uniformBlockSpec?: UniformBlockSpec; + transformFeedbackInfo?: { + [key: string]: TransformFeedbackInfo; + }; +}; +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link TextureOptions}. + * @memberOf module:twgl + */ +export type TextureFunc = (gl: WebGLRenderingContext, options: TextureOptions) => any; +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link setDefaults}. + * + * @memberOf module:twgl + */ +export type TextureOptions = { + target?: number; + level?: number; + width?: number; + height?: number; + depth?: number; + min?: number; + mag?: number; + minMag?: number; + internalFormat?: number; + format?: number; + type?: number; + wrap?: number; + wrapS?: number; + wrapT?: number; + wrapR?: number; + minLod?: number; + maxLod?: number; + baseLevel?: number; + maxLevel?: number; + compareFunc?: number; + compareMode?: number; + unpackAlignment?: number; + color?: number[] | ArrayBufferView; + premultiplyAlpha?: number; + flipY?: number; + colorspaceConversion?: number; + auto?: boolean; + cubeFaceOrder?: number[]; + src?: number[] | ArrayBufferView | TexImageSource | TexImageSource[] | string | string[] | TextureFunc; + crossOrigin?: string; +}; +/** + * The src image(s) used to create a texture. + * + * When you call {@link createTexture} or {@link createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ +export type TextureSrc = HTMLImageElement | HTMLImageElement[]; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ +export type TextureReadyCallback = (err: any, texture: WebGLTexture, source: TextureSrc) => void; +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ +export type TexturesReadyCallback = (err: any, textures: { + [key: string]: WebGLTexture; +}, sources: { + [key: string]: TextureSrc; +}) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ +export type CubemapReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ +export type ThreeDReadyCallback = (err: any, tex: WebGLTexture, imgs: HTMLImageElement[]) => void; +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +export function isWebGL2(gl: WebGLRenderingContext): boolean; +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +export function isWebGL1(gl: WebGLRenderingContext): boolean; +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +export function glEnumToString(gl: WebGLRenderingContext, value: number): string; +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ +export type VertexArrayInfo = { + numElements: number; + elementType?: number; + vertexArrayObject?: WebGLVertexArrayObject; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +export function setAttributePrefix(prefix: string): void; +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +export function createBufferFromTypedArray(gl: WebGLRenderingContext, typedArray: ArrayBuffer | SharedArrayBuffer | ArrayBufferView | WebGLBuffer, type?: number, drawType?: number): WebGLBuffer; +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ +export type TypedArrayConstructor = Int8ArrayConstructor | Uint8ArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor; +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {Arrays} arrays The arrays + * @param {BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +export function createAttribsFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): { + [key: string]: AttribInfo; +}; +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +export function setAttribInfoBufferFromArray(gl: WebGLRenderingContext, attribInfo: AttribInfo, array: ArraySpec, offset?: number): void; +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {Arrays} arrays Your data + * @param {BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +export function createBufferInfoFromArrays(gl: WebGLRenderingContext, arrays: Arrays, srcBufferInfo?: BufferInfo): BufferInfo; +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +export function createBufferFromArray(gl: WebGLRenderingContext, array: ArraySpec, arrayName: string): WebGLBuffer; +/** + * Creates buffers from arrays or 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 {Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +export function createBuffersFromArrays(gl: WebGLRenderingContext, arrays: Arrays): { + [key: string]: WebGLBuffer; +}; + + +/** + * 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 {(BufferInfo|VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +export function drawBufferInfo(gl: WebGLRenderingContext, bufferInfo: BufferInfo | VertexArrayInfo, type?: number, count?: number, offset?: number, instanceCount?: number): void; +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +export function drawObjectList(gl: WebGLRenderingContext, objectsToDraw: DrawObject[]): void; + + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +export function createFramebufferInfo(gl: WebGLRenderingContext, attachments?: AttachmentOptions[], width?: number, height?: number): FramebufferInfo; +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link createFramebufferInfo}. + * @param {AttachmentOptions[]} [attachments] the same attachments options as passed to {@link createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +export function resizeFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo: FramebufferInfo, attachments?: AttachmentOptions[], width?: number, height?: number): void; +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ +export function bindFramebufferInfo(gl: WebGLRenderingContext, framebufferInfo?: FramebufferInfo | null, target?: number): void; + + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|ProgramInfo} [result] the program or programInfo + */ +export type ProgramCallback = (err?: string, result?: WebGLProgram | ProgramInfo) => void; +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgram(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created program + * @memberOf module:twgl/programs + */ +export function createProgramAsync(gl: WebGLRenderingContext, shaders: WebGLShader[] | string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +export function createProgramInfoAsync(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): Promise; +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromScripts(gl: WebGLRenderingContext, shaderScriptIds: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +export function createProgramFromSources(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): WebGLProgram; +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +export function createUniformSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +export function createUniformBlockSpecFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram): UniformBlockSpec; +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ +export type UniformBlockInfoOptions = { + array?: ArrayBuffer; + offset?: number; + buffer?: WebGLBuffer; + bufferOffset?: number; +}; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfoFromProgram(gl: WebGL2RenderingContext, program: WebGLProgram, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} + * @param {string} blockName The name of the block. + * @param {UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +export function createUniformBlockInfo(gl: WebGL2RenderingContext, programInfo: ProgramInfo, blockName: string, options?: UniformBlockInfoOptions): UniformBlockInfo; +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +export function bindUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): boolean; +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(ProgramInfo|UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link createUniformBlockSpecFromProgram}. + * @param {UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +export function setUniformBlock(gl: WebGL2RenderingContext, programInfo: ProgramInfo | UniformBlockSpec, uniformBlockInfo: UniformBlockInfo): void; +/** + * Sets values of a uniform block object + * + * @param {UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +export function setBlockUniforms(uniformBlockInfo: UniformBlockInfo, values: { + [key: string]: any; +}): void; +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +export function setUniforms(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Alias for `setUniforms` + * @function + * @param {(ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +export function setUniformsAndBindTextures(setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, values: { + [key: string]: any; +}): void; +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +export function createAttributeSetters(gl: WebGLRenderingContext, program: WebGLProgram): { + [key: string]: (...params: any[]) => any; +}; +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link createProgramInfo} or Attribute setters as returned from {@link createAttributeSetters} + * @param {(BufferInfo|VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +export function setBuffersAndAttributes(gl: WebGLRenderingContext, setters: ProgramInfo | { + [key: string]: (...params: any[]) => any; +}, buffers: BufferInfo | VertexArrayInfo): void; +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +export function createProgramInfoFromProgram(gl: WebGLRenderingContext, program: WebGLProgram): ProgramInfo; +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {ProgramOptions|string[]|ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {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 {ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +export function createProgramInfo(gl: WebGLRenderingContext, shaderSources: string[], opt_attribs?: ProgramOptions | string[] | ErrorCallback, opt_locations?: number[] | ErrorCallback, opt_errorCallback?: ErrorCallback): ProgramInfo; +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createPrograms(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramInfos(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: ProgramInfo; +}; +/** + * Creates multiple programs asynchronously + * + * @see {@link createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +export function createProgramsAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): { + [key: string]: WebGLProgram; +}; +/** + * Creates multiple programInfos asynchronously + * + * @see {@link createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +export function createProgramInfosAsync(gl: WebGLRenderingContext, programSpecs: { + [key: string]: ProgramSpec; +}, programOptions?: ProgramOptions): Promise<{ + [key: string]: ProgramInfo; +}>; + + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +export function getBytesPerElementForInternalFormat(internalFormat: number, type: number): number; +/** + * Info related to a specific texture internalFormat as returned + * from {@link getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ +export type TextureFormatInfo = { + format: number; + type: number; +}; +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +export function getFormatAndTypeForInternalFormat(internalFormat: number): TextureFormatInfo; +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canGenerateMipmap(gl: WebGLRenderingContext, width: number, height: number, internalFormat: number): boolean; +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +export function canFilter(internalFormat: number): boolean; +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +export function getNumComponentsForFormat(format: number): number; +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link setDefaults} + * @memberOf module:twgl/textures + */ +export function setDefaultTextureColor(color: number[]): void; +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureParameters(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setSamplerParameters(gl: WebGLRenderingContext, sampler: WebGLSampler, options: TextureOptions): void; +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +export function setTextureFilteringForSize(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, width?: number, height?: number, internalFormat?: number): void; +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +export function setTextureFromElement(gl: WebGLRenderingContext, tex: WebGLTexture, element: HTMLElement, options?: TextureOptions): void; +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +export function loadTextureFromUrl(gl: WebGLRenderingContext, tex: WebGLTexture, options?: TextureOptions, callback?: TextureReadyCallback): HTMLImageElement; +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +export function setTextureFromArray(gl: WebGLRenderingContext, tex: WebGLTexture, src: number[] | ArrayBufferView, options?: TextureOptions): void; +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +export function setEmptyTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions): void; +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +export function createTexture(gl: WebGLRenderingContext, options?: TextureOptions, callback?: TextureReadyCallback): WebGLTexture; +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +export function resizeTexture(gl: WebGLRenderingContext, tex: WebGLTexture, options: TextureOptions, width?: number, height?: number, depth?: number): void; +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +export function createTextures(gl: WebGLRenderingContext, options: { + [key: string]: TextureOptions; +}, callback?: TexturesReadyCallback): { + [key: string]: WebGLTexture; +}; + + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArray(typedArray: ArrayBufferView): number; +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +export function getGLTypeForTypedArrayType(typedArrayType: ArrayBufferView): number; +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +export function getTypedArrayTypeForGLType(type: number): (...params: any[]) => any; + + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ProgramInfo|ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +export function createVertexArrayInfo(gl: WebGLRenderingContext, programInfo: ProgramInfo | ProgramInfo[], bufferInfo: BufferInfo): VertexArrayInfo; +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOAndSetAttributes(gl: WebGLRenderingContext, setters: { + [key: string]: (...params: any[]) => any; +}, attribs: { + [key: string]: AttribInfo; +}, indices?: WebGLBuffer): WebGLVertexArrayObject | null; +/** + * Creates a vertex array object and then sets the attributes + * on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {Object.| ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +export function createVAOFromBufferInfo(gl: WebGLRenderingContext, programInfo: { + [key: string]: (...params: any[]) => any; +} | ProgramInfo, bufferInfo: BufferInfo, indices?: WebGLBuffer): WebGLVertexArrayObject | null; diff --git a/npm/base/dist/6.x/twgl.js b/npm/base/dist/6.x/twgl.js new file mode 100644 index 00000000..9a4cc6f9 --- /dev/null +++ b/npm/base/dist/6.x/twgl.js @@ -0,0 +1,7263 @@ +/*! + * @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. + * Available via the MIT license. + * see: http://github.com/greggman/twgl.js for details + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["twgl"] = factory(); + else + root["twgl"] = factory(); +})(typeof self !== 'undefined' ? self : this, () => { +return /******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({ + +/***/ "./src/attributes.js": +/*!***************************!*\ + !*** ./src/attributes.js ***! + \***************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createAttribsFromArrays = createAttribsFromArrays; +exports.createBufferFromArray = createBufferFromArray; +exports.createBufferFromTypedArray = createBufferFromTypedArray; +exports.createBufferInfoFromArrays = createBufferInfoFromArrays; +exports.createBuffersFromArrays = createBuffersFromArrays; +exports.getArray_ = getArray; +exports.getNumComponents_ = getNumComponents; +exports.setAttribInfoBufferFromArray = setAttribInfoBufferFromArray; +exports.setAttributeDefaults_ = setDefaults; +exports.setAttributePrefix = setAttributePrefix; +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var STATIC_DRAW = 0x88e4; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var BUFFER_SIZE = 0x8764; +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; + +/** + * Low level attribute and buffer related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/attributes + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + attribPrefix: "" +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults.attribPrefix = prefix; +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); +} +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (helper.isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER; + var buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return true; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return true; + } // eslint-disable-line + return false; +} +function getArray(array) { + return array.length ? array : array.data; +} +var texcoordRE = /coord|texture/i; +var colorRE = /color|colour/i; +function guessNumComponentsFromName(name, length) { + var numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + if (length % numComponents > 0) { + throw new Error("Can not guess numComponents for attribute '".concat(name, "'. Tried ").concat(numComponents, " but ").concat(length, " values is not evenly divisible by ").concat(numComponents, ". You should specify it.")); + } + return numComponents; +} +function getNumComponents(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length); +} +function makeTypedArray(array, name) { + if (typedArrays.isArrayBuffer(array)) { + return array; + } + if (typedArrays.isArrayBuffer(array.data)) { + return array.data; + } + if (Array.isArray(array)) { + array = { + data: array + }; + } + var Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? glTypeOrTypedArrayCtor : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT; +} +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) : glTypeOrTypedArrayCtor || Float32Array; +} +function attribBufferFromBuffer(gl, array /*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, + // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) + }; +} +function attribBufferFromSize(gl, array /*, arrayName*/) { + var numValues = array.data || array; + var arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + var numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + var buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER, buffer); + gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW); + return { + buffer: buffer, + numValues: numValues, + type: typedArrays.getGLTypeForTypedArrayType(arrayType), + arrayType: arrayType + }; +} +function attribBufferFromArrayLike(gl, array, arrayName) { + var typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: typedArrays.getGLTypeForTypedArray(typedArray), + numValues: 0 + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + var attribs = {}; + Object.keys(arrays).forEach(function (arrayName) { + if (!isIndices(arrayName)) { + var array = arrays[arrayName]; + var attribName = array.attrib || array.name || array.attribName || defaults.attribPrefix + arrayName; + if (array.value) { + if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value + }; + } else { + var fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + var _fn = fn(gl, array, arrayName), + buffer = _fn.buffer, + type = _fn.type, + numValues = _fn.numValues, + arrayType = _fn.arrayType; + var normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + var numComponents = getNumComponents(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType); + } +} +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line + if (type === SHORT) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line + if (type === INT) return 4; // eslint-disable-line + if (type === UNSIGNED_INT) return 4; // eslint-disable-line + if (type === FLOAT) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +var positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + var array = arrays[key]; + var length = getArray(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + var numComponents = getNumComponents(array, key); + var numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} +function getNumElementsFromAttributes(gl, attribs) { + var key; + var ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + var attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER, attrib.buffer); + var numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER, null); + var bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + var totalElements = numBytes / bytesPerValue; + var numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + var numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error("numComponents ".concat(numComponents, " not correct for length ").concat(length)); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + var newAttribs = createAttribsFromArrays(gl, arrays); + var bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + var indices = arrays.indices; + if (indices) { + var newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + var type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER; + var typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + var buffers = {}; + Object.keys(arrays).forEach(function (key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices'); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + return buffers; +} + +/***/ }), + +/***/ "./src/draw.js": +/*!*********************!*\ + !*** ./src/draw.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.drawBufferInfo = drawBufferInfo; +exports.drawObjectList = drawObjectList; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +var TRIANGLES = 0x0004; +var UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + var indices = bufferInfo.indices; + var elementType = bufferInfo.elementType; + var numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + var lastUsedProgramInfo = null; + var lastUsedBufferInfo = null; + objectsToDraw.forEach(function (object) { + if (object.active === false) { + return; + } + var programInfo = object.programInfo; + var bufferInfo = object.vertexArrayInfo || object.bufferInfo; + var bindBuffers = false; + var type = object.type === undefined ? TRIANGLES : object.type; + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + programs.setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +/***/ }), + +/***/ "./src/framebuffers.js": +/*!*****************************!*\ + !*** ./src/framebuffers.js ***! + \*****************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindFramebufferInfo = bindFramebufferInfo; +exports.createFramebufferInfo = createFramebufferInfo; +exports.resizeFramebufferInfo = resizeFramebufferInfo; +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Framebuffer related functions + * + * For backward compatibility they are available at both `twgl.framebuffer` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/framebuffers + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var FRAMEBUFFER = 0x8d40; +var RENDERBUFFER = 0x8d41; +var TEXTURE_2D = 0x0de1; +var UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +var DEPTH_COMPONENT = 0x1902; +var RGBA = 0x1908; +var DEPTH_COMPONENT24 = 0x81a6; +var DEPTH_COMPONENT32F = 0x8cac; +var DEPTH24_STENCIL8 = 0x88f0; +var DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +var RGBA4 = 0x8056; +var RGB5_A1 = 0x8057; +var RGB565 = 0x8D62; +var DEPTH_COMPONENT16 = 0x81A5; +var STENCIL_INDEX = 0x1901; +var STENCIL_INDEX8 = 0x8D48; +var DEPTH_STENCIL = 0x84F9; +var COLOR_ATTACHMENT0 = 0x8CE0; +var DEPTH_ATTACHMENT = 0x8D00; +var STENCIL_ATTACHMENT = 0x8D20; +var DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +var CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +var LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +var defaultAttachments = [{ + format: RGBA, + type: UNSIGNED_BYTE, + min: LINEAR, + wrap: CLAMP_TO_EDGE +}, { + format: DEPTH_STENCIL +}]; +var attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} +var renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} +var MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + var target = FRAMEBUFFER; + var fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + var usedColorAttachmentsPoints = []; + var framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height + }; + attachments.forEach(function (attachmentOptions, i) { + var attachment = attachmentOptions.attachment; + var samples = attachmentOptions.samples; + var format = attachmentOptions.format; + var attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + var textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = textures.createTexture(gl, textureOptions); + } + } + if (helper.isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (helper.isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer(target, attachmentPoint, attachment, attachmentOptions.level || 0, attachmentOptions.layer); + } else { + gl.framebufferTexture2D(target, attachmentPoint, attachmentOptions.target || TEXTURE_2D, attachment, attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function (attachmentOptions, ndx) { + var attachment = framebufferInfo.attachments[ndx]; + var format = attachmentOptions.format; + var samples = attachmentOptions.samples; + if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (helper.isTexture(gl, attachment)) { + textures.resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +/***/ }), + +/***/ "./src/helper.js": +/*!***********************!*\ + !*** ./src/helper.js ***! + \***********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.copyExistingProperties = copyExistingProperties; +exports.copyNamedProperties = copyNamedProperties; +exports.error = error; +exports.isBuffer = isBuffer; +exports.isRenderbuffer = isRenderbuffer; +exports.isSampler = isSampler; +exports.isShader = isShader; +exports.isTexture = isTexture; +exports.warn = warn; +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* eslint no-console: "off" */ + +/** + * Copy named properties + * + * @param {string[]} names names of properties to copy + * @param {object} src object to copy properties from + * @param {object} dst object to copy properties to + * @private + */ +function copyNamedProperties(names, src, dst) { + names.forEach(function (name) { + var value = src[name]; + if (value !== undefined) { + dst[name] = value; + } + }); +} + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function (key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { + /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} +function error() { + var _console; + (_console = console).error.apply(_console, arguments); +} +function warn() { + var _console2; + (_console2 = console).warn.apply(_console2, arguments); +} +var isTypeWeakMaps = new Map(); +function isType(object, type) { + if (!object || _typeof(object) !== 'object') { + return false; + } + var weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + var isOfType = weakMap.get(object); + if (isOfType === undefined) { + var s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} +function isShader(gl, t) { + return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader'); +} +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/***/ }), + +/***/ "./src/programs.js": +/*!*************************!*\ + !*** ./src/programs.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.bindTransformFeedbackInfo = bindTransformFeedbackInfo; +exports.bindUniformBlock = bindUniformBlock; +exports.createAttributeSetters = createAttributeSetters; +exports.createProgram = createProgram; +exports.createProgramAsync = void 0; +exports.createProgramFromScripts = createProgramFromScripts; +exports.createProgramFromSources = createProgramFromSources; +exports.createProgramInfo = createProgramInfo; +exports.createProgramInfoAsync = void 0; +exports.createProgramInfoFromProgram = createProgramInfoFromProgram; +exports.createProgramInfos = createProgramInfos; +exports.createProgramInfosAsync = void 0; +exports.createPrograms = createPrograms; +exports.createProgramsAsync = void 0; +exports.createTransformFeedback = createTransformFeedback; +exports.createTransformFeedbackInfo = createTransformFeedbackInfo; +exports.createUniformBlockInfo = createUniformBlockInfo; +exports.createUniformBlockInfoFromProgram = createUniformBlockInfoFromProgram; +exports.createUniformBlockSpecFromProgram = createUniformBlockSpecFromProgram; +exports.createUniformSetters = createUniformSetters; +exports.setAttributes = setAttributes; +exports.setBlockUniforms = setBlockUniforms; +exports.setBuffersAndAttributes = setBuffersAndAttributes; +exports.setUniformBlock = setUniformBlock; +exports.setUniforms = setUniforms; +exports.setUniformsAndBindTextures = void 0; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; } +function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } +function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } +function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } +function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } +function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } +function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } +function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } +function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); } +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } /* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +var error = helper.error; +var warn = helper.warn; +function getElementById(id) { + return typeof document !== 'undefined' && document.getElementById ? document.getElementById(id) : null; +} +var TEXTURE0 = 0x84c0; +var DYNAMIC_DRAW = 0x88e8; +var ARRAY_BUFFER = 0x8892; +var ELEMENT_ARRAY_BUFFER = 0x8893; +var UNIFORM_BUFFER = 0x8a11; +var TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; +var TRANSFORM_FEEDBACK = 0x8e22; +var COMPILE_STATUS = 0x8b81; +var LINK_STATUS = 0x8b82; +var FRAGMENT_SHADER = 0x8b30; +var VERTEX_SHADER = 0x8b31; +var SEPARATE_ATTRIBS = 0x8c8d; +var ACTIVE_UNIFORMS = 0x8b86; +var ACTIVE_ATTRIBUTES = 0x8b89; +var TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +var ACTIVE_UNIFORM_BLOCKS = 0x8a36; +var UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +var UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +var UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +var UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; +var FLOAT = 0x1406; +var FLOAT_VEC2 = 0x8B50; +var FLOAT_VEC3 = 0x8B51; +var FLOAT_VEC4 = 0x8B52; +var INT = 0x1404; +var INT_VEC2 = 0x8B53; +var INT_VEC3 = 0x8B54; +var INT_VEC4 = 0x8B55; +var BOOL = 0x8B56; +var BOOL_VEC2 = 0x8B57; +var BOOL_VEC3 = 0x8B58; +var BOOL_VEC4 = 0x8B59; +var FLOAT_MAT2 = 0x8B5A; +var FLOAT_MAT3 = 0x8B5B; +var FLOAT_MAT4 = 0x8B5C; +var SAMPLER_2D = 0x8B5E; +var SAMPLER_CUBE = 0x8B60; +var SAMPLER_3D = 0x8B5F; +var SAMPLER_2D_SHADOW = 0x8B62; +var FLOAT_MAT2x3 = 0x8B65; +var FLOAT_MAT2x4 = 0x8B66; +var FLOAT_MAT3x2 = 0x8B67; +var FLOAT_MAT3x4 = 0x8B68; +var FLOAT_MAT4x2 = 0x8B69; +var FLOAT_MAT4x3 = 0x8B6A; +var SAMPLER_2D_ARRAY = 0x8DC1; +var SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +var SAMPLER_CUBE_SHADOW = 0x8DC5; +var UNSIGNED_INT = 0x1405; +var UNSIGNED_INT_VEC2 = 0x8DC6; +var UNSIGNED_INT_VEC3 = 0x8DC7; +var UNSIGNED_INT_VEC4 = 0x8DC8; +var INT_SAMPLER_2D = 0x8DCA; +var INT_SAMPLER_3D = 0x8DCB; +var INT_SAMPLER_CUBE = 0x8DCC; +var INT_SAMPLER_2D_ARRAY = 0x8DCF; +var UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +var UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +var UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +var UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; +var TEXTURE_2D = 0x0DE1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806F; +var TEXTURE_2D_ARRAY = 0x8C1A; +var typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function (v) { + gl.uniform1f(location, v); + }; +} +function floatArraySetter(gl, location) { + return function (v) { + gl.uniform1fv(location, v); + }; +} +function floatVec2Setter(gl, location) { + return function (v) { + gl.uniform2fv(location, v); + }; +} +function floatVec3Setter(gl, location) { + return function (v) { + gl.uniform3fv(location, v); + }; +} +function floatVec4Setter(gl, location) { + return function (v) { + gl.uniform4fv(location, v); + }; +} +function intSetter(gl, location) { + return function (v) { + gl.uniform1i(location, v); + }; +} +function intArraySetter(gl, location) { + return function (v) { + gl.uniform1iv(location, v); + }; +} +function intVec2Setter(gl, location) { + return function (v) { + gl.uniform2iv(location, v); + }; +} +function intVec3Setter(gl, location) { + return function (v) { + gl.uniform3iv(location, v); + }; +} +function intVec4Setter(gl, location) { + return function (v) { + gl.uniform4iv(location, v); + }; +} +function uintSetter(gl, location) { + return function (v) { + gl.uniform1ui(location, v); + }; +} +function uintArraySetter(gl, location) { + return function (v) { + gl.uniform1uiv(location, v); + }; +} +function uintVec2Setter(gl, location) { + return function (v) { + gl.uniform2uiv(location, v); + }; +} +function uintVec3Setter(gl, location) { + return function (v) { + gl.uniform3uiv(location, v); + }; +} +function uintVec4Setter(gl, location) { + return function (v) { + gl.uniform4uiv(location, v); + }; +} +function floatMat2Setter(gl, location) { + return function (v) { + gl.uniformMatrix2fv(location, false, v); + }; +} +function floatMat3Setter(gl, location) { + return function (v) { + gl.uniformMatrix3fv(location, false, v); + }; +} +function floatMat4Setter(gl, location) { + return function (v) { + gl.uniformMatrix4fv(location, false, v); + }; +} +function floatMat23Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} +function floatMat32Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} +function floatMat24Setter(gl, location) { + return function (v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} +function floatMat42Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} +function floatMat34Setter(gl, location) { + return function (v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} +function floatMat43Setter(gl, location) { + return function (v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} +function samplerSetter(gl, type, unit, location) { + var bindPoint = getBindPointForSamplerType(gl, type); + return utils.isWebGL2(gl) ? function (textureOrPair) { + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function (texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} +function samplerArraySetter(gl, type, unit, location, size) { + var bindPoint = getBindPointForSamplerType(gl, type); + var units = new Int32Array(size); + for (var ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + return utils.isWebGL2(gl) ? function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + var texture; + var sampler; + if (!textureOrPair || helper.isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function (textures) { + gl.uniform1iv(location, units); + textures.forEach(function (texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} +typeMap[FLOAT] = { + Type: Float32Array, + size: 4, + setter: floatSetter, + arraySetter: floatArraySetter +}; +typeMap[FLOAT_VEC2] = { + Type: Float32Array, + size: 8, + setter: floatVec2Setter, + cols: 2 +}; +typeMap[FLOAT_VEC3] = { + Type: Float32Array, + size: 12, + setter: floatVec3Setter, + cols: 3 +}; +typeMap[FLOAT_VEC4] = { + Type: Float32Array, + size: 16, + setter: floatVec4Setter, + cols: 4 +}; +typeMap[INT] = { + Type: Int32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[INT_VEC2] = { + Type: Int32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[INT_VEC3] = { + Type: Int32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[INT_VEC4] = { + Type: Int32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[UNSIGNED_INT] = { + Type: Uint32Array, + size: 4, + setter: uintSetter, + arraySetter: uintArraySetter +}; +typeMap[UNSIGNED_INT_VEC2] = { + Type: Uint32Array, + size: 8, + setter: uintVec2Setter, + cols: 2 +}; +typeMap[UNSIGNED_INT_VEC3] = { + Type: Uint32Array, + size: 12, + setter: uintVec3Setter, + cols: 3 +}; +typeMap[UNSIGNED_INT_VEC4] = { + Type: Uint32Array, + size: 16, + setter: uintVec4Setter, + cols: 4 +}; +typeMap[BOOL] = { + Type: Uint32Array, + size: 4, + setter: intSetter, + arraySetter: intArraySetter +}; +typeMap[BOOL_VEC2] = { + Type: Uint32Array, + size: 8, + setter: intVec2Setter, + cols: 2 +}; +typeMap[BOOL_VEC3] = { + Type: Uint32Array, + size: 12, + setter: intVec3Setter, + cols: 3 +}; +typeMap[BOOL_VEC4] = { + Type: Uint32Array, + size: 16, + setter: intVec4Setter, + cols: 4 +}; +typeMap[FLOAT_MAT2] = { + Type: Float32Array, + size: 32, + setter: floatMat2Setter, + rows: 2, + cols: 2 +}; +typeMap[FLOAT_MAT3] = { + Type: Float32Array, + size: 48, + setter: floatMat3Setter, + rows: 3, + cols: 3 +}; +typeMap[FLOAT_MAT4] = { + Type: Float32Array, + size: 64, + setter: floatMat4Setter, + rows: 4, + cols: 4 +}; +typeMap[FLOAT_MAT2x3] = { + Type: Float32Array, + size: 32, + setter: floatMat23Setter, + rows: 2, + cols: 3 +}; +typeMap[FLOAT_MAT2x4] = { + Type: Float32Array, + size: 32, + setter: floatMat24Setter, + rows: 2, + cols: 4 +}; +typeMap[FLOAT_MAT3x2] = { + Type: Float32Array, + size: 48, + setter: floatMat32Setter, + rows: 3, + cols: 2 +}; +typeMap[FLOAT_MAT3x4] = { + Type: Float32Array, + size: 48, + setter: floatMat34Setter, + rows: 3, + cols: 4 +}; +typeMap[FLOAT_MAT4x2] = { + Type: Float32Array, + size: 64, + setter: floatMat42Setter, + rows: 4, + cols: 2 +}; +typeMap[FLOAT_MAT4x3] = { + Type: Float32Array, + size: 64, + setter: floatMat43Setter, + rows: 4, + cols: 3 +}; +typeMap[SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[SAMPLER_2D_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[SAMPLER_CUBE_SHADOW] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D +}; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_3D +}; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_CUBE_MAP +}; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { + Type: null, + size: 0, + setter: samplerSetter, + arraySetter: samplerArraySetter, + bindPoint: TEXTURE_2D_ARRAY +}; +function floatAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer(index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function intAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function uintAttribSetter(gl, index) { + return function (b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer(index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} +function matAttribSetter(gl, index, typeInfo) { + var defaultSize = typeInfo.size; + var count = typeInfo.count; + return function (b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + var numComponents = b.size || b.numComponents || defaultSize; + var size = numComponents / count; + var type = b.type || FLOAT; + var typeInfo = typeMap[type]; + var stride = typeInfo.size * numComponents; + var normalize = b.normalize || false; + var offset = b.offset || 0; + var rowOffset = stride / count; + for (var i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer(index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} +var attrTypeMap = {}; +attrTypeMap[FLOAT] = { + size: 4, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC2] = { + size: 8, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC3] = { + size: 12, + setter: floatAttribSetter +}; +attrTypeMap[FLOAT_VEC4] = { + size: 16, + setter: floatAttribSetter +}; +attrTypeMap[INT] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[INT_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[UNSIGNED_INT] = { + size: 4, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC2] = { + size: 8, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC3] = { + size: 12, + setter: uintAttribSetter +}; +attrTypeMap[UNSIGNED_INT_VEC4] = { + size: 16, + setter: uintAttribSetter +}; +attrTypeMap[BOOL] = { + size: 4, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC2] = { + size: 8, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC3] = { + size: 12, + setter: intAttribSetter +}; +attrTypeMap[BOOL_VEC4] = { + size: 16, + setter: intAttribSetter +}; +attrTypeMap[FLOAT_MAT2] = { + size: 4, + setter: matAttribSetter, + count: 2 +}; +attrTypeMap[FLOAT_MAT3] = { + size: 9, + setter: matAttribSetter, + count: 3 +}; +attrTypeMap[FLOAT_MAT4] = { + size: 16, + setter: matAttribSetter, + count: 4 +}; + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +var errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src) { + var log = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + var lineOffset = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; + // Note: Error message formats are not defined by any spec so this may or may not work. + var matches = _toConsumableArray(log.matchAll(errorRE)); + var lineNoToErrorMap = new Map(matches.map(function (m, ndx) { + var lineNo = parseInt(m[1]); + var next = matches[ndx + 1]; + var end = next ? next.index : log.length; + var msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map(function (line, lineNo) { + var err = lineNoToErrorMap.get(lineNo); + return "".concat(lineNo + 1 + lineOffset, ": ").concat(line).concat(err ? "\n\n^^^ ".concat(err) : ''); + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +var spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + var lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return { + lineOffset: lineOffset, + shaderSource: shaderSource + }; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(function () { + progOptions.callback("".concat(msg, "\n").concat(progOptions.errors.join('\n'))); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + var compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + var lastError = gl.getShaderInfoLog(shader); + var _prepShaderSource = prepShaderSource(gl.getShaderSource(shader)), + lineOffset = _prepShaderSource.lineOffset, + shaderSource = _prepShaderSource.shaderSource; + var _error = "".concat(addLineNumbersWithError(shaderSource, lastError, lineOffset), "\nError compiling ").concat(utils.glEnumToString(gl, shaderType), ": ").concat(lastError); + errFn(_error); + return _error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + var transformFeedbackVaryings; + var transformFeedbackMode; + var callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + var opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + var _errorCallback = opt_errorCallback || error; + var errors = []; + var options = { + errorCallback: function errorCallback(msg) { + errors.push(msg); + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + _errorCallback.apply(void 0, [msg].concat(args)); + }, + transformFeedbackVaryings: transformFeedbackVaryings, + transformFeedbackMode: transformFeedbackMode, + callback: callback, + errors: errors + }; + { + var attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function (attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + return options; +} +var defaultShaderType = ["VERTEX_SHADER", "FRAGMENT_SHADER"]; +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} +function deleteProgramAndShaders(gl, program, notThese) { + var shaders = gl.getAttachedShaders(program); + var _iterator = _createForOfIteratorHelper(shaders), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var shader = _step.value; + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + gl.deleteProgram(program); +} +var wait = function wait() { + var ms = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + return new Promise(function (resolve) { + return setTimeout(resolve, ms); + }); +}; +function createProgramNoCheck(gl, shaders, programOptions) { + var program = gl.createProgram(); + var _getProgramOptions = getProgramOptions(programOptions), + attribLocations = _getProgramOptions.attribLocations, + transformFeedbackVaryings = _getProgramOptions.transformFeedbackVaryings, + transformFeedbackMode = _getProgramOptions.transformFeedbackMode; + for (var ndx = 0; ndx < shaders.length; ++ndx) { + var shader = shaders[ndx]; + if (typeof shader === 'string') { + var elem = getElementById(shader); + var src = elem ? elem.text : shader; + var type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + Object.entries(attribLocations).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + attrib = _ref2[0], + loc = _ref2[1]; + return gl.bindAttribLocation(program, loc, attrib); + }); + { + var varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaderSet = new Set(shaders); + var program = createProgramNoCheck(gl, shaders, progOptions); + function hasErrors(gl, program) { + var errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(function () { + var errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function (gl, arg1) { + for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + args[_key2 - 2] = arguments[_key2]; + } + return new Promise(function (resolve, reject) { + var programOptions = getProgramOptions.apply(void 0, args); + programOptions.callback = function (err, program) { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +var createProgramAsync = exports.createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +var createProgramInfoAsync = exports.createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); +function waitForProgramLinkCompletionAsync(_x, _x2) { + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function _waitForProgramLinkCompletionAsync() { + _waitForProgramLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(gl, program) { + var ext, checkFn, waitTime; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + ext = gl.getExtension('KHR_parallel_shader_compile'); + checkFn = ext ? function (gl, program) { + return gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR); + } : function () { + return true; + }; + waitTime = 0; + case 3: + _context.next = 5; + return wait(waitTime); + case 5: + // must wait at least once + waitTime = 1000 / 60; + case 6: + if (!checkFn(gl, program)) { + _context.next = 3; + break; + } + case 7: + case "end": + return _context.stop(); + } + }, _callee); + })); + return _waitForProgramLinkCompletionAsync.apply(this, arguments); +} +function waitForAllProgramsLinkCompletionAsync(_x3, _x4) { + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function _waitForAllProgramsLinkCompletionAsync() { + _waitForAllProgramsLinkCompletionAsync = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(gl, programs) { + var _i3, _Object$values2, program; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + _i3 = 0, _Object$values2 = Object.values(programs); + case 1: + if (!(_i3 < _Object$values2.length)) { + _context2.next = 8; + break; + } + program = _Object$values2[_i3]; + _context2.next = 5; + return waitForProgramLinkCompletionAsync(gl, program); + case 5: + _i3++; + _context2.next = 1; + break; + case 8: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return _waitForAllProgramsLinkCompletionAsync.apply(this, arguments); +} +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + var linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + var lastError = gl.getProgramInfoLog(program); + errFn("Error in program linking: ".concat(lastError)); + // print any errors from these shaders + var shaders = gl.getAttachedShaders(program); + var errors = shaders.map(function (shader) { + return checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn); + }); + return "".concat(lastError, "\n").concat(errors.filter(function (_) { + return _; + }).join('\n')); + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts(gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var shaders = []; + var _iterator2 = _createForOfIteratorHelper(shaderScriptIds), + _step2; + try { + for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { + var scriptId = _step2.value; + var shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, "unknown script element: ".concat(scriptId)); + } + shaders.push(shaderScript.text); + } + } catch (err) { + _iterator2.e(err); + } finally { + _iterator2.f(); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + var name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} +var tokenRE = /(\.|\[|]|\w+)/g; +var isDigit = function isDigit(s) { + return s >= '0' && s <= '9'; +}; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + var tokens = fullPath.split(tokenRE).filter(function (s) { + return s !== ''; + }); + var tokenNdx = 0; + var path = ''; + for (;;) { + var token = tokens[tokenNdx++]; // has to be name or number + path += token; + var isArrayIndex = isDigit(token[0]); + var accessor = isArrayIndex ? parseInt(token) : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + var isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + var _token = tokens[tokenNdx++]; // has to be . or [ + var isArray = _token === '['; + var child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function (node) { + return function (value) { + setUniformTree(node, value); + }; + }(child); + path += _token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +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, location) { + var isArray = uniformInfo.name.endsWith("[0]"); + var type = uniformInfo.type; + var typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error("unknown type: 0x".concat(type.toString(16))); // we should never get here. + } + var setter; + if (typeInfo.bindPoint) { + // it's a sampler + var unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + var uniformSetters = {}; + var uniformTree = {}; + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + for (var ii = 0; ii < numUniforms; ++ii) { + var uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + var name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + var location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + var setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + var info = {}; + var numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (var ii = 0; ii < numVaryings; ++ii) { + var varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (var name in bufferInfo) { + var varying = transformFeedbackInfo[name]; + if (varying) { + var buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + var tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + var numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + var uniformData = []; + var uniformIndices = []; + for (var ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + var uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + [["UNIFORM_TYPE", "type"], ["UNIFORM_SIZE", "size"], + // num elements + ["UNIFORM_BLOCK_INDEX", "blockNdx"], ["UNIFORM_OFFSET", "offset"]].forEach(function (pair) { + var pname = pair[0]; + var key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function (value, ndx) { + uniformData[ndx][key] = value; + }); + }); + var blockSpecs = {}; + var numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (var _ii = 0; _ii < numUniformBlocks; ++_ii) { + var name = gl.getActiveUniformBlockName(program, _ii); + var blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, _ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + return { + blockSpecs: blockSpecs, + uniformData: uniformData + }; +} +var arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +var pad = function pad(v, padding) { + return ((v + (padding - 1)) / padding | 0) * padding; +}; +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + var numElements = view.length; + var totalRows = numElements / 4; + return function (value) { + var dst = 0; + var src = 0; + for (var row = 0; row < totalRows; ++row) { + for (var col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function (value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName) { + var _options$offset, _options$array, _options$buffer, _options$bufferOffset; + var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; + var blockSpecs = uniformBlockSpec.blockSpecs; + var uniformData = uniformBlockSpec.uniformData; + var blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {} + }; + } + var offset = (_options$offset = options.offset) !== null && _options$offset !== void 0 ? _options$offset : 0; + var array = (_options$array = options.array) !== null && _options$array !== void 0 ? _options$array : new ArrayBuffer(blockSpec.size); + var buffer = (_options$buffer = options.buffer) !== null && _options$buffer !== void 0 ? _options$buffer : gl.createBuffer(); + var uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + var prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + var uniforms = {}; + var setters = {}; + var setterTree = {}; + blockSpec.uniformIndices.forEach(function (uniformNdx) { + var data = uniformData[uniformNdx]; + var name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + var isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + var typeInfo = typeMap[data.type]; + var Type = typeInfo.Type; + var byteLength = isArray ? pad(typeInfo.size, 16) * data.size : typeInfo.size * data.size; + var uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + var setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array: array, + asFloat: new Float32Array(array), + // for debugging + asUint8: new Uint8Array(array), + // needed for gl.bufferSubData because it doesn't take an array buffer + buffer: buffer, + uniforms: uniforms, + setters: setters, + offset: (_options$bufferOffset = options.bufferOffset) !== null && _options$bufferOffset !== void 0 ? _options$bufferOffset : offset, + size: blockSpec.size + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName) { + var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + var uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + var blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + var _uniformBlockInfo$siz; + var bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, (_uniformBlockInfo$siz = uniformBlockInfo.size) !== null && _uniformBlockInfo$siz !== void 0 ? _uniformBlockInfo$siz : uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + var setters = uniformBlockInfo.setters; + for (var name in values) { + var setter = setters[name]; + if (setter) { + var value = values[name]; + setter(value); + } + } +} +function setUniformTree(tree, values) { + for (var name in values) { + var prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters) { + // eslint-disable-line + var actualSetters = setters.uniformSetters || setters; + var numArgs = arguments.length <= 1 ? 0 : arguments.length - 1; + for (var aNdx = 0; aNdx < numArgs; ++aNdx) { + var values = aNdx + 1 < 1 || arguments.length <= aNdx + 1 ? undefined : arguments[aNdx + 1]; + if (Array.isArray(values)) { + var numValues = values.length; + for (var ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (var name in values) { + var setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +var setUniformsAndBindTextures = exports.setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + var attribSetters = {}; + var numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (var ii = 0; ii < numAttribs; ++ii) { + var attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + var index = gl.getAttribLocation(program, attribInfo.name); + var typeInfo = attrTypeMap[attribInfo.type]; + var setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (var name in buffers) { + var setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + var uniformSetters = createUniformSetters(gl, program); + var attribSetters = createAttributeSetters(gl, program); + var programInfo = { + program: program, + uniformSetters: uniformSetters, + attribSetters: attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(function (_ref3) { + var _ref4 = _slicedToArray(_ref3, 2), + k = _ref4[0], + v = _ref4[1]; + return [k, v.location]; + })), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(function (_ref5) { + var _ref6 = _slicedToArray(_ref5, 2), + k = _ref6[0], + v = _ref6[1]; + return [k, v.location]; + })) + }; + if (utils.isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + return programInfo; +} +var notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + var progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + var errors = []; + shaderSources = shaderSources.map(function (source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + var script = getElementById(source); + if (!script) { + var err = "no element with id: ".concat(source); + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + if (errors.length) { + return reportError(progOptions, ''); + } + var origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = function (err, program) { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + var program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + return createProgramInfoFromProgram(gl, program); +} +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (var _i = 0, _Object$entries = Object.entries(programs); _i < _Object$entries.length; _i++) { + var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), + name = _Object$entries$_i[0], + program = _Object$entries$_i[1]; + var options = _objectSpread({}, programOptions); + var spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + var errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (var _i2 = 0, _Object$values = Object.values(programs); _i2 < _Object$values.length; _i2++) { + var _program = _Object$values[_i2]; + var shaders = gl.getAttachedShaders(_program); + gl.deleteProgram(_program); + var _iterator3 = _createForOfIteratorHelper(shaders), + _step3; + try { + for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { + var shader = _step3.value; + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } catch (err) { + _iterator3.e(err); + } finally { + _iterator3.f(); + } + } + return errors; + } + } + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs) { + var programOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + // Remember existing shaders so that if there is an error we don't delete them + var noDeleteShadersSet = new Set(); + + // compile and link everything + var programs = Object.fromEntries(Object.entries(programSpecs).map(function (_ref7) { + var _ref8 = _slicedToArray(_ref7, 2), + name = _ref8[0], + spec = _ref8[1]; + var options = _objectSpread({}, programOptions); + var shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(function () { + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + var errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(function (_ref9) { + var _ref10 = _slicedToArray(_ref9, 2), + name = _ref10[0], + program = _ref10[1]; + return [name, createProgramInfoFromProgram(gl, program)]; + })); + } + var origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = function (err, programs) { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + var programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +var createProgramsAsync = exports.createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +var createProgramInfosAsync = exports.createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +/***/ }), + +/***/ "./src/textures.js": +/*!*************************!*\ + !*** ./src/textures.js ***! + \*************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.canFilter = canFilter; +exports.canGenerateMipmap = canGenerateMipmap; +exports.createSampler = createSampler; +exports.createSamplers = createSamplers; +exports.createTexture = createTexture; +exports.createTextures = createTextures; +exports.getBytesPerElementForInternalFormat = getBytesPerElementForInternalFormat; +exports.getFormatAndTypeForInternalFormat = getFormatAndTypeForInternalFormat; +exports.getNumComponentsForFormat = getNumComponentsForFormat; +exports.loadTextureFromUrl = loadTextureFromUrl; +exports.resizeTexture = resizeTexture; +exports.setDefaultTextureColor = setDefaultTextureColor; +exports.setEmptyTexture = setEmptyTexture; +exports.setSamplerParameters = setSamplerParameters; +exports.setTextureDefaults_ = setDefaults; +exports.setTextureFilteringForSize = setTextureFilteringForSize; +exports.setTextureFromArray = setTextureFromArray; +exports.setTextureFromElement = setTextureFromElement; +exports.setTextureParameters = setTextureParameters; +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +var typedArrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level texture related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.textures` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/textures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined +}; +var isArrayBuffer = typedArrays.isArrayBuffer; + +// Should we make this on demand? +var getShared2DContext = function () { + var s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || (typeof document !== 'undefined' && document.createElement ? document.createElement("canvas").getContext("2d") : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +var ALPHA = 0x1906; +var RGB = 0x1907; +var RGBA = 0x1908; +var LUMINANCE = 0x1909; +var LUMINANCE_ALPHA = 0x190A; +var DEPTH_COMPONENT = 0x1902; +var DEPTH_STENCIL = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +var CLAMP_TO_EDGE = 0x812f; + +/* TextureMagFilter */ +var NEAREST = 0x2600; +var LINEAR = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +var TEXTURE_2D = 0x0de1; +var TEXTURE_CUBE_MAP = 0x8513; +var TEXTURE_3D = 0x806f; +var TEXTURE_2D_ARRAY = 0x8c1a; + +/* Cubemap Targets */ +var TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +var TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +var TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +var TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +var TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +var TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +var TEXTURE_MIN_FILTER = 0x2801; +var TEXTURE_MAG_FILTER = 0x2800; +var TEXTURE_WRAP_S = 0x2802; +var TEXTURE_WRAP_T = 0x2803; +var TEXTURE_WRAP_R = 0x8072; +var TEXTURE_MIN_LOD = 0x813a; +var TEXTURE_MAX_LOD = 0x813b; +var TEXTURE_BASE_LEVEL = 0x813c; +var TEXTURE_MAX_LEVEL = 0x813d; +var TEXTURE_COMPARE_MODE = 0x884C; +var TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +var UNPACK_ALIGNMENT = 0x0cf5; +var UNPACK_ROW_LENGTH = 0x0cf2; +var UNPACK_IMAGE_HEIGHT = 0x806e; +var UNPACK_SKIP_PIXELS = 0x0cf4; +var UNPACK_SKIP_ROWS = 0x0cf3; +var UNPACK_SKIP_IMAGES = 0x806d; +var UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +var UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +var UNPACK_FLIP_Y_WEBGL = 0x9240; +var R8 = 0x8229; +var R8_SNORM = 0x8F94; +var R16F = 0x822D; +var R32F = 0x822E; +var R8UI = 0x8232; +var R8I = 0x8231; +var RG16UI = 0x823A; +var RG16I = 0x8239; +var RG32UI = 0x823C; +var RG32I = 0x823B; +var RG8 = 0x822B; +var RG8_SNORM = 0x8F95; +var RG16F = 0x822F; +var RG32F = 0x8230; +var RG8UI = 0x8238; +var RG8I = 0x8237; +var R16UI = 0x8234; +var R16I = 0x8233; +var R32UI = 0x8236; +var R32I = 0x8235; +var RGB8 = 0x8051; +var SRGB8 = 0x8C41; +var RGB565 = 0x8D62; +var RGB8_SNORM = 0x8F96; +var R11F_G11F_B10F = 0x8C3A; +var RGB9_E5 = 0x8C3D; +var RGB16F = 0x881B; +var RGB32F = 0x8815; +var RGB8UI = 0x8D7D; +var RGB8I = 0x8D8F; +var RGB16UI = 0x8D77; +var RGB16I = 0x8D89; +var RGB32UI = 0x8D71; +var RGB32I = 0x8D83; +var RGBA8 = 0x8058; +var SRGB8_ALPHA8 = 0x8C43; +var RGBA8_SNORM = 0x8F97; +var RGB5_A1 = 0x8057; +var RGBA4 = 0x8056; +var RGB10_A2 = 0x8059; +var RGBA16F = 0x881A; +var RGBA32F = 0x8814; +var RGBA8UI = 0x8D7C; +var RGBA8I = 0x8D8E; +var RGB10_A2UI = 0x906F; +var RGBA16UI = 0x8D76; +var RGBA16I = 0x8D88; +var RGBA32I = 0x8D82; +var RGBA32UI = 0x8D70; +var DEPTH_COMPONENT16 = 0x81A5; +var DEPTH_COMPONENT24 = 0x81A6; +var DEPTH_COMPONENT32F = 0x8CAC; +var DEPTH32F_STENCIL8 = 0x8CAD; +var DEPTH24_STENCIL8 = 0x88F0; + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var RG = 0x8227; +var RG_INTEGER = 0x8228; +var RED = 0x1903; +var RED_INTEGER = 0x8D94; +var RGB_INTEGER = 0x8D98; +var RGBA_INTEGER = 0x8D99; +var formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + var f = formatInfo; + f[ALPHA] = { + numColorComponents: 1 + }; + f[LUMINANCE] = { + numColorComponents: 1 + }; + f[LUMINANCE_ALPHA] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RED] = { + numColorComponents: 1 + }; + f[RED_INTEGER] = { + numColorComponents: 1 + }; + f[RG] = { + numColorComponents: 2 + }; + f[RG_INTEGER] = { + numColorComponents: 2 + }; + f[RGB] = { + numColorComponents: 3 + }; + f[RGB_INTEGER] = { + numColorComponents: 3 + }; + f[RGBA] = { + numColorComponents: 4 + }; + f[RGBA_INTEGER] = { + numColorComponents: 4 + }; + f[DEPTH_COMPONENT] = { + numColorComponents: 1 + }; + f[DEPTH_STENCIL] = { + numColorComponents: 2 + }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +var s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + var t = {}; + // unsized formats + t[ALPHA] = { + textureFormat: ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE] = { + textureFormat: LUMINANCE, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1, 2, 2, 4], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[LUMINANCE_ALPHA] = { + textureFormat: LUMINANCE_ALPHA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2, 4, 4, 8], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT] + }; + t[RGB] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 6, 6, 12, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5] + }; + t[RGBA] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 8, 8, 16, 2, 2], + type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1] + }; + t[DEPTH_COMPONENT] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_INT, UNSIGNED_SHORT] + }; + + // sized formats + t[R8] = { + textureFormat: RED, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8_SNORM] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [FLOAT, HALF_FLOAT] + }; + t[R32F] = { + textureFormat: RED, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[R8UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [UNSIGNED_BYTE] + }; + t[R8I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [1], + type: [BYTE] + }; + t[R16UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_SHORT] + }; + t[R16I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [SHORT] + }; + t[R32UI] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[R32I] = { + textureFormat: RED_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [INT] + }; + t[RG8] = { + textureFormat: RG, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8_SNORM] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [8, 4], + type: [FLOAT, HALF_FLOAT] + }; + t[RG32F] = { + textureFormat: RG, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [8], + type: [FLOAT] + }; + t[RG8UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [UNSIGNED_BYTE] + }; + t[RG8I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2], + type: [BYTE] + }; + t[RG16UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_SHORT] + }; + t[RG16I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [SHORT] + }; + t[RG32UI] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_INT] + }; + t[RG32I] = { + textureFormat: RG_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [INT] + }; + t[RGB8] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[SRGB8] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB565] = { + textureFormat: RGB, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [3, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5] + }; + t[RGB8_SNORM] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [3], + type: [BYTE] + }; + t[R11F_G11F_B10F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV] + }; + t[RGB9_E5] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6, 4], + type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV] + }; + t[RGB16F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [12, 6], + type: [FLOAT, HALF_FLOAT] + }; + t[RGB32F] = { + textureFormat: RGB, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [FLOAT] + }; + t[RGB8UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [UNSIGNED_BYTE] + }; + t[RGB8I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [3], + type: [BYTE] + }; + t[RGB16UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [UNSIGNED_SHORT] + }; + t[RGB16I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [6], + type: [SHORT] + }; + t[RGB32UI] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [UNSIGNED_INT] + }; + t[RGB32I] = { + textureFormat: RGB_INTEGER, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [12], + type: [INT] + }; + t[RGBA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[SRGB8_ALPHA8] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8_SNORM] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB5_A1] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2, 4], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA4] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4, 2], + type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4] + }; + t[RGB10_A2] = { + textureFormat: RGBA, + colorRenderable: true, + textureFilterable: true, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: true, + bytesPerElement: [16, 8], + type: [FLOAT, HALF_FLOAT] + }; + t[RGBA32F] = { + textureFormat: RGBA, + colorRenderable: false, + textureFilterable: false, + bytesPerElement: [16], + type: [FLOAT] + }; + t[RGBA8UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_BYTE] + }; + t[RGBA8I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [BYTE] + }; + t[RGB10_A2UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_2_10_10_10_REV] + }; + t[RGBA16UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [UNSIGNED_SHORT] + }; + t[RGBA16I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [8], + type: [SHORT] + }; + t[RGBA32I] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [INT] + }; + t[RGBA32UI] = { + textureFormat: RGBA_INTEGER, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [16], + type: [UNSIGNED_INT] + }; + // Sized Internal + t[DEPTH_COMPONENT16] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [2, 4], + type: [UNSIGNED_SHORT, UNSIGNED_INT] + }; + t[DEPTH_COMPONENT24] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT] + }; + t[DEPTH_COMPONENT32F] = { + textureFormat: DEPTH_COMPONENT, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT] + }; + t[DEPTH24_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [UNSIGNED_INT_24_8] + }; + t[DEPTH32F_STENCIL8] = { + textureFormat: DEPTH_STENCIL, + colorRenderable: true, + textureFilterable: false, + bytesPerElement: [4], + type: [FLOAT_32_UNSIGNED_INT_24_8_REV] + }; + Object.keys(t).forEach(function (internalFormat) { + var info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function (bytesPerElement, ndx) { + var type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + var bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0] + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & value - 1) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!utils.isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + var info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + var info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return typedArrays.getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE; +} +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + var size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + var colorspaceConversion; + var premultiplyAlpha; + var flipY; + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + fn(); + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (utils.isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D || helper.isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + var sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + var samplers = {}; + Object.keys(samplerOptions).forEach(function (name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults.textureOptions; + internalFormat = internalFormat || RGBA; + var target = options.target || TEXTURE_2D; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + var filtering = canFilter(internalFormat) ? LINEAR : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } +} +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || options.auto === undefined && options.level === undefined; +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [TEXTURE_CUBE_MAP_POSITIVE_X, TEXTURE_CUBE_MAP_NEGATIVE_X, TEXTURE_CUBE_MAP_POSITIVE_Y, TEXTURE_CUBE_MAP_NEGATIVE_Y, TEXTURE_CUBE_MAP_POSITIVE_Z, TEXTURE_CUBE_MAP_NEGATIVE_Z]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + var faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + var facesWithNdx = faces.map(function (face, ndx) { + return { + face: face, + ndx: ndx + }; + }); + facesWithNdx.sort(function (a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + var level = options.level || 0; + var width = element.width; + var height = element.height; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // guess the parts + var imgWidth = element.width; + var imgHeight = element.height; + var size; + var slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + var ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, function () { + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var xOffset = slices[f.ndx * 2 + 0] * size; + var yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }).then(function (imageBitmap) { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + scopedSetPackState(gl, options, function () { + var smallest = Math.min(element.width, element.height); + var largest = Math.max(element.width, element.height); + var depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + var xMult = element.width === largest ? 1 : 0; + var yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (var d = 0; d < depth; ++d) { + var srcX = d * smallest * xMult; + var srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, function () { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} +function noop() {} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + var a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && a.port === location.port && a.protocol === location.protocol; + } else { + var localOrigin = new URL(location.href).origin; + var urlOrigin = new URL(url, location.href).origin; + return urlOrigin === localOrigin; + } +} +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) ? 'anonymous' : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + var img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + var clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + var onError = function onError() { + var msg = "couldn't load image: " + url; + helper.error(msg); + callback(msg, img); + clearEventHandlers(); + }; + var onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + var err; + var bm; + var cb = function cb() { + callback(err, bm); + }; + var options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function (response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function (blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none' + }); + }).then(function (bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + })["catch"](function (e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap || typeof ImageData !== 'undefined' && obj instanceof ImageData || typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement; +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function () { + callback(null, obj); + }); + return obj; + } + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + var color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } else { + gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var img = loadAndUseImage(options.src, options.crossOrigin, function (err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D; + if (target !== TEXTURE_CUBE_MAP) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = 6; + var errors = []; + var faces = getCubeFaceOrder(gl, options); + var imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder(gl).forEach(function (otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + var urls = options.src; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || UNSIGNED_BYTE; + var target = options.target || TEXTURE_2D_ARRAY; + if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + var numToLoad = urls.length; + var errors = []; + var imgs; // eslint-disable-line + var level = options.level || 0; + var width = options.width; + var height = options.height; + var depth = urls.length; + var firstImage = true; + function uploadImg(slice) { + return function (err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, function () { + gl.bindTexture(target, tex); + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (var s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + var src = img; + var ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + imgs = urls.map(function (url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults.textureOptions; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var width = options.width; + var height = options.height; + var depth = options.depth; + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + var Type = typedArrays.getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + var bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + var numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + utils.glEnumToString(gl, format); + } + var dimensions; + if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + if (!width && !height && !depth) { + var size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + var elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + var faceSize = numElements / 6 * elementsPerElement; + getCubeFacesWithNdx(gl, options).forEach(function (f) { + var offset = faceSize * f.ndx; + var data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type = options.type || formatType.type; + scopedSetPackState(gl, options, function () { + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults.textureOptions; + var tex = gl.createTexture(); + var target = options.target || TEXTURE_2D; + var width = options.width || 1; + var height = options.height || 1; + var internalFormat = options.internalFormat || RGBA; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE); + } + var src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof src === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || Array.isArray(src) && (typeof src[0] === 'number' || Array.isArray(src[0]) || isArrayBuffer(src[0]))) { + var dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof src[0] === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { + // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + var target = options.target || TEXTURE_2D; + gl.bindTexture(target, tex); + var level = options.level || 0; + var internalFormat = options.internalFormat || options.format || RGBA; + var formatType = getFormatAndTypeForInternalFormat(internalFormat); + var format = options.format || formatType.format; + var type; + var src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || Array.isArray(src) && typeof src[0] === 'number') { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP) { + for (var ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || Array.isArray(src) && typeof src[0] === 'string'; +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + var numDownloading = 0; + var errors = []; + var textures = {}; + var images = {}; + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function () { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + Object.keys(textureOptions).forEach(function (name) { + var options = textureOptions[name]; + var onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function onLoadFn(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + return textures; +} + +/***/ }), + +/***/ "./src/twgl-base.js": +/*!**************************!*\ + !*** ./src/twgl-base.js ***! + \**************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +exports.__esModule = true; +var _twgl = __webpack_require__(/*! ./twgl.js */ "./src/twgl.js"); +Object.keys(_twgl).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (key in exports && exports[key] === _twgl[key]) return; + exports[key] = _twgl[key]; +}); + +/***/ }), + +/***/ "./src/twgl.js": +/*!*********************!*\ + !*** ./src/twgl.js ***! + \*********************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +var _exportNames = { + addExtensionsToContext: true, + getContext: true, + getWebGLContext: true, + resizeCanvasToDisplaySize: true, + setDefaults: true, + attributes: true, + textures: true, + utils: true, + draw: true, + framebuffers: true, + programs: true, + typedarrays: true, + vertexArrays: true +}; +exports.addExtensionsToContext = addExtensionsToContext; +exports.framebuffers = exports.draw = exports.attributes = void 0; +exports.getContext = getContext; +exports.getWebGLContext = getWebGLContext; +exports.programs = void 0; +exports.resizeCanvasToDisplaySize = resizeCanvasToDisplaySize; +exports.setDefaults = setDefaults; +exports.vertexArrays = exports.utils = exports.typedarrays = exports.textures = void 0; +var attributes = _interopRequireWildcard(__webpack_require__(/*! ./attributes.js */ "./src/attributes.js")); +exports.attributes = attributes; +Object.keys(attributes).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === attributes[key]) return; + exports[key] = attributes[key]; +}); +var textures = _interopRequireWildcard(__webpack_require__(/*! ./textures.js */ "./src/textures.js")); +exports.textures = textures; +Object.keys(textures).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === textures[key]) return; + exports[key] = textures[key]; +}); +var helper = _interopRequireWildcard(__webpack_require__(/*! ./helper.js */ "./src/helper.js")); +var utils = _interopRequireWildcard(__webpack_require__(/*! ./utils.js */ "./src/utils.js")); +exports.utils = utils; +Object.keys(utils).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === utils[key]) return; + exports[key] = utils[key]; +}); +var draw = _interopRequireWildcard(__webpack_require__(/*! ./draw.js */ "./src/draw.js")); +exports.draw = draw; +Object.keys(draw).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === draw[key]) return; + exports[key] = draw[key]; +}); +var framebuffers = _interopRequireWildcard(__webpack_require__(/*! ./framebuffers.js */ "./src/framebuffers.js")); +exports.framebuffers = framebuffers; +Object.keys(framebuffers).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === framebuffers[key]) return; + exports[key] = framebuffers[key]; +}); +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +exports.programs = programs; +Object.keys(programs).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === programs[key]) return; + exports[key] = programs[key]; +}); +var typedarrays = _interopRequireWildcard(__webpack_require__(/*! ./typedarrays.js */ "./src/typedarrays.js")); +exports.typedarrays = typedarrays; +Object.keys(typedarrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === typedarrays[key]) return; + exports[key] = typedarrays[key]; +}); +var vertexArrays = _interopRequireWildcard(__webpack_require__(/*! ./vertex-arrays.js */ "./src/vertex-arrays.js")); +exports.vertexArrays = vertexArrays; +Object.keys(vertexArrays).forEach(function (key) { + if (key === "default" || key === "__esModule") return; + if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; + if (key in exports && exports[key] === vertexArrays[key]) return; + exports[key] = vertexArrays[key]; +}); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * The main TWGL module. + * + * For most use cases you shouldn't need anything outside this module. + * Exceptions between the stuff added to twgl-full (v3, m4, primitives) + * + * @module twgl + * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray + * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays + * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo + * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo + * @borrows module:twgl/draw.drawObjectList as drawObjectList + * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo + * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo + * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo + * @borrows module:twgl/programs.createProgramInfo as createProgramInfo + * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo + * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock + * @borrows module:twgl/programs.setUniformBlock as setUniformBlock + * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms + * @borrows module:twgl/programs.setUniforms as setUniforms + * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes + * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray + * @borrows module:twgl/textures.createTexture as createTexture + * @borrows module:twgl/textures.resizeTexture as resizeTexture + * @borrows module:twgl/textures.createTextures as createTextures + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ +var defaults = { + addExtensionsToContext: true +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + helper.copyExistingProperties(newDefaults, defaults); + attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line + textures.setTextureDefaults_(newDefaults); // eslint-disable-line +} +var prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + utils.glEnumToString(gl, 0); + var ext = gl.getExtension(extensionName); + if (ext) { + var enums = {}; + var fnSuffix = prefixRE.exec(extensionName)[1]; + var enumSuffix = '_' + fnSuffix; + for (var key in ext) { + var value = ext[key]; + var isFunc = typeof value === 'function'; + var suffix = isFunc ? fnSuffix : enumSuffix; + var name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + helper.warn(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function (origFn) { + return function () { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name + }; + utils.glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +var supportedExtensions = ['ANGLE_instanced_arrays', 'EXT_blend_minmax', 'EXT_color_buffer_float', 'EXT_color_buffer_half_float', 'EXT_disjoint_timer_query', 'EXT_disjoint_timer_query_webgl2', 'EXT_frag_depth', 'EXT_sRGB', 'EXT_shader_texture_lod', 'EXT_texture_filter_anisotropic', 'OES_element_index_uint', 'OES_standard_derivatives', 'OES_texture_float', 'OES_texture_float_linear', 'OES_texture_half_float', 'OES_texture_half_float_linear', 'OES_vertex_array_object', 'WEBGL_color_buffer_float', 'WEBGL_compressed_texture_atc', 'WEBGL_compressed_texture_etc1', 'WEBGL_compressed_texture_pvrtc', 'WEBGL_compressed_texture_s3tc', 'WEBGL_compressed_texture_s3tc_srgb', 'WEBGL_depth_texture', 'WEBGL_draw_buffers']; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (var ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + var names = ["webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + var gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + var names = ["webgl2", "webgl", "experimental-webgl"]; + var context = null; + for (var ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + var gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + 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; +} + +// function notPrivate(name) { +// return name[name.length - 1] !== '_'; +// } +// +// function copyPublicProperties(src, dst) { +// Object.keys(src).filter(notPrivate).forEach(function(key) { +// dst[key] = src[key]; +// }); +// return dst; +// } + +/***/ }), + +/***/ "./src/typedarrays.js": +/*!****************************!*\ + !*** ./src/typedarrays.js ***! + \****************************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.getGLTypeForTypedArray = getGLTypeForTypedArray; +exports.getGLTypeForTypedArrayType = getGLTypeForTypedArrayType; +exports.getTypedArrayTypeForGLType = getTypedArrayTypeForGLType; +exports.isArrayBuffer = void 0; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader typed array related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.typedArray` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/typedArray + */ + +// make sure we don't see a global gl +var gl = undefined; /* eslint-disable-line */ + +/* DataType */ +var BYTE = 0x1400; +var UNSIGNED_BYTE = 0x1401; +var SHORT = 0x1402; +var UNSIGNED_SHORT = 0x1403; +var INT = 0x1404; +var UNSIGNED_INT = 0x1405; +var FLOAT = 0x1406; +var UNSIGNED_SHORT_4_4_4_4 = 0x8033; +var UNSIGNED_SHORT_5_5_5_1 = 0x8034; +var UNSIGNED_SHORT_5_6_5 = 0x8363; +var HALF_FLOAT = 0x140B; +var UNSIGNED_INT_2_10_10_10_REV = 0x8368; +var UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +var UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +var FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +var UNSIGNED_INT_24_8 = 0x84FA; +var glTypeToTypedArray = {}; +{ + var tt = glTypeToTypedArray; + tt[BYTE] = Int8Array; + tt[UNSIGNED_BYTE] = Uint8Array; + tt[SHORT] = Int16Array; + tt[UNSIGNED_SHORT] = Uint16Array; + tt[INT] = Int32Array; + tt[UNSIGNED_INT] = Uint32Array; + tt[FLOAT] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5] = Uint16Array; + tt[HALF_FLOAT] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array; + tt[UNSIGNED_INT_24_8] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArray instanceof Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArray instanceof Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArray instanceof Int32Array) { + return INT; + } // eslint-disable-line + if (typedArray instanceof Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArray instanceof Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { + return BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8Array) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { + return UNSIGNED_BYTE; + } // eslint-disable-line + if (typedArrayType === Int16Array) { + return SHORT; + } // eslint-disable-line + if (typedArrayType === Uint16Array) { + return UNSIGNED_SHORT; + } // eslint-disable-line + if (typedArrayType === Int32Array) { + return INT; + } // eslint-disable-line + if (typedArrayType === Uint32Array) { + return UNSIGNED_INT; + } // eslint-disable-line + if (typedArrayType === Float32Array) { + return FLOAT; + } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + var CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} +var isArrayBuffer = exports.isArrayBuffer = typeof SharedArrayBuffer !== 'undefined' ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); +} : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; +}; + +/***/ }), + +/***/ "./src/utils.js": +/*!**********************!*\ + !*** ./src/utils.js ***! + \**********************/ +/***/ ((__unused_webpack_module, exports) => { + + + +exports.__esModule = true; +exports.glEnumToString = void 0; +exports.isWebGL1 = isWebGL1; +exports.isWebGL2 = isWebGL2; +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +var glEnumToString = exports.glEnumToString = function () { + var haveEnumsForType = {}; + var enums = {}; + function addEnums(gl) { + var type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (var key in gl) { + if (typeof gl[key] === 'number') { + var existing = enums[gl[key]]; + enums[gl[key]] = existing ? "".concat(existing, " | ").concat(key) : key; + } + } + haveEnumsForType[type] = true; + } + } + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? "0x".concat(value.toString(16)) : value); + }; +}(); + +/***/ }), + +/***/ "./src/vertex-arrays.js": +/*!******************************!*\ + !*** ./src/vertex-arrays.js ***! + \******************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + + + +function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } +exports.__esModule = true; +exports.createVAOAndSetAttributes = createVAOAndSetAttributes; +exports.createVAOFromBufferInfo = createVAOFromBufferInfo; +exports.createVertexArrayInfo = createVertexArrayInfo; +var programs = _interopRequireWildcard(__webpack_require__(/*! ./programs.js */ "./src/programs.js")); +function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } +function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; } +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +var ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function (programInfo) { + programs.setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + var vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + programs.setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module is referenced by other modules so it can't be inlined +/******/ var __webpack_exports__ = __webpack_require__("./src/twgl-base.js"); +/******/ +/******/ return __webpack_exports__; +/******/ })() +; +}); +//# sourceMappingURL=twgl.js.map \ No newline at end of file diff --git a/npm/base/dist/6.x/twgl.js.map b/npm/base/dist/6.x/twgl.js.map new file mode 100644 index 00000000..e037e65d --- /dev/null +++ b/npm/base/dist/6.x/twgl.js.map @@ -0,0 +1 @@ +{"version":3,"file":"twgl.js","mappings":"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AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASsB,uBAAuBA,CAAC5D,EAAE,EAAE6D,MAAM,EAAE;EAC3C,IAAMC,OAAO,GAAG,CAAC,CAAC;EAClBlF,MAAM,CAACmF,IAAI,CAACF,MAAM,CAAC,CAACG,OAAO,CAAC,UAAS3B,SAAS,EAAE;IAC9C,IAAI,CAACjB,SAAS,CAACiB,SAAS,CAAC,EAAE;MACzB,IAAMzB,KAAK,GAAGiD,MAAM,CAACxB,SAAS,CAAC;MAC/B,IAAM4B,UAAU,GAAGrD,KAAK,CAACsD,MAAM,IAAItD,KAAK,CAACS,IAAI,IAAIT,KAAK,CAACqD,UAAU,IAAK/D,QAAQ,CAACC,YAAY,GAAGkC,SAAU;MACxG,IAAIzB,KAAK,CAACuD,KAAK,EAAE;QACf,IAAI,CAACzB,KAAK,CAACC,OAAO,CAAC/B,KAAK,CAACuD,KAAK,CAAC,IAAI,CAACvG,WAAW,CAAC6E,aAAa,CAAC7B,KAAK,CAACuD,KAAK,CAAC,EAAE;UAC1E,MAAM,IAAIjC,KAAK,CAAC,wCAAwC,CAAC;QAC3D;QACA4B,OAAO,CAACG,UAAU,CAAC,GAAG;UACpBE,KAAK,EAAEvD,KAAK,CAACuD;QACf,CAAC;MACH,CAAC,MAAM;QACL,IAAIC,EAAE;QA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,IAAM4C,QAAQ,GAAGvD,EAAE,CAACsF,kBAAkB,CAAChG,YAAY,EAAEE,WAAW,CAAC;EACjEQ,EAAE,CAACc,UAAU,CAACxB,YAAY,EAAE,IAAI,CAAC;EAEjC,IAAMiG,aAAa,GAAGR,yBAAyB,CAAC/E,EAAE,EAAEkE,MAAM,CAACxD,IAAI,CAAC;EAChE,IAAM8E,aAAa,GAAGjC,QAAQ,GAAGgC,aAAa;EAC9C,IAAMvD,aAAa,GAAGkC,MAAM,CAAClC,aAAa,IAAIkC,MAAM,CAAC3B,IAAI;EACzD;EACA,IAAM6C,WAAW,GAAGI,aAAa,GAAGxD,aAAa;EACjD,IAAIoD,WAAW,GAAG,CAAC,KAAK,CAAC,EAAE;IACzB,MAAM,IAAIlD,KAAK,kBAAAC,MAAA,CAAkBH,aAAa,8BAAAG,MAAA,CAA2BR,MAAM,CAAE,CAAC;EACpF;EACA,OAAOyD,WAAW;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASK,0BAA0BA,CAACzF,EAAE,EAAE6D,MAAM,EAAE6B,aAAa,EAAE;EAC7D,IAAMC,UAAU,GAAG/B,uBAAuB,CAAC5D,EAAE,EAAE6D,MAAM,CAAC;EACtD,IAAM+B,UAAU,GAAGhH,MAAM,CAACiH,MAAM,CAAC,CAAC,CAAC,EAAEH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AAMijB,SAAS,GAAGe,gBAAgB,CAAClB,UAAU,CAACqC,gBAAgB,CAACjrB,IAAI,CAAC;EACpE,IAAI+oB,SAAS,EAAE;IAAA,IAAAmC,qBAAA;IACb,IAAMC,eAAe,GAAGpC,SAAS,CAACtM,KAAK;IACvC9d,EAAE,CAACspB,eAAe,CAAChT,cAAc,EAAEkW,eAAe,EAAEF,gBAAgB,CAAC3rB,MAAM,EAAE2rB,gBAAgB,CAAC5nB,MAAM,IAAI,CAAC,GAAA6nB,qBAAA,GAAED,gBAAgB,CAAC/pB,IAAI,cAAAgqB,qBAAA,cAAAA,qBAAA,GAAID,gBAAgB,CAAC1rB,KAAK,CAAC+qB,UAAU,CAAC;IACtK,OAAO,IAAI;EACb;EACA,OAAO,KAAK;AACd;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASc,eAAeA,CAACzsB,EAAE,EAAEmH,WAAW,EAAEmlB,gBAAgB,EAAE;EAC1D,IAAID,gBAAgB,CAACrsB,EAAE,EAAEmH,WAAW,EAAEmlB,gBAAgB,CAAC,EAAE;IACvDtsB,EAAE,CAAC8E,aAAa,CAACwR,cAAc,EAAE,CAAC,EAAEgW,gBAAgB,CAACJ,OAAO,EAAEI,gBAAgB,CAAC5nB,MAAM,IAAI,CAAC,EAAE4nB,gBAAgB,CAAC/pB,IAAI,IAAI,CAAC,CAAC;EACzH;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASmqB,gBAAgBA,CAACJ,gBAAgB,EAAExc,MAAM,EAAE;EAClD,IAAM+b,OAAO,GAAGS,gBAAgB,CAACT,OAAO;EACxC,KAAK,IAAMxqB,IAAI,IAAIyO,MAAM,EAAE;IACzB,IAAMiO,MAAM,GAAG8N,OAAO,CAACxqB,IAAI,CAAC;IAC5B,IAAI0c,MAAM,EAAE;MACV,IAAM5Z,KAAK,GAAG2L,MAAM,CAACzO,IAAI,CAAC;MAC1B0c,MAAM,CAAC5Z,KAAK,CAAC;IACf;EACF;AACF;AAEA,SAASikB,cAAcA,CAACuE,IAAI,EAAE7c,MAAM,EAAE;EACpC,KAAK,IAAMzO,IAAI,IAAIyO,MAAM,EAAE;IACzB,IAAM8c,IAAI,GAAGD,IAAI,CAACtrB,IAAI,CAAC;IACvB,IAAI,OAAOurB,IAAI,KAAK,UAAU,EAAE;MAC9BA,IAAI,CAAC9c,MAAM,CAACzO,IAAI,CAAC,CAAC;IACpB,CAAC,MAAM;MACL+mB,cAAc,CAACuE,IAAI,CAACtrB,IAAI,CAAC,EAAEyO,MAAM,CAACzO,IAAI,CAAC,CAAC;IAC1C;EACF;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA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","sources":["webpack://twgl/webpack/universalModuleDefinition","webpack://twgl/./src/attributes.js","webpack://twgl/./src/draw.js","webpack://twgl/./src/framebuffers.js","webpack://twgl/./src/helper.js","webpack://twgl/./src/programs.js","webpack://twgl/./src/textures.js","webpack://twgl/./src/twgl-base.js","webpack://twgl/./src/twgl.js","webpack://twgl/./src/typedarrays.js","webpack://twgl/./src/utils.js","webpack://twgl/./src/vertex-arrays.js","webpack://twgl/webpack/bootstrap","webpack://twgl/webpack/before-startup","webpack://twgl/webpack/startup","webpack://twgl/webpack/after-startup"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"twgl\"] = factory();\n\telse\n\t\troot[\"twgl\"] = factory();\n})(typeof self !== 'undefined' ? self : this, () => {\nreturn ","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\nconst STATIC_DRAW = 0x88e4;\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst BUFFER_SIZE = 0x8764;\n\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\n\n/**\n * Low level attribute and buffer related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/attributes\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n attribPrefix: \"\",\n};\n\n/**\n * Sets the default attrib prefix\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * var arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * @deprecated see {@link module:twgl.setDefaults}\n * @param {string} prefix prefix for attribs\n * @memberOf module:twgl/attributes\n */\nfunction setAttributePrefix(prefix) {\n defaults.attribPrefix = prefix;\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n}\n\nfunction setBufferFromTypedArray(gl, type, buffer, array, drawType) {\n gl.bindBuffer(type, buffer);\n gl.bufferData(type, array, drawType || STATIC_DRAW);\n}\n\n/**\n * Given typed array creates a WebGLBuffer and copies the typed array\n * into it.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken\n * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`.\n * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`.\n * @return {WebGLBuffer} the created WebGLBuffer\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromTypedArray(gl, typedArray, type, drawType) {\n if (helper.isBuffer(gl, typedArray)) {\n return typedArray;\n }\n type = type || ARRAY_BUFFER;\n const buffer = gl.createBuffer();\n setBufferFromTypedArray(gl, type, buffer, typedArray, drawType);\n return buffer;\n}\n\nfunction isIndices(name) {\n return name === \"indices\";\n}\n\n// This is really just a guess. Though I can't really imagine using\n// anything else? Maybe for some compression?\nfunction getNormalizationForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return true; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line\n return false;\n}\n\nfunction getArray(array) {\n return array.length ? array : array.data;\n}\n\nconst texcoordRE = /coord|texture/i;\nconst colorRE = /color|colour/i;\n\nfunction guessNumComponentsFromName(name, length) {\n let numComponents;\n if (texcoordRE.test(name)) {\n numComponents = 2;\n } else if (colorRE.test(name)) {\n numComponents = 4;\n } else {\n numComponents = 3; // position, normals, indices ...\n }\n\n if (length % numComponents > 0) {\n throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`);\n }\n\n return numComponents;\n}\n\nfunction getNumComponents(array, arrayName, numValues) {\n return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length);\n}\n\nfunction makeTypedArray(array, name) {\n if (typedArrays.isArrayBuffer(array)) {\n return array;\n }\n\n if (typedArrays.isArrayBuffer(array.data)) {\n return array.data;\n }\n\n if (Array.isArray(array)) {\n array = {\n data: array,\n };\n }\n\n let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined;\n if (!Type) {\n if (isIndices(name)) {\n Type = Uint16Array;\n } else {\n Type = Float32Array;\n }\n }\n return new Type(array.data);\n}\n\nfunction glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? glTypeOrTypedArrayCtor\n : glTypeOrTypedArrayCtor ? typedArrays.getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT;\n}\n\nfunction typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) {\n return typeof glTypeOrTypedArrayCtor === 'number'\n ? typedArrays.getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor)\n : glTypeOrTypedArrayCtor || Float32Array;\n}\n\nfunction attribBufferFromBuffer(gl, array/*, arrayName */) {\n return {\n buffer: array.buffer,\n numValues: 2 * 3 * 4, // safely divided by 2, 3, 4\n type: glTypeFromGLTypeOrTypedArrayType(array.type),\n arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type),\n };\n}\n\nfunction attribBufferFromSize(gl, array/*, arrayName*/) {\n const numValues = array.data || array;\n const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type);\n const numBytes = numValues * arrayType.BYTES_PER_ELEMENT;\n const buffer = gl.createBuffer();\n gl.bindBuffer(ARRAY_BUFFER, buffer);\n gl.bufferData(ARRAY_BUFFER, numBytes, array.drawType || STATIC_DRAW);\n return {\n buffer,\n numValues,\n type: typedArrays.getGLTypeForTypedArrayType(arrayType),\n arrayType,\n };\n}\n\nfunction attribBufferFromArrayLike(gl, array, arrayName) {\n const typedArray = makeTypedArray(array, arrayName);\n return {\n arrayType: typedArray.constructor,\n buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType),\n type: typedArrays.getGLTypeForTypedArray(typedArray),\n numValues: 0,\n };\n}\n\n/**\n * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer\n * for the attribute.\n *\n * @typedef {Object} AttribInfo\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {number} [numComponents] the number of components for this attribute.\n * @property {number} [size] synonym for `numComponents`.\n * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT`\n * @property {boolean} [normalize] whether or not to normalize the data. Default = false\n * @property {number} [offset] offset into buffer in bytes. Default = 0\n * @property {number} [stride] the stride in bytes per element. Default = 0\n * @property {number} [divisor] the divisor in instances. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor\n */\n\n/**\n * Use this type of array spec when TWGL can't guess the type or number of components of an array\n * @typedef {Object} FullArraySpec\n * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be\n * disabled and set to this constant value and all other values will be ignored.\n * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type.\n * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array.\n * If `coord` is in the name assumes `numComponents = 2`.\n * If `color` is in the name assumes `numComponents = 4`.\n * otherwise assumes `numComponents = 3`\n * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number.\n * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`).\n * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`.\n * @property {number} [size] synonym for `numComponents`.\n * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false.\n * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0\n * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0\n * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0.\n * Requires WebGL2 or the ANGLE_instanced_arrays extension.\n * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext}\n * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix.\n * @property {string} [name] synonym for `attrib`.\n * @property {string} [attribName] synonym for `attrib`.\n * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer\n * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo`\n * to provide this. Example:\n *\n * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, {\n * position: [1, 2, 3, ... ],\n * });\n * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, {\n * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1\n * });\n *\n * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW\n * @memberOf module:twgl\n */\n\n/**\n * An individual array in {@link module:twgl.Arrays}\n *\n * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView`\n * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will\n * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer.\n *\n * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec\n * @memberOf module:twgl\n */\n\n/**\n * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your\n * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}.\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * Objects with various fields. See {@link module:twgl.FullArraySpec}.\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * @typedef {Object.} Arrays\n * @memberOf module:twgl\n */\n\n\n/**\n * Creates a set of attribute data and WebGLBuffers from set of arrays\n *\n * Given\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * color: { numComponents: 4, data: [255, 255, 255, 255, 255, 0, 0, 255, 0, 0, 255, 255], type: Uint8Array, },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * returns something like\n *\n * var attribs = {\n * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, },\n * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, },\n * };\n *\n * notes:\n *\n * * Arrays can take various forms\n *\n * Bare JavaScript Arrays\n *\n * var arrays = {\n * position: [-1, 1, 0],\n * normal: [0, 1, 0],\n * ...\n * }\n *\n * Bare TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([-1, 1, 0]),\n * color: new Uint8Array([255, 128, 64, 255]),\n * ...\n * }\n *\n * * Will guess at `numComponents` if not specified based on name.\n *\n * If `coord` is in the name assumes `numComponents = 2`\n *\n * If `color` is in the name assumes `numComponents = 4`\n *\n * otherwise assumes `numComponents = 3`\n *\n * @param {WebGLRenderingContext} gl The webgl rendering context.\n * @param {module:twgl.Arrays} arrays The arrays\n * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from\n * This lets you share buffers. Any arrays you supply will override\n * the buffers from srcBufferInfo.\n * @return {Object.} the attribs\n * @memberOf module:twgl/attributes\n */\nfunction createAttribsFromArrays(gl, arrays) {\n const attribs = {};\n Object.keys(arrays).forEach(function(arrayName) {\n if (!isIndices(arrayName)) {\n const array = arrays[arrayName];\n const attribName = array.attrib || array.name || array.attribName || (defaults.attribPrefix + arrayName);\n if (array.value) {\n if (!Array.isArray(array.value) && !typedArrays.isArrayBuffer(array.value)) {\n throw new Error('array.value is not array or typedarray');\n }\n attribs[attribName] = {\n value: array.value,\n };\n } else {\n let fn;\n if (array.buffer && array.buffer instanceof WebGLBuffer) {\n fn = attribBufferFromBuffer;\n } else if (typeof array === \"number\" || typeof array.data === \"number\") {\n fn = attribBufferFromSize;\n } else {\n fn = attribBufferFromArrayLike;\n }\n const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName);\n const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType);\n const numComponents = getNumComponents(array, arrayName, numValues);\n attribs[attribName] = {\n buffer: buffer,\n numComponents: numComponents,\n type: type,\n normalize: normalization,\n stride: array.stride || 0,\n offset: array.offset || 0,\n divisor: array.divisor === undefined ? undefined : array.divisor,\n drawType: array.drawType,\n };\n }\n }\n });\n gl.bindBuffer(ARRAY_BUFFER, null);\n return attribs;\n}\n\n/**\n * Sets the contents of a buffer attached to an attribInfo\n *\n * This is helper function to dynamically update a buffer.\n *\n * Let's say you make a bufferInfo\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);\n *\n * And you want to dynamically update the positions. You could do this\n *\n * // assuming arrays.position has already been updated with new data.\n * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position);\n *\n * @param {WebGLRenderingContext} gl\n * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix\n * the name of the attribute will include the prefix.\n * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything\n * else will have to be converted to a typed array before it can be used by WebGL. During init time that\n * inefficiency is usually not important but if you're updating data dynamically best to be efficient.\n * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer\n * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView`\n * for the portion of the array you want to use.\n *\n * var someArray = new Float32Array(1000); // an array with 1000 floats\n * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray\n *\n * Now you can pass `someSubArray` into setAttribInfoBufferFromArray`\n * @memberOf module:twgl/attributes\n */\nfunction setAttribInfoBufferFromArray(gl, attribInfo, array, offset) {\n array = makeTypedArray(array);\n if (offset !== undefined) {\n gl.bindBuffer(ARRAY_BUFFER, attribInfo.buffer);\n gl.bufferSubData(ARRAY_BUFFER, offset, array);\n } else {\n setBufferFromTypedArray(gl, ARRAY_BUFFER, attribInfo.buffer, array, attribInfo.drawType);\n }\n}\n\nfunction getBytesPerValueForGLType(gl, type) {\n if (type === BYTE) return 1; // eslint-disable-line\n if (type === UNSIGNED_BYTE) return 1; // eslint-disable-line\n if (type === SHORT) return 2; // eslint-disable-line\n if (type === UNSIGNED_SHORT) return 2; // eslint-disable-line\n if (type === INT) return 4; // eslint-disable-line\n if (type === UNSIGNED_INT) return 4; // eslint-disable-line\n if (type === FLOAT) return 4; // eslint-disable-line\n return 0;\n}\n\n// Tries to get the number of elements from a set of arrays.\nconst positionKeys = ['position', 'positions', 'a_position'];\nfunction getNumElementsFromNonIndexedArrays(arrays) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in arrays) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(arrays)[0];\n }\n const array = arrays[key];\n const length = getArray(array).length;\n if (length === undefined) {\n return 1; // There's no arrays\n }\n const numComponents = getNumComponents(array, key);\n const numElements = length / numComponents;\n if (length % numComponents > 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\nfunction getNumElementsFromAttributes(gl, attribs) {\n let key;\n let ii;\n for (ii = 0; ii < positionKeys.length; ++ii) {\n key = positionKeys[ii];\n if (key in attribs) {\n break;\n }\n key = defaults.attribPrefix + key;\n if (key in attribs) {\n break;\n }\n }\n if (ii === positionKeys.length) {\n key = Object.keys(attribs)[0];\n }\n const attrib = attribs[key];\n if (!attrib.buffer) {\n return 1; // There's no buffer\n }\n gl.bindBuffer(ARRAY_BUFFER, attrib.buffer);\n const numBytes = gl.getBufferParameter(ARRAY_BUFFER, BUFFER_SIZE);\n gl.bindBuffer(ARRAY_BUFFER, null);\n\n const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type);\n const totalElements = numBytes / bytesPerValue;\n const numComponents = attrib.numComponents || attrib.size;\n // TODO: check stride\n const numElements = totalElements / numComponents;\n if (numElements % 1 !== 0) {\n throw new Error(`numComponents ${numComponents} not correct for length ${length}`);\n }\n return numElements;\n}\n\n/**\n * @typedef {Object} BufferInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist.\n * @property {Object.} [attribs] The attribs appropriate to call `setAttributes`\n * @memberOf module:twgl\n */\n\n/**\n * Creates a BufferInfo from an object of arrays.\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * Given an object like\n *\n * var arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * normal: { numComponents: 3, data: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1], },\n * indices: { numComponents: 3, data: [0, 1, 2, 1, 2, 3], },\n * };\n *\n * Creates an BufferInfo like this\n *\n * bufferInfo = {\n * numElements: 4, // or whatever the number of elements is\n * indices: WebGLBuffer, // this property will not exist if there are no indices\n * attribs: {\n * position: { buffer: WebGLBuffer, numComponents: 3, },\n * normal: { buffer: WebGLBuffer, numComponents: 3, },\n * texcoord: { buffer: WebGLBuffer, numComponents: 2, },\n * },\n * };\n *\n * The properties of arrays can be JavaScript arrays in which case the number of components\n * will be guessed.\n *\n * var arrays = {\n * position: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0],\n * texcoord: [0, 0, 0, 1, 1, 0, 1, 1],\n * normal: [0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],\n * indices: [0, 1, 2, 1, 2, 3],\n * };\n *\n * They can also be TypedArrays\n *\n * var arrays = {\n * position: new Float32Array([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]),\n * texcoord: new Float32Array([0, 0, 0, 1, 1, 0, 1, 1]),\n * normal: new Float32Array([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]),\n * indices: new Uint16Array([0, 1, 2, 1, 2, 3]),\n * };\n *\n * Or AugmentedTypedArrays\n *\n * var positions = createAugmentedTypedArray(3, 4);\n * var texcoords = createAugmentedTypedArray(2, 4);\n * var normals = createAugmentedTypedArray(3, 4);\n * var indices = createAugmentedTypedArray(3, 2, Uint16Array);\n *\n * positions.push([0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0]);\n * texcoords.push([0, 0, 0, 1, 1, 0, 1, 1]);\n * normals.push([0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);\n * indices.push([0, 1, 2, 1, 2, 3]);\n *\n * var arrays = {\n * position: positions,\n * texcoord: texcoords,\n * normal: normals,\n * indices: indices,\n * };\n *\n * For the last example it is equivalent to\n *\n * var bufferInfo = {\n * attribs: {\n * position: { numComponents: 3, buffer: gl.createBuffer(), },\n * texcoord: { numComponents: 2, buffer: gl.createBuffer(), },\n * normal: { numComponents: 3, buffer: gl.createBuffer(), },\n * },\n * indices: gl.createBuffer(),\n * numElements: 6,\n * };\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.normal.buffer);\n * gl.bufferData(gl.ARRAY_BUFFER, arrays.normal, gl.STATIC_DRAW);\n * gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.indices);\n * gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, arrays.indices, gl.STATIC_DRAW);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.Arrays} arrays Your data\n * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing\n * buffer info to start from. WebGLBuffers etc specified\n * in the srcBufferInfo will be used in a new BufferInfo\n * with any arrays specified overriding the ones in\n * srcBufferInfo.\n * @return {module:twgl.BufferInfo} A BufferInfo\n * @memberOf module:twgl/attributes\n */\nfunction createBufferInfoFromArrays(gl, arrays, srcBufferInfo) {\n const newAttribs = createAttribsFromArrays(gl, arrays);\n const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {});\n bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs);\n const indices = arrays.indices;\n if (indices) {\n const newIndices = makeTypedArray(indices, \"indices\");\n bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER);\n bufferInfo.numElements = newIndices.length;\n bufferInfo.elementType = typedArrays.getGLTypeForTypedArray(newIndices);\n } else if (!bufferInfo.numElements) {\n bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs);\n }\n\n return bufferInfo;\n}\n\n/**\n * Creates a buffer from an array, typed array, or array spec\n *\n * Given something like this\n *\n * [1, 2, 3],\n *\n * or\n *\n * new Uint16Array([1,2,3]);\n *\n * or\n *\n * {\n * data: [1, 2, 3],\n * type: Uint8Array,\n * }\n *\n * returns a WebGLBuffer that contains the given data.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.ArraySpec} array an array, typed array, or array spec.\n * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise.\n * @return {WebGLBuffer} a WebGLBuffer containing the data in array.\n * @memberOf module:twgl/attributes\n */\nfunction createBufferFromArray(gl, array, arrayName) {\n const type = arrayName === \"indices\" ? ELEMENT_ARRAY_BUFFER : ARRAY_BUFFER;\n const typedArray = makeTypedArray(array, arrayName);\n return createBufferFromTypedArray(gl, typedArray, type);\n}\n\n/**\n * Creates buffers from arrays or typed arrays\n *\n * Given something like this\n *\n * var arrays = {\n * positions: [1, 2, 3],\n * normals: [0, 0, 1],\n * }\n *\n * returns something like\n *\n * buffers = {\n * positions: WebGLBuffer,\n * normals: WebGLBuffer,\n * }\n *\n * If the buffer is named 'indices' it will be made an ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {module:twgl.Arrays} arrays\n * @return {Object} returns an object with one WebGLBuffer per array\n * @memberOf module:twgl/attributes\n */\nfunction createBuffersFromArrays(gl, arrays) {\n const buffers = { };\n Object.keys(arrays).forEach(function(key) {\n buffers[key] = createBufferFromArray(gl, arrays[key], key);\n });\n\n // Ugh!\n if (arrays.indices) {\n buffers.numElements = arrays.indices.length;\n buffers.elementType = typedArrays.getGLTypeForTypedArray(makeTypedArray(arrays.indices), 'indices');\n } else {\n buffers.numElements = getNumElementsFromNonIndexedArrays(arrays);\n }\n\n return buffers;\n}\n\nexport {\n createAttribsFromArrays,\n createBuffersFromArrays,\n createBufferFromArray,\n createBufferFromTypedArray,\n createBufferInfoFromArrays,\n setAttribInfoBufferFromArray,\n\n setAttributePrefix,\n\n setDefaults as setAttributeDefaults_,\n getNumComponents as getNumComponents_,\n getArray as getArray_,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\nconst TRIANGLES = 0x0004;\nconst UNSIGNED_SHORT = 0x1403;\n\n/**\n * Drawing related functions\n *\n * For backward compatibility they are available at both `twgl.draw` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/draw\n */\n\n/**\n * Calls `gl.drawElements` or `gl.drawArrays`, whichever is appropriate\n *\n * normally you'd call `gl.drawElements` or `gl.drawArrays` yourself\n * but calling this means if you switch from indexed data to non-indexed\n * data you don't have to remember to update your draw call.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or\n * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES`\n * @param {number} [count] An optional count. Defaults to bufferInfo.numElements\n * @param {number} [offset] An optional offset. Defaults to 0.\n * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called\n * @memberOf module:twgl/draw\n */\nfunction drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) {\n type = type === undefined ? TRIANGLES : type;\n const indices = bufferInfo.indices;\n const elementType = bufferInfo.elementType;\n const numElements = count === undefined ? bufferInfo.numElements : count;\n offset = offset === undefined ? 0 : offset;\n if (elementType || indices) {\n if (instanceCount !== undefined) {\n gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount);\n } else {\n gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset);\n }\n } else {\n if (instanceCount !== undefined) {\n gl.drawArraysInstanced(type, offset, numElements, instanceCount);\n } else {\n gl.drawArrays(type, offset, numElements);\n }\n }\n}\n\n/**\n * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}.\n *\n * You need either a `BufferInfo` or a `VertexArrayInfo`.\n *\n * @typedef {Object} DrawObject\n * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true`\n * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc...\n * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays}\n * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo}\n * @property {Object} uniforms The values for the uniforms.\n * You can pass multiple objects by putting them in an array. For example\n *\n * var sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * var localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * var drawObj = {\n * ...\n * uniforms: [sharedUniforms, localUniforms],\n * };\n *\n * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0.\n * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements.\n * @property {number} [instanceCount] the number of instances. Defaults to undefined.\n * @memberOf module:twgl\n */\n\n/**\n * Draws a list of objects\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {DrawObject[]} objectsToDraw an array of objects to draw.\n * @memberOf module:twgl/draw\n */\nfunction drawObjectList(gl, objectsToDraw) {\n let lastUsedProgramInfo = null;\n let lastUsedBufferInfo = null;\n\n objectsToDraw.forEach(function(object) {\n if (object.active === false) {\n return;\n }\n\n const programInfo = object.programInfo;\n const bufferInfo = object.vertexArrayInfo || object.bufferInfo;\n let bindBuffers = false;\n const type = object.type === undefined ? TRIANGLES : object.type;\n\n if (programInfo !== lastUsedProgramInfo) {\n lastUsedProgramInfo = programInfo;\n gl.useProgram(programInfo.program);\n\n // We have to rebind buffers when changing programs because we\n // only bind buffers the program uses. So if 2 programs use the same\n // bufferInfo but the 1st one uses only positions the when the\n // we switch to the 2nd one some of the attributes will not be on.\n bindBuffers = true;\n }\n\n // Setup all the needed attributes.\n if (bindBuffers || bufferInfo !== lastUsedBufferInfo) {\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n lastUsedBufferInfo = bufferInfo;\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n }\n\n // Set the uniforms.\n programs.setUniforms(programInfo, object.uniforms);\n\n // Draw\n drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount);\n });\n\n if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) {\n gl.bindVertexArray(null);\n }\n}\n\nexport {\n drawBufferInfo,\n drawObjectList,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\n\n/**\n * Framebuffer related functions\n *\n * For backward compatibility they are available at both `twgl.framebuffer` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/framebuffers\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst FRAMEBUFFER = 0x8d40;\nconst RENDERBUFFER = 0x8d41;\nconst TEXTURE_2D = 0x0de1;\n\nconst UNSIGNED_BYTE = 0x1401;\n\n/* PixelFormat */\nconst DEPTH_COMPONENT = 0x1902;\nconst RGBA = 0x1908;\nconst DEPTH_COMPONENT24 = 0x81a6;\nconst DEPTH_COMPONENT32F = 0x8cac;\nconst DEPTH24_STENCIL8 = 0x88f0;\nconst DEPTH32F_STENCIL8 = 0x8cad;\n\n/* Framebuffer Object. */\nconst RGBA4 = 0x8056;\nconst RGB5_A1 = 0x8057;\nconst RGB565 = 0x8D62;\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst STENCIL_INDEX = 0x1901;\nconst STENCIL_INDEX8 = 0x8D48;\nconst DEPTH_STENCIL = 0x84F9;\nconst COLOR_ATTACHMENT0 = 0x8CE0;\nconst DEPTH_ATTACHMENT = 0x8D00;\nconst STENCIL_ATTACHMENT = 0x8D20;\nconst DEPTH_STENCIL_ATTACHMENT = 0x821A;\n\n/* TextureWrapMode */\nconst CLAMP_TO_EDGE = 0x812F;\n\n/* TextureMagFilter */\nconst LINEAR = 0x2601;\n\n/**\n * The options for a framebuffer attachment.\n *\n * Note: For a `format` that is a texture include all the texture\n * options from {@link module:twgl.TextureOptions} for example\n * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions}\n * `auto` defaults to `false` for attachment textures but `min` and `mag` default\n * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE`\n *\n * @typedef {Object} AttachmentOptions\n * @property {number} [attachmentPoint] The attachment point. Defaults\n * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type\n * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending\n * on the format or attachment type.\n * @property {number} [format] The format. If one of `gl.RGBA4`,\n * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`,\n * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a\n * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA`\n * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`.\n * @property {number} [target] The texture target for `gl.framebufferTexture2D`.\n * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps.\n * @property {number} [samples] The number of samples. Default = 1\n * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0.\n * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined.\n * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D`\n * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture.\n * If provided will attach this Object. This allows you to share\n * attachments across framebuffers.\n * @memberOf module:twgl\n * @mixes module:twgl.TextureOptions\n */\n\nconst defaultAttachments = [\n { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, },\n { format: DEPTH_STENCIL, },\n];\n\nconst attachmentsByFormat = {};\nattachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT;\nattachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT;\nattachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\nattachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT;\n\nfunction getAttachmentPointForFormat(format, internalFormat) {\n return attachmentsByFormat[format] || attachmentsByFormat[internalFormat];\n}\n\nconst renderbufferFormats = {};\nrenderbufferFormats[RGBA4] = true;\nrenderbufferFormats[RGB5_A1] = true;\nrenderbufferFormats[RGB565] = true;\nrenderbufferFormats[DEPTH_STENCIL] = true;\nrenderbufferFormats[DEPTH_COMPONENT16] = true;\nrenderbufferFormats[STENCIL_INDEX] = true;\nrenderbufferFormats[STENCIL_INDEX8] = true;\n\nfunction isRenderbufferFormat(format) {\n return renderbufferFormats[format];\n}\n\nconst MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32\n\nfunction isColorAttachmentPoint(attachmentPoint) {\n return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS;\n}\n\n/**\n * @typedef {Object} FramebufferInfo\n * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo\n * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}.\n * @property {number} width The width of the framebuffer and its attachments\n * @property {number} height The width of the framebuffer and its attachments\n * @memberOf module:twgl\n */\n\n/**\n * Creates a framebuffer and attachments.\n *\n * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer.\n * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`.\n * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers\n * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * Passing in a specific size\n *\n * const width = 256;\n * const height = 256;\n * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height);\n *\n * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`.\n * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6).\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an\n * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @return {module:twgl.FramebufferInfo} the framebuffer and attachments.\n * @memberOf module:twgl/framebuffers\n */\nfunction createFramebufferInfo(gl, attachments, width, height) {\n const target = FRAMEBUFFER;\n const fb = gl.createFramebuffer();\n gl.bindFramebuffer(target, fb);\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n attachments = attachments || defaultAttachments;\n const usedColorAttachmentsPoints = [];\n const framebufferInfo = {\n framebuffer: fb,\n attachments: [],\n width: width,\n height: height,\n };\n\n attachments.forEach(function(attachmentOptions, i) {\n let attachment = attachmentOptions.attachment;\n const samples = attachmentOptions.samples;\n const format = attachmentOptions.format;\n let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat);\n if (!attachmentPoint) {\n attachmentPoint = COLOR_ATTACHMENT0 + i;\n }\n if (isColorAttachmentPoint(attachmentPoint)) {\n usedColorAttachmentsPoints.push(attachmentPoint);\n }\n if (!attachment) {\n if (samples !== undefined || isRenderbufferFormat(format)) {\n attachment = gl.createRenderbuffer();\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else {\n const textureOptions = Object.assign({}, attachmentOptions);\n textureOptions.width = width;\n textureOptions.height = height;\n if (textureOptions.auto === undefined) {\n textureOptions.auto = false;\n textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR;\n textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR;\n textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE;\n textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE;\n }\n attachment = textures.createTexture(gl, textureOptions);\n }\n }\n if (helper.isRenderbuffer(gl, attachment)) {\n gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment);\n } else if (helper.isTexture(gl, attachment)) {\n if (attachmentOptions.layer !== undefined) {\n gl.framebufferTextureLayer(\n target,\n attachmentPoint,\n attachment,\n attachmentOptions.level || 0,\n attachmentOptions.layer);\n } else {\n gl.framebufferTexture2D(\n target,\n attachmentPoint,\n attachmentOptions.target || TEXTURE_2D,\n attachment,\n attachmentOptions.level || 0);\n }\n } else {\n throw new Error('unknown attachment type');\n }\n framebufferInfo.attachments.push(attachment);\n });\n if (gl.drawBuffers) {\n gl.drawBuffers(usedColorAttachmentsPoints);\n }\n return framebufferInfo;\n}\n\n/**\n * Resizes the attachments of a framebuffer.\n *\n * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo}\n * because TWGL has no idea the format/type of each attachment.\n *\n * The simplest usage\n *\n * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer\n * const fbi = twgl.createFramebufferInfo(gl);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments\n * twgl.resizeFramebufferInfo(gl, fbi);\n * }\n *\n * More complex usage\n *\n * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer\n * const attachments = [\n * { format: RGB565, mag: NEAREST },\n * { format: STENCIL_INDEX8 },\n * ]\n * const fbi = twgl.createFramebufferInfo(gl, attachments);\n *\n * ...\n *\n * function render() {\n * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) {\n * // resize the attachments to match\n * twgl.resizeFramebufferInfo(gl, fbi, attachments);\n * }\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}.\n * @param {number} [width] the width for the attachments. Default = size of drawingBuffer\n * @param {number} [height] the height for the attachments. Default = size of drawingBuffer\n * @memberOf module:twgl/framebuffers\n */\nfunction resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) {\n width = width || gl.drawingBufferWidth;\n height = height || gl.drawingBufferHeight;\n framebufferInfo.width = width;\n framebufferInfo.height = height;\n attachments = attachments || defaultAttachments;\n attachments.forEach(function(attachmentOptions, ndx) {\n const attachment = framebufferInfo.attachments[ndx];\n const format = attachmentOptions.format;\n const samples = attachmentOptions.samples;\n if (samples !== undefined || helper.isRenderbuffer(gl, attachment)) {\n gl.bindRenderbuffer(RENDERBUFFER, attachment);\n if (samples > 1) {\n gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height);\n } else {\n gl.renderbufferStorage(RENDERBUFFER, format, width, height);\n }\n } else if (helper.isTexture(gl, attachment)) {\n textures.resizeTexture(gl, attachment, attachmentOptions, width, height);\n } else {\n throw new Error('unknown attachment type');\n }\n });\n}\n\n/**\n * Binds a framebuffer\n *\n * This function pretty much solely exists because I spent hours\n * trying to figure out why something I wrote wasn't working only\n * to realize I forget to set the viewport dimensions.\n * My hope is this function will fix that.\n *\n * It is effectively the same as\n *\n * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer);\n * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height);\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}.\n * If falsy will bind the canvas.\n * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used.\n * @memberOf module:twgl/framebuffers\n */\n\nfunction bindFramebufferInfo(gl, framebufferInfo, target) {\n target = target || FRAMEBUFFER;\n if (framebufferInfo) {\n gl.bindFramebuffer(target, framebufferInfo.framebuffer);\n gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height);\n } else {\n gl.bindFramebuffer(target, null);\n gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);\n }\n}\n\nexport {\n bindFramebufferInfo,\n createFramebufferInfo,\n resizeFramebufferInfo,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/* eslint no-console: \"off\" */\n\n/**\n * Copy named properties\n *\n * @param {string[]} names names of properties to copy\n * @param {object} src object to copy properties from\n * @param {object} dst object to copy properties to\n * @private\n */\nfunction copyNamedProperties(names, src, dst) {\n names.forEach(function(name) {\n const value = src[name];\n if (value !== undefined) {\n dst[name] = value;\n }\n });\n}\n\n/**\n * Copies properties from source to dest only if a matching key is in dest\n *\n * @param {Object.} src the source\n * @param {Object.} dst the dest\n * @private\n */\nfunction copyExistingProperties(src, dst) {\n Object.keys(dst).forEach(function(key) {\n if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */\n dst[key] = src[key];\n }\n });\n}\n\nfunction error(...args) {\n console.error(...args);\n}\n\nfunction warn(...args) {\n console.warn(...args);\n}\n\nconst isTypeWeakMaps = new Map();\n\nfunction isType(object, type) {\n if (!object || typeof object !== 'object') {\n return false;\n }\n let weakMap = isTypeWeakMaps.get(type);\n if (!weakMap) {\n weakMap = new WeakMap();\n isTypeWeakMaps.set(type, weakMap);\n }\n let isOfType = weakMap.get(object);\n if (isOfType === undefined) {\n const s = Object.prototype.toString.call(object);\n isOfType = s.substring(8, s.length - 1) === type;\n weakMap.set(object, isOfType);\n }\n return isOfType;\n}\n\nfunction isBuffer(gl, t) {\n return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer');\n}\n\nfunction isRenderbuffer(gl, t) {\n return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer');\n}\n\nfunction isShader(gl, t) {\n return typeof WebGLShader !== 'undefined' && isType(t, 'WebGLShader');\n}\n\nfunction isTexture(gl, t) {\n return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture');\n}\n\nfunction isSampler(gl, t) {\n return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler');\n}\n\nexport {\n copyExistingProperties,\n copyNamedProperties,\n error,\n warn,\n isBuffer,\n isRenderbuffer,\n isShader,\n isTexture,\n isSampler,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level shader program related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.programs` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/programs\n */\n\nconst error = helper.error;\nconst warn = helper.warn;\nfunction getElementById(id) {\n return (typeof document !== 'undefined' && document.getElementById)\n ? document.getElementById(id)\n : null;\n}\n\nconst TEXTURE0 = 0x84c0;\nconst DYNAMIC_DRAW = 0x88e8;\n\nconst ARRAY_BUFFER = 0x8892;\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\nconst UNIFORM_BUFFER = 0x8a11;\nconst TRANSFORM_FEEDBACK_BUFFER = 0x8c8e;\n\nconst TRANSFORM_FEEDBACK = 0x8e22;\n\nconst COMPILE_STATUS = 0x8b81;\nconst LINK_STATUS = 0x8b82;\nconst FRAGMENT_SHADER = 0x8b30;\nconst VERTEX_SHADER = 0x8b31;\nconst SEPARATE_ATTRIBS = 0x8c8d;\n\nconst ACTIVE_UNIFORMS = 0x8b86;\nconst ACTIVE_ATTRIBUTES = 0x8b89;\nconst TRANSFORM_FEEDBACK_VARYINGS = 0x8c83;\nconst ACTIVE_UNIFORM_BLOCKS = 0x8a36;\nconst UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44;\nconst UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46;\nconst UNIFORM_BLOCK_DATA_SIZE = 0x8a40;\nconst UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43;\n\nconst FLOAT = 0x1406;\nconst FLOAT_VEC2 = 0x8B50;\nconst FLOAT_VEC3 = 0x8B51;\nconst FLOAT_VEC4 = 0x8B52;\nconst INT = 0x1404;\nconst INT_VEC2 = 0x8B53;\nconst INT_VEC3 = 0x8B54;\nconst INT_VEC4 = 0x8B55;\nconst BOOL = 0x8B56;\nconst BOOL_VEC2 = 0x8B57;\nconst BOOL_VEC3 = 0x8B58;\nconst BOOL_VEC4 = 0x8B59;\nconst FLOAT_MAT2 = 0x8B5A;\nconst FLOAT_MAT3 = 0x8B5B;\nconst FLOAT_MAT4 = 0x8B5C;\nconst SAMPLER_2D = 0x8B5E;\nconst SAMPLER_CUBE = 0x8B60;\nconst SAMPLER_3D = 0x8B5F;\nconst SAMPLER_2D_SHADOW = 0x8B62;\nconst FLOAT_MAT2x3 = 0x8B65;\nconst FLOAT_MAT2x4 = 0x8B66;\nconst FLOAT_MAT3x2 = 0x8B67;\nconst FLOAT_MAT3x4 = 0x8B68;\nconst FLOAT_MAT4x2 = 0x8B69;\nconst FLOAT_MAT4x3 = 0x8B6A;\nconst SAMPLER_2D_ARRAY = 0x8DC1;\nconst SAMPLER_2D_ARRAY_SHADOW = 0x8DC4;\nconst SAMPLER_CUBE_SHADOW = 0x8DC5;\nconst UNSIGNED_INT = 0x1405;\nconst UNSIGNED_INT_VEC2 = 0x8DC6;\nconst UNSIGNED_INT_VEC3 = 0x8DC7;\nconst UNSIGNED_INT_VEC4 = 0x8DC8;\nconst INT_SAMPLER_2D = 0x8DCA;\nconst INT_SAMPLER_3D = 0x8DCB;\nconst INT_SAMPLER_CUBE = 0x8DCC;\nconst INT_SAMPLER_2D_ARRAY = 0x8DCF;\nconst UNSIGNED_INT_SAMPLER_2D = 0x8DD2;\nconst UNSIGNED_INT_SAMPLER_3D = 0x8DD3;\nconst UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4;\nconst UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7;\n\nconst TEXTURE_2D = 0x0DE1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806F;\nconst TEXTURE_2D_ARRAY = 0x8C1A;\n\nconst typeMap = {};\n\n/**\n * Returns the corresponding bind point for a given sampler type\n * @private\n */\nfunction getBindPointForSamplerType(gl, type) {\n return typeMap[type].bindPoint;\n}\n\n// This kind of sucks! If you could compose functions as in `var fn = gl[name];`\n// this code could be a lot smaller but that is sadly really slow (T_T)\n\nfunction floatSetter(gl, location) {\n return function(v) {\n gl.uniform1f(location, v);\n };\n}\n\nfunction floatArraySetter(gl, location) {\n return function(v) {\n gl.uniform1fv(location, v);\n };\n}\n\nfunction floatVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2fv(location, v);\n };\n}\n\nfunction floatVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3fv(location, v);\n };\n}\n\nfunction floatVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4fv(location, v);\n };\n}\n\nfunction intSetter(gl, location) {\n return function(v) {\n gl.uniform1i(location, v);\n };\n}\n\nfunction intArraySetter(gl, location) {\n return function(v) {\n gl.uniform1iv(location, v);\n };\n}\n\nfunction intVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2iv(location, v);\n };\n}\n\nfunction intVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3iv(location, v);\n };\n}\n\nfunction intVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4iv(location, v);\n };\n}\n\nfunction uintSetter(gl, location) {\n return function(v) {\n gl.uniform1ui(location, v);\n };\n}\n\nfunction uintArraySetter(gl, location) {\n return function(v) {\n gl.uniform1uiv(location, v);\n };\n}\n\nfunction uintVec2Setter(gl, location) {\n return function(v) {\n gl.uniform2uiv(location, v);\n };\n}\n\nfunction uintVec3Setter(gl, location) {\n return function(v) {\n gl.uniform3uiv(location, v);\n };\n}\n\nfunction uintVec4Setter(gl, location) {\n return function(v) {\n gl.uniform4uiv(location, v);\n };\n}\n\nfunction floatMat2Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2fv(location, false, v);\n };\n}\n\nfunction floatMat3Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3fv(location, false, v);\n };\n}\n\nfunction floatMat4Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4fv(location, false, v);\n };\n}\n\nfunction floatMat23Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x3fv(location, false, v);\n };\n}\n\nfunction floatMat32Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x2fv(location, false, v);\n };\n}\n\nfunction floatMat24Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix2x4fv(location, false, v);\n };\n}\n\nfunction floatMat42Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x2fv(location, false, v);\n };\n}\n\nfunction floatMat34Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix3x4fv(location, false, v);\n };\n}\n\nfunction floatMat43Setter(gl, location) {\n return function(v) {\n gl.uniformMatrix4x3fv(location, false, v);\n };\n}\n\nfunction samplerSetter(gl, type, unit, location) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n return utils.isWebGL2(gl) ? function(textureOrPair) {\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n gl.bindSampler(unit, sampler);\n } : function(texture) {\n gl.uniform1i(location, unit);\n gl.activeTexture(TEXTURE0 + unit);\n gl.bindTexture(bindPoint, texture);\n };\n}\n\nfunction samplerArraySetter(gl, type, unit, location, size) {\n const bindPoint = getBindPointForSamplerType(gl, type);\n const units = new Int32Array(size);\n for (let ii = 0; ii < size; ++ii) {\n units[ii] = unit + ii;\n }\n\n return utils.isWebGL2(gl) ? function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(textureOrPair, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n let texture;\n let sampler;\n if (!textureOrPair || helper.isTexture(gl, textureOrPair)) {\n texture = textureOrPair;\n sampler = null;\n } else {\n texture = textureOrPair.texture;\n sampler = textureOrPair.sampler;\n }\n gl.bindSampler(unit, sampler);\n gl.bindTexture(bindPoint, texture);\n });\n } : function(textures) {\n gl.uniform1iv(location, units);\n textures.forEach(function(texture, index) {\n gl.activeTexture(TEXTURE0 + units[index]);\n gl.bindTexture(bindPoint, texture);\n });\n };\n}\n\ntypeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, };\ntypeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, };\ntypeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, };\ntypeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, };\ntypeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, };\ntypeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, };\ntypeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, };\ntypeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, };\ntypeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, };\ntypeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, };\ntypeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, };\ntypeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, };\ntypeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, };\ntypeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, };\ntypeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, };\ntypeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, };\ntypeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, };\ntypeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, };\ntypeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, };\ntypeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, };\ntypeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, };\ntypeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D, };\ntypeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, };\ntypeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, };\ntypeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, };\n\nfunction floatAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n switch (b.value.length) {\n case 4:\n gl.vertexAttrib4fv(index, b.value);\n break;\n case 3:\n gl.vertexAttrib3fv(index, b.value);\n break;\n case 2:\n gl.vertexAttrib2fv(index, b.value);\n break;\n case 1:\n gl.vertexAttrib1fv(index, b.value);\n break;\n default:\n throw new Error('the length of a float constant value must be between 1 and 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribPointer(\n index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction intAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4iv(index, b.value);\n } else {\n throw new Error('The length of an integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction uintAttribSetter(gl, index) {\n return function(b) {\n if (b.value) {\n gl.disableVertexAttribArray(index);\n if (b.value.length === 4) {\n gl.vertexAttrib4uiv(index, b.value);\n } else {\n throw new Error('The length of an unsigned integer constant value must be 4!');\n }\n } else {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n gl.enableVertexAttribArray(index);\n gl.vertexAttribIPointer(\n index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index, b.divisor || 0);\n }\n }\n };\n}\n\nfunction matAttribSetter(gl, index, typeInfo) {\n const defaultSize = typeInfo.size;\n const count = typeInfo.count;\n\n return function(b) {\n gl.bindBuffer(ARRAY_BUFFER, b.buffer);\n const numComponents = b.size || b.numComponents || defaultSize;\n const size = numComponents / count;\n const type = b.type || FLOAT;\n const typeInfo = typeMap[type];\n const stride = typeInfo.size * numComponents;\n const normalize = b.normalize || false;\n const offset = b.offset || 0;\n const rowOffset = stride / count;\n for (let i = 0; i < count; ++i) {\n gl.enableVertexAttribArray(index + i);\n gl.vertexAttribPointer(\n index + i, size, type, normalize, stride, offset + rowOffset * i);\n if (gl.vertexAttribDivisor) {\n gl.vertexAttribDivisor(index + i, b.divisor || 0);\n }\n }\n };\n}\n\n\n\nconst attrTypeMap = {};\nattrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, };\nattrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, };\nattrTypeMap[INT] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, };\nattrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, };\nattrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, };\nattrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, };\nattrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, };\nattrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, };\nattrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, };\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\nconst errorRE = /ERROR:\\s*\\d+:(\\d+)/gi;\nfunction addLineNumbersWithError(src, log = '', lineOffset = 0) {\n // Note: Error message formats are not defined by any spec so this may or may not work.\n const matches = [...log.matchAll(errorRE)];\n const lineNoToErrorMap = new Map(matches.map((m, ndx) => {\n const lineNo = parseInt(m[1]);\n const next = matches[ndx + 1];\n const end = next ? next.index : log.length;\n const msg = log.substring(m.index, end);\n return [lineNo - 1, msg];\n }));\n return src.split('\\n').map((line, lineNo) => {\n const err = lineNoToErrorMap.get(lineNo);\n return `${lineNo + 1 + lineOffset}: ${line}${err ? `\\n\\n^^^ ${err}` : ''}`;\n }).join('\\n');\n}\n\n/**\n * Error Callback\n * @callback ErrorCallback\n * @param {string} msg error message.\n * @param {number} [lineOffset] amount to add to line number\n * @memberOf module:twgl\n */\n\n/**\n * Program Callback\n * @callback ProgramCallback\n * @param {string} [err] error message, falsy if no error\n * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo\n */\n\nconst spaceRE = /^[ \\t]*\\n/;\n\n/**\n * Remove the first end of line because WebGL 2.0 requires\n * #version 300 es\n * as the first line. No whitespace allowed before that line\n * so\n *\n * \n *\n * Has one line before it which is invalid according to GLSL ES 3.00\n *\n * @param {string} shaderSource The source of the shader\n * @returns {{shaderSource: string, lineOffset: number}}\n * @private\n */\nfunction prepShaderSource(shaderSource) {\n let lineOffset = 0;\n if (spaceRE.test(shaderSource)) {\n lineOffset = 1;\n shaderSource = shaderSource.replace(spaceRE, '');\n }\n return {lineOffset, shaderSource};\n}\n\n/**\n * @param {module:twgl.ProgramOptions} progOptions\n * @param {string} msg\n * @return null\n * @private\n */\nfunction reportError(progOptions, msg) {\n progOptions.errorCallback(msg);\n if (progOptions.callback) {\n setTimeout(() => {\n progOptions.callback(`${msg}\\n${progOptions.errors.join('\\n')}`);\n });\n }\n return null;\n}\n\n/**\n * Check Shader status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {number} shaderType The shader type\n * @param {WebGLShader} shader The shader\n * @param {ErrorCallback} [errFn] function to receive error message.\n * @return {string} errors or empty string\n * @private\n */\nfunction checkShaderStatus(gl, shaderType, shader, errFn) {\n errFn = errFn || error;\n // Check the compile status\n const compiled = gl.getShaderParameter(shader, COMPILE_STATUS);\n if (!compiled) {\n // Something went wrong during compilation; get the error\n const lastError = gl.getShaderInfoLog(shader);\n const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader));\n const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\\nError compiling ${utils.glEnumToString(gl, shaderType)}: ${lastError}`;\n errFn(error);\n return error;\n }\n return '';\n}\n\n/**\n * @typedef {Object} FullProgramSpec\n * @property {string[]} shaders the shader source or element ids.\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec\n * @memberOf module:twgl\n */\n\n/**\n * @typedef {Object} ProgramOptions\n * @property {function(string)} [errorCallback] callback for errors\n * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location.\n * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed\n * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise\n * you can pass an array of names.\n * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`.\n * @property {ProgramCallback} [callback] callback for async program compilation.\n * @memberOf module:twgl\n */\n\n/**\n * Gets the program options based on all these optional arguments\n * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or an array of attribs names. Locations will be assigned by index if not passed in\n * @param {number[]} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in\n * @private\n */\nfunction getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) {\n let transformFeedbackVaryings;\n let transformFeedbackMode;\n let callback;\n if (typeof opt_locations === 'function') {\n opt_errorCallback = opt_locations;\n opt_locations = undefined;\n }\n if (typeof opt_attribs === 'function') {\n opt_errorCallback = opt_attribs;\n opt_attribs = undefined;\n } else if (opt_attribs && !Array.isArray(opt_attribs)) {\n const opt = opt_attribs;\n opt_errorCallback = opt.errorCallback;\n opt_attribs = opt.attribLocations;\n transformFeedbackVaryings = opt.transformFeedbackVaryings;\n transformFeedbackMode = opt.transformFeedbackMode;\n callback = opt.callback;\n }\n\n const errorCallback = opt_errorCallback || error;\n const errors = [];\n const options = {\n errorCallback(msg, ...args) {\n errors.push(msg);\n errorCallback(msg, ...args);\n },\n transformFeedbackVaryings,\n transformFeedbackMode,\n callback,\n errors,\n };\n\n {\n let attribLocations = {};\n if (Array.isArray(opt_attribs)) {\n opt_attribs.forEach(function(attrib, ndx) {\n attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx;\n });\n } else {\n attribLocations = opt_attribs || {};\n }\n options.attribLocations = attribLocations;\n }\n\n return options;\n}\n\nconst defaultShaderType = [\n \"VERTEX_SHADER\",\n \"FRAGMENT_SHADER\",\n];\n\nfunction getShaderTypeFromScriptType(gl, scriptType) {\n if (scriptType.indexOf(\"frag\") >= 0) {\n return FRAGMENT_SHADER;\n } else if (scriptType.indexOf(\"vert\") >= 0) {\n return VERTEX_SHADER;\n }\n return undefined;\n}\n\nfunction deleteProgramAndShaders(gl, program, notThese) {\n const shaders = gl.getAttachedShaders(program);\n for (const shader of shaders) {\n if (notThese.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n gl.deleteProgram(program);\n}\n\nconst wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));\n\nfunction createProgramNoCheck(gl, shaders, programOptions) {\n const program = gl.createProgram();\n const {\n attribLocations,\n transformFeedbackVaryings,\n transformFeedbackMode,\n } = getProgramOptions(programOptions);\n\n for (let ndx = 0; ndx < shaders.length; ++ndx) {\n let shader = shaders[ndx];\n if (typeof shader === 'string') {\n const elem = getElementById(shader);\n const src = elem ? elem.text : shader;\n let type = gl[defaultShaderType[ndx]];\n if (elem && elem.type) {\n type = getShaderTypeFromScriptType(gl, elem.type) || type;\n }\n shader = gl.createShader(type);\n gl.shaderSource(shader, prepShaderSource(src).shaderSource);\n gl.compileShader(shader);\n gl.attachShader(program, shader);\n }\n }\n\n Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib));\n\n {\n let varyings = transformFeedbackVaryings;\n if (varyings) {\n if (varyings.attribs) {\n varyings = varyings.attribs;\n }\n if (!Array.isArray(varyings)) {\n varyings = Object.keys(varyings);\n }\n gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS);\n }\n }\n\n gl.linkProgram(program);\n return program;\n}\n\n/**\n * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the\n * program.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgram(gl, [vs, fs], options);\n * twgl.createProgram(gl, [vs, fs], opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error of a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgram(\n gl, shaders, opt_attribs, opt_locations, opt_errorCallback) {\n // This code is really convoluted, because it may or may not be async\n // Maybe it would be better to have a separate function\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaderSet = new Set(shaders);\n const program = createProgramNoCheck(gl, shaders, progOptions);\n\n function hasErrors(gl, program) {\n const errors = getProgramErrors(gl, program, progOptions.errorCallback);\n if (errors) {\n deleteProgramAndShaders(gl, program, shaderSet);\n }\n return errors;\n }\n\n if (progOptions.callback) {\n waitForProgramLinkCompletionAsync(gl, program).then(() => {\n const errors = hasErrors(gl, program);\n progOptions.callback(errors, errors ? undefined : program);\n });\n return undefined;\n }\n\n return hasErrors(gl, program) ? undefined : program;\n}\n\n/**\n * This only works because the functions it wraps the first 2 arguments\n * are gl and any, followed by things that become programOptions\n * @private\n */\nfunction wrapCallbackFnToAsyncFn(fn) {\n return function(gl, arg1, ...args) {\n return new Promise((resolve, reject) => {\n const programOptions = getProgramOptions(...args);\n programOptions.callback = (err, program) => {\n if (err) {\n reject(err);\n } else {\n resolve(program);\n }\n };\n fn(gl, arg1, programOptions);\n });\n };\n}\n\n/**\n * Same as createProgram but returns a promise\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramAsync(gl, [vs, fs], options);\n * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created program\n * @memberOf module:twgl/programs\n */\nconst createProgramAsync = wrapCallbackFnToAsyncFn(createProgram);\n\n/**\n * Same as createProgramInfo but returns a promise\n * @function\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {Promise} The created ProgramInfo\n * @memberOf module:twgl/programs\n */\nconst createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo);\n\nasync function waitForProgramLinkCompletionAsync(gl, program) {\n const ext = gl.getExtension('KHR_parallel_shader_compile');\n const checkFn = ext\n ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR)\n : () => true;\n\n let waitTime = 0;\n do {\n await wait(waitTime); // must wait at least once\n waitTime = 1000 / 60;\n } while (!checkFn(gl, program));\n}\n\nasync function waitForAllProgramsLinkCompletionAsync(gl, programs) {\n for (const program of Object.values(programs)) {\n await waitForProgramLinkCompletionAsync(gl, program);\n }\n}\n\n/**\n * Check a program's link status\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program Program to check\n * @param {ErrorCallback} [errFn] func for errors\n * @return {string?} errors if program is failed, else undefined\n * @private\n */\nfunction getProgramErrors(gl, program, errFn) {\n errFn = errFn || error;\n // Check the link status\n const linked = gl.getProgramParameter(program, LINK_STATUS);\n if (!linked) {\n // something went wrong with the link\n const lastError = gl.getProgramInfoLog(program);\n errFn(`Error in program linking: ${lastError}`);\n // print any errors from these shaders\n const shaders = gl.getAttachedShaders(program);\n const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn));\n return `${lastError}\\n${errors.filter(_ => _).join('\\n')}`;\n }\n return undefined;\n}\n\n/**\n * Creates a program from 2 script tags.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_options);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderScriptIds Array of ids of the script\n * tags for the shaders. The first is assumed to be the\n * vertex shader, the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromScripts(\n gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const shaders = [];\n for (const scriptId of shaderScriptIds) {\n const shaderScript = getElementById(scriptId);\n if (!shaderScript) {\n return reportError(progOptions, `unknown script element: ${scriptId}`);\n }\n shaders.push(shaderScript.text);\n }\n return createProgram(gl, shaders, progOptions);\n}\n\n/**\n * Creates a program from 2 sources.\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramFromSource(gl, [vs, fs], opt_options);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {WebGLProgram?} the created program or null if error or a callback was provided.\n * @memberOf module:twgl/programs\n */\nfunction createProgramFromSources(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback);\n}\n\n/**\n * Returns true if attribute/uniform is a reserved/built in\n *\n * It makes no sense to me why GL returns these because it's\n * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation`\n * with names that start with `gl_` (and `webgl_` in WebGL)\n *\n * I can only assume they are there because they might count\n * when computing the number of uniforms/attributes used when you want to\n * know if you are near the limit. That doesn't really make sense\n * to me but the fact that these get returned are in the spec.\n *\n * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or\n * `gl.getActiveAttrib`.\n * @return {bool} true if it's reserved\n * @private\n */\nfunction isBuiltIn(info) {\n const name = info.name;\n return name.startsWith(\"gl_\") || name.startsWith(\"webgl_\");\n}\n\nconst tokenRE = /(\\.|\\[|]|\\w+)/g;\nconst isDigit = s => s >= '0' && s <= '9';\nfunction addSetterToUniformTree(fullPath, setter, node, uniformSetters) {\n const tokens = fullPath.split(tokenRE).filter(s => s !== '');\n let tokenNdx = 0;\n let path = '';\n\n for (;;) {\n const token = tokens[tokenNdx++]; // has to be name or number\n path += token;\n const isArrayIndex = isDigit(token[0]);\n const accessor = isArrayIndex\n ? parseInt(token)\n : token;\n if (isArrayIndex) {\n path += tokens[tokenNdx++]; // skip ']'\n }\n const isLastToken = tokenNdx === tokens.length;\n if (isLastToken) {\n node[accessor] = setter;\n break;\n } else {\n const token = tokens[tokenNdx++]; // has to be . or [\n const isArray = token === '[';\n const child = node[accessor] || (isArray ? [] : {});\n node[accessor] = child;\n node = child;\n uniformSetters[path] = uniformSetters[path] || function(node) {\n return function(value) {\n setUniformTree(node, value);\n };\n }(child);\n path += token;\n }\n }\n}\n\n/**\n * Creates setter functions for all uniforms of a shader\n * program.\n *\n * @see {@link module:twgl.setUniforms}\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @returns {Object.} an object with a setter by name for each uniform\n * @memberOf module:twgl/programs\n */\nfunction createUniformSetters(gl, program) {\n let textureUnit = 0;\n\n /**\n * Creates a setter for a uniform of the given program with it's\n * location embedded in the setter.\n * @param {WebGLProgram} program\n * @param {WebGLUniformInfo} uniformInfo\n * @returns {function} the created setter.\n */\n function createUniformSetter(program, uniformInfo, location) {\n const isArray = uniformInfo.name.endsWith(\"[0]\");\n const type = uniformInfo.type;\n const typeInfo = typeMap[type];\n if (!typeInfo) {\n throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here.\n }\n let setter;\n if (typeInfo.bindPoint) {\n // it's a sampler\n const unit = textureUnit;\n textureUnit += uniformInfo.size;\n if (isArray) {\n setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size);\n } else {\n setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size);\n }\n } else {\n if (typeInfo.arraySetter && isArray) {\n setter = typeInfo.arraySetter(gl, location);\n } else {\n setter = typeInfo.setter(gl, location);\n }\n }\n setter.location = location;\n return setter;\n }\n\n const uniformSetters = {};\n const uniformTree = {};\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n const uniformInfo = gl.getActiveUniform(program, ii);\n if (isBuiltIn(uniformInfo)) {\n continue;\n }\n let name = uniformInfo.name;\n // remove the array suffix.\n if (name.endsWith(\"[0]\")) {\n name = name.substr(0, name.length - 3);\n }\n const location = gl.getUniformLocation(program, uniformInfo.name);\n // the uniform will have no location if it's in a uniform block\n if (location) {\n const setter = createUniformSetter(program, uniformInfo, location);\n uniformSetters[name] = setter;\n addSetterToUniformTree(name, setter, uniformTree, uniformSetters);\n }\n }\n\n return uniformSetters;\n}\n\n/**\n * @typedef {Object} TransformFeedbackInfo\n * @property {number} index index of transform feedback\n * @property {number} type GL type\n * @property {number} size 1 - 4\n * @memberOf module:twgl\n */\n\n/**\n * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo.\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {Object}\n * @memberOf module:twgl\n */\nfunction createTransformFeedbackInfo(gl, program) {\n const info = {};\n const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS);\n for (let ii = 0; ii < numVaryings; ++ii) {\n const varying = gl.getTransformFeedbackVarying(program, ii);\n info[varying.name] = {\n index: ii,\n type: varying.type,\n size: varying.size,\n };\n }\n return info;\n}\n\n/**\n * Binds buffers for transform feedback.\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo.\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @memberOf module:twgl\n */\nfunction bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) {\n if (transformFeedbackInfo.transformFeedbackInfo) {\n transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo;\n }\n if (bufferInfo.attribs) {\n bufferInfo = bufferInfo.attribs;\n }\n for (const name in bufferInfo) {\n const varying = transformFeedbackInfo[name];\n if (varying) {\n const buf = bufferInfo[name];\n if (buf.offset) {\n gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size);\n } else {\n gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer);\n }\n }\n }\n}\n\n/**\n * Creates a transform feedback and sets the buffers\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo}\n * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos.\n * @return {WebGLTransformFeedback} the created transform feedback\n * @memberOf module:twgl\n */\nfunction createTransformFeedback(gl, programInfo, bufferInfo) {\n const tf = gl.createTransformFeedback();\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf);\n gl.useProgram(programInfo.program);\n bindTransformFeedbackInfo(gl, programInfo, bufferInfo);\n gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null);\n return tf;\n}\n\n/**\n * @typedef {Object} UniformData\n * @property {string} name The name of the uniform\n * @property {number} type The WebGL type enum for this uniform\n * @property {number} size The number of elements for this uniform\n * @property {number} blockNdx The block index this uniform appears in\n * @property {number} offset The byte offset in the block for this uniform's value\n * @memberOf module:twgl\n */\n\n/**\n * The specification for one UniformBlockObject\n *\n * @typedef {Object} BlockSpec\n * @property {number} index The index of the block.\n * @property {number} size The size in bytes needed for the block\n * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices\n * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}.\n * @property {bool} usedByVertexShader Self explanatory\n * @property {bool} usedByFragmentShader Self explanatory\n * @property {bool} used Self explanatory\n * @memberOf module:twgl\n */\n\n/**\n * A `UniformBlockSpec` represents the data needed to create and bind\n * UniformBlockObjects for a given program\n *\n * @typedef {Object} UniformBlockSpec\n * @property {Object.} blockSpecs The BlockSpec for each block by block name\n * @property {UniformData[]} uniformData An array of data for each uniform by uniform index.\n * @memberOf module:twgl\n */\n\n/**\n * Creates a UniformBlockSpec for the given program.\n *\n * A UniformBlockSpec represents the data needed to create and bind\n * UniformBlockObjects\n *\n * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context\n * @param {WebGLProgram} program A WebGLProgram for a successfully linked program\n * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockSpecFromProgram(gl, program) {\n const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS);\n const uniformData = [];\n const uniformIndices = [];\n\n for (let ii = 0; ii < numUniforms; ++ii) {\n uniformIndices.push(ii);\n uniformData.push({});\n const uniformInfo = gl.getActiveUniform(program, ii);\n uniformData[ii].name = uniformInfo.name;\n }\n\n [\n [ \"UNIFORM_TYPE\", \"type\" ],\n [ \"UNIFORM_SIZE\", \"size\" ], // num elements\n [ \"UNIFORM_BLOCK_INDEX\", \"blockNdx\" ],\n [ \"UNIFORM_OFFSET\", \"offset\", ],\n ].forEach(function(pair) {\n const pname = pair[0];\n const key = pair[1];\n gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) {\n uniformData[ndx][key] = value;\n });\n });\n\n const blockSpecs = {};\n\n const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS);\n for (let ii = 0; ii < numUniformBlocks; ++ii) {\n const name = gl.getActiveUniformBlockName(program, ii);\n const blockSpec = {\n index: gl.getUniformBlockIndex(program, name),\n usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER),\n usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER),\n size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE),\n uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES),\n };\n blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader;\n blockSpecs[name] = blockSpec;\n }\n\n return {\n blockSpecs: blockSpecs,\n uniformData: uniformData,\n };\n}\n\nconst arraySuffixRE = /\\[\\d+\\]\\.$/; // better way to check?\n\nconst pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding;\n\nfunction createUniformBlockUniformSetter(view, isArray, rows, cols) {\n if (isArray || rows) {\n cols = cols || 1;\n const numElements = view.length;\n const totalRows = numElements / 4;\n return function(value) {\n let dst = 0;\n let src = 0;\n for (let row = 0; row < totalRows; ++row) {\n for (let col = 0; col < cols; ++col) {\n view[dst++] = value[src++];\n }\n dst += 4 - cols;\n }\n };\n } else {\n return function(value) {\n if (value.length) {\n view.set(value);\n } else {\n view[0] = value;\n }\n };\n }\n}\n\n/**\n * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values\n * and a corresponding WebGLBuffer to hold those values on the GPU\n *\n * @typedef {Object} UniformBlockInfo\n * @property {string} name The name of the block\n * @property {ArrayBuffer} array The array buffer that contains the uniform values\n * @property {Float32Array} asFloat A float view on the array buffer. This is useful\n * inspecting the contents of the buffer in the debugger.\n * @property {Uint8Array} asUint8t A uint8 view on the array buffer.\n * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering.\n * @property {number} [offset] offset into buffer\n * @property {Object} uniforms A uniform name to ArrayBufferView map.\n * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset\n * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array`\n * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an\n * `Int32Array` view, etc.\n * @property {Object} setters A setter for this uniform.\n * The reason to use setters is elements of arrays are padded to vec4 sizes which\n * means if you want to set an array of 4 floats you'd need to set 16 values\n * (or set elements 0, 4, 8, 12). In other words\n * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])`\n * where as the setter handles just passing in [0, 1, 2, 3] either directly as in\n * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended)\n * or via {@link module:twgl.setBlockUniforms}\n * @memberOf module:twgl\n */\n\n/**\n * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset\n * @typedef {Object} UniformBlockInfoOptions\n * @property {ArrayBuffer} [array] an existing array buffer to use for values\n * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0)\n * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info\n * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above)\n */\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {WebGLProgram} program A WebGLProgram\n * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned\n * from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) {\n const blockSpecs = uniformBlockSpec.blockSpecs;\n const uniformData = uniformBlockSpec.uniformData;\n const blockSpec = blockSpecs[blockName];\n if (!blockSpec) {\n warn(\"no uniform block object named:\", blockName);\n return {\n name: blockName,\n uniforms: {},\n };\n }\n const offset = options.offset ?? 0;\n const array = options.array ?? new ArrayBuffer(blockSpec.size);\n const buffer = options.buffer ?? gl.createBuffer();\n const uniformBufferIndex = blockSpec.index;\n gl.bindBuffer(UNIFORM_BUFFER, buffer);\n if (!options.buffer) {\n gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW);\n }\n gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex);\n\n let prefix = blockName + \".\";\n if (arraySuffixRE.test(prefix)) {\n prefix = prefix.replace(arraySuffixRE, \".\");\n }\n const uniforms = {};\n const setters = {};\n const setterTree = {};\n blockSpec.uniformIndices.forEach(function(uniformNdx) {\n const data = uniformData[uniformNdx];\n let name = data.name;\n if (name.startsWith(prefix)) {\n name = name.substr(prefix.length);\n }\n const isArray = name.endsWith('[0]');\n if (isArray) {\n name = name.substr(0, name.length - 3);\n }\n const typeInfo = typeMap[data.type];\n const Type = typeInfo.Type;\n const byteLength = isArray\n ? pad(typeInfo.size, 16) * data.size\n : typeInfo.size * data.size;\n const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT);\n uniforms[name] = uniformView;\n // Note: I'm not sure what to do here. The original\n // idea was to create TypedArray views into each part\n // of the block. This is useful, for example if you have\n // a block with { mat4: model; mat4 view; mat4 projection; }\n // you'll get a Float32Array for each one suitable for\n // passing to most JS math libraries including twgl's and glMatrix.js.\n //\n // But, if you have a an array of structures, especially if that\n // array is large, you get a whole bunch of TypedArray views.\n // Every one of them has overhead and switching between them all\n // is probably a cache miss. In that case it would really be better\n // to just have one view (asFloat) and have all the setters\n // just reference the correct portion. But, then you can't easily\n // treat a matrix, or a vec4, as a standalone thing like you can\n // with all the views.\n //\n // Another problem with the views is they are not shared. With\n // uniforms you have one set of setters. With UniformBlockInfo\n // you have a set of setters *pre block instance*. That's because\n // TypedArray views can't be mapped to different buffers.\n //\n // My gut right now is if you really want the speed and compactness\n // then you should probably roll your own solution. TWGL's goal\n // here is ease of use as AFAICT there is no simple generic efficient\n // solution.\n const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols);\n setters[name] = setter;\n addSetterToUniformTree(name, setter, setterTree, setters);\n });\n return {\n name: blockName,\n array,\n asFloat: new Float32Array(array), // for debugging\n asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer\n buffer,\n uniforms,\n setters,\n offset: options.bufferOffset ?? offset,\n size: blockSpec.size,\n };\n}\n\n/**\n * Creates a `UniformBlockInfo` for the specified block\n *\n * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy\n * `UniformBlockInfo` is returned**. This is because when debugging GLSL\n * it is common to comment out large portions of a shader or for example set\n * the final output to a constant. When that happens blocks get optimized out.\n * If this function did not create dummy blocks your code would crash when debugging.\n *\n * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext\n * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo}\n * @param {string} blockName The name of the block.\n * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer\n * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo\n * @memberOf module:twgl/programs\n */\nfunction createUniformBlockInfo(gl, programInfo, blockName, options = {}) {\n return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options);\n}\n\n/**\n * Binds a uniform block to the matching uniform block point.\n * Matches by blocks by name so blocks must have the same name not just the same\n * structure.\n *\n * If you have changed any values and you upload the values into the corresponding WebGLBuffer\n * call {@link module:twgl.setUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name\n * no buffer is bound.\n * @memberOf module:twgl/programs\n */\nfunction bindUniformBlock(gl, programInfo, uniformBlockInfo) {\n const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo;\n const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name];\n if (blockSpec) {\n const bufferBindIndex = blockSpec.index;\n gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength);\n return true;\n }\n return false;\n}\n\n/**\n * Uploads the current uniform values to the corresponding WebGLBuffer\n * and binds that buffer to the program's corresponding bind point for the uniform block object.\n *\n * If you haven't changed any values and you only need to bind the uniform block object\n * call {@link module:twgl.bindUniformBlock} instead.\n *\n * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context.\n * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo`\n * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as\n * returned from {@link module:twgl.createUniformBlockSpecFromProgram}.\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from\n * {@link module:twgl.createUniformBlockInfo}.\n * @memberOf module:twgl/programs\n */\nfunction setUniformBlock(gl, programInfo, uniformBlockInfo) {\n if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) {\n gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0);\n }\n}\n\n/**\n * Sets values of a uniform block object\n *\n * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}.\n * @param {Object.} values A uniform name to value map where the value is correct for the given\n * type of uniform. So for example given a block like\n *\n * uniform SomeBlock {\n * float someFloat;\n * vec2 someVec2;\n * vec3 someVec3Array[2];\n * int someInt;\n * }\n *\n * You can set the values of the uniform block with\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * someFloat: 12.3,\n * someVec2: [1, 2],\n * someVec3Array: [1, 2, 3, 4, 5, 6],\n * someInt: 5,\n * }\n *\n * Arrays can be JavaScript arrays or typed arrays\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Lights {\n * Light lights[2];\n * };\n *\n * // in JavaScript\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices.\n *\n * twgl.setBlockUniforms(someBlockInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * **IMPORTANT!**, packing in a UniformBlock is unintuitive.\n * For example the actual layout of `someVec3Array` above in memory\n * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values\n * as shown about and copies them, skipping the padding. This might\n * be confusing if you're already familiar with Uniform blocks.\n *\n * If you want to deal with the padding yourself you can access the array\n * buffer views directly. eg:\n *\n * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]);\n *\n * Any name that doesn't match will be ignored\n * @memberOf module:twgl/programs\n */\nfunction setBlockUniforms(uniformBlockInfo, values) {\n const setters = uniformBlockInfo.setters;\n for (const name in values) {\n const setter = setters[name];\n if (setter) {\n const value = values[name];\n setter(value);\n }\n }\n}\n\nfunction setUniformTree(tree, values) {\n for (const name in values) {\n const prop = tree[name];\n if (typeof prop === 'function') {\n prop(values[name]);\n } else {\n setUniformTree(tree[name], values[name]);\n }\n }\n}\n\n/**\n * Set uniforms and binds related textures.\n *\n * example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\"]);\n *\n * const tex1 = gl.createTexture();\n * const tex2 = gl.createTexture();\n *\n * ... assume we setup the textures with data ...\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the textures AND set the\n * uniforms.\n *\n * twgl.setUniforms(programInfo, uniforms);\n *\n * For the example above it is equivalent to\n *\n * let texUnit = 0;\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex1);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.activeTexture(gl.TEXTURE0 + texUnit);\n * gl.bindTexture(gl.TEXTURE_2D, tex2);\n * gl.uniform1i(u_someSamplerLocation, texUnit++);\n * gl.uniform4fv(u_someColorLocation, [1, 0, 0, 1]);\n * gl.uniform3fv(u_somePositionLocation, [0, 1, 1]);\n * gl.uniformMatrix4fv(u_someMatrix, false, [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ]);\n *\n * Note it is perfectly reasonable to call `setUniforms` multiple times. For example\n *\n * const uniforms = {\n * u_someSampler: tex1,\n * u_someOtherSampler: tex2,\n * };\n *\n * const moreUniforms {\n * u_someColor: [1,0,0,1],\n * u_somePosition: [0,1,1],\n * u_someMatrix: [\n * 1,0,0,0,\n * 0,1,0,0,\n * 0,0,1,0,\n * 0,0,0,0,\n * ],\n * };\n *\n * twgl.setUniforms(programInfo, uniforms);\n * twgl.setUniforms(programInfo, moreUniforms);\n *\n * You can also add WebGLSamplers to uniform samplers as in\n *\n * const uniforms = {\n * u_someSampler: {\n * texture: someWebGLTexture,\n * sampler: someWebGLSampler,\n * },\n * };\n *\n * In which case both the sampler and texture will be bound to the\n * same unit.\n *\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * uniforms.\n * You can pass multiple objects by putting them in an array or by calling with more arguments.For example\n *\n * const sharedUniforms = {\n * u_fogNear: 10,\n * u_projection: ...\n * ...\n * };\n *\n * const localUniforms = {\n * u_world: ...\n * u_diffuseColor: ...\n * };\n *\n * twgl.setUniforms(programInfo, sharedUniforms, localUniforms);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]);\n *\n * // is the same as\n *\n * twgl.setUniforms(programInfo, sharedUniforms);\n * twgl.setUniforms(programInfo, localUniforms};\n *\n * You can also fill out structure and array values either via\n * shortcut. Example\n *\n * // -- in shader --\n * struct Light {\n * float intensity;\n * vec4 color;\n * float nearFar[2];\n * };\n * uniform Light lights[2];\n *\n * // in JavaScript\n *\n * twgl.setUniforms(programInfo, {\n * lights: [\n * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] },\n * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] },\n * ],\n * });\n *\n * or the more traditional way\n *\n * twgl.setUniforms(programInfo, {\n * \"lights[0].intensity\": 5.0,\n * \"lights[0].color\": [1, 0, 0, 1],\n * \"lights[0].nearFar\": [0.1, 10],\n * \"lights[1].intensity\": 2.0,\n * \"lights[1].color\": [0, 0, 1, 1],\n * \"lights[1].nearFar\": [0.2, 15],\n * });\n *\n * You can also specify partial paths\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] },\n * });\n *\n * But you can not specify leaf array indices\n *\n * twgl.setUniforms(programInfo, {\n * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf\n * 'lights[1].nearFar': [0.2, 15], // GOOD\n * });\n *\n * @memberOf module:twgl/programs\n */\nfunction setUniforms(setters, ...args) { // eslint-disable-line\n const actualSetters = setters.uniformSetters || setters;\n const numArgs = args.length;\n for (let aNdx = 0; aNdx < numArgs; ++aNdx) {\n const values = args[aNdx];\n if (Array.isArray(values)) {\n const numValues = values.length;\n for (let ii = 0; ii < numValues; ++ii) {\n setUniforms(actualSetters, values[ii]);\n }\n } else {\n for (const name in values) {\n const setter = actualSetters[name];\n if (setter) {\n setter(values[name]);\n }\n }\n }\n }\n}\n\n/**\n * Alias for `setUniforms`\n * @function\n * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from\n * `createUniformSetters`.\n * @param {Object.} values an object with values for the\n * @memberOf module:twgl/programs\n */\nconst setUniformsAndBindTextures = setUniforms;\n\n/**\n * Creates setter functions for all attributes of a shader\n * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes.\n *\n * @see {@link module:twgl.setAttributes} for example\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {WebGLProgram} program the program to create setters for.\n * @return {Object.} an object with a setter for each attribute by name.\n * @memberOf module:twgl/programs\n */\nfunction createAttributeSetters(gl, program) {\n const attribSetters = {\n };\n\n const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES);\n for (let ii = 0; ii < numAttribs; ++ii) {\n const attribInfo = gl.getActiveAttrib(program, ii);\n if (isBuiltIn(attribInfo)) {\n continue;\n }\n const index = gl.getAttribLocation(program, attribInfo.name);\n const typeInfo = attrTypeMap[attribInfo.type];\n const setter = typeInfo.setter(gl, index, typeInfo);\n setter.location = index;\n attribSetters[attribInfo.name] = setter;\n }\n\n return attribSetters;\n}\n\n/**\n * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes})\n *\n * Example:\n *\n * const program = createProgramFromScripts(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const attribSetters = createAttributeSetters(program);\n *\n * const positionBuffer = gl.createBuffer();\n * const texcoordBuffer = gl.createBuffer();\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * };\n *\n * gl.useProgram(program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setAttributes(attribSetters, attribs);\n *\n * Properties of attribs. For each attrib you can add\n * properties:\n *\n * * type: the type of data in the buffer. Default = gl.FLOAT\n * * normalize: whether or not to normalize the data. Default = false\n * * stride: the stride. Default = 0\n * * offset: offset into the buffer. Default = 0\n * * divisor: the divisor for instances. Default = undefined\n *\n * For example if you had 3 value float positions, 2 value\n * float texcoord and 4 value uint8 colors you'd setup your\n * attribs like this\n *\n * const attribs = {\n * a_position: {buffer: positionBuffer, numComponents: 3},\n * a_texcoord: {buffer: texcoordBuffer, numComponents: 2},\n * a_color: {\n * buffer: colorBuffer,\n * numComponents: 4,\n * type: gl.UNSIGNED_BYTE,\n * normalize: true,\n * },\n * };\n *\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} buffers AttribInfos mapped by attribute name.\n * @memberOf module:twgl/programs\n * @deprecated use {@link module:twgl.setBuffersAndAttributes}\n * @private\n */\nfunction setAttributes(setters, buffers) {\n for (const name in buffers) {\n const setter = setters[name];\n if (setter) {\n setter(buffers[name]);\n }\n }\n}\n\n/**\n * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate\n *\n * Example:\n *\n * const programInfo = createProgramInfo(\n * gl, [\"some-vs\", \"some-fs\");\n *\n * const arrays = {\n * position: { numComponents: 3, data: [0, 0, 0, 10, 0, 0, 0, 10, 0, 10, 10, 0], },\n * texcoord: { numComponents: 2, data: [0, 0, 0, 1, 1, 0, 1, 1], },\n * };\n *\n * const bufferInfo = createBufferInfoFromArrays(gl, arrays);\n *\n * gl.useProgram(programInfo.program);\n *\n * This will automatically bind the buffers AND set the\n * attributes.\n *\n * setBuffersAndAttributes(gl, programInfo, bufferInfo);\n *\n * For the example above it is equivalent to\n *\n * gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n * gl.enableVertexAttribArray(a_positionLocation);\n * gl.vertexAttribPointer(a_positionLocation, 3, gl.FLOAT, false, 0, 0);\n * gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);\n * gl.enableVertexAttribArray(a_texcoordLocation);\n * gl.vertexAttribPointer(a_texcoordLocation, 4, gl.FLOAT, false, 0, 0);\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext.\n * @param {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters}\n * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}.\n * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo}\n * @memberOf module:twgl/programs\n */\nfunction setBuffersAndAttributes(gl, programInfo, buffers) {\n if (buffers.vertexArrayObject) {\n gl.bindVertexArray(buffers.vertexArrayObject);\n } else {\n setAttributes(programInfo.attribSetters || programInfo, buffers.attribs);\n if (buffers.indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, buffers.indices);\n }\n }\n}\n\n/**\n * @typedef {Object} ProgramInfo\n * @property {WebGLProgram} program A shader program\n * @property {Object} uniformLocations The uniform locations of each uniform\n * @property {Object} attribLocations The locations of each attribute\n * @property {Object} uniformSetters object of setters as returned from createUniformSetters,\n * @property {Object} attribSetters object of setters as returned from createAttribSetters,\n * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc..\n * @property {Object} [transformFeedbackInfo] info for transform feedbacks\n * @memberOf module:twgl\n */\n\n/**\n * Creates a ProgramInfo from an existing program.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {WebGLProgram} program an existing WebGLProgram.\n * @return {module:twgl.ProgramInfo} The created ProgramInfo.\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfoFromProgram(gl, program) {\n const uniformSetters = createUniformSetters(gl, program);\n const attribSetters = createAttributeSetters(gl, program);\n const programInfo = {\n program,\n uniformSetters,\n attribSetters,\n uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])),\n attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])),\n };\n\n if (utils.isWebGL2(gl)) {\n programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program);\n programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program);\n }\n\n return programInfo;\n}\n\nconst notIdRE = /\\s|{|}|;/;\n\n/**\n * Creates a ProgramInfo from 2 sources.\n *\n * A ProgramInfo contains\n *\n * programInfo = {\n * program: WebGLProgram,\n * uniformSetters: object of setters as returned from createUniformSetters,\n * attribSetters: object of setters as returned from createAttribSetters,\n * }\n *\n * NOTE: There are 4 signatures for this function\n *\n * twgl.createProgramInfo(gl, [vs, fs], options);\n * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc);\n * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc);\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {string[]} shaderSources Array of sources for the\n * shaders or ids. The first is assumed to be the vertex shader,\n * the second the fragment shader.\n * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in\n * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback.\n * @param {module:twgl.ErrorCallback} [opt_errorCallback] callback for errors. By default it just prints an error to the console\n * on error. If you want something else pass an callback. It's passed an error message.\n * @return {module:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile\n * @memberOf module:twgl/programs\n */\nfunction createProgramInfo(\n gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) {\n const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback);\n const errors = [];\n shaderSources = shaderSources.map(function(source) {\n // Lets assume if there is no \\n it's an id\n if (!notIdRE.test(source)) {\n const script = getElementById(source);\n if (!script) {\n const err = `no element with id: ${source}`;\n progOptions.errorCallback(err);\n errors.push(err);\n } else {\n source = script.text;\n }\n }\n return source;\n });\n\n if (errors.length) {\n return reportError(progOptions, '');\n }\n\n const origCallback = progOptions.callback;\n if (origCallback) {\n progOptions.callback = (err, program) => {\n origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program));\n };\n }\n\n const program = createProgramFromSources(gl, shaderSources, progOptions);\n if (!program) {\n return null;\n }\n\n return createProgramInfoFromProgram(gl, program);\n}\n\nfunction checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) {\n // check errors for everything.\n for (const [name, program] of Object.entries(programs)) {\n const options = {...programOptions};\n const spec = programSpecs[name];\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n const errors = getProgramErrors(gl, program, options.errorCallback);\n if (errors) {\n // delete everything we created\n for (const program of Object.values(programs)) {\n const shaders = gl.getAttachedShaders(program);\n gl.deleteProgram(program);\n for (const shader of shaders) {\n // Don't delete it if we didn't create it.\n if (!noDeleteShadersSet.has(shader)) {\n gl.deleteShader(shader);\n }\n }\n }\n return errors;\n }\n }\n\n return undefined;\n}\n\n/**\n * Creates multiple programs\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgram}\n *\n * Example:\n *\n * const programs = twgl.createPrograms(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createPrograms(gl, programSpecs, programOptions = {}) {\n // Remember existing shaders so that if there is an error we don't delete them\n const noDeleteShadersSet = new Set();\n\n // compile and link everything\n const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => {\n const options = {...programOptions};\n const shaders = Array.isArray(spec) ? spec : spec.shaders;\n if (!Array.isArray(spec)) {\n Object.assign(options, spec);\n }\n shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet);\n return [name, createProgramNoCheck(gl, shaders, options)];\n }));\n\n if (programOptions.callback) {\n waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => {\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n programOptions.callback(errors, errors ? undefined : programs);\n });\n return undefined;\n }\n\n const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions);\n return errors ? undefined : programs;\n}\n\n/**\n * Creates multiple programInfos\n *\n * Note: the reason this function exists is because the fastest way to create multiple\n * programs in WebGL is to create and compile all shaders and link all programs and only\n * afterwards check if they succeeded. In that way, giving all your shaders\n *\n * @see {@link module:twgl.createProgramInfo}\n *\n * Examples:\n *\n * const programInfos = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * or\n *\n * const {lambert, phong, particles} = twgl.createProgramInfos(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nfunction createProgramInfos(gl, programSpecs, programOptions) {\n programOptions = getProgramOptions(programOptions);\n\n function createProgramInfosForPrograms(gl, programs) {\n return Object.fromEntries(Object.entries(programs).map(([name, program]) =>\n [name, createProgramInfoFromProgram(gl, program)]\n ));\n }\n\n const origCallback = programOptions.callback;\n if (origCallback) {\n programOptions.callback = (err, programs) => {\n origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs));\n };\n }\n\n const programs = createPrograms(gl, programSpecs, programOptions);\n if (origCallback || !programs) {\n return undefined;\n }\n\n return createProgramInfosForPrograms(gl, programs);\n}\n\n/**\n * Creates multiple programs asynchronously\n *\n * @see {@link module:twgl.createProgramAsync}\n *\n * Example:\n *\n * const programs = await twgl.createProgramsAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Object.?} the created programInfos by name\n */\nconst createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms);\n\n/**\n * Creates multiple programInfos asynchronously\n *\n * @see {@link module:twgl.createProgramInfoAsync}\n *\n * Example:\n *\n * const programInfos = await twgl.createProgramInfosAsync(gl, {\n * lambert: [lambertVS, lambertFS],\n * phong: [phongVS, phoneFS],\n * particles: {\n * shaders: [particlesVS, particlesFS],\n * transformFeedbackVaryings: ['position', 'velocity'],\n * },\n * });\n *\n * @function\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} programSpecs An object of ProgramSpecs, one per program.\n * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs\n * @return {Promise>} the created programInfos by name\n */\nconst createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos);\n\nexport {\n createAttributeSetters,\n\n createProgram,\n createProgramAsync,\n createPrograms,\n createProgramsAsync,\n createProgramFromScripts,\n createProgramFromSources,\n createProgramInfo,\n createProgramInfoAsync,\n createProgramInfos,\n createProgramInfosAsync,\n createProgramInfoFromProgram,\n createUniformSetters,\n createUniformBlockSpecFromProgram,\n createUniformBlockInfoFromProgram,\n createUniformBlockInfo,\n\n createTransformFeedback,\n createTransformFeedbackInfo,\n bindTransformFeedbackInfo,\n\n setAttributes,\n setBuffersAndAttributes,\n setUniforms,\n setUniformsAndBindTextures,\n setUniformBlock,\n setBlockUniforms,\n bindUniformBlock,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as utils from './utils.js';\nimport * as typedArrays from './typedarrays.js';\nimport * as helper from './helper.js';\n\n/**\n * Low level texture related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.textures` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/textures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n textureColor: new Uint8Array([128, 192, 255, 255]),\n textureOptions: {},\n crossOrigin: undefined,\n};\nconst isArrayBuffer = typedArrays.isArrayBuffer;\n\n// Should we make this on demand?\nconst getShared2DContext = function() {\n let s_ctx;\n return function getShared2DContext() {\n s_ctx = s_ctx ||\n ((typeof document !== 'undefined' && document.createElement)\n ? document.createElement(\"canvas\").getContext(\"2d\")\n : null);\n return s_ctx;\n };\n}();\n\n// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but\n// not only does Firefox NOT support it but Firefox freezes immediately\n// if you try to create one instead of just returning null and continuing.\n// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext(\"2d\")); // OffscreenCanvas may not support 2d\n\n// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2\n// we can use the various unpack settings. Otherwise we could try using\n// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap\n// is async and the current TWGL code expects a non-Async result though that\n// might not be a problem. ImageBitmap though is not available in Edge or Safari\n// as of 2018-01-02\n\n/* PixelFormat */\nconst ALPHA = 0x1906;\nconst RGB = 0x1907;\nconst RGBA = 0x1908;\nconst LUMINANCE = 0x1909;\nconst LUMINANCE_ALPHA = 0x190A;\nconst DEPTH_COMPONENT = 0x1902;\nconst DEPTH_STENCIL = 0x84F9;\n\n/* TextureWrapMode */\n// const REPEAT = 0x2901;\n// const MIRRORED_REPEAT = 0x8370;\nconst CLAMP_TO_EDGE = 0x812f;\n\n/* TextureMagFilter */\nconst NEAREST = 0x2600;\nconst LINEAR = 0x2601;\n\n/* TextureMinFilter */\n// const NEAREST_MIPMAP_NEAREST = 0x2700;\n// const LINEAR_MIPMAP_NEAREST = 0x2701;\n// const NEAREST_MIPMAP_LINEAR = 0x2702;\n// const LINEAR_MIPMAP_LINEAR = 0x2703;\n\n/* Texture Target */\nconst TEXTURE_2D = 0x0de1;\nconst TEXTURE_CUBE_MAP = 0x8513;\nconst TEXTURE_3D = 0x806f;\nconst TEXTURE_2D_ARRAY = 0x8c1a;\n\n/* Cubemap Targets */\nconst TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515;\nconst TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516;\nconst TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518;\nconst TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519;\nconst TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a;\n\n/* Texture Parameters */\nconst TEXTURE_MIN_FILTER = 0x2801;\nconst TEXTURE_MAG_FILTER = 0x2800;\nconst TEXTURE_WRAP_S = 0x2802;\nconst TEXTURE_WRAP_T = 0x2803;\nconst TEXTURE_WRAP_R = 0x8072;\nconst TEXTURE_MIN_LOD = 0x813a;\nconst TEXTURE_MAX_LOD = 0x813b;\nconst TEXTURE_BASE_LEVEL = 0x813c;\nconst TEXTURE_MAX_LEVEL = 0x813d;\nconst TEXTURE_COMPARE_MODE = 0x884C;\nconst TEXTURE_COMPARE_FUNC = 0x884D;\n\n/* Pixel store */\nconst UNPACK_ALIGNMENT = 0x0cf5;\nconst UNPACK_ROW_LENGTH = 0x0cf2;\nconst UNPACK_IMAGE_HEIGHT = 0x806e;\nconst UNPACK_SKIP_PIXELS = 0x0cf4;\nconst UNPACK_SKIP_ROWS = 0x0cf3;\nconst UNPACK_SKIP_IMAGES = 0x806d;\nconst UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;\nconst UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;\nconst UNPACK_FLIP_Y_WEBGL = 0x9240;\n\nconst R8 = 0x8229;\nconst R8_SNORM = 0x8F94;\nconst R16F = 0x822D;\nconst R32F = 0x822E;\nconst R8UI = 0x8232;\nconst R8I = 0x8231;\nconst RG16UI = 0x823A;\nconst RG16I = 0x8239;\nconst RG32UI = 0x823C;\nconst RG32I = 0x823B;\nconst RG8 = 0x822B;\nconst RG8_SNORM = 0x8F95;\nconst RG16F = 0x822F;\nconst RG32F = 0x8230;\nconst RG8UI = 0x8238;\nconst RG8I = 0x8237;\nconst R16UI = 0x8234;\nconst R16I = 0x8233;\nconst R32UI = 0x8236;\nconst R32I = 0x8235;\nconst RGB8 = 0x8051;\nconst SRGB8 = 0x8C41;\nconst RGB565 = 0x8D62;\nconst RGB8_SNORM = 0x8F96;\nconst R11F_G11F_B10F = 0x8C3A;\nconst RGB9_E5 = 0x8C3D;\nconst RGB16F = 0x881B;\nconst RGB32F = 0x8815;\nconst RGB8UI = 0x8D7D;\nconst RGB8I = 0x8D8F;\nconst RGB16UI = 0x8D77;\nconst RGB16I = 0x8D89;\nconst RGB32UI = 0x8D71;\nconst RGB32I = 0x8D83;\nconst RGBA8 = 0x8058;\nconst SRGB8_ALPHA8 = 0x8C43;\nconst RGBA8_SNORM = 0x8F97;\nconst RGB5_A1 = 0x8057;\nconst RGBA4 = 0x8056;\nconst RGB10_A2 = 0x8059;\nconst RGBA16F = 0x881A;\nconst RGBA32F = 0x8814;\nconst RGBA8UI = 0x8D7C;\nconst RGBA8I = 0x8D8E;\nconst RGB10_A2UI = 0x906F;\nconst RGBA16UI = 0x8D76;\nconst RGBA16I = 0x8D88;\nconst RGBA32I = 0x8D82;\nconst RGBA32UI = 0x8D70;\n\nconst DEPTH_COMPONENT16 = 0x81A5;\nconst DEPTH_COMPONENT24 = 0x81A6;\nconst DEPTH_COMPONENT32F = 0x8CAC;\nconst DEPTH32F_STENCIL8 = 0x8CAD;\nconst DEPTH24_STENCIL8 = 0x88F0;\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:(\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst RG = 0x8227;\nconst RG_INTEGER = 0x8228;\nconst RED = 0x1903;\nconst RED_INTEGER = 0x8D94;\nconst RGB_INTEGER = 0x8D98;\nconst RGBA_INTEGER = 0x8D99;\n\nconst formatInfo = {};\n{\n // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle\n // the name.\n const f = formatInfo;\n f[ALPHA] = { numColorComponents: 1, };\n f[LUMINANCE] = { numColorComponents: 1, };\n f[LUMINANCE_ALPHA] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RED] = { numColorComponents: 1, };\n f[RED_INTEGER] = { numColorComponents: 1, };\n f[RG] = { numColorComponents: 2, };\n f[RG_INTEGER] = { numColorComponents: 2, };\n f[RGB] = { numColorComponents: 3, };\n f[RGB_INTEGER] = { numColorComponents: 3, };\n f[RGBA] = { numColorComponents: 4, };\n f[RGBA_INTEGER] = { numColorComponents: 4, };\n f[DEPTH_COMPONENT] = { numColorComponents: 1, };\n f[DEPTH_STENCIL] = { numColorComponents: 2, };\n}\n\n/**\n * @typedef {Object} TextureFormatDetails\n * @property {number} textureFormat format to pass texImage2D and similar functions.\n * @property {boolean} colorRenderable true if you can render to this format of texture.\n * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`.\n * @property {number[]} type Array of possible types you can pass to texImage2D and similar function\n * @property {Object.} bytesPerElementMap A map of types to bytes per element\n * @private\n */\n\nlet s_textureInternalFormatInfo;\nfunction getTextureInternalFormatInfo(internalFormat) {\n if (!s_textureInternalFormatInfo) {\n // NOTE: these properties need unique names so we can let Uglify mangle the name.\n const t = {};\n // unsized formats\n t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT], };\n t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_5_6_5], };\n t[RGBA] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE, HALF_FLOAT, HALF_FLOAT_OES, FLOAT, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], };\n t[DEPTH_COMPONENT] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT, UNSIGNED_SHORT], };\n\n // sized formats\n t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], };\n t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT, HALF_FLOAT], };\n t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE], };\n t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], };\n t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT], };\n t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], };\n t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT], };\n t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], };\n t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT, HALF_FLOAT], };\n t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT], };\n t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE], };\n t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], };\n t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT], };\n t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], };\n t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT], };\n t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT], };\n t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB565] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5], };\n t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], };\n t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], };\n t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], };\n t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT, HALF_FLOAT], };\n t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT], };\n t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE], };\n t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], };\n t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT], };\n t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], };\n t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT], };\n t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT], };\n t[RGBA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[SRGB8_ALPHA8] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8_SNORM] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], };\n t[RGB5_A1] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA4] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4], };\n t[RGB10_A2] = { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT, HALF_FLOAT], };\n t[RGBA32F] = { textureFormat: RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT], };\n t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE], };\n t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], };\n t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], };\n t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT], };\n t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], };\n t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT], };\n t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT], };\n // Sized Internal\n t[DEPTH_COMPONENT16] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT, UNSIGNED_INT], };\n t[DEPTH_COMPONENT24] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT], };\n t[DEPTH_COMPONENT32F] = { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT], };\n t[DEPTH24_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], };\n t[DEPTH32F_STENCIL8] = { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], };\n\n Object.keys(t).forEach(function(internalFormat) {\n const info = t[internalFormat];\n info.bytesPerElementMap = {};\n info.bytesPerElement.forEach(function(bytesPerElement, ndx) {\n const type = info.type[ndx];\n info.bytesPerElementMap[type] = bytesPerElement;\n });\n });\n s_textureInternalFormatInfo = t;\n }\n return s_textureInternalFormatInfo[internalFormat];\n}\n\n/**\n * Gets the number of bytes per element for a given internalFormat / type\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @param {number} type The type parameter for texImage2D etc..\n * @return {number} the number of bytes per element for the given internalFormat, type combo\n * @memberOf module:twgl/textures\n */\nfunction getBytesPerElementForInternalFormat(internalFormat, type) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n const bytesPerElement = info.bytesPerElementMap[type];\n if (bytesPerElement === undefined) {\n throw \"unknown internal format\";\n }\n return bytesPerElement;\n}\n\n/**\n * Info related to a specific texture internalFormat as returned\n * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}.\n *\n * @typedef {Object} TextureFormatInfo\n * @property {number} format Format to pass to texImage2D and related functions\n * @property {number} type Type to pass to texImage2D and related functions\n * @memberOf module:twgl/textures\n */\n\n/**\n * Gets the format and type for a given internalFormat\n *\n * @param {number} internalFormat The internal format\n * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type,\n * @memberOf module:twgl/textures\n */\nfunction getFormatAndTypeForInternalFormat(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return {\n format: info.textureFormat,\n type: info.type[0],\n };\n}\n\n/**\n * Returns true if value is power of 2\n * @param {number} value number to check.\n * @return true if value is power of 2\n * @private\n */\nfunction isPowerOf2(value) {\n return (value & (value - 1)) === 0;\n}\n\n/**\n * Gets whether or not we can generate mips for the given\n * internal format.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number} width The width parameter from texImage2D etc..\n * @param {number} height The height parameter from texImage2D etc..\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canGenerateMipmap(gl, width, height, internalFormat) {\n if (!utils.isWebGL2(gl)) {\n return isPowerOf2(width) && isPowerOf2(height);\n }\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.colorRenderable && info.textureFilterable;\n}\n\n/**\n * Gets whether or not we can generate mips for the given format\n * @param {number} internalFormat The internalFormat parameter from texImage2D etc..\n * @return {boolean} true if we can generate mips\n * @memberOf module:twgl/textures\n */\nfunction canFilter(internalFormat) {\n const info = getTextureInternalFormatInfo(internalFormat);\n if (!info) {\n throw \"unknown internal format\";\n }\n return info.textureFilterable;\n}\n\n/**\n * Gets the number of components for a given image format.\n * @param {number} format the format.\n * @return {number} the number of components for the format.\n * @memberOf module:twgl/textures\n */\nfunction getNumComponentsForFormat(format) {\n const info = formatInfo[format];\n if (!info) {\n throw \"unknown format: \" + format;\n }\n return info.numColorComponents;\n}\n\n/**\n * Gets the texture type for a given array type.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @return {number} the gl texture type\n * @private\n */\nfunction getTextureTypeForArrayType(gl, src, defaultType) {\n if (isArrayBuffer(src)) {\n return typedArrays.getGLTypeForTypedArray(src);\n }\n return defaultType || UNSIGNED_BYTE;\n}\n\nfunction guessDimensions(gl, target, width, height, numElements) {\n if (numElements % 1 !== 0) {\n throw \"can't guess dimensions\";\n }\n if (!width && !height) {\n const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP ? 6 : 1));\n if (size % 1 === 0) {\n width = size;\n height = size;\n } else {\n width = numElements;\n height = 1;\n }\n } else if (!height) {\n height = numElements / width;\n if (height % 1) {\n throw \"can't guess dimensions\";\n }\n } else if (!width) {\n width = numElements / height;\n if (width % 1) {\n throw \"can't guess dimensions\";\n }\n }\n return {\n width: width,\n height: height,\n };\n}\n\n/**\n * Sets the default texture color.\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * @param {number[]} color Array of 4 values in the range 0 to 1\n * @deprecated see {@link module:twgl.setDefaults}\n * @memberOf module:twgl/textures\n */\nfunction setDefaultTextureColor(color) {\n defaults.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n if (newDefaults.textureColor) {\n setDefaultTextureColor(newDefaults.textureColor);\n }\n}\n\n/**\n * A function to generate the source for a texture.\n * @callback TextureFunc\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options the texture options\n * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}.\n * @memberOf module:twgl\n */\n\n/**\n * Texture options passed to most texture functions. Each function will use whatever options\n * are appropriate for its needs. This lets you pass the same options to all functions.\n *\n * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`,\n * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`.\n *\n * @typedef {Object} TextureOptions\n * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`.\n * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true.\n * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null.\n * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null.\n * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` .\n * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR`\n * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`.\n * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR`\n * @property {number} [minMag] both the min and mag filter settings.\n * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA`\n * @property {number} [format] format for texture. Defaults to `gl.RGBA`.\n * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src`\n * is ArrayBufferView defaults to type that matches ArrayBufferView type.\n * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube\n * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`.\n * @property {number} [minLod] TEXTURE_MIN_LOD setting\n * @property {number} [maxLod] TEXTURE_MAX_LOD setting\n * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting\n * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting\n * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting\n * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting\n * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1.\n * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously.\n * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults`\n * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink\n * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is.\n * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override\n * the current setting for specific textures.\n * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and\n * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above\n * then then `auto` is assumed to be `false` unless explicity set to `true`.\n * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is\n *\n * [gl.TEXTURE_CUBE_MAP_POSITIVE_X,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_X,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Y,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,\n * gl.TEXTURE_CUBE_MAP_POSITIVE_Z,\n * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]\n *\n * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture\n *\n * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable\n * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded.\n * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3.\n * The pieces will be uploaded in `cubeFaceOrder`\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map.\n *\n * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture\n * and will be scaled to the specified width and height OR to the size of the first image that loads.\n *\n * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`,\n * `HTMLCanvasElement`, `HTMLVideoElement`.\n *\n * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is\n * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents`\n * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided\n * by 6. Then\n *\n * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height\n * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`.\n *\n * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`.\n *\n * If `number[]` will be converted to `type`.\n *\n * If `src` is a function it will be called with a `WebGLRenderingContext` and these options.\n * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement`\n * an array etc...\n *\n * If `src` is undefined then an empty texture will be created of size `width` by `height`.\n *\n * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded.\n * default: undefined. Also see {@link module:twgl.setDefaults}.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Saves the current packing state, sets the packing state as specified\n * then calls a function, after which the packing state will be restored.\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {function():void} [fn] A function to call, after which the packing state will be restored.\n * @private\n */\nfunction scopedSetPackState(gl, options, fn) {\n let colorspaceConversion;\n let premultiplyAlpha;\n let flipY;\n\n if (options.colorspaceConversion !== undefined) {\n colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL);\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion);\n }\n if (options.premultiplyAlpha !== undefined) {\n premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL);\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha);\n }\n if (options.flipY !== undefined) {\n flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL);\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY);\n }\n\n fn();\n\n if (colorspaceConversion !== undefined) {\n gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion);\n }\n if (premultiplyAlpha !== undefined) {\n gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha);\n }\n if (flipY !== undefined) {\n gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY);\n }\n}\n\n/**\n * Set skip state to defaults\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @private\n */\nfunction setSkipStateToDefault(gl) {\n gl.pixelStorei(UNPACK_ALIGNMENT, 4);\n if (utils.isWebGL2(gl)) {\n gl.pixelStorei(UNPACK_ROW_LENGTH, 0);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_PIXELS, 0);\n gl.pixelStorei(UNPACK_SKIP_ROWS, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n }\n}\n\n/**\n * Sets the parameters of a texture or sampler\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {number|WebGLSampler} target texture target or sampler\n * @param {function()} parameteriFn texParameteri or samplerParameteri fn\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @private\n */\nfunction setTextureSamplerParameters(gl, target, parameteriFn, options) {\n if (options.minMag) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag);\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag);\n }\n if (options.min) {\n parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min);\n }\n if (options.mag) {\n parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag);\n }\n if (options.wrap) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap);\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap);\n if (target === TEXTURE_3D || helper.isSampler(gl, target)) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap);\n }\n }\n if (options.wrapR) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR);\n }\n if (options.wrapS) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS);\n }\n if (options.wrapT) {\n parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT);\n }\n if (options.minLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod);\n }\n if (options.maxLod !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod);\n }\n if (options.baseLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel);\n }\n if (options.maxLevel !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel);\n }\n if (options.compareFunc !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc);\n }\n if (options.compareMode !== undefined) {\n parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode);\n }\n}\n\n/**\n * Sets the texture parameters of a texture.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureParameters(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n setTextureSamplerParameters(gl, target, gl.texParameteri, options);\n}\n\n/**\n * Sets the sampler parameters of a sampler.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLSampler} sampler the WebGLSampler to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setSamplerParameters(gl, sampler, options) {\n setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options);\n}\n\n/**\n * Creates a new sampler object and sets parameters.\n *\n * Example:\n *\n * const sampler = twgl.createSampler(gl, {\n * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER\n * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per sampler.\n * @return {Object.} the created samplers by name\n * @private\n */\nfunction createSampler(gl, options) {\n const sampler = gl.createSampler();\n setSamplerParameters(gl, sampler, options);\n return sampler;\n}\n\n/**\n * Creates a multiple sampler objects and sets parameters on each.\n *\n * Example:\n *\n * const samplers = twgl.createSamplers(gl, {\n * nearest: {\n * minMag: gl.NEAREST,\n * },\n * nearestClampS: {\n * minMag: gl.NEAREST,\n * wrapS: gl.CLAMP_TO_NEAREST,\n * },\n * linear: {\n * minMag: gl.LINEAR,\n * },\n * nearestClamp: {\n * minMag: gl.NEAREST,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClamp: {\n * minMag: gl.LINEAR,\n * wrap: gl.CLAMP_TO_EDGE,\n * },\n * linearClampT: {\n * minMag: gl.LINEAR,\n * wrapT: gl.CLAMP_TO_EDGE,\n * },\n * });\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler\n * @private\n */\nfunction createSamplers(gl, samplerOptions) {\n const samplers = {};\n Object.keys(samplerOptions).forEach(function(name) {\n samplers[name] = createSampler(gl, samplerOptions[name]);\n });\n return samplers;\n}\n\n/**\n * Makes a 1x1 pixel\n * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`.\n * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values\n * @return {Uint8Array} Unit8Array with color.\n * @private\n */\nfunction make1Pixel(color) {\n color = color || defaults.textureColor;\n if (isArrayBuffer(color)) {\n return color;\n }\n return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]);\n}\n\n/**\n * Sets filtering or generates mips for texture based on width or height\n * If width or height is not passed in uses `options.width` and//or `options.height`\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @param {number} [width] width of texture\n * @param {number} [height] height of texture\n * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc..\n * @memberOf module:twgl/textures\n */\nfunction setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) {\n options = options || defaults.textureOptions;\n internalFormat = internalFormat || RGBA;\n const target = options.target || TEXTURE_2D;\n width = width || options.width;\n height = height || options.height;\n gl.bindTexture(target, tex);\n if (canGenerateMipmap(gl, width, height, internalFormat)) {\n gl.generateMipmap(target);\n } else {\n const filtering = canFilter(internalFormat) ? LINEAR : NEAREST;\n gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering);\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n}\n\nfunction shouldAutomaticallySetTextureFilteringForSize(options) {\n return options.auto === true || (options.auto === undefined && options.level === undefined);\n}\n\n/**\n * Gets an array of cubemap face enums\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @return {number[]} cubemap face enums\n * @private\n */\nfunction getCubeFaceOrder(gl, options) {\n options = options || {};\n return options.cubeFaceOrder || [\n TEXTURE_CUBE_MAP_POSITIVE_X,\n TEXTURE_CUBE_MAP_NEGATIVE_X,\n TEXTURE_CUBE_MAP_POSITIVE_Y,\n TEXTURE_CUBE_MAP_NEGATIVE_Y,\n TEXTURE_CUBE_MAP_POSITIVE_Z,\n TEXTURE_CUBE_MAP_NEGATIVE_Z,\n ];\n}\n\n/**\n * @typedef {Object} FaceInfo\n * @property {number} face gl enum for texImage2D\n * @property {number} ndx face index (0 - 5) into source data\n * @ignore\n */\n\n/**\n * Gets an array of FaceInfos\n * There's a bug in some NVidia drivers that will crash the driver if\n * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take\n * the user's desired order from his faces to WebGL and make sure we\n * do the faces in WebGL order\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but\n * it's needed internally to sort the array of `ndx` properties by `face`.\n * @private\n */\nfunction getCubeFacesWithNdx(gl, options) {\n const faces = getCubeFaceOrder(gl, options);\n // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :(\n const facesWithNdx = faces.map(function(face, ndx) {\n return { face: face, ndx: ndx };\n });\n facesWithNdx.sort(function(a, b) {\n return a.face - b.face;\n });\n return facesWithNdx;\n}\n\n/**\n * Set a texture from the contents of an element. Will also set\n * texture filtering or generate mips based on the dimensions of the element\n * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will\n * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {HTMLElement} element a canvas, img, or video element.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @kind function\n */\nfunction setTextureFromElement(gl, tex, element, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n const level = options.level || 0;\n let width = element.width;\n let height = element.height;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // guess the parts\n const imgWidth = element.width;\n const imgHeight = element.height;\n let size;\n let slices;\n if (imgWidth / 6 === imgHeight) {\n // It's 6x1\n size = imgHeight;\n slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0];\n } else if (imgHeight / 6 === imgWidth) {\n // It's 1x6\n size = imgWidth;\n slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5];\n } else if (imgWidth / 3 === imgHeight / 2) {\n // It's 3x2\n size = imgWidth / 3;\n slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1];\n } else if (imgWidth / 2 === imgHeight / 3) {\n // It's 2x3\n size = imgWidth / 2;\n slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2];\n } else {\n throw \"can't figure out cube map from element: \" + (element.src ? element.src : element.nodeName);\n }\n const ctx = getShared2DContext();\n if (ctx) {\n ctx.canvas.width = size;\n ctx.canvas.height = size;\n width = size;\n height = size;\n scopedSetPackState(gl, options, () => {\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size);\n gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas);\n });\n // Free up the canvas memory\n ctx.canvas.width = 1;\n ctx.canvas.height = 1;\n });\n } else if (typeof createImageBitmap !== 'undefined') {\n // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's\n // note lossy? (alpha is not premultiplied? although I'm not sure what\n width = size;\n height = size;\n getCubeFacesWithNdx(gl, options).forEach(function(f) {\n const xOffset = slices[f.ndx * 2 + 0] * size;\n const yOffset = slices[f.ndx * 2 + 1] * size;\n // We can't easily use a default texture color here as it would have to match\n // the type across all faces where as with a 2D one there's only one face\n // so we're replacing everything all at once. It also has to be the correct size.\n // On the other hand we need all faces to be the same size so as one face loads\n // the rest match else the texture will be un-renderable.\n gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null);\n createImageBitmap(element, xOffset, yOffset, size, size, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n })\n .then(function(imageBitmap) {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap);\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n });\n });\n });\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n scopedSetPackState(gl, options, () => {\n const smallest = Math.min(element.width, element.height);\n const largest = Math.max(element.width, element.height);\n const depth = largest / smallest;\n if (depth % 1 !== 0) {\n throw \"can not compute 3D dimensions of element\";\n }\n const xMult = element.width === largest ? 1 : 0;\n const yMult = element.height === largest ? 1 : 0;\n gl.pixelStorei(UNPACK_ALIGNMENT, 1);\n gl.pixelStorei(UNPACK_ROW_LENGTH, element.width);\n gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0);\n gl.pixelStorei(UNPACK_SKIP_IMAGES, 0);\n gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null);\n for (let d = 0; d < depth; ++d) {\n const srcX = d * smallest * xMult;\n const srcY = d * smallest * yMult;\n gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX);\n gl.pixelStorei(UNPACK_SKIP_ROWS, srcY);\n gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element);\n }\n setSkipStateToDefault(gl);\n });\n } else {\n scopedSetPackState(gl, options, () => {\n gl.texImage2D(target, level, internalFormat, format, type, element);\n });\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n}\n\nfunction noop() {\n}\n\n/**\n * Checks whether the url's origin is the same so that we can set the `crossOrigin`\n * @param {string} url url to image\n * @returns {boolean} true if the window's origin is the same as image's url\n * @private\n */\nfunction urlIsSameOrigin(url) {\n if (typeof document !== 'undefined') {\n // for IE really\n const a = document.createElement('a');\n a.href = url;\n return a.hostname === location.hostname &&\n a.port === location.port &&\n a.protocol === location.protocol;\n } else {\n const localOrigin = (new URL(location.href)).origin;\n const urlOrigin = (new URL(url, location.href)).origin;\n return urlOrigin === localOrigin;\n }\n}\n\nfunction setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) {\n return crossOrigin === undefined && !urlIsSameOrigin(url)\n ? 'anonymous'\n : crossOrigin;\n}\n\n/**\n * Loads an image\n * @param {string} url url to image\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @return {HTMLImageElement} the image being loaded.\n * @private\n */\nfunction loadImage(url, crossOrigin, callback) {\n callback = callback || noop;\n let img;\n crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults.crossOrigin;\n crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin);\n if (typeof Image !== 'undefined') {\n img = new Image();\n if (crossOrigin !== undefined) {\n img.crossOrigin = crossOrigin;\n }\n\n const clearEventHandlers = function clearEventHandlers() {\n img.removeEventListener('error', onError); // eslint-disable-line\n img.removeEventListener('load', onLoad); // eslint-disable-line\n img = null;\n };\n\n const onError = function onError() {\n const msg = \"couldn't load image: \" + url;\n helper.error(msg);\n callback(msg, img);\n clearEventHandlers();\n };\n\n const onLoad = function onLoad() {\n callback(null, img);\n clearEventHandlers();\n };\n\n img.addEventListener('error', onError);\n img.addEventListener('load', onLoad);\n img.src = url;\n return img;\n } else if (typeof ImageBitmap !== 'undefined') {\n let err;\n let bm;\n const cb = function cb() {\n callback(err, bm);\n };\n\n const options = {};\n if (crossOrigin) {\n options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin\n }\n fetch(url, options).then(function(response) {\n if (!response.ok) {\n throw response;\n }\n return response.blob();\n }).then(function(blob) {\n return createImageBitmap(blob, {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n });\n }).then(function(bitmap) {\n // not sure if this works. We don't want\n // to catch the user's error. So, call\n // the callback in a timeout so we're\n // not in this scope inside the promise.\n bm = bitmap;\n setTimeout(cb);\n }).catch(function(e) {\n err = e;\n setTimeout(cb);\n });\n img = null;\n }\n return img;\n}\n\n/**\n * check if object is a TexImageSource\n *\n * @param {Object} obj Object to test\n * @return {boolean} true if object is a TexImageSource\n * @private\n */\nfunction isTexImageSource(obj) {\n return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) ||\n (typeof ImageData !== 'undefined' && obj instanceof ImageData) ||\n (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement);\n}\n\n/**\n * if obj is an TexImageSource then just\n * uses it otherwise if obj is a string\n * then load it first.\n *\n * @param {string|TexImageSource} obj\n * @param {string} crossOrigin\n * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null\n * if there was an error\n * @private\n */\nfunction loadAndUseImage(obj, crossOrigin, callback) {\n if (isTexImageSource(obj)) {\n setTimeout(function() {\n callback(null, obj);\n });\n return obj;\n }\n\n return loadImage(obj, crossOrigin, callback);\n}\n\n/**\n * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set\n * the default texture color is used which can be set by calling `setDefaultTextureColor`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction setTextureTo1PixelColor(gl, tex, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n if (options.color === false) {\n return;\n }\n // Assume it's a URL\n // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering.\n const color = make1Pixel(options.color);\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, 0, RGBA, 1, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n } else {\n gl.texImage2D(target, 0, RGBA, 1, 1, 0, RGBA, UNSIGNED_BYTE, color);\n }\n}\n\n/**\n * The src image(s) used to create a texture.\n *\n * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures}\n * you can pass in urls for images to load into the textures. If it's a single url\n * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap\n * this will be a corresponding array of images for the cubemap.\n *\n * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback TextureReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} texture the texture.\n * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when all images have finished downloading and been uploaded into their respective textures\n * @callback TexturesReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}.\n * @param {Object.} sources the image(s) used for the texture by name.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback CubemapReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each face.\n * @memberOf module:twgl\n */\n\n/**\n * A callback for when an image finished downloading and been uploaded into a texture\n * @callback ThreeDReadyCallback\n * @param {*} err If truthy there was an error.\n * @param {WebGLTexture} tex the texture.\n * @param {HTMLImageElement[]} imgs the images for each slice.\n * @memberOf module:twgl\n */\n\n/**\n * Loads a texture from an image from a Url as specified in `options.src`\n * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is\n * immediately useable. It will be updated with the contents of the image once the image has finished\n * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will\n * be non null if there was an error.\n * @return {HTMLImageElement} the image being downloaded.\n * @memberOf module:twgl/textures\n */\nfunction loadTextureFromUrl(gl, tex, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) {\n if (err) {\n callback(err, tex, img);\n } else {\n setTextureFromElement(gl, tex, img, options);\n callback(null, tex, img);\n }\n });\n return img;\n}\n\n/**\n * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadCubemapFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n if (urls.length !== 6) {\n throw \"there must be 6 urls for a cubemap\";\n }\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D;\n if (target !== TEXTURE_CUBE_MAP) {\n throw \"target must be TEXTURE_CUBE_MAP\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = 6;\n const errors = [];\n const faces = getCubeFaceOrder(gl, options);\n let imgs; // eslint-disable-line\n\n function uploadImg(faceTarget) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n if (img.width !== img.height) {\n errors.push(\"cubemap face img is not a square: \" + img.src);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n // So assuming this is the first image we now have one face that's img sized\n // and 5 faces that are 1x1 pixel so size the other faces\n if (numToLoad === 5) {\n // use the default order\n getCubeFaceOrder(gl).forEach(function(otherTarget) {\n // Should we re-use the same face or a color?\n gl.texImage2D(otherTarget, level, internalFormat, format, type, img);\n });\n } else {\n gl.texImage2D(faceTarget, level, internalFormat, format, type, img);\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx]));\n });\n}\n\n/**\n * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`.\n * Will set the texture to a 1x1 pixel color\n * so that it is usable immediately unless `option.color === false`.\n *\n * If the width and height is not specified the width and height of the first\n * image loaded will be used. Note that since images are loaded async\n * which image downloads first is unknown.\n *\n * If an image is not the same size as the width and height it will be scaled\n * to that width and height.\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will\n * be non null if there was an error.\n * @memberOf module:twgl/textures\n * @private\n */\nfunction loadSlicesFromUrls(gl, tex, options, callback) {\n callback = callback || noop;\n const urls = options.src;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || UNSIGNED_BYTE;\n const target = options.target || TEXTURE_2D_ARRAY;\n if (target !== TEXTURE_3D && target !== TEXTURE_2D_ARRAY) {\n throw \"target must be TEXTURE_3D or TEXTURE_2D_ARRAY\";\n }\n setTextureTo1PixelColor(gl, tex, options);\n // Because it's async we need to copy the options.\n options = Object.assign({}, options);\n let numToLoad = urls.length;\n const errors = [];\n let imgs; // eslint-disable-line\n const level = options.level || 0;\n let width = options.width;\n let height = options.height;\n const depth = urls.length;\n let firstImage = true;\n\n function uploadImg(slice) {\n return function(err, img) {\n --numToLoad;\n if (err) {\n errors.push(err);\n } else {\n scopedSetPackState(gl, options, () => {\n gl.bindTexture(target, tex);\n\n if (firstImage) {\n firstImage = false;\n width = options.width || img.width;\n height = options.height || img.height;\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n\n // put it in every slice otherwise some slices will be 0,0,0,0\n for (let s = 0; s < depth; ++s) {\n gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img);\n }\n } else {\n let src = img;\n let ctx;\n if (img.width !== width || img.height !== height) {\n // Size the image to fix\n ctx = getShared2DContext();\n src = ctx.canvas;\n ctx.canvas.width = width;\n ctx.canvas.height = height;\n ctx.drawImage(img, 0, 0, width, height);\n }\n\n gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src);\n\n // free the canvas memory\n if (ctx && src === ctx.canvas) {\n ctx.canvas.width = 0;\n ctx.canvas.height = 0;\n }\n }\n\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n gl.generateMipmap(target);\n }\n });\n }\n\n if (numToLoad === 0) {\n callback(errors.length ? errors : undefined, tex, imgs);\n }\n };\n }\n\n imgs = urls.map(function(url, ndx) {\n return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx));\n });\n}\n\n/**\n * Sets a texture from an array or typed array. If the width or height is not provided will attempt to\n * guess the size. See {@link module:twgl.TextureOptions}.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data.\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * This is often the same options you passed in when you created the texture.\n * @memberOf module:twgl/textures\n */\nfunction setTextureFromArray(gl, tex, src, options) {\n options = options || defaults.textureOptions;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n let width = options.width;\n let height = options.height;\n let depth = options.depth;\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n if (!isArrayBuffer(src)) {\n const Type = typedArrays.getTypedArrayTypeForGLType(type);\n src = new Type(src);\n } else if (src instanceof Uint8ClampedArray) {\n src = new Uint8Array(src.buffer);\n }\n\n const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type);\n const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT?\n if (numElements % 1) {\n throw \"length wrong size for format: \" + utils.glEnumToString(gl, format);\n }\n let dimensions;\n if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n if (!width && !height && !depth) {\n const size = Math.cbrt(numElements);\n if (size % 1 !== 0) {\n throw \"can't guess cube size of array of numElements: \" + numElements;\n }\n width = size;\n height = size;\n depth = size;\n } else if (width && (!height || !depth)) {\n dimensions = guessDimensions(gl, target, height, depth, numElements / width);\n height = dimensions.width;\n depth = dimensions.height;\n } else if (height && (!width || !depth)) {\n dimensions = guessDimensions(gl, target, width, depth, numElements / height);\n width = dimensions.width;\n depth = dimensions.height;\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements / depth);\n width = dimensions.width;\n height = dimensions.height;\n }\n } else {\n dimensions = guessDimensions(gl, target, width, height, numElements);\n width = dimensions.width;\n height = dimensions.height;\n }\n setSkipStateToDefault(gl);\n gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1);\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT;\n const faceSize = numElements / 6 * elementsPerElement;\n\n getCubeFacesWithNdx(gl, options).forEach(f => {\n const offset = faceSize * f.ndx;\n const data = src.subarray(offset, offset + faceSize);\n gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data);\n });\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src);\n }\n });\n return {\n width: width,\n height: height,\n depth: depth,\n type: type,\n };\n}\n\n/**\n * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`.\n * You must set `options.width` and `options.height`.\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the WebGLTexture to set parameters for\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @memberOf module:twgl/textures\n */\nfunction setEmptyTexture(gl, tex, options) {\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n const type = options.type || formatType.type;\n scopedSetPackState(gl, options, () => {\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null);\n }\n });\n}\n\n/**\n * Creates a texture based on the options passed in.\n *\n * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES\n * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set.\n * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture.\n * @return {WebGLTexture} the created texture.\n * @memberOf module:twgl/textures\n */\nfunction createTexture(gl, options, callback) {\n callback = callback || noop;\n options = options || defaults.textureOptions;\n const tex = gl.createTexture();\n const target = options.target || TEXTURE_2D;\n let width = options.width || 1;\n let height = options.height || 1;\n const internalFormat = options.internalFormat || RGBA;\n gl.bindTexture(target, tex);\n if (target === TEXTURE_CUBE_MAP) {\n // this should have been the default for cubemaps :(\n gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE);\n gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE);\n }\n let src = options.src;\n if (src) {\n if (typeof src === \"function\") {\n src = src(gl, options);\n }\n if (typeof (src) === \"string\") {\n loadTextureFromUrl(gl, tex, options, callback);\n } else if (isArrayBuffer(src) ||\n (Array.isArray(src) && (\n typeof src[0] === 'number' ||\n Array.isArray(src[0]) ||\n isArrayBuffer(src[0]))\n )\n ) {\n const dimensions = setTextureFromArray(gl, tex, src, options);\n width = dimensions.width;\n height = dimensions.height;\n } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) {\n if (target === TEXTURE_CUBE_MAP) {\n loadCubemapFromUrls(gl, tex, options, callback);\n } else {\n loadSlicesFromUrls(gl, tex, options, callback);\n }\n } else { // if (isTexImageSource(src))\n setTextureFromElement(gl, tex, src, options);\n width = src.width;\n height = src.height;\n }\n } else {\n setEmptyTexture(gl, tex, options);\n }\n if (shouldAutomaticallySetTextureFilteringForSize(options)) {\n setTextureFilteringForSize(gl, tex, options, width, height, internalFormat);\n }\n setTextureParameters(gl, tex, options);\n return tex;\n}\n\n/**\n * Resizes a texture based on the options passed in.\n *\n * Note: This is not a generic resize anything function.\n * It's mostly used by {@link module:twgl.resizeFramebufferInfo}\n * It will use `options.src` if it exists to try to determine a `type`\n * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided\n * for the texture. Texture parameters will be set accordingly\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {WebGLTexture} tex the texture to resize\n * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set.\n * @param {number} [width] the new width. If not passed in will use `options.width`\n * @param {number} [height] the new height. If not passed in will use `options.height`\n * @param {number} [depth] the new depth. If not passed in will use `options.depth`\n * @memberOf module:twgl/textures\n */\nfunction resizeTexture(gl, tex, options, width, height, depth) {\n width = width || options.width;\n height = height || options.height;\n depth = depth || options.depth;\n const target = options.target || TEXTURE_2D;\n gl.bindTexture(target, tex);\n const level = options.level || 0;\n const internalFormat = options.internalFormat || options.format || RGBA;\n const formatType = getFormatAndTypeForInternalFormat(internalFormat);\n const format = options.format || formatType.format;\n let type;\n const src = options.src;\n if (!src) {\n type = options.type || formatType.type;\n } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) {\n type = options.type || getTextureTypeForArrayType(gl, src, formatType.type);\n } else {\n type = options.type || formatType.type;\n }\n if (target === TEXTURE_CUBE_MAP) {\n for (let ii = 0; ii < 6; ++ii) {\n gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null);\n }\n } else if (target === TEXTURE_3D || target === TEXTURE_2D_ARRAY) {\n gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null);\n } else {\n gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null);\n }\n}\n\n/**\n * Check if a src is an async request.\n * if src is a string we're going to download an image\n * if src is an array of strings we're going to download cubemap images\n * @param {*} src The src from a TextureOptions\n * @returns {bool} true if src is async.\n * @private\n */\nfunction isAsyncSrc(src) {\n return typeof src === 'string' ||\n (Array.isArray(src) && typeof src[0] === 'string');\n}\n\n/**\n * Creates a bunch of textures based on the passed in options.\n *\n * Example:\n *\n * const textures = twgl.createTextures(gl, {\n * // a power of 2 image\n * hftIcon: { src: \"images/hft-icon-16.png\", mag: gl.NEAREST },\n * // a non-power of 2 image\n * clover: { src: \"images/clover.jpg\" },\n * // From a canvas\n * fromCanvas: { src: ctx.canvas },\n * // A cubemap from 6 images\n * yokohama: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: [\n * 'images/yokohama/posx.jpg',\n * 'images/yokohama/negx.jpg',\n * 'images/yokohama/posy.jpg',\n * 'images/yokohama/negy.jpg',\n * 'images/yokohama/posz.jpg',\n * 'images/yokohama/negz.jpg',\n * ],\n * },\n * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1)\n * goldengate: {\n * target: gl.TEXTURE_CUBE_MAP,\n * src: 'images/goldengate.jpg',\n * },\n * // A 2x2 pixel texture from a JavaScript array\n * checker: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * src: [\n * 255,255,255,255,\n * 192,192,192,255,\n * 192,192,192,255,\n * 255,255,255,255,\n * ],\n * },\n * // a 1x2 pixel texture from a typed array.\n * stripe: {\n * mag: gl.NEAREST,\n * min: gl.LINEAR,\n * format: gl.LUMINANCE,\n * src: new Uint8Array([\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * 255,\n * 128,\n * ]),\n * width: 1,\n * },\n * });\n *\n * Now\n *\n * * `textures.hftIcon` will be a 2d texture\n * * `textures.clover` will be a 2d texture\n * * `textures.fromCanvas` will be a 2d texture\n * * `textures.yohohama` will be a cubemap texture\n * * `textures.goldengate` will be a cubemap texture\n * * `textures.checker` will be a 2d texture\n * * `textures.stripe` will be a 2d texture\n *\n * @param {WebGLRenderingContext} gl the WebGLRenderingContext\n * @param {Object.} options A object of TextureOptions one per texture.\n * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded.\n * @return {Object.} the created textures by name\n * @memberOf module:twgl/textures\n */\nfunction createTextures(gl, textureOptions, callback) {\n callback = callback || noop;\n let numDownloading = 0;\n const errors = [];\n const textures = {};\n const images = {};\n\n function callCallbackIfReady() {\n if (numDownloading === 0) {\n setTimeout(function() {\n callback(errors.length ? errors : undefined, textures, images);\n }, 0);\n }\n }\n\n Object.keys(textureOptions).forEach(function(name) {\n const options = textureOptions[name];\n let onLoadFn;\n if (isAsyncSrc(options.src)) {\n onLoadFn = function(err, tex, img) {\n images[name] = img;\n --numDownloading;\n if (err) {\n errors.push(err);\n }\n callCallbackIfReady();\n };\n ++numDownloading;\n }\n textures[name] = createTexture(gl, options, onLoadFn);\n });\n\n // queue the callback if there are no images to download.\n // We do this because if your code is structured to wait for\n // images to download but then you comment out all the async\n // images your code would break.\n callCallbackIfReady();\n\n return textures;\n}\n\nexport {\n setDefaults as setTextureDefaults_,\n\n createSampler,\n createSamplers,\n setSamplerParameters,\n\n createTexture,\n setEmptyTexture,\n setTextureFromArray,\n loadTextureFromUrl,\n setTextureFromElement,\n setTextureFilteringForSize,\n setTextureParameters,\n setDefaultTextureColor,\n createTextures,\n resizeTexture,\n\n canGenerateMipmap,\n canFilter,\n getNumComponentsForFormat,\n getBytesPerElementForInternalFormat,\n getFormatAndTypeForInternalFormat,\n};\n\n","export * from './twgl.js';\n\n\n\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as attributes from './attributes.js';\nimport * as textures from './textures.js';\nimport * as helper from './helper.js';\nimport * as utils from './utils.js';\n\nimport * as draw from './draw.js';\nimport * as framebuffers from './framebuffers.js';\nimport * as programs from './programs.js';\nimport * as typedarrays from './typedarrays.js';\nimport * as vertexArrays from './vertex-arrays.js';\n\n/**\n * The main TWGL module.\n *\n * For most use cases you shouldn't need anything outside this module.\n * Exceptions between the stuff added to twgl-full (v3, m4, primitives)\n *\n * @module twgl\n * @borrows module:twgl/attributes.setAttribInfoBufferFromArray as setAttribInfoBufferFromArray\n * @borrows module:twgl/attributes.createBufferInfoFromArrays as createBufferInfoFromArrays\n * @borrows module:twgl/attributes.createVertexArrayInfo as createVertexArrayInfo\n * @borrows module:twgl/draw.drawBufferInfo as drawBufferInfo\n * @borrows module:twgl/draw.drawObjectList as drawObjectList\n * @borrows module:twgl/framebuffers.createFramebufferInfo as createFramebufferInfo\n * @borrows module:twgl/framebuffers.resizeFramebufferInfo as resizeFramebufferInfo\n * @borrows module:twgl/framebuffers.bindFramebufferInfo as bindFramebufferInfo\n * @borrows module:twgl/programs.createProgramInfo as createProgramInfo\n * @borrows module:twgl/programs.createUniformBlockInfo as createUniformBlockInfo\n * @borrows module:twgl/programs.bindUniformBlock as bindUniformBlock\n * @borrows module:twgl/programs.setUniformBlock as setUniformBlock\n * @borrows module:twgl/programs.setBlockUniforms as setBlockUniforms\n * @borrows module:twgl/programs.setUniforms as setUniforms\n * @borrows module:twgl/programs.setBuffersAndAttributes as setBuffersAndAttributes\n * @borrows module:twgl/textures.setTextureFromArray as setTextureFromArray\n * @borrows module:twgl/textures.createTexture as createTexture\n * @borrows module:twgl/textures.resizeTexture as resizeTexture\n * @borrows module:twgl/textures.createTextures as createTextures\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\nconst defaults = {\n addExtensionsToContext: true,\n};\n\n/**\n * Various default settings for twgl.\n *\n * Note: You can call this any number of times. Example:\n *\n * twgl.setDefaults({ textureColor: [1, 0, 0, 1] });\n * twgl.setDefaults({ attribPrefix: 'a_' });\n *\n * is equivalent to\n *\n * twgl.setDefaults({\n * textureColor: [1, 0, 0, 1],\n * attribPrefix: 'a_',\n * });\n *\n * @typedef {Object} Defaults\n * @property {string} [attribPrefix] The prefix to stick on attributes\n *\n * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_`\n * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names.\n *\n * In other words I'll create arrays of geometry like this\n *\n * const arrays = {\n * position: ...\n * normal: ...\n * texcoord: ...\n * };\n *\n * But need those mapped to attributes and my attributes start with `a_`.\n *\n * Default: `\"\"`\n *\n * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1\n *\n * The default texture color is used when loading textures from\n * urls. Because the URL will be loaded async we'd like to be\n * able to use the texture immediately. By putting a 1x1 pixel\n * color in the texture we can start using the texture before\n * the URL has loaded.\n *\n * Default: `[0.5, 0.75, 1, 1]`\n *\n * @property {string} [crossOrigin]\n *\n * If not undefined sets the crossOrigin attribute on images\n * that twgl creates when downloading images for textures.\n *\n * Also see {@link module:twgl.TextureOptions}.\n *\n * @property {bool} [addExtensionsToContext]\n *\n * If true, then, when twgl will try to add any supported WebGL extensions\n * directly to the context under their normal GL names. For example\n * if ANGLE_instances_arrays exists then twgl would enable it,\n * add the functions `vertexAttribDivisor`, `drawArraysInstanced`,\n * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR`\n * to the `WebGLRenderingContext`.\n *\n * @memberOf module:twgl\n */\n\n/**\n * Sets various defaults for twgl.\n *\n * In the interest of terseness which is kind of the point\n * of twgl I've integrated a few of the older functions here\n *\n * @param {module:twgl.Defaults} newDefaults The default settings.\n * @memberOf module:twgl\n */\nfunction setDefaults(newDefaults) {\n helper.copyExistingProperties(newDefaults, defaults);\n attributes.setAttributeDefaults_(newDefaults); // eslint-disable-line\n textures.setTextureDefaults_(newDefaults); // eslint-disable-line\n}\n\nconst prefixRE = /^(.*?)_/;\nfunction addExtensionToContext(gl, extensionName) {\n utils.glEnumToString(gl, 0);\n const ext = gl.getExtension(extensionName);\n if (ext) {\n const enums = {};\n const fnSuffix = prefixRE.exec(extensionName)[1];\n const enumSuffix = '_' + fnSuffix;\n for (const key in ext) {\n const value = ext[key];\n const isFunc = typeof (value) === 'function';\n const suffix = isFunc ? fnSuffix : enumSuffix;\n let name = key;\n // examples of where this is not true are WEBGL_compressed_texture_s3tc\n // and WEBGL_compressed_texture_pvrtc\n if (key.endsWith(suffix)) {\n name = key.substring(0, key.length - suffix.length);\n }\n if (gl[name] !== undefined) {\n if (!isFunc && gl[name] !== value) {\n helper.warn(name, gl[name], value, key);\n }\n } else {\n if (isFunc) {\n gl[name] = function(origFn) {\n return function() {\n return origFn.apply(ext, arguments);\n };\n }(value);\n } else {\n gl[name] = value;\n enums[name] = value;\n }\n }\n }\n // pass the modified enums to glEnumToString\n enums.constructor = {\n name: ext.constructor.name,\n };\n utils.glEnumToString(enums, 0);\n }\n return ext;\n}\n\n/*\n * If you're wondering why the code doesn't just iterate\n * over all extensions using `gl.getExtensions` is that it's possible\n * some future extension is incompatible with this code. Rather than\n * have thing suddenly break it seems better to manually add to this\n * list.\n *\n */\nconst supportedExtensions = [\n 'ANGLE_instanced_arrays',\n 'EXT_blend_minmax',\n 'EXT_color_buffer_float',\n 'EXT_color_buffer_half_float',\n 'EXT_disjoint_timer_query',\n 'EXT_disjoint_timer_query_webgl2',\n 'EXT_frag_depth',\n 'EXT_sRGB',\n 'EXT_shader_texture_lod',\n 'EXT_texture_filter_anisotropic',\n 'OES_element_index_uint',\n 'OES_standard_derivatives',\n 'OES_texture_float',\n 'OES_texture_float_linear',\n 'OES_texture_half_float',\n 'OES_texture_half_float_linear',\n 'OES_vertex_array_object',\n 'WEBGL_color_buffer_float',\n 'WEBGL_compressed_texture_atc',\n 'WEBGL_compressed_texture_etc1',\n 'WEBGL_compressed_texture_pvrtc',\n 'WEBGL_compressed_texture_s3tc',\n 'WEBGL_compressed_texture_s3tc_srgb',\n 'WEBGL_depth_texture',\n 'WEBGL_draw_buffers',\n];\n\n/**\n * Attempts to enable all of the following extensions\n * and add their functions and constants to the\n * `WebGLRenderingContext` using their normal non-extension like names.\n *\n * ANGLE_instanced_arrays\n * EXT_blend_minmax\n * EXT_color_buffer_float\n * EXT_color_buffer_half_float\n * EXT_disjoint_timer_query\n * EXT_disjoint_timer_query_webgl2\n * EXT_frag_depth\n * EXT_sRGB\n * EXT_shader_texture_lod\n * EXT_texture_filter_anisotropic\n * OES_element_index_uint\n * OES_standard_derivatives\n * OES_texture_float\n * OES_texture_float_linear\n * OES_texture_half_float\n * OES_texture_half_float_linear\n * OES_vertex_array_object\n * WEBGL_color_buffer_float\n * WEBGL_compressed_texture_atc\n * WEBGL_compressed_texture_etc1\n * WEBGL_compressed_texture_pvrtc\n * WEBGL_compressed_texture_s3tc\n * WEBGL_compressed_texture_s3tc_srgb\n * WEBGL_depth_texture\n * WEBGL_draw_buffers\n *\n * For example if `ANGLE_instanced_arrays` exists then the functions\n * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor`\n * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the\n * `WebGLRenderingContext`.\n *\n * Note that if you want to know if the extension exists you should\n * probably call `gl.getExtension` for each extension. Alternatively\n * you can check for the existence of the functions or constants that\n * are expected to be added. For example\n *\n * if (gl.drawBuffers) {\n * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2\n * ....\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @memberOf module:twgl\n */\nfunction addExtensionsToContext(gl) {\n for (let ii = 0; ii < supportedExtensions.length; ++ii) {\n addExtensionToContext(gl, supportedExtensions[ii]);\n }\n}\n\n/**\n * Creates a webgl context.\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n * @private\n */\nfunction create3DContext(canvas, opt_attribs) {\n const names = [\"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL1 context.\n *\n * Note: Will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n * @deprecated\n * @private\n */\nfunction getWebGLContext(canvas, opt_attribs) {\n const gl = create3DContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Creates a webgl context.\n *\n * Will return a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * twgl.isWebGL2(gl);\n *\n * @param {HTMLCanvasElement} canvas The canvas tag to get\n * context from. If one is not passed in one will be\n * created.\n * @return {WebGLRenderingContext} The created context.\n */\nfunction createContext(canvas, opt_attribs) {\n const names = [\"webgl2\", \"webgl\", \"experimental-webgl\"];\n let context = null;\n for (let ii = 0; ii < names.length; ++ii) {\n context = canvas.getContext(names[ii], opt_attribs);\n if (context) {\n if (defaults.addExtensionsToContext) {\n addExtensionsToContext(context);\n }\n break;\n }\n }\n return context;\n}\n\n/**\n * Gets a WebGL context. Will create a WebGL2 context if possible.\n *\n * You can check if it's WebGL2 with\n *\n * function isWebGL2(gl) {\n * return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0 \") == 0;\n * }\n *\n * Note: For a WebGL1 context will attempt to enable Vertex Array Objects\n * and add WebGL2 entry points. (unless you first set defaults with\n * `twgl.setDefaults({enableVertexArrayObjects: false})`;\n *\n * @param {HTMLCanvasElement} canvas a canvas element.\n * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes\n * @return {WebGLRenderingContext} The created context.\n * @memberOf module:twgl\n */\nfunction getContext(canvas, opt_attribs) {\n const gl = createContext(canvas, opt_attribs);\n return gl;\n}\n\n/**\n * Resize a canvas to match the size it's displayed.\n * @param {HTMLCanvasElement} canvas The canvas to resize.\n * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to.\n * @return {boolean} true if the canvas was resized.\n * @memberOf module:twgl\n */\nfunction resizeCanvasToDisplaySize(canvas, multiplier) {\n multiplier = multiplier || 1;\n multiplier = Math.max(0, multiplier);\n const width = canvas.clientWidth * multiplier | 0;\n const height = canvas.clientHeight * multiplier | 0;\n if (canvas.width !== width || canvas.height !== height) {\n canvas.width = width;\n canvas.height = height;\n return true;\n }\n return false;\n}\n\nexport {\n addExtensionsToContext,\n getContext,\n getWebGLContext,\n resizeCanvasToDisplaySize,\n setDefaults,\n\n attributes,\n draw,\n framebuffers,\n programs,\n textures,\n typedarrays,\n utils,\n vertexArrays,\n};\n\n// function notPrivate(name) {\n// return name[name.length - 1] !== '_';\n// }\n//\n// function copyPublicProperties(src, dst) {\n// Object.keys(src).filter(notPrivate).forEach(function(key) {\n// dst[key] = src[key];\n// });\n// return dst;\n// }\n\nexport * from './attributes.js';\nexport * from './draw.js';\nexport * from './framebuffers.js';\nexport * from './programs.js';\nexport * from './textures.js';\nexport * from './typedarrays.js';\nexport * from './utils.js';\nexport * from './vertex-arrays.js';\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Low level shader typed array related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.typedArray` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/typedArray\n */\n\n// make sure we don't see a global gl\nconst gl = undefined; /* eslint-disable-line */\n\n/* DataType */\nconst BYTE = 0x1400;\nconst UNSIGNED_BYTE = 0x1401;\nconst SHORT = 0x1402;\nconst UNSIGNED_SHORT = 0x1403;\nconst INT = 0x1404;\nconst UNSIGNED_INT = 0x1405;\nconst FLOAT = 0x1406;\nconst UNSIGNED_SHORT_4_4_4_4 = 0x8033;\nconst UNSIGNED_SHORT_5_5_5_1 = 0x8034;\nconst UNSIGNED_SHORT_5_6_5 = 0x8363;\nconst HALF_FLOAT = 0x140B;\nconst UNSIGNED_INT_2_10_10_10_REV = 0x8368;\nconst UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B;\nconst UNSIGNED_INT_5_9_9_9_REV = 0x8C3E;\nconst FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD;\nconst UNSIGNED_INT_24_8 = 0x84FA;\n\nconst glTypeToTypedArray = {};\n{\n const tt = glTypeToTypedArray;\n tt[BYTE] = Int8Array;\n tt[UNSIGNED_BYTE] = Uint8Array;\n tt[SHORT] = Int16Array;\n tt[UNSIGNED_SHORT] = Uint16Array;\n tt[INT] = Int32Array;\n tt[UNSIGNED_INT] = Uint32Array;\n tt[FLOAT] = Float32Array;\n tt[UNSIGNED_SHORT_4_4_4_4] = Uint16Array;\n tt[UNSIGNED_SHORT_5_5_5_1] = Uint16Array;\n tt[UNSIGNED_SHORT_5_6_5] = Uint16Array;\n tt[HALF_FLOAT] = Uint16Array;\n tt[UNSIGNED_INT_2_10_10_10_REV] = Uint32Array;\n tt[UNSIGNED_INT_10F_11F_11F_REV] = Uint32Array;\n tt[UNSIGNED_INT_5_9_9_9_REV] = Uint32Array;\n tt[FLOAT_32_UNSIGNED_INT_24_8_REV] = Uint32Array;\n tt[UNSIGNED_INT_24_8] = Uint32Array;\n}\n\n/**\n * Get the GL type for a typedArray\n * @param {ArrayBufferView} typedArray a typedArray\n * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will\n * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArray(typedArray) {\n if (typedArray instanceof Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArray instanceof Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArray instanceof Int32Array) { return INT; } // eslint-disable-line\n if (typedArray instanceof Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArray instanceof Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the GL type for a typedArray type\n * @param {ArrayBufferView} typedArrayType a typedArray constructor\n * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will\n * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned\n * @memberOf module:twgl/typedArray\n */\nfunction getGLTypeForTypedArrayType(typedArrayType) {\n if (typedArrayType === Int8Array) { return BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE; } // eslint-disable-line\n if (typedArrayType === Int16Array) { return SHORT; } // eslint-disable-line\n if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT; } // eslint-disable-line\n if (typedArrayType === Int32Array) { return INT; } // eslint-disable-line\n if (typedArrayType === Uint32Array) { return UNSIGNED_INT; } // eslint-disable-line\n if (typedArrayType === Float32Array) { return FLOAT; } // eslint-disable-line\n throw new Error('unsupported typed array type');\n}\n\n/**\n * Get the typed array constructor for a given GL type\n * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`)\n * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`).\n * @memberOf module:twgl/typedArray\n */\nfunction getTypedArrayTypeForGLType(type) {\n const CTOR = glTypeToTypedArray[type];\n if (!CTOR) {\n throw new Error('unknown gl type');\n }\n return CTOR;\n}\n\nconst isArrayBuffer = typeof SharedArrayBuffer !== 'undefined'\n ? function isArrayBufferOrSharedArrayBuffer(a) {\n return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer);\n }\n : function isArrayBuffer(a) {\n return a && a.buffer && a.buffer instanceof ArrayBuffer;\n };\n\nexport {\n getGLTypeForTypedArray,\n getGLTypeForTypedArrayType,\n getTypedArrayTypeForGLType,\n isArrayBuffer,\n};\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\n/**\n * Gets the gl version as a number\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {number} version of gl\n * @private\n */\n//function getVersionAsNumber(gl) {\n// return parseFloat(gl.getParameter(gl.VERSION).substr(6));\n//}\n\n/**\n * Check if context is WebGL 2.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 2.0\n * @memberOf module:twgl\n */\nfunction isWebGL2(gl) {\n // This is the correct check but it's slow\n // return gl.getParameter(gl.VERSION).indexOf(\"WebGL 2.0\") === 0;\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGL2RenderingContext;\n return !!gl.texStorage2D;\n}\n\n/**\n * Check if context is WebGL 1.0\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @return {bool} true if it's WebGL 1.0\n * @memberOf module:twgl\n */\nfunction isWebGL1(gl) {\n // This is the correct check but it's slow\n // const version = getVersionAsNumber(gl);\n // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96\n // This might also be the correct check but I'm assuming it's slow-ish\n // return gl instanceof WebGLRenderingContext;\n return !gl.texStorage2D;\n}\n\n/**\n * Gets a string for WebGL enum\n *\n * Note: Several enums are the same. Without more\n * context (which function) it's impossible to always\n * give the correct enum. As it is, for matching values\n * it gives all enums. Checking the WebGL2RenderingContext\n * that means\n *\n * 0 = ZERO | POINT | NONE | NO_ERROR\n * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT\n * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB\n * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING\n * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING\n * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING\n *\n * It's also not useful for bits really unless you pass in individual bits.\n * In other words\n *\n * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT;\n * twgl.glEnumToString(gl, bits); // not going to work\n *\n * Note that some enums only exist on extensions. If you\n * want them to show up you need to pass the extension at least\n * once. For example\n *\n * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc');\n * if (ext) {\n * twgl.glEnumToString(ext, 0); // just prime the function\n *\n * ..later..\n *\n * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT;\n * console.log(twgl.glEnumToString(gl, internalFormat));\n *\n * Notice I didn't have to pass the extension the second time. This means\n * you can have place that generically gets an enum for texture formats for example.\n * and as long as you primed the function with the extensions\n *\n * If you're using `twgl.addExtensionsToContext` to enable your extensions\n * then twgl will automatically get the extension's enums.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object\n * @param {number} value the value of the enum you want to look up.\n * @return {string} enum string or hex value\n * @memberOf module:twgl\n * @function glEnumToString\n */\nconst glEnumToString = (function() {\n const haveEnumsForType = {};\n const enums = {};\n\n function addEnums(gl) {\n const type = gl.constructor.name;\n if (!haveEnumsForType[type]) {\n for (const key in gl) {\n if (typeof gl[key] === 'number') {\n const existing = enums[gl[key]];\n enums[gl[key]] = existing ? `${existing} | ${key}` : key;\n }\n }\n haveEnumsForType[type] = true;\n }\n }\n\n return function glEnumToString(gl, value) {\n addEnums(gl);\n return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value);\n };\n}());\n\nexport {\n glEnumToString,\n isWebGL1,\n isWebGL2,\n};\n\n\n","/*\n * Copyright 2019 Gregg Tavares\n *\n * Permission is hereby granted, free of charge, to any person obtaining a\n * copy of this software and associated documentation files (the \"Software\"),\n * to deal in the Software without restriction, including without limitation\n * the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n * DEALINGS IN THE SOFTWARE.\n */\n\nimport * as programs from './programs.js';\n\n/**\n * vertex array object related functions\n *\n * You should generally not need to use these functions. They are provided\n * for those cases where you're doing something out of the ordinary\n * and you need lower level access.\n *\n * For backward compatibility they are available at both `twgl.attributes` and `twgl`\n * itself\n *\n * See {@link module:twgl} for core functions\n *\n * @module twgl/vertexArrays\n */\n\nconst ELEMENT_ARRAY_BUFFER = 0x8893;\n\n/**\n * @typedef {Object} VertexArrayInfo\n * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`.\n * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc..\n * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object\n * @memberOf module:twgl\n */\n\n/**\n * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos\n *\n * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to\n * {@link module:twgl:drawBufferInfo}.\n *\n * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects\n * assign buffers to specific attributes at creation time. That means they can only be used with programs\n * who's attributes use the same attribute locations for the same purposes.\n *\n * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo}\n * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match.\n *\n * also\n *\n * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object\n * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES**\n * will affect the Vertex Array Object state.\n *\n * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER.\n *\n * @param {WebGLRenderingContext} gl A WebGLRenderingContext\n * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n *\n * You need to make sure every attribute that will be used is bound. So for example assume shader 1\n * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo\n * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't\n * now attribute D's location.\n *\n * So, you can pass in both shader 1 and shader 2's programInfo\n *\n * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVertexArrayInfo(gl, programInfos, bufferInfo) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n if (!programInfos.length) {\n programInfos = [programInfos];\n }\n programInfos.forEach(function(programInfo) {\n programs.setBuffersAndAttributes(gl, programInfo, bufferInfo);\n });\n gl.bindVertexArray(null);\n return {\n numElements: bufferInfo.numElements,\n elementType: bufferInfo.elementType,\n vertexArrayObject: vao,\n };\n}\n\n/**\n * Creates a vertex array object and then sets the attributes on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use.\n * @param {Object.} setters Attribute setters as returned from createAttributeSetters\n * @param {Object.} attribs AttribInfos mapped by attribute name.\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOAndSetAttributes(gl, setters, attribs, indices) {\n const vao = gl.createVertexArray();\n gl.bindVertexArray(vao);\n programs.setAttributes(setters, attribs);\n if (indices) {\n gl.bindBuffer(ELEMENT_ARRAY_BUFFER, indices);\n }\n // We unbind this because otherwise any change to ELEMENT_ARRAY_BUFFER\n // like when creating buffers for other stuff will mess up this VAO's binding\n gl.bindVertexArray(null);\n return vao;\n}\n\n/**\n * Creates a vertex array object and then sets the attributes\n * on it\n *\n * @param {WebGLRenderingContext} gl The WebGLRenderingContext\n * to use.\n * @param {Object.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters\n * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc...\n * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices\n *\n * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject\n *\n * @memberOf module:twgl/vertexArrays\n */\nfunction createVAOFromBufferInfo(gl, programInfo, bufferInfo) {\n return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices);\n}\n\nexport {\n createVertexArrayInfo,\n createVAOAndSetAttributes,\n createVAOFromBufferInfo,\n};\n\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = __webpack_require__(\"./src/twgl-base.js\");\n",""],"names":["typedArrays","_interopRequireWildcard","require","helper","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","_typeof","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","prototype","hasOwnProperty","call","i","set","STATIC_DRAW","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","BUFFER_SIZE","BYTE","UNSIGNED_BYTE","SHORT","UNSIGNED_SHORT","INT","UNSIGNED_INT","FLOAT","gl","undefined","defaults","attribPrefix","setAttributePrefix","prefix","setDefaults","newDefaults","copyExistingProperties","setBufferFromTypedArray","type","buffer","array","drawType","bindBuffer","bufferData","createBufferFromTypedArray","typedArray","isBuffer","createBuffer","isIndices","name","getNormalizationForTypedArrayType","typedArrayType","Int8Array","Uint8Array","getArray","length","data","texcoordRE","colorRE","guessNumComponentsFromName","numComponents","test","Error","concat","getNumComponents","arrayName","numValues","size","makeTypedArray","isArrayBuffer","Array","isArray","Type","typedArrayTypeFromGLTypeOrTypedArrayCtor","Uint16Array","Float32Array","glTypeFromGLTypeOrTypedArrayType","glTypeOrTypedArrayCtor","getGLTypeForTypedArrayType","getTypedArrayTypeForGLType","attribBufferFromBuffer","arrayType","attribBufferFromSize","numBytes","BYTES_PER_ELEMENT","attribBufferFromArrayLike","constructor","getGLTypeForTypedArray","createAttribsFromArrays","arrays","attribs","keys","forEach","attribName","attrib","value","fn","WebGLBuffer","_fn","normalization","normalize","stride","offset","divisor","setAttribInfoBufferFromArray","attribInfo","bufferSubData","getBytesPerValueForGLType","positionKeys","getNumElementsFromNonIndexedArrays","key","ii","numElements","getNumElementsFromAttributes","getBufferParameter","bytesPerValue","totalElements","createBufferInfoFromArrays","srcBufferInfo","newAttribs","bufferInfo","assign","indices","newIndices","elementType","createBufferFromArray","createBuffersFromArrays","buffers","programs","TRIANGLES","drawBufferInfo","count","instanceCount","drawElementsInstanced","drawElements","drawArraysInstanced","drawArrays","drawObjectList","objectsToDraw","lastUsedProgramInfo","lastUsedBufferInfo","object","active","programInfo","vertexArrayInfo","bindBuffers","useProgram","program","vertexArrayObject","bindVertexArray","setBuffersAndAttributes","setUniforms","uniforms","textures","FRAMEBUFFER","RENDERBUFFER","TEXTURE_2D","DEPTH_COMPONENT","RGBA","DEPTH_COMPONENT24","DEPTH_COMPONENT32F","DEPTH24_STENCIL8","DEPTH32F_STENCIL8","RGBA4","RGB5_A1","RGB565","DEPTH_COMPONENT16","STENCIL_INDEX","STENCIL_INDEX8","DEPTH_STENCIL","COLOR_ATTACHMENT0","DEPTH_ATTACHMENT","STENCIL_ATTACHMENT","DEPTH_STENCIL_ATTACHMENT","CLAMP_TO_EDGE","LINEAR","defaultAttachments","format","min","wrap","attachmentsByFormat","getAttachmentPointForFormat","internalFormat","renderbufferFormats","isRenderbufferFormat","MAX_COLOR_ATTACHMENT_POINTS","isColorAttachmentPoint","attachmentPoint","createFramebufferInfo","attachments","width","height","target","fb","createFramebuffer","bindFramebuffer","drawingBufferWidth","drawingBufferHeight","usedColorAttachmentsPoints","framebufferInfo","framebuffer","attachmentOptions","attachment","samples","push","createRenderbuffer","bindRenderbuffer","renderbufferStorageMultisample","renderbufferStorage","textureOptions","auto","minMag","mag","wrapS","wrapT","createTexture","isRenderbuffer","framebufferRenderbuffer","isTexture","layer","framebufferTextureLayer","level","framebufferTexture2D","drawBuffers","resizeFramebufferInfo","ndx","resizeTexture","bindFramebufferInfo","viewport","copyNamedProperties","names","src","dst","error","_console","console","apply","arguments","warn","_console2","isTypeWeakMaps","Map","isType","weakMap","isOfType","s","toString","substring","WebGLRenderbuffer","isShader","WebGLShader","WebGLTexture","isSampler","WebGLSampler","utils","_regeneratorRuntime","o","Symbol","iterator","c","asyncIterator","toStringTag","define","enumerable","configurable","writable","Generator","create","Context","makeInvokeMethod","tryCatch","arg","h","l","f","y","GeneratorFunction","GeneratorFunctionPrototype","p","d","getPrototypeOf","v","values","g","defineIteratorMethods","_invoke","AsyncIterator","invoke","resolve","__await","then","callInvokeWithMethodAndArg","done","method","delegate","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","TypeError","resultName","next","nextLoc","pushTryEntry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","isNaN","displayName","isGeneratorFunction","mark","setPrototypeOf","awrap","async","Promise","reverse","pop","prev","charAt","slice","stop","rval","handle","complete","finish","_catch","delegateYield","ownKeys","getOwnPropertySymbols","filter","_objectSpread","_defineProperty","getOwnPropertyDescriptors","defineProperties","obj","_toPropertyKey","_toPrimitive","String","toPrimitive","Number","asyncGeneratorStep","gen","reject","_next","_throw","info","_asyncToGenerator","self","args","err","_slicedToArray","arr","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","_createForOfIteratorHelper","allowArrayLike","it","F","_e","normalCompletion","didErr","step","_e2","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","minLen","_arrayLikeToArray","from","iter","len","arr2","getElementById","id","document","TEXTURE0","DYNAMIC_DRAW","UNIFORM_BUFFER","TRANSFORM_FEEDBACK_BUFFER","TRANSFORM_FEEDBACK","COMPILE_STATUS","LINK_STATUS","FRAGMENT_SHADER","VERTEX_SHADER","SEPARATE_ATTRIBS","ACTIVE_UNIFORMS","ACTIVE_ATTRIBUTES","TRANSFORM_FEEDBACK_VARYINGS","ACTIVE_UNIFORM_BLOCKS","UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER","UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER","UNIFORM_BLOCK_DATA_SIZE","UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES","FLOAT_VEC2","FLOAT_VEC3","FLOAT_VEC4","INT_VEC2","INT_VEC3","INT_VEC4","BOOL","BOOL_VEC2","BOOL_VEC3","BOOL_VEC4","FLOAT_MAT2","FLOAT_MAT3","FLOAT_MAT4","SAMPLER_2D","SAMPLER_CUBE","SAMPLER_3D","SAMPLER_2D_SHADOW","FLOAT_MAT2x3","FLOAT_MAT2x4","FLOAT_MAT3x2","FLOAT_MAT3x4","FLOAT_MAT4x2","FLOAT_MAT4x3","SAMPLER_2D_ARRAY","SAMPLER_2D_ARRAY_SHADOW","SAMPLER_CUBE_SHADOW","UNSIGNED_INT_VEC2","UNSIGNED_INT_VEC3","UNSIGNED_INT_VEC4","INT_SAMPLER_2D","INT_SAMPLER_3D","INT_SAMPLER_CUBE","INT_SAMPLER_2D_ARRAY","UNSIGNED_INT_SAMPLER_2D","UNSIGNED_INT_SAMPLER_3D","UNSIGNED_INT_SAMPLER_CUBE","UNSIGNED_INT_SAMPLER_2D_ARRAY","TEXTURE_CUBE_MAP","TEXTURE_3D","TEXTURE_2D_ARRAY","typeMap","getBindPointForSamplerType","bindPoint","floatSetter","location","uniform1f","floatArraySetter","uniform1fv","floatVec2Setter","uniform2fv","floatVec3Setter","uniform3fv","floatVec4Setter","uniform4fv","intSetter","uniform1i","intArraySetter","uniform1iv","intVec2Setter","uniform2iv","intVec3Setter","uniform3iv","intVec4Setter","uniform4iv","uintSetter","uniform1ui","uintArraySetter","uniform1uiv","uintVec2Setter","uniform2uiv","uintVec3Setter","uniform3uiv","uintVec4Setter","uniform4uiv","floatMat2Setter","uniformMatrix2fv","floatMat3Setter","uniformMatrix3fv","floatMat4Setter","uniformMatrix4fv","floatMat23Setter","uniformMatrix2x3fv","floatMat32Setter","uniformMatrix3x2fv","floatMat24Setter","uniformMatrix2x4fv","floatMat42Setter","uniformMatrix4x2fv","floatMat34Setter","uniformMatrix3x4fv","floatMat43Setter","uniformMatrix4x3fv","samplerSetter","unit","isWebGL2","textureOrPair","texture","sampler","activeTexture","bindTexture","bindSampler","samplerArraySetter","units","Int32Array","index","setter","arraySetter","cols","Uint32Array","rows","floatAttribSetter","b","disableVertexAttribArray","vertexAttrib4fv","vertexAttrib3fv","vertexAttrib2fv","vertexAttrib1fv","enableVertexAttribArray","vertexAttribPointer","vertexAttribDivisor","intAttribSetter","vertexAttrib4iv","vertexAttribIPointer","uintAttribSetter","vertexAttrib4uiv","matAttribSetter","typeInfo","defaultSize","rowOffset","attrTypeMap","errorRE","addLineNumbersWithError","log","lineOffset","matches","matchAll","lineNoToErrorMap","map","m","lineNo","parseInt","end","msg","split","line","join","spaceRE","prepShaderSource","shaderSource","replace","reportError","progOptions","errorCallback","callback","setTimeout","errors","checkShaderStatus","shaderType","shader","errFn","compiled","getShaderParameter","lastError","getShaderInfoLog","_prepShaderSource","getShaderSource","glEnumToString","getProgramOptions","opt_attribs","opt_locations","opt_errorCallback","transformFeedbackVaryings","transformFeedbackMode","opt","attribLocations","options","_len","_key","defaultShaderType","getShaderTypeFromScriptType","scriptType","indexOf","deleteProgramAndShaders","notThese","shaders","getAttachedShaders","_iterator","_step","deleteShader","deleteProgram","wait","ms","createProgramNoCheck","programOptions","createProgram","_getProgramOptions","elem","text","createShader","compileShader","attachShader","entries","_ref","_ref2","loc","bindAttribLocation","varyings","linkProgram","shaderSet","Set","hasErrors","getProgramErrors","waitForProgramLinkCompletionAsync","wrapCallbackFnToAsyncFn","arg1","_len2","_key2","createProgramAsync","exports","createProgramInfoAsync","createProgramInfo","_x","_x2","_waitForProgramLinkCompletionAsync","_callee","ext","checkFn","waitTime","_callee$","_context","getExtension","getProgramParameter","COMPLETION_STATUS_KHR","waitForAllProgramsLinkCompletionAsync","_x3","_x4","_waitForAllProgramsLinkCompletionAsync","_callee2","_i3","_Object$values2","_callee2$","_context2","linked","getProgramInfoLog","SHADER_TYPE","_","createProgramFromScripts","shaderScriptIds","_iterator2","_step2","scriptId","shaderScript","createProgramFromSources","shaderSources","isBuiltIn","startsWith","tokenRE","isDigit","addSetterToUniformTree","fullPath","node","uniformSetters","tokens","tokenNdx","path","token","isArrayIndex","accessor","isLastToken","child","setUniformTree","createUniformSetters","textureUnit","createUniformSetter","uniformInfo","endsWith","uniformTree","numUniforms","getActiveUniform","substr","getUniformLocation","createTransformFeedbackInfo","numVaryings","varying","getTransformFeedbackVarying","bindTransformFeedbackInfo","transformFeedbackInfo","buf","bindBufferRange","bindBufferBase","createTransformFeedback","tf","bindTransformFeedback","createUniformBlockSpecFromProgram","uniformData","uniformIndices","pair","pname","getActiveUniforms","blockSpecs","numUniformBlocks","getActiveUniformBlockName","blockSpec","getUniformBlockIndex","usedByVertexShader","getActiveUniformBlockParameter","usedByFragmentShader","used","arraySuffixRE","pad","padding","createUniformBlockUniformSetter","view","totalRows","row","col","createUniformBlockInfoFromProgram","uniformBlockSpec","blockName","_options$offset","_options$array","_options$buffer","_options$bufferOffset","ArrayBuffer","uniformBufferIndex","byteLength","uniformBlockBinding","setters","setterTree","uniformNdx","uniformView","asFloat","asUint8","bufferOffset","createUniformBlockInfo","bindUniformBlock","uniformBlockInfo","_uniformBlockInfo$siz","bufferBindIndex","setUniformBlock","setBlockUniforms","tree","prop","actualSetters","numArgs","aNdx","setUniformsAndBindTextures","createAttributeSetters","attribSetters","numAttribs","getActiveAttrib","getAttribLocation","setAttributes","createProgramInfoFromProgram","uniformLocations","fromEntries","_ref3","_ref4","k","_ref5","_ref6","notIdRE","source","script","origCallback","checkAllPrograms","programSpecs","noDeleteShadersSet","_i","_Object$entries","_Object$entries$_i","spec","_i2","_Object$values","_iterator3","_step3","createPrograms","_ref7","_ref8","add","createProgramInfos","createProgramInfosForPrograms","_ref9","_ref10","createProgramsAsync","createProgramInfosAsync","textureColor","crossOrigin","getShared2DContext","s_ctx","createElement","getContext","ALPHA","RGB","LUMINANCE","LUMINANCE_ALPHA","NEAREST","TEXTURE_CUBE_MAP_POSITIVE_X","TEXTURE_CUBE_MAP_NEGATIVE_X","TEXTURE_CUBE_MAP_POSITIVE_Y","TEXTURE_CUBE_MAP_NEGATIVE_Y","TEXTURE_CUBE_MAP_POSITIVE_Z","TEXTURE_CUBE_MAP_NEGATIVE_Z","TEXTURE_MIN_FILTER","TEXTURE_MAG_FILTER","TEXTURE_WRAP_S","TEXTURE_WRAP_T","TEXTURE_WRAP_R","TEXTURE_MIN_LOD","TEXTURE_MAX_LOD","TEXTURE_BASE_LEVEL","TEXTURE_MAX_LEVEL","TEXTURE_COMPARE_MODE","TEXTURE_COMPARE_FUNC","UNPACK_ALIGNMENT","UNPACK_ROW_LENGTH","UNPACK_IMAGE_HEIGHT","UNPACK_SKIP_PIXELS","UNPACK_SKIP_ROWS","UNPACK_SKIP_IMAGES","UNPACK_COLORSPACE_CONVERSION_WEBGL","UNPACK_PREMULTIPLY_ALPHA_WEBGL","UNPACK_FLIP_Y_WEBGL","R8","R8_SNORM","R16F","R32F","R8UI","R8I","RG16UI","RG16I","RG32UI","RG32I","RG8","RG8_SNORM","RG16F","RG32F","RG8UI","RG8I","R16UI","R16I","R32UI","R32I","RGB8","SRGB8","RGB8_SNORM","R11F_G11F_B10F","RGB9_E5","RGB16F","RGB32F","RGB8UI","RGB8I","RGB16UI","RGB16I","RGB32UI","RGB32I","RGBA8","SRGB8_ALPHA8","RGBA8_SNORM","RGB10_A2","RGBA16F","RGBA32F","RGBA8UI","RGBA8I","RGB10_A2UI","RGBA16UI","RGBA16I","RGBA32I","RGBA32UI","UNSIGNED_SHORT_4_4_4_4","UNSIGNED_SHORT_5_5_5_1","UNSIGNED_SHORT_5_6_5","HALF_FLOAT","HALF_FLOAT_OES","UNSIGNED_INT_2_10_10_10_REV","UNSIGNED_INT_10F_11F_11F_REV","UNSIGNED_INT_5_9_9_9_REV","FLOAT_32_UNSIGNED_INT_24_8_REV","UNSIGNED_INT_24_8","RG","RG_INTEGER","RED","RED_INTEGER","RGB_INTEGER","RGBA_INTEGER","formatInfo","numColorComponents","s_textureInternalFormatInfo","getTextureInternalFormatInfo","textureFormat","colorRenderable","textureFilterable","bytesPerElement","bytesPerElementMap","getBytesPerElementForInternalFormat","getFormatAndTypeForInternalFormat","isPowerOf2","canGenerateMipmap","canFilter","getNumComponentsForFormat","getTextureTypeForArrayType","defaultType","guessDimensions","Math","sqrt","setDefaultTextureColor","color","scopedSetPackState","colorspaceConversion","premultiplyAlpha","flipY","getParameter","pixelStorei","setSkipStateToDefault","setTextureSamplerParameters","parameteriFn","wrapR","minLod","maxLod","baseLevel","maxLevel","compareFunc","compareMode","setTextureParameters","tex","texParameteri","setSamplerParameters","samplerParameteri","createSampler","createSamplers","samplerOptions","samplers","make1Pixel","setTextureFilteringForSize","generateMipmap","filtering","shouldAutomaticallySetTextureFilteringForSize","getCubeFaceOrder","cubeFaceOrder","getCubeFacesWithNdx","faces","facesWithNdx","face","sort","setTextureFromElement","element","formatType","imgWidth","imgHeight","slices","nodeName","ctx","canvas","xOffset","yOffset","drawImage","texImage2D","createImageBitmap","colorSpaceConversion","imageBitmap","smallest","largest","max","depth","xMult","yMult","texImage3D","srcX","srcY","texSubImage3D","noop","urlIsSameOrigin","url","href","hostname","port","protocol","localOrigin","URL","origin","urlOrigin","setToAnonymousIfUndefinedAndURLIsNotSameOrigin","loadImage","img","Image","clearEventHandlers","removeEventListener","onError","onLoad","addEventListener","ImageBitmap","bm","cb","mode","fetch","response","ok","blob","bitmap","isTexImageSource","ImageData","HTMLElement","loadAndUseImage","setTextureTo1PixelColor","loadTextureFromUrl","loadCubemapFromUrls","urls","numToLoad","imgs","uploadImg","faceTarget","otherTarget","loadSlicesFromUrls","firstImage","setTextureFromArray","Uint8ClampedArray","dimensions","cbrt","unpackAlignment","elementsPerElement","faceSize","subarray","setEmptyTexture","isAsyncSrc","createTextures","numDownloading","images","callCallbackIfReady","onLoadFn","_twgl","attributes","_exportNames","draw","framebuffers","typedarrays","vertexArrays","addExtensionsToContext","setAttributeDefaults_","setTextureDefaults_","prefixRE","addExtensionToContext","extensionName","enums","fnSuffix","exec","enumSuffix","isFunc","suffix","origFn","supportedExtensions","create3DContext","context","getWebGLContext","createContext","resizeCanvasToDisplaySize","multiplier","clientWidth","clientHeight","glTypeToTypedArray","tt","Int16Array","CTOR","SharedArrayBuffer","isArrayBufferOrSharedArrayBuffer","texStorage2D","isWebGL1","haveEnumsForType","addEnums","existing","createVertexArrayInfo","programInfos","vao","createVertexArray","createVAOAndSetAttributes","createVAOFromBufferInfo"],"sourceRoot":""} \ No newline at end of file diff --git a/npm/base/dist/6.x/twgl.module.js b/npm/base/dist/6.x/twgl.module.js new file mode 100644 index 00000000..9f68e597 --- /dev/null +++ b/npm/base/dist/6.x/twgl.module.js @@ -0,0 +1,6233 @@ +/* @license twgl.js 6.0.0 Copyright (c) 2015, Gregg Tavares All Rights Reserved. +Available via the MIT license. +see: http://github.com/greggman/twgl.js for details */ +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* DataType */ +const BYTE$2 = 0x1400; +const UNSIGNED_BYTE$3 = 0x1401; +const SHORT$2 = 0x1402; +const UNSIGNED_SHORT$3 = 0x1403; +const INT$3 = 0x1404; +const UNSIGNED_INT$3 = 0x1405; +const FLOAT$3 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4$1 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1$1 = 0x8034; +const UNSIGNED_SHORT_5_6_5$1 = 0x8363; +const HALF_FLOAT$1 = 0x140B; +const UNSIGNED_INT_2_10_10_10_REV$1 = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV$1 = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV$1 = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV$1 = 0x8DAD; +const UNSIGNED_INT_24_8$1 = 0x84FA; + +const glTypeToTypedArray = {}; +{ + const tt = glTypeToTypedArray; + tt[BYTE$2] = Int8Array; + tt[UNSIGNED_BYTE$3] = Uint8Array; + tt[SHORT$2] = Int16Array; + tt[UNSIGNED_SHORT$3] = Uint16Array; + tt[INT$3] = Int32Array; + tt[UNSIGNED_INT$3] = Uint32Array; + tt[FLOAT$3] = Float32Array; + tt[UNSIGNED_SHORT_4_4_4_4$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_5_5_1$1] = Uint16Array; + tt[UNSIGNED_SHORT_5_6_5$1] = Uint16Array; + tt[HALF_FLOAT$1] = Uint16Array; + tt[UNSIGNED_INT_2_10_10_10_REV$1] = Uint32Array; + tt[UNSIGNED_INT_10F_11F_11F_REV$1] = Uint32Array; + tt[UNSIGNED_INT_5_9_9_9_REV$1] = Uint32Array; + tt[FLOAT_32_UNSIGNED_INT_24_8_REV$1] = Uint32Array; + tt[UNSIGNED_INT_24_8$1] = Uint32Array; +} + +/** + * Get the GL type for a typedArray + * @param {ArrayBufferView} typedArray a typedArray + * @return {number} the GL type for array. For example pass in an `Int8Array` and `gl.BYTE` will + * be returned. Pass in a `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArray(typedArray) { + if (typedArray instanceof Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArray instanceof Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArray instanceof Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArray instanceof Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArray instanceof Int32Array) { return INT$3; } // eslint-disable-line + if (typedArray instanceof Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArray instanceof Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the GL type for a typedArray type + * @param {ArrayBufferView} typedArrayType a typedArray constructor + * @return {number} the GL type for type. For example pass in `Int8Array` and `gl.BYTE` will + * be returned. Pass in `Uint32Array` and `gl.UNSIGNED_INT` will be returned + * @memberOf module:twgl/typedArray + */ +function getGLTypeForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return BYTE$2; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Uint8ClampedArray) { return UNSIGNED_BYTE$3; } // eslint-disable-line + if (typedArrayType === Int16Array) { return SHORT$2; } // eslint-disable-line + if (typedArrayType === Uint16Array) { return UNSIGNED_SHORT$3; } // eslint-disable-line + if (typedArrayType === Int32Array) { return INT$3; } // eslint-disable-line + if (typedArrayType === Uint32Array) { return UNSIGNED_INT$3; } // eslint-disable-line + if (typedArrayType === Float32Array) { return FLOAT$3; } // eslint-disable-line + throw new Error('unsupported typed array type'); +} + +/** + * Get the typed array constructor for a given GL type + * @param {number} type the GL type. (eg: `gl.UNSIGNED_INT`) + * @return {function} the constructor for a the corresponding typed array. (eg. `Uint32Array`). + * @memberOf module:twgl/typedArray + */ +function getTypedArrayTypeForGLType(type) { + const CTOR = glTypeToTypedArray[type]; + if (!CTOR) { + throw new Error('unknown gl type'); + } + return CTOR; +} + +const isArrayBuffer$1 = typeof SharedArrayBuffer !== 'undefined' + ? function isArrayBufferOrSharedArrayBuffer(a) { + return a && a.buffer && (a.buffer instanceof ArrayBuffer || a.buffer instanceof SharedArrayBuffer); + } + : function isArrayBuffer(a) { + return a && a.buffer && a.buffer instanceof ArrayBuffer; + }; + +var typedarrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + getGLTypeForTypedArray: getGLTypeForTypedArray, + getGLTypeForTypedArrayType: getGLTypeForTypedArrayType, + getTypedArrayTypeForGLType: getTypedArrayTypeForGLType, + isArrayBuffer: isArrayBuffer$1 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Copies properties from source to dest only if a matching key is in dest + * + * @param {Object.} src the source + * @param {Object.} dst the dest + * @private + */ +function copyExistingProperties(src, dst) { + Object.keys(dst).forEach(function(key) { + if (dst.hasOwnProperty(key) && src.hasOwnProperty(key)) { /* eslint no-prototype-builtins: 0 */ + dst[key] = src[key]; + } + }); +} + +function error$1(...args) { + console.error(...args); +} + +function warn$1(...args) { + console.warn(...args); +} + +const isTypeWeakMaps = new Map(); + +function isType(object, type) { + if (!object || typeof object !== 'object') { + return false; + } + let weakMap = isTypeWeakMaps.get(type); + if (!weakMap) { + weakMap = new WeakMap(); + isTypeWeakMaps.set(type, weakMap); + } + let isOfType = weakMap.get(object); + if (isOfType === undefined) { + const s = Object.prototype.toString.call(object); + isOfType = s.substring(8, s.length - 1) === type; + weakMap.set(object, isOfType); + } + return isOfType; +} + +function isBuffer(gl, t) { + return typeof WebGLBuffer !== 'undefined' && isType(t, 'WebGLBuffer'); +} + +function isRenderbuffer(gl, t) { + return typeof WebGLRenderbuffer !== 'undefined' && isType(t, 'WebGLRenderbuffer'); +} + +function isTexture(gl, t) { + return typeof WebGLTexture !== 'undefined' && isType(t, 'WebGLTexture'); +} + +function isSampler(gl, t) { + return typeof WebGLSampler !== 'undefined' && isType(t, 'WebGLSampler'); +} + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const STATIC_DRAW = 0x88e4; +const ARRAY_BUFFER$1 = 0x8892; +const ELEMENT_ARRAY_BUFFER$2 = 0x8893; +const BUFFER_SIZE = 0x8764; + +const BYTE$1 = 0x1400; +const UNSIGNED_BYTE$2 = 0x1401; +const SHORT$1 = 0x1402; +const UNSIGNED_SHORT$2 = 0x1403; +const INT$2 = 0x1404; +const UNSIGNED_INT$2 = 0x1405; +const FLOAT$2 = 0x1406; +const defaults$2 = { + attribPrefix: "", +}; + +/** + * Sets the default attrib prefix + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * var arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * @deprecated see {@link module:twgl.setDefaults} + * @param {string} prefix prefix for attribs + * @memberOf module:twgl/attributes + */ +function setAttributePrefix(prefix) { + defaults$2.attribPrefix = prefix; +} + +function setDefaults$2(newDefaults) { + copyExistingProperties(newDefaults, defaults$2); +} + +function setBufferFromTypedArray(gl, type, buffer, array, drawType) { + gl.bindBuffer(type, buffer); + gl.bufferData(type, array, drawType || STATIC_DRAW); +} + +/** + * Given typed array creates a WebGLBuffer and copies the typed array + * into it. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {ArrayBuffer|SharedArrayBuffer|ArrayBufferView|WebGLBuffer} typedArray the typed array. Note: If a WebGLBuffer is passed in it will just be returned. No action will be taken + * @param {number} [type] the GL bind type for the buffer. Default = `gl.ARRAY_BUFFER`. + * @param {number} [drawType] the GL draw type for the buffer. Default = 'gl.STATIC_DRAW`. + * @return {WebGLBuffer} the created WebGLBuffer + * @memberOf module:twgl/attributes + */ +function createBufferFromTypedArray(gl, typedArray, type, drawType) { + if (isBuffer(gl, typedArray)) { + return typedArray; + } + type = type || ARRAY_BUFFER$1; + const buffer = gl.createBuffer(); + setBufferFromTypedArray(gl, type, buffer, typedArray, drawType); + return buffer; +} + +function isIndices(name) { + return name === "indices"; +} + +// This is really just a guess. Though I can't really imagine using +// anything else? Maybe for some compression? +function getNormalizationForTypedArrayType(typedArrayType) { + if (typedArrayType === Int8Array) { return true; } // eslint-disable-line + if (typedArrayType === Uint8Array) { return true; } // eslint-disable-line + return false; +} + +function getArray(array) { + return array.length ? array : array.data; +} + +const texcoordRE = /coord|texture/i; +const colorRE = /color|colour/i; + +function guessNumComponentsFromName(name, length) { + let numComponents; + if (texcoordRE.test(name)) { + numComponents = 2; + } else if (colorRE.test(name)) { + numComponents = 4; + } else { + numComponents = 3; // position, normals, indices ... + } + + if (length % numComponents > 0) { + throw new Error(`Can not guess numComponents for attribute '${name}'. Tried ${numComponents} but ${length} values is not evenly divisible by ${numComponents}. You should specify it.`); + } + + return numComponents; +} + +function getNumComponents(array, arrayName, numValues) { + return array.numComponents || array.size || guessNumComponentsFromName(arrayName, numValues || getArray(array).length); +} + +function makeTypedArray(array, name) { + if (isArrayBuffer$1(array)) { + return array; + } + + if (isArrayBuffer$1(array.data)) { + return array.data; + } + + if (Array.isArray(array)) { + array = { + data: array, + }; + } + + let Type = array.type ? typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type) : undefined; + if (!Type) { + if (isIndices(name)) { + Type = Uint16Array; + } else { + Type = Float32Array; + } + } + return new Type(array.data); +} + +function glTypeFromGLTypeOrTypedArrayType(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? glTypeOrTypedArrayCtor + : glTypeOrTypedArrayCtor ? getGLTypeForTypedArrayType(glTypeOrTypedArrayCtor) : FLOAT$2; +} + +function typedArrayTypeFromGLTypeOrTypedArrayCtor(glTypeOrTypedArrayCtor) { + return typeof glTypeOrTypedArrayCtor === 'number' + ? getTypedArrayTypeForGLType(glTypeOrTypedArrayCtor) + : glTypeOrTypedArrayCtor || Float32Array; +} + +function attribBufferFromBuffer(gl, array/*, arrayName */) { + return { + buffer: array.buffer, + numValues: 2 * 3 * 4, // safely divided by 2, 3, 4 + type: glTypeFromGLTypeOrTypedArrayType(array.type), + arrayType: typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type), + }; +} + +function attribBufferFromSize(gl, array/*, arrayName*/) { + const numValues = array.data || array; + const arrayType = typedArrayTypeFromGLTypeOrTypedArrayCtor(array.type); + const numBytes = numValues * arrayType.BYTES_PER_ELEMENT; + const buffer = gl.createBuffer(); + gl.bindBuffer(ARRAY_BUFFER$1, buffer); + gl.bufferData(ARRAY_BUFFER$1, numBytes, array.drawType || STATIC_DRAW); + return { + buffer, + numValues, + type: getGLTypeForTypedArrayType(arrayType), + arrayType, + }; +} + +function attribBufferFromArrayLike(gl, array, arrayName) { + const typedArray = makeTypedArray(array, arrayName); + return { + arrayType: typedArray.constructor, + buffer: createBufferFromTypedArray(gl, typedArray, undefined, array.drawType), + type: getGLTypeForTypedArray(typedArray), + numValues: 0, + }; +} + +/** + * The info for an attribute. This is effectively just the arguments to `gl.vertexAttribPointer` plus the WebGLBuffer + * for the attribute. + * + * @typedef {Object} AttribInfo + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {number} [numComponents] the number of components for this attribute. + * @property {number} [size] synonym for `numComponents`. + * @property {number} [type] the type of the attribute (eg. `gl.FLOAT`, `gl.UNSIGNED_BYTE`, etc...) Default = `gl.FLOAT` + * @property {boolean} [normalize] 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 {number} [divisor] the divisor in instances. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you're using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {WebGLBuffer} buffer the buffer that contains the data for this attribute + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * @typedef {(Int8ArrayConstructor|Uint8ArrayConstructor|Int16ArrayConstructor|Uint16ArrayConstructor|Int32ArrayConstructor|Uint32ArrayConstructor|Float32ArrayConstructor)} TypedArrayConstructor + */ + +/** + * Use this type of array spec when TWGL can't guess the type or number of components of an array + * @typedef {Object} FullArraySpec + * @property {number[]|ArrayBufferView} [value] a constant value for the attribute. Note: if this is set the attribute will be + * disabled and set to this constant value and all other values will be ignored. + * @property {(number|number[]|ArrayBufferView)} [data] The data of the array. A number alone becomes the number of elements of type. + * @property {number} [numComponents] number of components for `vertexAttribPointer`. Default is based on the name of the array. + * If `coord` is in the name assumes `numComponents = 2`. + * If `color` is in the name assumes `numComponents = 4`. + * otherwise assumes `numComponents = 3` + * @property {number|TypedArrayConstructor} [type] type. This is used if `data` is a JavaScript array, or `buffer` is passed in, or `data` is a number. + * It can either be the constructor for a typedarray. (eg. `Uint8Array`) OR a WebGL type, (eg `gl.UNSIGNED_BYTE`). + * For example if you want colors in a `Uint8Array` you might have a `FullArraySpec` like `{ type: gl.UNSIGNED_BYTE, data: [255,0,255,255, ...], }`. + * @property {number} [size] synonym for `numComponents`. + * @property {boolean} [normalize] normalize for `vertexAttribPointer`. Default is true if type is `Int8Array` or `Uint8Array` otherwise false. + * @property {number} [stride] stride for `vertexAttribPointer`. Default = 0 + * @property {number} [offset] offset for `vertexAttribPointer`. Default = 0 + * @property {number} [divisor] divisor for `vertexAttribDivisor`. Default = 0. + * Requires WebGL2 or the ANGLE_instanced_arrays extension. + * and, if you using WebGL1 you must have called {@link module:twgl.addExtensionsToContext} + * @property {string} [attrib] name of attribute this array maps to. Defaults to same name as array prefixed by the default attribPrefix. + * @property {string} [name] synonym for `attrib`. + * @property {string} [attribName] synonym for `attrib`. + * @property {WebGLBuffer} [buffer] Buffer to use for this attribute. This lets you use your own buffer + * but you will need to supply `numComponents` and `type`. You can effectively pass an `AttribInfo` + * to provide this. Example: + * + * const bufferInfo1 = twgl.createBufferInfoFromArrays(gl, { + * position: [1, 2, 3, ... ], + * }); + * const bufferInfo2 = twgl.createBufferInfoFromArrays(gl, { + * position: bufferInfo1.attribs.position, // use the same buffer from bufferInfo1 + * }); + * + * @property {number} [drawType] the draw type passed to gl.bufferData. Default = gl.STATIC_DRAW + * @memberOf module:twgl + */ + +/** + * An individual array in {@link module:twgl.Arrays} + * + * When passed to {@link module:twgl.createBufferInfoFromArrays} if an ArraySpec is `number[]` or `ArrayBufferView` + * the types will be guessed based on the name. `indices` will be `Uint16Array`, everything else will + * be `Float32Array`. If an ArraySpec is a number it's the number of floats for an empty (zeroed) buffer. + * + * @typedef {(number|number[]|ArrayBufferView|module:twgl.FullArraySpec)} ArraySpec + * @memberOf module:twgl + */ + +/** + * This is a JavaScript object of arrays by name. The names should match your shader's attributes. If your + * attributes have a common prefix you can specify it by calling {@link module:twgl.setAttributePrefix}. + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * Objects with various fields. See {@link module:twgl.FullArraySpec}. + * + * 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], }, + * }; + * + * @typedef {Object.} Arrays + * @memberOf module:twgl + */ + + +/** + * 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 = { + * position: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * texcoord: { numComponents: 2, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * normal: { numComponents: 3, type: gl.FLOAT, normalize: false, buffer: WebGLBuffer, }, + * color: { numComponents: 4, type: gl.UNSIGNED_BYTE, normalize: true, buffer: WebGLBuffer, }, + * }; + * + * notes: + * + * * Arrays can take various forms + * + * Bare JavaScript Arrays + * + * var arrays = { + * position: [-1, 1, 0], + * normal: [0, 1, 0], + * ... + * } + * + * Bare TypedArrays + * + * var arrays = { + * position: new Float32Array([-1, 1, 0]), + * color: new Uint8Array([255, 128, 64, 255]), + * ... + * } + * + * * Will guess at `numComponents` if not specified based on name. + * + * If `coord` is in the name assumes `numComponents = 2` + * + * If `color` is in the name assumes `numComponents = 4` + * + * otherwise assumes `numComponents = 3` + * + * @param {WebGLRenderingContext} gl The webgl rendering context. + * @param {module:twgl.Arrays} arrays The arrays + * @param {module:twgl.BufferInfo} [srcBufferInfo] a BufferInfo to copy from + * This lets you share buffers. Any arrays you supply will override + * the buffers from srcBufferInfo. + * @return {Object.} the attribs + * @memberOf module:twgl/attributes + */ +function createAttribsFromArrays(gl, arrays) { + const attribs = {}; + Object.keys(arrays).forEach(function(arrayName) { + if (!isIndices(arrayName)) { + const array = arrays[arrayName]; + const attribName = array.attrib || array.name || array.attribName || (defaults$2.attribPrefix + arrayName); + if (array.value) { + if (!Array.isArray(array.value) && !isArrayBuffer$1(array.value)) { + throw new Error('array.value is not array or typedarray'); + } + attribs[attribName] = { + value: array.value, + }; + } else { + let fn; + if (array.buffer && array.buffer instanceof WebGLBuffer) { + fn = attribBufferFromBuffer; + } else if (typeof array === "number" || typeof array.data === "number") { + fn = attribBufferFromSize; + } else { + fn = attribBufferFromArrayLike; + } + const {buffer, type, numValues, arrayType} = fn(gl, array, arrayName); + const normalization = array.normalize !== undefined ? array.normalize : getNormalizationForTypedArrayType(arrayType); + const numComponents = getNumComponents(array, arrayName, numValues); + attribs[attribName] = { + buffer: buffer, + numComponents: numComponents, + type: type, + normalize: normalization, + stride: array.stride || 0, + offset: array.offset || 0, + divisor: array.divisor === undefined ? undefined : array.divisor, + drawType: array.drawType, + }; + } + } + }); + gl.bindBuffer(ARRAY_BUFFER$1, null); + return attribs; +} + +/** + * Sets the contents of a buffer attached to an attribInfo + * + * This is helper function to dynamically update a buffer. + * + * Let's say you make a bufferInfo + * + * 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]), + * }; + * var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays); + * + * And you want to dynamically update the positions. You could do this + * + * // assuming arrays.position has already been updated with new data. + * twgl.setAttribInfoBufferFromArray(gl, bufferInfo.attribs.position, arrays.position); + * + * @param {WebGLRenderingContext} gl + * @param {AttribInfo} attribInfo The attribInfo who's buffer contents to set. NOTE: If you have an attribute prefix + * the name of the attribute will include the prefix. + * @param {ArraySpec} array Note: it is arguably inefficient to pass in anything but a typed array because anything + * else will have to be converted to a typed array before it can be used by WebGL. During init time that + * inefficiency is usually not important but if you're updating data dynamically best to be efficient. + * @param {number} [offset] an optional offset into the buffer. This is only an offset into the WebGL buffer + * not the array. To pass in an offset into the array itself use a typed array and create an `ArrayBufferView` + * for the portion of the array you want to use. + * + * var someArray = new Float32Array(1000); // an array with 1000 floats + * var someSubArray = new Float32Array(someArray.buffer, offsetInBytes, sizeInUnits); // a view into someArray + * + * Now you can pass `someSubArray` into setAttribInfoBufferFromArray` + * @memberOf module:twgl/attributes + */ +function setAttribInfoBufferFromArray(gl, attribInfo, array, offset) { + array = makeTypedArray(array); + if (offset !== undefined) { + gl.bindBuffer(ARRAY_BUFFER$1, attribInfo.buffer); + gl.bufferSubData(ARRAY_BUFFER$1, offset, array); + } else { + setBufferFromTypedArray(gl, ARRAY_BUFFER$1, attribInfo.buffer, array, attribInfo.drawType); + } +} + +function getBytesPerValueForGLType(gl, type) { + if (type === BYTE$1) return 1; // eslint-disable-line + if (type === UNSIGNED_BYTE$2) return 1; // eslint-disable-line + if (type === SHORT$1) return 2; // eslint-disable-line + if (type === UNSIGNED_SHORT$2) return 2; // eslint-disable-line + if (type === INT$2) return 4; // eslint-disable-line + if (type === UNSIGNED_INT$2) return 4; // eslint-disable-line + if (type === FLOAT$2) return 4; // eslint-disable-line + return 0; +} + +// Tries to get the number of elements from a set of arrays. +const positionKeys = ['position', 'positions', 'a_position']; +function getNumElementsFromNonIndexedArrays(arrays) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in arrays) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(arrays)[0]; + } + const array = arrays[key]; + const length = getArray(array).length; + if (length === undefined) { + return 1; // There's no arrays + } + const numComponents = getNumComponents(array, key); + const numElements = length / numComponents; + if (length % numComponents > 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +function getNumElementsFromAttributes(gl, attribs) { + let key; + let ii; + for (ii = 0; ii < positionKeys.length; ++ii) { + key = positionKeys[ii]; + if (key in attribs) { + break; + } + key = defaults$2.attribPrefix + key; + if (key in attribs) { + break; + } + } + if (ii === positionKeys.length) { + key = Object.keys(attribs)[0]; + } + const attrib = attribs[key]; + if (!attrib.buffer) { + return 1; // There's no buffer + } + gl.bindBuffer(ARRAY_BUFFER$1, attrib.buffer); + const numBytes = gl.getBufferParameter(ARRAY_BUFFER$1, BUFFER_SIZE); + gl.bindBuffer(ARRAY_BUFFER$1, null); + + const bytesPerValue = getBytesPerValueForGLType(gl, attrib.type); + const totalElements = numBytes / bytesPerValue; + const numComponents = attrib.numComponents || attrib.size; + // TODO: check stride + const numElements = totalElements / numComponents; + if (numElements % 1 !== 0) { + throw new Error(`numComponents ${numComponents} not correct for length ${length}`); + } + return numElements; +} + +/** + * @typedef {Object} BufferInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLBuffer} [indices] The indices `ELEMENT_ARRAY_BUFFER` if any indices exist. + * @property {Object.} [attribs] The attribs appropriate to call `setAttributes` + * @memberOf module:twgl + */ + +/** + * Creates a BufferInfo from an object of arrays. + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl: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: { + * position: { buffer: WebGLBuffer, numComponents: 3, }, + * normal: { buffer: WebGLBuffer, numComponents: 3, }, + * 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 be 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: { + * position: { numComponents: 3, buffer: gl.createBuffer(), }, + * texcoord: { numComponents: 2, buffer: gl.createBuffer(), }, + * normal: { numComponents: 3, buffer: gl.createBuffer(), }, + * }, + * indices: gl.createBuffer(), + * numElements: 6, + * }; + * + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.position.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.position, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.texcoord.buffer); + * gl.bufferData(gl.ARRAY_BUFFER, arrays.texcoord, gl.STATIC_DRAW); + * gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.attribs.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 {module:twgl.Arrays} arrays Your data + * @param {module:twgl.BufferInfo} [srcBufferInfo] An existing + * buffer info to start from. WebGLBuffers etc specified + * in the srcBufferInfo will be used in a new BufferInfo + * with any arrays specified overriding the ones in + * srcBufferInfo. + * @return {module:twgl.BufferInfo} A BufferInfo + * @memberOf module:twgl/attributes + */ +function createBufferInfoFromArrays(gl, arrays, srcBufferInfo) { + const newAttribs = createAttribsFromArrays(gl, arrays); + const bufferInfo = Object.assign({}, srcBufferInfo ? srcBufferInfo : {}); + bufferInfo.attribs = Object.assign({}, srcBufferInfo ? srcBufferInfo.attribs : {}, newAttribs); + const indices = arrays.indices; + if (indices) { + const newIndices = makeTypedArray(indices, "indices"); + bufferInfo.indices = createBufferFromTypedArray(gl, newIndices, ELEMENT_ARRAY_BUFFER$2); + bufferInfo.numElements = newIndices.length; + bufferInfo.elementType = getGLTypeForTypedArray(newIndices); + } else if (!bufferInfo.numElements) { + bufferInfo.numElements = getNumElementsFromAttributes(gl, bufferInfo.attribs); + } + + return bufferInfo; +} + +/** + * Creates a buffer from an array, typed array, or array spec + * + * Given something like this + * + * [1, 2, 3], + * + * or + * + * new Uint16Array([1,2,3]); + * + * or + * + * { + * data: [1, 2, 3], + * type: Uint8Array, + * } + * + * returns a WebGLBuffer that contains the given data. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext. + * @param {module:twgl.ArraySpec} array an array, typed array, or array spec. + * @param {string} arrayName name of array. Used to guess the type if type can not be derived otherwise. + * @return {WebGLBuffer} a WebGLBuffer containing the data in array. + * @memberOf module:twgl/attributes + */ +function createBufferFromArray(gl, array, arrayName) { + const type = arrayName === "indices" ? ELEMENT_ARRAY_BUFFER$2 : ARRAY_BUFFER$1; + const typedArray = makeTypedArray(array, arrayName); + return createBufferFromTypedArray(gl, typedArray, type); +} + +/** + * Creates buffers from arrays or 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 {module:twgl.Arrays} arrays + * @return {Object} returns an object with one WebGLBuffer per array + * @memberOf module:twgl/attributes + */ +function createBuffersFromArrays(gl, arrays) { + const buffers = { }; + Object.keys(arrays).forEach(function(key) { + buffers[key] = createBufferFromArray(gl, arrays[key], key); + }); + + // Ugh! + if (arrays.indices) { + buffers.numElements = arrays.indices.length; + buffers.elementType = getGLTypeForTypedArray(makeTypedArray(arrays.indices)); + } else { + buffers.numElements = getNumElementsFromNonIndexedArrays(arrays); + } + + return buffers; +} + +var attributes = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttribsFromArrays: createAttribsFromArrays, + createBuffersFromArrays: createBuffersFromArrays, + createBufferFromArray: createBufferFromArray, + createBufferFromTypedArray: createBufferFromTypedArray, + createBufferInfoFromArrays: createBufferInfoFromArrays, + setAttribInfoBufferFromArray: setAttribInfoBufferFromArray, + setAttributePrefix: setAttributePrefix, + setAttributeDefaults_: setDefaults$2, + getNumComponents_: getNumComponents, + getArray_: getArray +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Gets the gl version as a number + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {number} version of gl + * @private + */ +//function getVersionAsNumber(gl) { +// return parseFloat(gl.getParameter(gl.VERSION).substr(6)); +//} + +/** + * Check if context is WebGL 2.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 2.0 + * @memberOf module:twgl + */ +function isWebGL2(gl) { + // This is the correct check but it's slow + // return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0") === 0; + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGL2RenderingContext; + return !!gl.texStorage2D; +} + +/** + * Check if context is WebGL 1.0 + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @return {bool} true if it's WebGL 1.0 + * @memberOf module:twgl + */ +function isWebGL1(gl) { + // This is the correct check but it's slow + // const version = getVersionAsNumber(gl); + // return version <= 1.0 && version > 0.0; // because as of 2016/5 Edge returns 0.96 + // This might also be the correct check but I'm assuming it's slow-ish + // return gl instanceof WebGLRenderingContext; + return !gl.texStorage2D; +} + +/** + * Gets a string for WebGL enum + * + * Note: Several enums are the same. Without more + * context (which function) it's impossible to always + * give the correct enum. As it is, for matching values + * it gives all enums. Checking the WebGL2RenderingContext + * that means + * + * 0 = ZERO | POINT | NONE | NO_ERROR + * 1 = ONE | LINES | SYNC_FLUSH_COMMANDS_BIT + * 32777 = BLEND_EQUATION_RGB | BLEND_EQUATION_RGB + * 36662 = COPY_READ_BUFFER | COPY_READ_BUFFER_BINDING + * 36663 = COPY_WRITE_BUFFER | COPY_WRITE_BUFFER_BINDING + * 36006 = FRAMEBUFFER_BINDING | DRAW_FRAMEBUFFER_BINDING + * + * It's also not useful for bits really unless you pass in individual bits. + * In other words + * + * const bits = gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT; + * twgl.glEnumToString(gl, bits); // not going to work + * + * Note that some enums only exist on extensions. If you + * want them to show up you need to pass the extension at least + * once. For example + * + * const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); + * if (ext) { + * twgl.glEnumToString(ext, 0); // just prime the function + * + * ..later.. + * + * const internalFormat = ext.COMPRESSED_RGB_S3TC_DXT1_EXT; + * console.log(twgl.glEnumToString(gl, internalFormat)); + * + * Notice I didn't have to pass the extension the second time. This means + * you can have place that generically gets an enum for texture formats for example. + * and as long as you primed the function with the extensions + * + * If you're using `twgl.addExtensionsToContext` to enable your extensions + * then twgl will automatically get the extension's enums. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext or any extension object + * @param {number} value the value of the enum you want to look up. + * @return {string} enum string or hex value + * @memberOf module:twgl + * @function glEnumToString + */ +const glEnumToString = (function() { + const haveEnumsForType = {}; + const enums = {}; + + function addEnums(gl) { + const type = gl.constructor.name; + if (!haveEnumsForType[type]) { + for (const key in gl) { + if (typeof gl[key] === 'number') { + const existing = enums[gl[key]]; + enums[gl[key]] = existing ? `${existing} | ${key}` : key; + } + } + haveEnumsForType[type] = true; + } + } + + return function glEnumToString(gl, value) { + addEnums(gl); + return enums[value] || (typeof value === 'number' ? `0x${value.toString(16)}` : value); + }; +}()); + +var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + glEnumToString: glEnumToString, + isWebGL1: isWebGL1, + isWebGL2: isWebGL2 +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults$1 = { + textureColor: new Uint8Array([128, 192, 255, 255]), + textureOptions: {}, + crossOrigin: undefined, +}; +const isArrayBuffer = isArrayBuffer$1; + +// Should we make this on demand? +const getShared2DContext = function() { + let s_ctx; + return function getShared2DContext() { + s_ctx = s_ctx || + ((typeof document !== 'undefined' && document.createElement) + ? document.createElement("canvas").getContext("2d") + : null); + return s_ctx; + }; +}(); + +// NOTE: Chrome supports 2D canvas in a Worker (behind flag as of v64 but +// not only does Firefox NOT support it but Firefox freezes immediately +// if you try to create one instead of just returning null and continuing. +// : (global.OffscreenCanvas && (new global.OffscreenCanvas(1, 1)).getContext("2d")); // OffscreenCanvas may not support 2d + +// NOTE: We can maybe remove some of the need for the 2d canvas. In WebGL2 +// we can use the various unpack settings. Otherwise we could try using +// the ability of an ImageBitmap to be cut. Unfortunately cutting an ImageBitmap +// is async and the current TWGL code expects a non-Async result though that +// might not be a problem. ImageBitmap though is not available in Edge or Safari +// as of 2018-01-02 + +/* PixelFormat */ +const ALPHA = 0x1906; +const RGB = 0x1907; +const RGBA$1 = 0x1908; +const LUMINANCE = 0x1909; +const LUMINANCE_ALPHA = 0x190A; +const DEPTH_COMPONENT$1 = 0x1902; +const DEPTH_STENCIL$1 = 0x84F9; + +/* TextureWrapMode */ +// const REPEAT = 0x2901; +// const MIRRORED_REPEAT = 0x8370; +const CLAMP_TO_EDGE$1 = 0x812f; + +/* TextureMagFilter */ +const NEAREST = 0x2600; +const LINEAR$1 = 0x2601; + +/* TextureMinFilter */ +// const NEAREST_MIPMAP_NEAREST = 0x2700; +// const LINEAR_MIPMAP_NEAREST = 0x2701; +// const NEAREST_MIPMAP_LINEAR = 0x2702; +// const LINEAR_MIPMAP_LINEAR = 0x2703; + +/* Texture Target */ +const TEXTURE_2D$2 = 0x0de1; +const TEXTURE_CUBE_MAP$1 = 0x8513; +const TEXTURE_3D$1 = 0x806f; +const TEXTURE_2D_ARRAY$1 = 0x8c1a; + +/* Cubemap Targets */ +const TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; +const TEXTURE_CUBE_MAP_NEGATIVE_X = 0x8516; +const TEXTURE_CUBE_MAP_POSITIVE_Y = 0x8517; +const TEXTURE_CUBE_MAP_NEGATIVE_Y = 0x8518; +const TEXTURE_CUBE_MAP_POSITIVE_Z = 0x8519; +const TEXTURE_CUBE_MAP_NEGATIVE_Z = 0x851a; + +/* Texture Parameters */ +const TEXTURE_MIN_FILTER = 0x2801; +const TEXTURE_MAG_FILTER = 0x2800; +const TEXTURE_WRAP_S = 0x2802; +const TEXTURE_WRAP_T = 0x2803; +const TEXTURE_WRAP_R = 0x8072; +const TEXTURE_MIN_LOD = 0x813a; +const TEXTURE_MAX_LOD = 0x813b; +const TEXTURE_BASE_LEVEL = 0x813c; +const TEXTURE_MAX_LEVEL = 0x813d; +const TEXTURE_COMPARE_MODE = 0x884C; +const TEXTURE_COMPARE_FUNC = 0x884D; + +/* Pixel store */ +const UNPACK_ALIGNMENT = 0x0cf5; +const UNPACK_ROW_LENGTH = 0x0cf2; +const UNPACK_IMAGE_HEIGHT = 0x806e; +const UNPACK_SKIP_PIXELS = 0x0cf4; +const UNPACK_SKIP_ROWS = 0x0cf3; +const UNPACK_SKIP_IMAGES = 0x806d; +const UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +const UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; +const UNPACK_FLIP_Y_WEBGL = 0x9240; + +const R8 = 0x8229; +const R8_SNORM = 0x8F94; +const R16F = 0x822D; +const R32F = 0x822E; +const R8UI = 0x8232; +const R8I = 0x8231; +const RG16UI = 0x823A; +const RG16I = 0x8239; +const RG32UI = 0x823C; +const RG32I = 0x823B; +const RG8 = 0x822B; +const RG8_SNORM = 0x8F95; +const RG16F = 0x822F; +const RG32F = 0x8230; +const RG8UI = 0x8238; +const RG8I = 0x8237; +const R16UI = 0x8234; +const R16I = 0x8233; +const R32UI = 0x8236; +const R32I = 0x8235; +const RGB8 = 0x8051; +const SRGB8 = 0x8C41; +const RGB565$1 = 0x8D62; +const RGB8_SNORM = 0x8F96; +const R11F_G11F_B10F = 0x8C3A; +const RGB9_E5 = 0x8C3D; +const RGB16F = 0x881B; +const RGB32F = 0x8815; +const RGB8UI = 0x8D7D; +const RGB8I = 0x8D8F; +const RGB16UI = 0x8D77; +const RGB16I = 0x8D89; +const RGB32UI = 0x8D71; +const RGB32I = 0x8D83; +const RGBA8 = 0x8058; +const SRGB8_ALPHA8 = 0x8C43; +const RGBA8_SNORM = 0x8F97; +const RGB5_A1$1 = 0x8057; +const RGBA4$1 = 0x8056; +const RGB10_A2 = 0x8059; +const RGBA16F = 0x881A; +const RGBA32F = 0x8814; +const RGBA8UI = 0x8D7C; +const RGBA8I = 0x8D8E; +const RGB10_A2UI = 0x906F; +const RGBA16UI = 0x8D76; +const RGBA16I = 0x8D88; +const RGBA32I = 0x8D82; +const RGBA32UI = 0x8D70; + +const DEPTH_COMPONENT16$1 = 0x81A5; +const DEPTH_COMPONENT24$1 = 0x81A6; +const DEPTH_COMPONENT32F$1 = 0x8CAC; +const DEPTH32F_STENCIL8$1 = 0x8CAD; +const DEPTH24_STENCIL8$1 = 0x88F0; + +/* DataType */ +const BYTE = 0x1400; +const UNSIGNED_BYTE$1 = 0x1401; +const SHORT = 0x1402; +const UNSIGNED_SHORT$1 = 0x1403; +const INT$1 = 0x1404; +const UNSIGNED_INT$1 = 0x1405; +const FLOAT$1 = 0x1406; +const UNSIGNED_SHORT_4_4_4_4 = 0x8033; +const UNSIGNED_SHORT_5_5_5_1 = 0x8034; +const UNSIGNED_SHORT_5_6_5 = 0x8363; +const HALF_FLOAT = 0x140B; +const HALF_FLOAT_OES = 0x8D61; // Thanks Khronos for making this different >:( +const UNSIGNED_INT_2_10_10_10_REV = 0x8368; +const UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; +const UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; +const FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; +const UNSIGNED_INT_24_8 = 0x84FA; + +const RG = 0x8227; +const RG_INTEGER = 0x8228; +const RED = 0x1903; +const RED_INTEGER = 0x8D94; +const RGB_INTEGER = 0x8D98; +const RGBA_INTEGER = 0x8D99; + +const formatInfo = {}; +{ + // NOTE: this is named `numColorComponents` vs `numComponents` so we can let Uglify mangle + // the name. + const f = formatInfo; + f[ALPHA] = { numColorComponents: 1, }; + f[LUMINANCE] = { numColorComponents: 1, }; + f[LUMINANCE_ALPHA] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RED] = { numColorComponents: 1, }; + f[RED_INTEGER] = { numColorComponents: 1, }; + f[RG] = { numColorComponents: 2, }; + f[RG_INTEGER] = { numColorComponents: 2, }; + f[RGB] = { numColorComponents: 3, }; + f[RGB_INTEGER] = { numColorComponents: 3, }; + f[RGBA$1] = { numColorComponents: 4, }; + f[RGBA_INTEGER] = { numColorComponents: 4, }; + f[DEPTH_COMPONENT$1] = { numColorComponents: 1, }; + f[DEPTH_STENCIL$1] = { numColorComponents: 2, }; +} + +/** + * @typedef {Object} TextureFormatDetails + * @property {number} textureFormat format to pass texImage2D and similar functions. + * @property {boolean} colorRenderable true if you can render to this format of texture. + * @property {boolean} textureFilterable true if you can filter the texture, false if you can ony use `NEAREST`. + * @property {number[]} type Array of possible types you can pass to texImage2D and similar function + * @property {Object.} bytesPerElementMap A map of types to bytes per element + * @private + */ + +let s_textureInternalFormatInfo; +function getTextureInternalFormatInfo(internalFormat) { + if (!s_textureInternalFormatInfo) { + // NOTE: these properties need unique names so we can let Uglify mangle the name. + const t = {}; + // unsized formats + t[ALPHA] = { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE] = { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[LUMINANCE_ALPHA] = { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1], }; + t[RGB] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_5_6_5], }; + t[RGBA$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE$1, HALF_FLOAT, HALF_FLOAT_OES, FLOAT$1, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1], }; + t[DEPTH_COMPONENT$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_INT$1, UNSIGNED_SHORT$1], }; + + // sized formats + t[R8] = { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8_SNORM] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE], }; + t[R16F] = { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT$1, HALF_FLOAT], }; + t[R32F] = { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[R8UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE$1], }; + t[R8I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE], }; + t[R16UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT$1], }; + t[R16I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT], }; + t[R32UI] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[R32I] = { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT$1], }; + t[RG8] = { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8_SNORM] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE], }; + t[RG16F] = { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT$1, HALF_FLOAT], }; + t[RG32F] = { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT$1], }; + t[RG8UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE$1], }; + t[RG8I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE], }; + t[RG16UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT$1], }; + t[RG16I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT], }; + t[RG32UI] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT$1], }; + t[RG32I] = { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT$1], }; + t[RGB8] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[SRGB8] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB565$1] = { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_6_5], }; + t[RGB8_SNORM] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE], }; + t[R11F_G11F_B10F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV], }; + t[RGB9_E5] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV], }; + t[RGB16F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT$1, HALF_FLOAT], }; + t[RGB32F] = { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT$1], }; + t[RGB8UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE$1], }; + t[RGB8I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE], }; + t[RGB16UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT$1], }; + t[RGB16I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT], }; + t[RGB32UI] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT$1], }; + t[RGB32I] = { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT$1], }; + t[RGBA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[SRGB8_ALPHA8] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8_SNORM] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE], }; + t[RGB5_A1$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA4$1] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_4_4_4_4], }; + t[RGB10_A2] = { textureFormat: RGBA$1, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT$1, HALF_FLOAT], }; + t[RGBA32F] = { textureFormat: RGBA$1, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT$1], }; + t[RGBA8UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE$1], }; + t[RGBA8I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE], }; + t[RGB10_A2UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV], }; + t[RGBA16UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT$1], }; + t[RGBA16I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT], }; + t[RGBA32I] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT$1], }; + t[RGBA32UI] = { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT$1], }; + // Sized Internal + t[DEPTH_COMPONENT16$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT$1, UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT24$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1], }; + t[DEPTH_COMPONENT32F$1] = { textureFormat: DEPTH_COMPONENT$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1], }; + t[DEPTH24_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8], }; + t[DEPTH32F_STENCIL8$1] = { textureFormat: DEPTH_STENCIL$1, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV], }; + + Object.keys(t).forEach(function(internalFormat) { + const info = t[internalFormat]; + info.bytesPerElementMap = {}; + info.bytesPerElement.forEach(function(bytesPerElement, ndx) { + const type = info.type[ndx]; + info.bytesPerElementMap[type] = bytesPerElement; + }); + }); + s_textureInternalFormatInfo = t; + } + return s_textureInternalFormatInfo[internalFormat]; +} + +/** + * Gets the number of bytes per element for a given internalFormat / type + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @param {number} type The type parameter for texImage2D etc.. + * @return {number} the number of bytes per element for the given internalFormat, type combo + * @memberOf module:twgl/textures + */ +function getBytesPerElementForInternalFormat(internalFormat, type) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + const bytesPerElement = info.bytesPerElementMap[type]; + if (bytesPerElement === undefined) { + throw "unknown internal format"; + } + return bytesPerElement; +} + +/** + * Info related to a specific texture internalFormat as returned + * from {@link module:twgl/textures.getFormatAndTypeForInternalFormat}. + * + * @typedef {Object} TextureFormatInfo + * @property {number} format Format to pass to texImage2D and related functions + * @property {number} type Type to pass to texImage2D and related functions + * @memberOf module:twgl/textures + */ + +/** + * Gets the format and type for a given internalFormat + * + * @param {number} internalFormat The internal format + * @return {module:twgl/textures.TextureFormatInfo} the corresponding format and type, + * @memberOf module:twgl/textures + */ +function getFormatAndTypeForInternalFormat(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return { + format: info.textureFormat, + type: info.type[0], + }; +} + +/** + * Returns true if value is power of 2 + * @param {number} value number to check. + * @return true if value is power of 2 + * @private + */ +function isPowerOf2(value) { + return (value & (value - 1)) === 0; +} + +/** + * Gets whether or not we can generate mips for the given + * internal format. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number} width The width parameter from texImage2D etc.. + * @param {number} height The height parameter from texImage2D etc.. + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canGenerateMipmap(gl, width, height, internalFormat) { + if (!isWebGL2(gl)) { + return isPowerOf2(width) && isPowerOf2(height); + } + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.colorRenderable && info.textureFilterable; +} + +/** + * Gets whether or not we can generate mips for the given format + * @param {number} internalFormat The internalFormat parameter from texImage2D etc.. + * @return {boolean} true if we can generate mips + * @memberOf module:twgl/textures + */ +function canFilter(internalFormat) { + const info = getTextureInternalFormatInfo(internalFormat); + if (!info) { + throw "unknown internal format"; + } + return info.textureFilterable; +} + +/** + * Gets the number of components for a given image format. + * @param {number} format the format. + * @return {number} the number of components for the format. + * @memberOf module:twgl/textures + */ +function getNumComponentsForFormat(format) { + const info = formatInfo[format]; + if (!info) { + throw "unknown format: " + format; + } + return info.numColorComponents; +} + +/** + * Gets the texture type for a given array type. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @return {number} the gl texture type + * @private + */ +function getTextureTypeForArrayType(gl, src, defaultType) { + if (isArrayBuffer(src)) { + return getGLTypeForTypedArray(src); + } + return defaultType || UNSIGNED_BYTE$1; +} + +function guessDimensions(gl, target, width, height, numElements) { + if (numElements % 1 !== 0) { + throw "can't guess dimensions"; + } + if (!width && !height) { + const size = Math.sqrt(numElements / (target === TEXTURE_CUBE_MAP$1 ? 6 : 1)); + if (size % 1 === 0) { + width = size; + height = size; + } else { + width = numElements; + height = 1; + } + } else if (!height) { + height = numElements / width; + if (height % 1) { + throw "can't guess dimensions"; + } + } else if (!width) { + width = numElements / height; + if (width % 1) { + throw "can't guess dimensions"; + } + } + return { + width: width, + height: height, + }; +} + +/** + * Sets the default texture color. + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * @param {number[]} color Array of 4 values in the range 0 to 1 + * @deprecated see {@link module:twgl.setDefaults} + * @memberOf module:twgl/textures + */ +function setDefaultTextureColor(color) { + defaults$1.textureColor = new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +function setDefaults$1(newDefaults) { + copyExistingProperties(newDefaults, defaults$1); + if (newDefaults.textureColor) { + setDefaultTextureColor(newDefaults.textureColor); + } +} + +/** + * A function to generate the source for a texture. + * @callback TextureFunc + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.TextureOptions} options the texture options + * @return {*} Returns any of the things documented for `src` for {@link module:twgl.TextureOptions}. + * @memberOf module:twgl + */ + +/** + * Texture options passed to most texture functions. Each function will use whatever options + * are appropriate for its needs. This lets you pass the same options to all functions. + * + * Note: A `TexImageSource` is defined in the WebGL spec as a `HTMLImageElement`, `HTMLVideoElement`, + * `HTMLCanvasElement`, `ImageBitmap`, or `ImageData`. + * + * @typedef {Object} TextureOptions + * @property {number} [target] the type of texture `gl.TEXTURE_2D` or `gl.TEXTURE_CUBE_MAP`. Defaults to `gl.TEXTURE_2D`. + * @property {number} [level] the mip level to affect. Defaults to 0. Note, if set auto will be considered false unless explicitly set to true. + * @property {number} [width] the width of the texture. Only used if src is an array or typed array or null. + * @property {number} [height] the height of a texture. Only used if src is an array or typed array or null. + * @property {number} [depth] the depth of a texture. Only used if src is an array or type array or null and target is `TEXTURE_3D` . + * @property {number} [min] the min filter setting (eg. `gl.LINEAR`). Defaults to `gl.NEAREST_MIPMAP_LINEAR` + * or if texture is not a power of 2 on both dimensions then defaults to `gl.LINEAR`. + * @property {number} [mag] the mag filter setting (eg. `gl.LINEAR`). Defaults to `gl.LINEAR` + * @property {number} [minMag] both the min and mag filter settings. + * @property {number} [internalFormat] internal format for texture. Defaults to `gl.RGBA` + * @property {number} [format] format for texture. Defaults to `gl.RGBA`. + * @property {number} [type] type for texture. Defaults to `gl.UNSIGNED_BYTE` unless `src` is ArrayBufferView. If `src` + * is ArrayBufferView defaults to type that matches ArrayBufferView type. + * @property {number} [wrap] Texture wrapping for both S and T (and R if TEXTURE_3D or WebGLSampler). Defaults to `gl.REPEAT` for 2D unless src is WebGL1 and src not npot and `gl.CLAMP_TO_EDGE` for cube + * @property {number} [wrapS] Texture wrapping for S. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapT] Texture wrapping for T. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [wrapR] Texture wrapping for R. Defaults to `gl.REPEAT` and `gl.CLAMP_TO_EDGE` for cube. If set takes precedence over `wrap`. + * @property {number} [minLod] TEXTURE_MIN_LOD setting + * @property {number} [maxLod] TEXTURE_MAX_LOD setting + * @property {number} [baseLevel] TEXTURE_BASE_LEVEL setting + * @property {number} [maxLevel] TEXTURE_MAX_LEVEL setting + * @property {number} [compareFunc] TEXTURE_COMPARE_FUNC setting + * @property {number} [compareMode] TEXTURE_COMPARE_MODE setting + * @property {number} [unpackAlignment] The `gl.UNPACK_ALIGNMENT` used when uploading an array. Defaults to 1. + * @property {number[]|ArrayBufferView} [color] Color to initialize this texture with if loading an image asynchronously. + * The default use a blue 1x1 pixel texture. You can set another default by calling `twgl.setDefaults` + * or you can set an individual texture's initial color by setting this property. Example: `[1, .5, .5, 1]` = pink + * @property {number} [premultiplyAlpha] Whether or not to premultiply alpha. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [flipY] Whether or not to flip the texture vertically on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {number} [colorspaceConversion] Whether or not to let the browser do colorspace conversion of the texture on upload. Defaults to whatever the current setting is. + * This lets you set it once before calling `twgl.createTexture` or `twgl.createTextures` and only override + * the current setting for specific textures. + * @property {boolean} [auto] If `undefined` or `true`, in WebGL1, texture filtering is set automatically for non-power of 2 images and + * mips are generated for power of 2 images. In WebGL2 mips are generated if they can be. Note: if `level` is set above + * then then `auto` is assumed to be `false` unless explicity set to `true`. + * @property {number[]} [cubeFaceOrder] The order that cube faces are pulled out of an img or set of images. The default is + * + * [gl.TEXTURE_CUBE_MAP_POSITIVE_X, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_X, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Y, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, + * gl.TEXTURE_CUBE_MAP_POSITIVE_Z, + * gl.TEXTURE_CUBE_MAP_NEGATIVE_Z] + * + * @property {(number[]|ArrayBufferView|TexImageSource|TexImageSource[]|string|string[]|module:twgl.TextureFunc)} [src] source for texture + * + * If `string` then it's assumed to be a URL to an image. The image will be downloaded async. A usable + * 1x1 pixel texture will be returned immediately. The texture will be updated once the image has downloaded. + * If `target` is `gl.TEXTURE_CUBE_MAP` will attempt to divide image into 6 square pieces. 1x6, 6x1, 3x2, 2x3. + * The pieces will be uploaded in `cubeFaceOrder` + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_CUBE_MAP` then it must have 6 entries, one for each face of a cube map. + * + * If `string[]` or `TexImageSource[]` and target is `gl.TEXTURE_2D_ARRAY` then each entry is a slice of the a 2d array texture + * and will be scaled to the specified width and height OR to the size of the first image that loads. + * + * If `TexImageSource` then it wil be used immediately to create the contents of the texture. Examples `HTMLImageElement`, + * `HTMLCanvasElement`, `HTMLVideoElement`. + * + * If `number[]` or `ArrayBufferView` it's assumed to be data for a texture. If `width` or `height` is + * not specified it is guessed as follows. First the number of elements is computed by `src.length / numComponents` + * where `numComponents` is derived from `format`. If `target` is `gl.TEXTURE_CUBE_MAP` then `numElements` is divided + * by 6. Then + * + * * If neither `width` nor `height` are specified and `sqrt(numElements)` is an integer then width and height + * are set to `sqrt(numElements)`. Otherwise `width = numElements` and `height = 1`. + * + * * If only one of `width` or `height` is specified then the other equals `numElements / specifiedDimension`. + * + * If `number[]` will be converted to `type`. + * + * If `src` is a function it will be called with a `WebGLRenderingContext` and these options. + * Whatever it returns is subject to these rules. So it can return a string url, an `HTMLElement` + * an array etc... + * + * If `src` is undefined then an empty texture will be created of size `width` by `height`. + * + * @property {string} [crossOrigin] What to set the crossOrigin property of images when they are downloaded. + * default: undefined. Also see {@link module:twgl.setDefaults}. + * + * @memberOf module:twgl + */ + +/** + * Saves the current packing state, sets the packing state as specified + * then calls a function, after which the packing state will be restored. + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {function():void} [fn] A function to call, after which the packing state will be restored. + * @private + */ +function scopedSetPackState(gl, options, fn) { + let colorspaceConversion; + let premultiplyAlpha; + let flipY; + + if (options.colorspaceConversion !== undefined) { + colorspaceConversion = gl.getParameter(UNPACK_COLORSPACE_CONVERSION_WEBGL); + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, options.colorspaceConversion); + } + if (options.premultiplyAlpha !== undefined) { + premultiplyAlpha = gl.getParameter(UNPACK_PREMULTIPLY_ALPHA_WEBGL); + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, options.premultiplyAlpha); + } + if (options.flipY !== undefined) { + flipY = gl.getParameter(UNPACK_FLIP_Y_WEBGL); + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, options.flipY); + } + + fn(); + + if (colorspaceConversion !== undefined) { + gl.pixelStorei(UNPACK_COLORSPACE_CONVERSION_WEBGL, colorspaceConversion); + } + if (premultiplyAlpha !== undefined) { + gl.pixelStorei(UNPACK_PREMULTIPLY_ALPHA_WEBGL, premultiplyAlpha); + } + if (flipY !== undefined) { + gl.pixelStorei(UNPACK_FLIP_Y_WEBGL, flipY); + } +} + +/** + * Set skip state to defaults + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @private + */ +function setSkipStateToDefault(gl) { + gl.pixelStorei(UNPACK_ALIGNMENT, 4); + if (isWebGL2(gl)) { + gl.pixelStorei(UNPACK_ROW_LENGTH, 0); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_PIXELS, 0); + gl.pixelStorei(UNPACK_SKIP_ROWS, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + } +} + +/** + * Sets the parameters of a texture or sampler + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {number|WebGLSampler} target texture target or sampler + * @param {function()} parameteriFn texParameteri or samplerParameteri fn + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @private + */ +function setTextureSamplerParameters(gl, target, parameteriFn, options) { + if (options.minMag) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.minMag); + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.minMag); + } + if (options.min) { + parameteriFn.call(gl, target, TEXTURE_MIN_FILTER, options.min); + } + if (options.mag) { + parameteriFn.call(gl, target, TEXTURE_MAG_FILTER, options.mag); + } + if (options.wrap) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrap); + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrap); + if (target === TEXTURE_3D$1 || isSampler(gl, target)) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrap); + } + } + if (options.wrapR) { + parameteriFn.call(gl, target, TEXTURE_WRAP_R, options.wrapR); + } + if (options.wrapS) { + parameteriFn.call(gl, target, TEXTURE_WRAP_S, options.wrapS); + } + if (options.wrapT) { + parameteriFn.call(gl, target, TEXTURE_WRAP_T, options.wrapT); + } + if (options.minLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MIN_LOD, options.minLod); + } + if (options.maxLod !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LOD, options.maxLod); + } + if (options.baseLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_BASE_LEVEL, options.baseLevel); + } + if (options.maxLevel !== undefined) { + parameteriFn.call(gl, target, TEXTURE_MAX_LEVEL, options.maxLevel); + } + if (options.compareFunc !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_FUNC, options.compareFunc); + } + if (options.compareMode !== undefined) { + parameteriFn.call(gl, target, TEXTURE_COMPARE_MODE, options.compareMode); + } +} + +/** + * Sets the texture parameters of a texture. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureParameters(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + setTextureSamplerParameters(gl, target, gl.texParameteri, options); +} + +/** + * Sets the sampler parameters of a sampler. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLSampler} sampler the WebGLSampler to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setSamplerParameters(gl, sampler, options) { + setTextureSamplerParameters(gl, sampler, gl.samplerParameteri, options); +} + +/** + * Creates a new sampler object and sets parameters. + * + * Example: + * + * const sampler = twgl.createSampler(gl, { + * minMag: gl.NEAREST, // sets both TEXTURE_MIN_FILTER and TEXTURE_MAG_FILTER + * wrap: gl.CLAMP_TO_NEAREST, // sets both TEXTURE_WRAP_S and TEXTURE_WRAP_T and TEXTURE_WRAP_R + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per sampler. + * @return {Object.} the created samplers by name + * @private + */ +function createSampler(gl, options) { + const sampler = gl.createSampler(); + setSamplerParameters(gl, sampler, options); + return sampler; +} + +/** + * Creates a multiple sampler objects and sets parameters on each. + * + * Example: + * + * const samplers = twgl.createSamplers(gl, { + * nearest: { + * minMag: gl.NEAREST, + * }, + * nearestClampS: { + * minMag: gl.NEAREST, + * wrapS: gl.CLAMP_TO_NEAREST, + * }, + * linear: { + * minMag: gl.LINEAR, + * }, + * nearestClamp: { + * minMag: gl.NEAREST, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClamp: { + * minMag: gl.LINEAR, + * wrap: gl.CLAMP_TO_EDGE, + * }, + * linearClampT: { + * minMag: gl.LINEAR, + * wrapT: gl.CLAMP_TO_EDGE, + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set on the sampler + * @private + */ +function createSamplers(gl, samplerOptions) { + const samplers = {}; + Object.keys(samplerOptions).forEach(function(name) { + samplers[name] = createSampler(gl, samplerOptions[name]); + }); + return samplers; +} + +/** + * Makes a 1x1 pixel + * If no color is passed in uses the default color which can be set by calling `setDefaultTextureColor`. + * @param {(number[]|ArrayBufferView)} [color] The color using 0-1 values + * @return {Uint8Array} Unit8Array with color. + * @private + */ +function make1Pixel(color) { + color = color || defaults$1.textureColor; + if (isArrayBuffer(color)) { + return color; + } + return new Uint8Array([color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255]); +} + +/** + * Sets filtering or generates mips for texture based on width or height + * If width or height is not passed in uses `options.width` and//or `options.height` + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @param {number} [width] width of texture + * @param {number} [height] height of texture + * @param {number} [internalFormat] The internalFormat parameter from texImage2D etc.. + * @memberOf module:twgl/textures + */ +function setTextureFilteringForSize(gl, tex, options, width, height, internalFormat) { + options = options || defaults$1.textureOptions; + internalFormat = internalFormat || RGBA$1; + const target = options.target || TEXTURE_2D$2; + width = width || options.width; + height = height || options.height; + gl.bindTexture(target, tex); + if (canGenerateMipmap(gl, width, height, internalFormat)) { + gl.generateMipmap(target); + } else { + const filtering = canFilter(internalFormat) ? LINEAR$1 : NEAREST; + gl.texParameteri(target, TEXTURE_MIN_FILTER, filtering); + gl.texParameteri(target, TEXTURE_MAG_FILTER, filtering); + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } +} + +function shouldAutomaticallySetTextureFilteringForSize(options) { + return options.auto === true || (options.auto === undefined && options.level === undefined); +} + +/** + * Gets an array of cubemap face enums + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @return {number[]} cubemap face enums + * @private + */ +function getCubeFaceOrder(gl, options) { + options = options || {}; + return options.cubeFaceOrder || [ + TEXTURE_CUBE_MAP_POSITIVE_X, + TEXTURE_CUBE_MAP_NEGATIVE_X, + TEXTURE_CUBE_MAP_POSITIVE_Y, + TEXTURE_CUBE_MAP_NEGATIVE_Y, + TEXTURE_CUBE_MAP_POSITIVE_Z, + TEXTURE_CUBE_MAP_NEGATIVE_Z, + ]; +} + +/** + * @typedef {Object} FaceInfo + * @property {number} face gl enum for texImage2D + * @property {number} ndx face index (0 - 5) into source data + * @ignore + */ + +/** + * Gets an array of FaceInfos + * There's a bug in some NVidia drivers that will crash the driver if + * `gl.TEXTURE_CUBE_MAP_POSITIVE_X` is not uploaded first. So, we take + * the user's desired order from his faces to WebGL and make sure we + * do the faces in WebGL order + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @return {FaceInfo[]} cubemap face infos. Arguably the `face` property of each element is redundant but + * it's needed internally to sort the array of `ndx` properties by `face`. + * @private + */ +function getCubeFacesWithNdx(gl, options) { + const faces = getCubeFaceOrder(gl, options); + // work around bug in NVidia drivers. We have to upload the first face first else the driver crashes :( + const facesWithNdx = faces.map(function(face, ndx) { + return { face: face, ndx: ndx }; + }); + facesWithNdx.sort(function(a, b) { + return a.face - b.face; + }); + return facesWithNdx; +} + +/** + * Set a texture from the contents of an element. Will also set + * texture filtering or generate mips based on the dimensions of the element + * unless `options.auto === false`. If `target === gl.TEXTURE_CUBE_MAP` will + * attempt to slice image into 1x6, 2x3, 3x2, or 6x1 images, one for each face. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {HTMLElement} element a canvas, img, or video element. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @kind function + */ +function setTextureFromElement(gl, tex, element, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + const level = options.level || 0; + let width = element.width; + let height = element.height; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // guess the parts + const imgWidth = element.width; + const imgHeight = element.height; + let size; + let slices; + if (imgWidth / 6 === imgHeight) { + // It's 6x1 + size = imgHeight; + slices = [0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0]; + } else if (imgHeight / 6 === imgWidth) { + // It's 1x6 + size = imgWidth; + slices = [0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5]; + } else if (imgWidth / 3 === imgHeight / 2) { + // It's 3x2 + size = imgWidth / 3; + slices = [0, 0, 1, 0, 2, 0, 0, 1, 1, 1, 2, 1]; + } else if (imgWidth / 2 === imgHeight / 3) { + // It's 2x3 + size = imgWidth / 2; + slices = [0, 0, 1, 0, 0, 1, 1, 1, 0, 2, 1, 2]; + } else { + throw "can't figure out cube map from element: " + (element.src ? element.src : element.nodeName); + } + const ctx = getShared2DContext(); + if (ctx) { + ctx.canvas.width = size; + ctx.canvas.height = size; + width = size; + height = size; + scopedSetPackState(gl, options, () => { + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + ctx.drawImage(element, xOffset, yOffset, size, size, 0, 0, size, size); + gl.texImage2D(f.face, level, internalFormat, format, type, ctx.canvas); + }); + // Free up the canvas memory + ctx.canvas.width = 1; + ctx.canvas.height = 1; + }); + } else if (typeof createImageBitmap !== 'undefined') { + // NOTE: It seems like we should prefer ImageBitmap because unlike canvas it's + // note lossy? (alpha is not premultiplied? although I'm not sure what + width = size; + height = size; + getCubeFacesWithNdx(gl, options).forEach(function(f) { + const xOffset = slices[f.ndx * 2 + 0] * size; + const yOffset = slices[f.ndx * 2 + 1] * size; + // We can't easily use a default texture color here as it would have to match + // the type across all faces where as with a 2D one there's only one face + // so we're replacing everything all at once. It also has to be the correct size. + // On the other hand we need all faces to be the same size so as one face loads + // the rest match else the texture will be un-renderable. + gl.texImage2D(f.face, level, internalFormat, size, size, 0, format, type, null); + createImageBitmap(element, xOffset, yOffset, size, size, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }) + .then(function(imageBitmap) { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + gl.texImage2D(f.face, level, internalFormat, format, type, imageBitmap); + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + }); + }); + }); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + scopedSetPackState(gl, options, () => { + const smallest = Math.min(element.width, element.height); + const largest = Math.max(element.width, element.height); + const depth = largest / smallest; + if (depth % 1 !== 0) { + throw "can not compute 3D dimensions of element"; + } + const xMult = element.width === largest ? 1 : 0; + const yMult = element.height === largest ? 1 : 0; + gl.pixelStorei(UNPACK_ALIGNMENT, 1); + gl.pixelStorei(UNPACK_ROW_LENGTH, element.width); + gl.pixelStorei(UNPACK_IMAGE_HEIGHT, 0); + gl.pixelStorei(UNPACK_SKIP_IMAGES, 0); + gl.texImage3D(target, level, internalFormat, smallest, smallest, smallest, 0, format, type, null); + for (let d = 0; d < depth; ++d) { + const srcX = d * smallest * xMult; + const srcY = d * smallest * yMult; + gl.pixelStorei(UNPACK_SKIP_PIXELS, srcX); + gl.pixelStorei(UNPACK_SKIP_ROWS, srcY); + gl.texSubImage3D(target, level, 0, 0, d, smallest, smallest, 1, format, type, element); + } + setSkipStateToDefault(gl); + }); + } else { + scopedSetPackState(gl, options, () => { + gl.texImage2D(target, level, internalFormat, format, type, element); + }); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); +} + +function noop() { +} + +/** + * Checks whether the url's origin is the same so that we can set the `crossOrigin` + * @param {string} url url to image + * @returns {boolean} true if the window's origin is the same as image's url + * @private + */ +function urlIsSameOrigin(url) { + if (typeof document !== 'undefined') { + // for IE really + const a = document.createElement('a'); + a.href = url; + return a.hostname === location.hostname && + a.port === location.port && + a.protocol === location.protocol; + } else { + const localOrigin = (new URL(location.href)).origin; + const urlOrigin = (new URL(url, location.href)).origin; + return urlOrigin === localOrigin; + } +} + +function setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin) { + return crossOrigin === undefined && !urlIsSameOrigin(url) + ? 'anonymous' + : crossOrigin; +} + +/** + * Loads an image + * @param {string} url url to image + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @return {HTMLImageElement} the image being loaded. + * @private + */ +function loadImage(url, crossOrigin, callback) { + callback = callback || noop; + let img; + crossOrigin = crossOrigin !== undefined ? crossOrigin : defaults$1.crossOrigin; + crossOrigin = setToAnonymousIfUndefinedAndURLIsNotSameOrigin(url, crossOrigin); + if (typeof Image !== 'undefined') { + img = new Image(); + if (crossOrigin !== undefined) { + img.crossOrigin = crossOrigin; + } + + const clearEventHandlers = function clearEventHandlers() { + img.removeEventListener('error', onError); // eslint-disable-line + img.removeEventListener('load', onLoad); // eslint-disable-line + img = null; + }; + + const onError = function onError() { + const msg = "couldn't load image: " + url; + error$1(msg); + callback(msg, img); + clearEventHandlers(); + }; + + const onLoad = function onLoad() { + callback(null, img); + clearEventHandlers(); + }; + + img.addEventListener('error', onError); + img.addEventListener('load', onLoad); + img.src = url; + return img; + } else if (typeof ImageBitmap !== 'undefined') { + let err; + let bm; + const cb = function cb() { + callback(err, bm); + }; + + const options = {}; + if (crossOrigin) { + options.mode = 'cors'; // TODO: not sure how to translate image.crossOrigin + } + fetch(url, options).then(function(response) { + if (!response.ok) { + throw response; + } + return response.blob(); + }).then(function(blob) { + return createImageBitmap(blob, { + premultiplyAlpha: 'none', + colorSpaceConversion: 'none', + }); + }).then(function(bitmap) { + // not sure if this works. We don't want + // to catch the user's error. So, call + // the callback in a timeout so we're + // not in this scope inside the promise. + bm = bitmap; + setTimeout(cb); + }).catch(function(e) { + err = e; + setTimeout(cb); + }); + img = null; + } + return img; +} + +/** + * check if object is a TexImageSource + * + * @param {Object} obj Object to test + * @return {boolean} true if object is a TexImageSource + * @private + */ +function isTexImageSource(obj) { + return (typeof ImageBitmap !== 'undefined' && obj instanceof ImageBitmap) || + (typeof ImageData !== 'undefined' && obj instanceof ImageData) || + (typeof HTMLElement !== 'undefined' && obj instanceof HTMLElement); +} + +/** + * if obj is an TexImageSource then just + * uses it otherwise if obj is a string + * then load it first. + * + * @param {string|TexImageSource} obj + * @param {string} crossOrigin + * @param {function(err, img)} [callback] a callback that's passed an error and the image. The error will be non-null + * if there was an error + * @private + */ +function loadAndUseImage(obj, crossOrigin, callback) { + if (isTexImageSource(obj)) { + setTimeout(function() { + callback(null, obj); + }); + return obj; + } + + return loadImage(obj, crossOrigin, callback); +} + +/** + * Sets a texture to a 1x1 pixel color. If `options.color === false` is nothing happens. If it's not set + * the default texture color is used which can be set by calling `setDefaultTextureColor`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + * @private + */ +function setTextureTo1PixelColor(gl, tex, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + if (options.color === false) { + return; + } + // Assume it's a URL + // Put 1x1 pixels in texture. That makes it renderable immediately regardless of filtering. + const color = make1Pixel(options.color); + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, 0, RGBA$1, 1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } else { + gl.texImage2D(target, 0, RGBA$1, 1, 1, 0, RGBA$1, UNSIGNED_BYTE$1, color); + } +} + +/** + * The src image(s) used to create a texture. + * + * When you call {@link module:twgl.createTexture} or {@link module:twgl.createTextures} + * you can pass in urls for images to load into the textures. If it's a single url + * then this will be a single HTMLImageElement. If it's an array of urls used for a cubemap + * this will be a corresponding array of images for the cubemap. + * + * @typedef {HTMLImageElement|HTMLImageElement[]} TextureSrc + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback TextureReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} texture the texture. + * @param {module:twgl.TextureSrc} source image(s) used to as the src for the texture + * @memberOf module:twgl + */ + +/** + * A callback for when all images have finished downloading and been uploaded into their respective textures + * @callback TexturesReadyCallback + * @param {*} err If truthy there was an error. + * @param {Object.} textures the created textures by name. Same as returned by {@link module:twgl.createTextures}. + * @param {Object.} sources the image(s) used for the texture by name. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback CubemapReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each face. + * @memberOf module:twgl + */ + +/** + * A callback for when an image finished downloading and been uploaded into a texture + * @callback ThreeDReadyCallback + * @param {*} err If truthy there was an error. + * @param {WebGLTexture} tex the texture. + * @param {HTMLImageElement[]} imgs the images for each slice. + * @memberOf module:twgl + */ + +/** + * Loads a texture from an image from a Url as specified in `options.src` + * If `options.color !== false` will set the texture to a 1x1 pixel color so that the texture is + * immediately useable. It will be updated with the contents of the image once the image has finished + * downloading. Filtering options will be set as appropriate for image unless `options.auto === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A function to be called when the image has finished loading. err will + * be non null if there was an error. + * @return {HTMLImageElement} the image being downloaded. + * @memberOf module:twgl/textures + */ +function loadTextureFromUrl(gl, tex, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + const img = loadAndUseImage(options.src, options.crossOrigin, function(err, img) { + if (err) { + callback(err, tex, img); + } else { + setTextureFromElement(gl, tex, img, options); + callback(null, tex, img); + } + }); + return img; +} + +/** + * Loads a cubemap from 6 urls or TexImageSources as specified in `options.src`. Will set the cubemap to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.CubemapReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadCubemapFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + if (urls.length !== 6) { + throw "there must be 6 urls for a cubemap"; + } + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D$2; + if (target !== TEXTURE_CUBE_MAP$1) { + throw "target must be TEXTURE_CUBE_MAP"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = 6; + const errors = []; + const faces = getCubeFaceOrder(gl, options); + let imgs; // eslint-disable-line + + function uploadImg(faceTarget) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + if (img.width !== img.height) { + errors.push("cubemap face img is not a square: " + img.src); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + // So assuming this is the first image we now have one face that's img sized + // and 5 faces that are 1x1 pixel so size the other faces + if (numToLoad === 5) { + // use the default order + getCubeFaceOrder().forEach(function(otherTarget) { + // Should we re-use the same face or a color? + gl.texImage2D(otherTarget, level, internalFormat, format, type, img); + }); + } else { + gl.texImage2D(faceTarget, level, internalFormat, format, type, img); + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(faces[ndx])); + }); +} + +/** + * Loads a 2d array or 3d texture from urls OR TexImageSources as specified in `options.src`. + * Will set the texture to a 1x1 pixel color + * so that it is usable immediately unless `option.color === false`. + * + * If the width and height is not specified the width and height of the first + * image loaded will be used. Note that since images are loaded async + * which image downloads first is unknown. + * + * If an image is not the same size as the width and height it will be scaled + * to that width and height. + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.ThreeDReadyCallback} [callback] A function to be called when all the images have finished loading. err will + * be non null if there was an error. + * @memberOf module:twgl/textures + * @private + */ +function loadSlicesFromUrls(gl, tex, options, callback) { + callback = callback || noop; + const urls = options.src; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || UNSIGNED_BYTE$1; + const target = options.target || TEXTURE_2D_ARRAY$1; + if (target !== TEXTURE_3D$1 && target !== TEXTURE_2D_ARRAY$1) { + throw "target must be TEXTURE_3D or TEXTURE_2D_ARRAY"; + } + setTextureTo1PixelColor(gl, tex, options); + // Because it's async we need to copy the options. + options = Object.assign({}, options); + let numToLoad = urls.length; + const errors = []; + let imgs; // eslint-disable-line + const level = options.level || 0; + let width = options.width; + let height = options.height; + const depth = urls.length; + let firstImage = true; + + function uploadImg(slice) { + return function(err, img) { + --numToLoad; + if (err) { + errors.push(err); + } else { + scopedSetPackState(gl, options, () => { + gl.bindTexture(target, tex); + + if (firstImage) { + firstImage = false; + width = options.width || img.width; + height = options.height || img.height; + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + + // put it in every slice otherwise some slices will be 0,0,0,0 + for (let s = 0; s < depth; ++s) { + gl.texSubImage3D(target, level, 0, 0, s, width, height, 1, format, type, img); + } + } else { + let src = img; + let ctx; + if (img.width !== width || img.height !== height) { + // Size the image to fix + ctx = getShared2DContext(); + src = ctx.canvas; + ctx.canvas.width = width; + ctx.canvas.height = height; + ctx.drawImage(img, 0, 0, width, height); + } + + gl.texSubImage3D(target, level, 0, 0, slice, width, height, 1, format, type, src); + + // free the canvas memory + if (ctx && src === ctx.canvas) { + ctx.canvas.width = 0; + ctx.canvas.height = 0; + } + } + + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + gl.generateMipmap(target); + } + }); + } + + if (numToLoad === 0) { + callback(errors.length ? errors : undefined, tex, imgs); + } + }; + } + + imgs = urls.map(function(url, ndx) { + return loadAndUseImage(url, options.crossOrigin, uploadImg(ndx)); + }); +} + +/** + * Sets a texture from an array or typed array. If the width or height is not provided will attempt to + * guess the size. See {@link module:twgl.TextureOptions}. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {(number[]|ArrayBufferView)} src An array or typed arry with texture data. + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * This is often the same options you passed in when you created the texture. + * @memberOf module:twgl/textures + */ +function setTextureFromArray(gl, tex, src, options) { + options = options || defaults$1.textureOptions; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + let width = options.width; + let height = options.height; + let depth = options.depth; + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + if (!isArrayBuffer(src)) { + const Type = getTypedArrayTypeForGLType(type); + src = new Type(src); + } else if (src instanceof Uint8ClampedArray) { + src = new Uint8Array(src.buffer); + } + + const bytesPerElement = getBytesPerElementForInternalFormat(internalFormat, type); + const numElements = src.byteLength / bytesPerElement; // TODO: check UNPACK_ALIGNMENT? + if (numElements % 1) { + throw "length wrong size for format: " + glEnumToString(gl, format); + } + let dimensions; + if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + if (!width && !height && !depth) { + const size = Math.cbrt(numElements); + if (size % 1 !== 0) { + throw "can't guess cube size of array of numElements: " + numElements; + } + width = size; + height = size; + depth = size; + } else if (width && (!height || !depth)) { + dimensions = guessDimensions(gl, target, height, depth, numElements / width); + height = dimensions.width; + depth = dimensions.height; + } else if (height && (!width || !depth)) { + dimensions = guessDimensions(gl, target, width, depth, numElements / height); + width = dimensions.width; + depth = dimensions.height; + } else { + dimensions = guessDimensions(gl, target, width, height, numElements / depth); + width = dimensions.width; + height = dimensions.height; + } + } else { + dimensions = guessDimensions(gl, target, width, height, numElements); + width = dimensions.width; + height = dimensions.height; + } + setSkipStateToDefault(gl); + gl.pixelStorei(UNPACK_ALIGNMENT, options.unpackAlignment || 1); + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + const elementsPerElement = bytesPerElement / src.BYTES_PER_ELEMENT; + const faceSize = numElements / 6 * elementsPerElement; + + getCubeFacesWithNdx(gl, options).forEach(f => { + const offset = faceSize * f.ndx; + const data = src.subarray(offset, offset + faceSize); + gl.texImage2D(f.face, level, internalFormat, width, height, 0, format, type, data); + }); + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, src); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, src); + } + }); + return { + width: width, + height: height, + depth: depth, + type: type, + }; +} + +/** + * Sets a texture with no contents of a certain size. In other words calls `gl.texImage2D` with `null`. + * You must set `options.width` and `options.height`. + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the WebGLTexture to set parameters for + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @memberOf module:twgl/textures + */ +function setEmptyTexture(gl, tex, options) { + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + const type = options.type || formatType.type; + scopedSetPackState(gl, options, () => { + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, options.width, options.height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, options.width, options.height, options.depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, options.width, options.height, 0, format, type, null); + } + }); +} + +/** + * Creates a texture based on the options passed in. + * + * Note: may reset UNPACK_ALIGNMENT, UNPACK_ROW_LENGTH, UNPACK_IMAGE_HEIGHT, UNPACK_SKIP_IMAGES + * UNPACK_SKIP_PIXELS, and UNPACK_SKIP_ROWS + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.TextureOptions} [options] A TextureOptions object with whatever parameters you want set. + * @param {module:twgl.TextureReadyCallback} [callback] A callback called when an image has been downloaded and uploaded to the texture. + * @return {WebGLTexture} the created texture. + * @memberOf module:twgl/textures + */ +function createTexture(gl, options, callback) { + callback = callback || noop; + options = options || defaults$1.textureOptions; + const tex = gl.createTexture(); + const target = options.target || TEXTURE_2D$2; + let width = options.width || 1; + let height = options.height || 1; + const internalFormat = options.internalFormat || RGBA$1; + gl.bindTexture(target, tex); + if (target === TEXTURE_CUBE_MAP$1) { + // this should have been the default for cubemaps :( + gl.texParameteri(target, TEXTURE_WRAP_S, CLAMP_TO_EDGE$1); + gl.texParameteri(target, TEXTURE_WRAP_T, CLAMP_TO_EDGE$1); + } + let src = options.src; + if (src) { + if (typeof src === "function") { + src = src(gl, options); + } + if (typeof (src) === "string") { + loadTextureFromUrl(gl, tex, options, callback); + } else if (isArrayBuffer(src) || + (Array.isArray(src) && ( + typeof src[0] === 'number' || + Array.isArray(src[0]) || + isArrayBuffer(src[0])) + ) + ) { + const dimensions = setTextureFromArray(gl, tex, src, options); + width = dimensions.width; + height = dimensions.height; + } else if (Array.isArray(src) && (typeof (src[0]) === 'string' || isTexImageSource(src[0]))) { + if (target === TEXTURE_CUBE_MAP$1) { + loadCubemapFromUrls(gl, tex, options, callback); + } else { + loadSlicesFromUrls(gl, tex, options, callback); + } + } else { // if (isTexImageSource(src)) + setTextureFromElement(gl, tex, src, options); + width = src.width; + height = src.height; + } + } else { + setEmptyTexture(gl, tex, options); + } + if (shouldAutomaticallySetTextureFilteringForSize(options)) { + setTextureFilteringForSize(gl, tex, options, width, height, internalFormat); + } + setTextureParameters(gl, tex, options); + return tex; +} + +/** + * Resizes a texture based on the options passed in. + * + * Note: This is not a generic resize anything function. + * It's mostly used by {@link module:twgl.resizeFramebufferInfo} + * It will use `options.src` if it exists to try to determine a `type` + * otherwise it will assume `gl.UNSIGNED_BYTE`. No data is provided + * for the texture. Texture parameters will be set accordingly + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {WebGLTexture} tex the texture to resize + * @param {module:twgl.TextureOptions} options A TextureOptions object with whatever parameters you want set. + * @param {number} [width] the new width. If not passed in will use `options.width` + * @param {number} [height] the new height. If not passed in will use `options.height` + * @param {number} [depth] the new depth. If not passed in will use `options.depth` + * @memberOf module:twgl/textures + */ +function resizeTexture(gl, tex, options, width, height, depth) { + width = width || options.width; + height = height || options.height; + depth = depth || options.depth; + const target = options.target || TEXTURE_2D$2; + gl.bindTexture(target, tex); + const level = options.level || 0; + const internalFormat = options.internalFormat || options.format || RGBA$1; + const formatType = getFormatAndTypeForInternalFormat(internalFormat); + const format = options.format || formatType.format; + let type; + const src = options.src; + if (!src) { + type = options.type || formatType.type; + } else if (isArrayBuffer(src) || (Array.isArray(src) && typeof (src[0]) === 'number')) { + type = options.type || getTextureTypeForArrayType(gl, src, formatType.type); + } else { + type = options.type || formatType.type; + } + if (target === TEXTURE_CUBE_MAP$1) { + for (let ii = 0; ii < 6; ++ii) { + gl.texImage2D(TEXTURE_CUBE_MAP_POSITIVE_X + ii, level, internalFormat, width, height, 0, format, type, null); + } + } else if (target === TEXTURE_3D$1 || target === TEXTURE_2D_ARRAY$1) { + gl.texImage3D(target, level, internalFormat, width, height, depth, 0, format, type, null); + } else { + gl.texImage2D(target, level, internalFormat, width, height, 0, format, type, null); + } +} + +/** + * Check if a src is an async request. + * if src is a string we're going to download an image + * if src is an array of strings we're going to download cubemap images + * @param {*} src The src from a TextureOptions + * @returns {bool} true if src is async. + * @private + */ +function isAsyncSrc(src) { + return typeof src === 'string' || + (Array.isArray(src) && typeof src[0] === 'string'); +} + +/** + * Creates a bunch of textures based on the passed in options. + * + * Example: + * + * const textures = twgl.createTextures(gl, { + * // a power of 2 image + * hftIcon: { src: "images/hft-icon-16.png", mag: gl.NEAREST }, + * // a non-power of 2 image + * clover: { src: "images/clover.jpg" }, + * // From a canvas + * fromCanvas: { src: ctx.canvas }, + * // A cubemap from 6 images + * yokohama: { + * target: gl.TEXTURE_CUBE_MAP, + * src: [ + * 'images/yokohama/posx.jpg', + * 'images/yokohama/negx.jpg', + * 'images/yokohama/posy.jpg', + * 'images/yokohama/negy.jpg', + * 'images/yokohama/posz.jpg', + * 'images/yokohama/negz.jpg', + * ], + * }, + * // A cubemap from 1 image (can be 1x6, 2x3, 3x2, 6x1) + * goldengate: { + * target: gl.TEXTURE_CUBE_MAP, + * src: 'images/goldengate.jpg', + * }, + * // A 2x2 pixel texture from a JavaScript array + * checker: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * src: [ + * 255,255,255,255, + * 192,192,192,255, + * 192,192,192,255, + * 255,255,255,255, + * ], + * }, + * // a 1x2 pixel texture from a typed array. + * stripe: { + * mag: gl.NEAREST, + * min: gl.LINEAR, + * format: gl.LUMINANCE, + * src: new Uint8Array([ + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * 255, + * 128, + * ]), + * width: 1, + * }, + * }); + * + * Now + * + * * `textures.hftIcon` will be a 2d texture + * * `textures.clover` will be a 2d texture + * * `textures.fromCanvas` will be a 2d texture + * * `textures.yohohama` will be a cubemap texture + * * `textures.goldengate` will be a cubemap texture + * * `textures.checker` will be a 2d texture + * * `textures.stripe` will be a 2d texture + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} options A object of TextureOptions one per texture. + * @param {module:twgl.TexturesReadyCallback} [callback] A callback called when all textures have been downloaded. + * @return {Object.} the created textures by name + * @memberOf module:twgl/textures + */ +function createTextures(gl, textureOptions, callback) { + callback = callback || noop; + let numDownloading = 0; + const errors = []; + const textures = {}; + const images = {}; + + function callCallbackIfReady() { + if (numDownloading === 0) { + setTimeout(function() { + callback(errors.length ? errors : undefined, textures, images); + }, 0); + } + } + + Object.keys(textureOptions).forEach(function(name) { + const options = textureOptions[name]; + let onLoadFn; + if (isAsyncSrc(options.src)) { + onLoadFn = function(err, tex, img) { + images[name] = img; + --numDownloading; + if (err) { + errors.push(err); + } + callCallbackIfReady(); + }; + ++numDownloading; + } + textures[name] = createTexture(gl, options, onLoadFn); + }); + + // queue the callback if there are no images to download. + // We do this because if your code is structured to wait for + // images to download but then you comment out all the async + // images your code would break. + callCallbackIfReady(); + + return textures; +} + +var textures = /*#__PURE__*/Object.freeze({ + __proto__: null, + setTextureDefaults_: setDefaults$1, + createSampler: createSampler, + createSamplers: createSamplers, + setSamplerParameters: setSamplerParameters, + createTexture: createTexture, + setEmptyTexture: setEmptyTexture, + setTextureFromArray: setTextureFromArray, + loadTextureFromUrl: loadTextureFromUrl, + setTextureFromElement: setTextureFromElement, + setTextureFilteringForSize: setTextureFilteringForSize, + setTextureParameters: setTextureParameters, + setDefaultTextureColor: setDefaultTextureColor, + createTextures: createTextures, + resizeTexture: resizeTexture, + canGenerateMipmap: canGenerateMipmap, + canFilter: canFilter, + getNumComponentsForFormat: getNumComponentsForFormat, + getBytesPerElementForInternalFormat: getBytesPerElementForInternalFormat, + getFormatAndTypeForInternalFormat: getFormatAndTypeForInternalFormat +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * Low level shader program related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.programs` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/programs + */ + +const error = error$1; +const warn = warn$1; +function getElementById(id) { + return (typeof document !== 'undefined' && document.getElementById) + ? document.getElementById(id) + : null; +} + +const TEXTURE0 = 0x84c0; +const DYNAMIC_DRAW = 0x88e8; + +const ARRAY_BUFFER = 0x8892; +const ELEMENT_ARRAY_BUFFER$1 = 0x8893; +const UNIFORM_BUFFER = 0x8a11; +const TRANSFORM_FEEDBACK_BUFFER = 0x8c8e; + +const TRANSFORM_FEEDBACK = 0x8e22; + +const COMPILE_STATUS = 0x8b81; +const LINK_STATUS = 0x8b82; +const FRAGMENT_SHADER = 0x8b30; +const VERTEX_SHADER = 0x8b31; +const SEPARATE_ATTRIBS = 0x8c8d; + +const ACTIVE_UNIFORMS = 0x8b86; +const ACTIVE_ATTRIBUTES = 0x8b89; +const TRANSFORM_FEEDBACK_VARYINGS = 0x8c83; +const ACTIVE_UNIFORM_BLOCKS = 0x8a36; +const UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8a44; +const UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8a46; +const UNIFORM_BLOCK_DATA_SIZE = 0x8a40; +const UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8a43; + +const FLOAT = 0x1406; +const FLOAT_VEC2 = 0x8B50; +const FLOAT_VEC3 = 0x8B51; +const FLOAT_VEC4 = 0x8B52; +const INT = 0x1404; +const INT_VEC2 = 0x8B53; +const INT_VEC3 = 0x8B54; +const INT_VEC4 = 0x8B55; +const BOOL = 0x8B56; +const BOOL_VEC2 = 0x8B57; +const BOOL_VEC3 = 0x8B58; +const BOOL_VEC4 = 0x8B59; +const FLOAT_MAT2 = 0x8B5A; +const FLOAT_MAT3 = 0x8B5B; +const FLOAT_MAT4 = 0x8B5C; +const SAMPLER_2D = 0x8B5E; +const SAMPLER_CUBE = 0x8B60; +const SAMPLER_3D = 0x8B5F; +const SAMPLER_2D_SHADOW = 0x8B62; +const FLOAT_MAT2x3 = 0x8B65; +const FLOAT_MAT2x4 = 0x8B66; +const FLOAT_MAT3x2 = 0x8B67; +const FLOAT_MAT3x4 = 0x8B68; +const FLOAT_MAT4x2 = 0x8B69; +const FLOAT_MAT4x3 = 0x8B6A; +const SAMPLER_2D_ARRAY = 0x8DC1; +const SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; +const SAMPLER_CUBE_SHADOW = 0x8DC5; +const UNSIGNED_INT = 0x1405; +const UNSIGNED_INT_VEC2 = 0x8DC6; +const UNSIGNED_INT_VEC3 = 0x8DC7; +const UNSIGNED_INT_VEC4 = 0x8DC8; +const INT_SAMPLER_2D = 0x8DCA; +const INT_SAMPLER_3D = 0x8DCB; +const INT_SAMPLER_CUBE = 0x8DCC; +const INT_SAMPLER_2D_ARRAY = 0x8DCF; +const UNSIGNED_INT_SAMPLER_2D = 0x8DD2; +const UNSIGNED_INT_SAMPLER_3D = 0x8DD3; +const UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; +const UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; + +const TEXTURE_2D$1 = 0x0DE1; +const TEXTURE_CUBE_MAP = 0x8513; +const TEXTURE_3D = 0x806F; +const TEXTURE_2D_ARRAY = 0x8C1A; + +const typeMap = {}; + +/** + * Returns the corresponding bind point for a given sampler type + * @private + */ +function getBindPointForSamplerType(gl, type) { + return typeMap[type].bindPoint; +} + +// This kind of sucks! If you could compose functions as in `var fn = gl[name];` +// this code could be a lot smaller but that is sadly really slow (T_T) + +function floatSetter(gl, location) { + return function(v) { + gl.uniform1f(location, v); + }; +} + +function floatArraySetter(gl, location) { + return function(v) { + gl.uniform1fv(location, v); + }; +} + +function floatVec2Setter(gl, location) { + return function(v) { + gl.uniform2fv(location, v); + }; +} + +function floatVec3Setter(gl, location) { + return function(v) { + gl.uniform3fv(location, v); + }; +} + +function floatVec4Setter(gl, location) { + return function(v) { + gl.uniform4fv(location, v); + }; +} + +function intSetter(gl, location) { + return function(v) { + gl.uniform1i(location, v); + }; +} + +function intArraySetter(gl, location) { + return function(v) { + gl.uniform1iv(location, v); + }; +} + +function intVec2Setter(gl, location) { + return function(v) { + gl.uniform2iv(location, v); + }; +} + +function intVec3Setter(gl, location) { + return function(v) { + gl.uniform3iv(location, v); + }; +} + +function intVec4Setter(gl, location) { + return function(v) { + gl.uniform4iv(location, v); + }; +} + +function uintSetter(gl, location) { + return function(v) { + gl.uniform1ui(location, v); + }; +} + +function uintArraySetter(gl, location) { + return function(v) { + gl.uniform1uiv(location, v); + }; +} + +function uintVec2Setter(gl, location) { + return function(v) { + gl.uniform2uiv(location, v); + }; +} + +function uintVec3Setter(gl, location) { + return function(v) { + gl.uniform3uiv(location, v); + }; +} + +function uintVec4Setter(gl, location) { + return function(v) { + gl.uniform4uiv(location, v); + }; +} + +function floatMat2Setter(gl, location) { + return function(v) { + gl.uniformMatrix2fv(location, false, v); + }; +} + +function floatMat3Setter(gl, location) { + return function(v) { + gl.uniformMatrix3fv(location, false, v); + }; +} + +function floatMat4Setter(gl, location) { + return function(v) { + gl.uniformMatrix4fv(location, false, v); + }; +} + +function floatMat23Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x3fv(location, false, v); + }; +} + +function floatMat32Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x2fv(location, false, v); + }; +} + +function floatMat24Setter(gl, location) { + return function(v) { + gl.uniformMatrix2x4fv(location, false, v); + }; +} + +function floatMat42Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x2fv(location, false, v); + }; +} + +function floatMat34Setter(gl, location) { + return function(v) { + gl.uniformMatrix3x4fv(location, false, v); + }; +} + +function floatMat43Setter(gl, location) { + return function(v) { + gl.uniformMatrix4x3fv(location, false, v); + }; +} + +function samplerSetter(gl, type, unit, location) { + const bindPoint = getBindPointForSamplerType(gl, type); + return isWebGL2(gl) ? function(textureOrPair) { + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + gl.bindSampler(unit, sampler); + } : function(texture) { + gl.uniform1i(location, unit); + gl.activeTexture(TEXTURE0 + unit); + gl.bindTexture(bindPoint, texture); + }; +} + +function samplerArraySetter(gl, type, unit, location, size) { + const bindPoint = getBindPointForSamplerType(gl, type); + const units = new Int32Array(size); + for (let ii = 0; ii < size; ++ii) { + units[ii] = unit + ii; + } + + return isWebGL2(gl) ? function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(textureOrPair, index) { + gl.activeTexture(TEXTURE0 + units[index]); + let texture; + let sampler; + if (!textureOrPair || isTexture(gl, textureOrPair)) { + texture = textureOrPair; + sampler = null; + } else { + texture = textureOrPair.texture; + sampler = textureOrPair.sampler; + } + gl.bindSampler(unit, sampler); + gl.bindTexture(bindPoint, texture); + }); + } : function(textures) { + gl.uniform1iv(location, units); + textures.forEach(function(texture, index) { + gl.activeTexture(TEXTURE0 + units[index]); + gl.bindTexture(bindPoint, texture); + }); + }; +} + +typeMap[FLOAT] = { Type: Float32Array, size: 4, setter: floatSetter, arraySetter: floatArraySetter, }; +typeMap[FLOAT_VEC2] = { Type: Float32Array, size: 8, setter: floatVec2Setter, cols: 2, }; +typeMap[FLOAT_VEC3] = { Type: Float32Array, size: 12, setter: floatVec3Setter, cols: 3, }; +typeMap[FLOAT_VEC4] = { Type: Float32Array, size: 16, setter: floatVec4Setter, cols: 4, }; +typeMap[INT] = { Type: Int32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[INT_VEC2] = { Type: Int32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[INT_VEC3] = { Type: Int32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[INT_VEC4] = { Type: Int32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[UNSIGNED_INT] = { Type: Uint32Array, size: 4, setter: uintSetter, arraySetter: uintArraySetter, }; +typeMap[UNSIGNED_INT_VEC2] = { Type: Uint32Array, size: 8, setter: uintVec2Setter, cols: 2, }; +typeMap[UNSIGNED_INT_VEC3] = { Type: Uint32Array, size: 12, setter: uintVec3Setter, cols: 3, }; +typeMap[UNSIGNED_INT_VEC4] = { Type: Uint32Array, size: 16, setter: uintVec4Setter, cols: 4, }; +typeMap[BOOL] = { Type: Uint32Array, size: 4, setter: intSetter, arraySetter: intArraySetter, }; +typeMap[BOOL_VEC2] = { Type: Uint32Array, size: 8, setter: intVec2Setter, cols: 2, }; +typeMap[BOOL_VEC3] = { Type: Uint32Array, size: 12, setter: intVec3Setter, cols: 3, }; +typeMap[BOOL_VEC4] = { Type: Uint32Array, size: 16, setter: intVec4Setter, cols: 4, }; +typeMap[FLOAT_MAT2] = { Type: Float32Array, size: 32, setter: floatMat2Setter, rows: 2, cols: 2, }; +typeMap[FLOAT_MAT3] = { Type: Float32Array, size: 48, setter: floatMat3Setter, rows: 3, cols: 3, }; +typeMap[FLOAT_MAT4] = { Type: Float32Array, size: 64, setter: floatMat4Setter, rows: 4, cols: 4, }; +typeMap[FLOAT_MAT2x3] = { Type: Float32Array, size: 32, setter: floatMat23Setter, rows: 2, cols: 3, }; +typeMap[FLOAT_MAT2x4] = { Type: Float32Array, size: 32, setter: floatMat24Setter, rows: 2, cols: 4, }; +typeMap[FLOAT_MAT3x2] = { Type: Float32Array, size: 48, setter: floatMat32Setter, rows: 3, cols: 2, }; +typeMap[FLOAT_MAT3x4] = { Type: Float32Array, size: 48, setter: floatMat34Setter, rows: 3, cols: 4, }; +typeMap[FLOAT_MAT4x2] = { Type: Float32Array, size: 64, setter: floatMat42Setter, rows: 4, cols: 2, }; +typeMap[FLOAT_MAT4x3] = { Type: Float32Array, size: 64, setter: floatMat43Setter, rows: 4, cols: 3, }; +typeMap[SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[SAMPLER_2D_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_2D_ARRAY_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[SAMPLER_CUBE_SHADOW] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; +typeMap[UNSIGNED_INT_SAMPLER_2D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D$1, }; +typeMap[UNSIGNED_INT_SAMPLER_3D] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_3D, }; +typeMap[UNSIGNED_INT_SAMPLER_CUBE] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_CUBE_MAP, }; +typeMap[UNSIGNED_INT_SAMPLER_2D_ARRAY] = { Type: null, size: 0, setter: samplerSetter, arraySetter: samplerArraySetter, bindPoint: TEXTURE_2D_ARRAY, }; + +function floatAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + switch (b.value.length) { + case 4: + gl.vertexAttrib4fv(index, b.value); + break; + case 3: + gl.vertexAttrib3fv(index, b.value); + break; + case 2: + gl.vertexAttrib2fv(index, b.value); + break; + case 1: + gl.vertexAttrib1fv(index, b.value); + break; + default: + throw new Error('the length of a float constant value must be between 1 and 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribPointer( + index, b.numComponents || b.size, b.type || FLOAT, b.normalize || false, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function intAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4iv(index, b.value); + } else { + throw new Error('The length of an integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function uintAttribSetter(gl, index) { + return function(b) { + if (b.value) { + gl.disableVertexAttribArray(index); + if (b.value.length === 4) { + gl.vertexAttrib4uiv(index, b.value); + } else { + throw new Error('The length of an unsigned integer constant value must be 4!'); + } + } else { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + gl.enableVertexAttribArray(index); + gl.vertexAttribIPointer( + index, b.numComponents || b.size, b.type || UNSIGNED_INT, b.stride || 0, b.offset || 0); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index, b.divisor || 0); + } + } + }; +} + +function matAttribSetter(gl, index, typeInfo) { + const defaultSize = typeInfo.size; + const count = typeInfo.count; + + return function(b) { + gl.bindBuffer(ARRAY_BUFFER, b.buffer); + const numComponents = b.size || b.numComponents || defaultSize; + const size = numComponents / count; + const type = b.type || FLOAT; + const typeInfo = typeMap[type]; + const stride = typeInfo.size * numComponents; + const normalize = b.normalize || false; + const offset = b.offset || 0; + const rowOffset = stride / count; + for (let i = 0; i < count; ++i) { + gl.enableVertexAttribArray(index + i); + gl.vertexAttribPointer( + index + i, size, type, normalize, stride, offset + rowOffset * i); + if (gl.vertexAttribDivisor) { + gl.vertexAttribDivisor(index + i, b.divisor || 0); + } + } + }; +} + + + +const attrTypeMap = {}; +attrTypeMap[FLOAT] = { size: 4, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC2] = { size: 8, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC3] = { size: 12, setter: floatAttribSetter, }; +attrTypeMap[FLOAT_VEC4] = { size: 16, setter: floatAttribSetter, }; +attrTypeMap[INT] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[INT_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[INT_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[INT_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[UNSIGNED_INT] = { size: 4, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC2] = { size: 8, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC3] = { size: 12, setter: uintAttribSetter, }; +attrTypeMap[UNSIGNED_INT_VEC4] = { size: 16, setter: uintAttribSetter, }; +attrTypeMap[BOOL] = { size: 4, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC2] = { size: 8, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC3] = { size: 12, setter: intAttribSetter, }; +attrTypeMap[BOOL_VEC4] = { size: 16, setter: intAttribSetter, }; +attrTypeMap[FLOAT_MAT2] = { size: 4, setter: matAttribSetter, count: 2, }; +attrTypeMap[FLOAT_MAT3] = { size: 9, setter: matAttribSetter, count: 3, }; +attrTypeMap[FLOAT_MAT4] = { size: 16, setter: matAttribSetter, count: 4, }; + +const errorRE = /ERROR:\s*\d+:(\d+)/gi; +function addLineNumbersWithError(src, log = '', lineOffset = 0) { + // Note: Error message formats are not defined by any spec so this may or may not work. + const matches = [...log.matchAll(errorRE)]; + const lineNoToErrorMap = new Map(matches.map((m, ndx) => { + const lineNo = parseInt(m[1]); + const next = matches[ndx + 1]; + const end = next ? next.index : log.length; + const msg = log.substring(m.index, end); + return [lineNo - 1, msg]; + })); + return src.split('\n').map((line, lineNo) => { + const err = lineNoToErrorMap.get(lineNo); + return `${lineNo + 1 + lineOffset}: ${line}${err ? `\n\n^^^ ${err}` : ''}`; + }).join('\n'); +} + +/** + * Error Callback + * @callback ErrorCallback + * @param {string} msg error message. + * @param {number} [lineOffset] amount to add to line number + * @memberOf module:twgl + */ + +/** + * Program Callback + * @callback ProgramCallback + * @param {string} [err] error message, falsy if no error + * @param {WebGLProgram|module:twgl.ProgramInfo} [result] the program or programInfo + */ + +const spaceRE = /^[ \t]*\n/; + +/** + * Remove the first end of line because WebGL 2.0 requires + * #version 300 es + * as the first line. No whitespace allowed before that line + * so + * + * + * + * Has one line before it which is invalid according to GLSL ES 3.00 + * + * @param {string} shaderSource The source of the shader + * @returns {{shaderSource: string, lineOffset: number}} + * @private + */ +function prepShaderSource(shaderSource) { + let lineOffset = 0; + if (spaceRE.test(shaderSource)) { + lineOffset = 1; + shaderSource = shaderSource.replace(spaceRE, ''); + } + return {lineOffset, shaderSource}; +} + +/** + * @param {module:twgl.ProgramOptions} progOptions + * @param {string} msg + * @return null + * @private + */ +function reportError(progOptions, msg) { + progOptions.errorCallback(msg); + if (progOptions.callback) { + setTimeout(() => { + progOptions.callback(`${msg}\n${progOptions.errors.join('\n')}`); + }); + } + return null; +} + +/** + * Check Shader status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {number} shaderType The shader type + * @param {WebGLShader} shader The shader + * @param {ErrorCallback} [errFn] function to receive error message. + * @return {string} errors or empty string + * @private + */ +function checkShaderStatus(gl, shaderType, shader, errFn) { + errFn = errFn || error; + // Check the compile status + const compiled = gl.getShaderParameter(shader, COMPILE_STATUS); + if (!compiled) { + // Something went wrong during compilation; get the error + const lastError = gl.getShaderInfoLog(shader); + const {lineOffset, shaderSource} = prepShaderSource(gl.getShaderSource(shader)); + const error = `${addLineNumbersWithError(shaderSource, lastError, lineOffset)}\nError compiling ${glEnumToString(gl, shaderType)}: ${lastError}`; + errFn(error); + return error; + } + return ''; +} + +/** + * @typedef {Object} FullProgramSpec + * @property {string[]} shaders the shader source or element ids. + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * @typedef {string[]|module:twgl.FullProgramSpec} ProgramSpec + * @memberOf module:twgl + */ + +/** + * @typedef {Object} ProgramOptions + * @property {function(string)} [errorCallback] callback for errors + * @property {Object.|string[]} [attribLocations] a attribute name to location map, or array of attribute names where index = location. + * @property {(module:twgl.BufferInfo|Object.|string[])} [transformFeedbackVaryings] If passed + * a BufferInfo will use the attribs names inside. If passed an object of AttribInfos will use the names from that object. Otherwise + * you can pass an array of names. + * @property {number} [transformFeedbackMode] the mode to pass `gl.transformFeedbackVaryings`. Defaults to `SEPARATE_ATTRIBS`. + * @property {ProgramCallback} [callback] callback for async program compilation. + * @memberOf module:twgl + */ + +/** + * Gets the program options based on all these optional arguments + * @param {module:twgl.ProgramOptions|string[]} [opt_attribs] Options for the program or 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:twgl.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:twgl.ProgramOptions} an instance of ProgramOptions based on the arguments passed in + * @private + */ +function getProgramOptions(opt_attribs, opt_locations, opt_errorCallback) { + let transformFeedbackVaryings; + let transformFeedbackMode; + let callback; + if (typeof opt_locations === 'function') { + opt_errorCallback = opt_locations; + opt_locations = undefined; + } + if (typeof opt_attribs === 'function') { + opt_errorCallback = opt_attribs; + opt_attribs = undefined; + } else if (opt_attribs && !Array.isArray(opt_attribs)) { + const opt = opt_attribs; + opt_errorCallback = opt.errorCallback; + opt_attribs = opt.attribLocations; + transformFeedbackVaryings = opt.transformFeedbackVaryings; + transformFeedbackMode = opt.transformFeedbackMode; + callback = opt.callback; + } + + const errorCallback = opt_errorCallback || error; + const errors = []; + const options = { + errorCallback(msg, ...args) { + errors.push(msg); + errorCallback(msg, ...args); + }, + transformFeedbackVaryings, + transformFeedbackMode, + callback, + errors, + }; + + { + let attribLocations = {}; + if (Array.isArray(opt_attribs)) { + opt_attribs.forEach(function(attrib, ndx) { + attribLocations[attrib] = opt_locations ? opt_locations[ndx] : ndx; + }); + } else { + attribLocations = opt_attribs || {}; + } + options.attribLocations = attribLocations; + } + + return options; +} + +const defaultShaderType = [ + "VERTEX_SHADER", + "FRAGMENT_SHADER", +]; + +function getShaderTypeFromScriptType(gl, scriptType) { + if (scriptType.indexOf("frag") >= 0) { + return FRAGMENT_SHADER; + } else if (scriptType.indexOf("vert") >= 0) { + return VERTEX_SHADER; + } + return undefined; +} + +function deleteProgramAndShaders(gl, program, notThese) { + const shaders = gl.getAttachedShaders(program); + for (const shader of shaders) { + if (notThese.has(shader)) { + gl.deleteShader(shader); + } + } + gl.deleteProgram(program); +} + +const wait = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms)); + +function createProgramNoCheck(gl, shaders, programOptions) { + const program = gl.createProgram(); + const { + attribLocations, + transformFeedbackVaryings, + transformFeedbackMode, + } = getProgramOptions(programOptions); + + for (let ndx = 0; ndx < shaders.length; ++ndx) { + let shader = shaders[ndx]; + if (typeof shader === 'string') { + const elem = getElementById(shader); + const src = elem ? elem.text : shader; + let type = gl[defaultShaderType[ndx]]; + if (elem && elem.type) { + type = getShaderTypeFromScriptType(gl, elem.type) || type; + } + shader = gl.createShader(type); + gl.shaderSource(shader, prepShaderSource(src).shaderSource); + gl.compileShader(shader); + gl.attachShader(program, shader); + } + } + + Object.entries(attribLocations).forEach(([attrib, loc]) => gl.bindAttribLocation(program, loc, attrib)); + + { + let varyings = transformFeedbackVaryings; + if (varyings) { + if (varyings.attribs) { + varyings = varyings.attribs; + } + if (!Array.isArray(varyings)) { + varyings = Object.keys(varyings); + } + gl.transformFeedbackVaryings(program, varyings, transformFeedbackMode || SEPARATE_ATTRIBS); + } + } + + gl.linkProgram(program); + return program; +} + +/** + * Creates a program, attaches (and/or compiles) shaders, binds attrib locations, links the + * program. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgram(gl, [vs, fs], options); + * twgl.createProgram(gl, [vs, fs], opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgram(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error of a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgram( + gl, shaders, opt_attribs, opt_locations, opt_errorCallback) { + // This code is really convoluted, because it may or may not be async + // Maybe it would be better to have a separate function + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaderSet = new Set(shaders); + const program = createProgramNoCheck(gl, shaders, progOptions); + + function hasErrors(gl, program) { + const errors = getProgramErrors(gl, program, progOptions.errorCallback); + if (errors) { + deleteProgramAndShaders(gl, program, shaderSet); + } + return errors; + } + + if (progOptions.callback) { + waitForProgramLinkCompletionAsync(gl, program).then(() => { + const errors = hasErrors(gl, program); + progOptions.callback(errors, errors ? undefined : program); + }); + return undefined; + } + + return hasErrors(gl, program) ? undefined : program; +} + +/** + * This only works because the functions it wraps the first 2 arguments + * are gl and any, followed by things that become programOptions + * @private + */ +function wrapCallbackFnToAsyncFn(fn) { + return function(gl, arg1, ...args) { + return new Promise((resolve, reject) => { + const programOptions = getProgramOptions(...args); + programOptions.callback = (err, program) => { + if (err) { + reject(err); + } else { + resolve(program); + } + }; + fn(gl, arg1, programOptions); + }); + }; +} + +/** + * Same as createProgram but returns a promise + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramAsync(gl, [vs, fs], options); + * twgl.createProgramAsync(gl, [vs, fs], opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramAsync(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLShader[]|string[]} shaders The shaders to attach, or element ids for their source, or strings that contain their source + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created program + * @memberOf module:twgl/programs + */ +const createProgramAsync = wrapCallbackFnToAsyncFn(createProgram); + +/** + * Same as createProgramInfo but returns a promise + * @function + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 {Promise} The created ProgramInfo + * @memberOf module:twgl/programs + */ +const createProgramInfoAsync = wrapCallbackFnToAsyncFn(createProgramInfo); + +async function waitForProgramLinkCompletionAsync(gl, program) { + const ext = gl.getExtension('KHR_parallel_shader_compile'); + const checkFn = ext + ? (gl, program) => gl.getProgramParameter(program, ext.COMPLETION_STATUS_KHR) + : () => true; + + let waitTime = 0; + do { + await wait(waitTime); // must wait at least once + waitTime = 1000 / 60; + } while (!checkFn(gl, program)); +} + +async function waitForAllProgramsLinkCompletionAsync(gl, programs) { + for (const program of Object.values(programs)) { + await waitForProgramLinkCompletionAsync(gl, program); + } +} + +/** + * Check a program's link status + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program Program to check + * @param {ErrorCallback} [errFn] func for errors + * @return {string?} errors if program is failed, else undefined + * @private + */ +function getProgramErrors(gl, program, errFn) { + errFn = errFn || error; + // Check the link status + const linked = gl.getProgramParameter(program, LINK_STATUS); + if (!linked) { + // something went wrong with the link + const lastError = gl.getProgramInfoLog(program); + errFn(`Error in program linking: ${lastError}`); + // print any errors from these shaders + const shaders = gl.getAttachedShaders(program); + const errors = shaders.map(shader => checkShaderStatus(gl, gl.getShaderParameter(shader, gl.SHADER_TYPE), shader, errFn)); + return `${lastError}\n${errors.filter(_ => _).join('\n')}`; + } + return undefined; +} + +/** + * Creates a program from 2 script tags. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromScripts(gl, [vs, fs], opt_options); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromScripts(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @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 {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromScripts( + gl, shaderScriptIds, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const shaders = []; + for (const scriptId of shaderScriptIds) { + const shaderScript = getElementById(scriptId); + if (!shaderScript) { + return reportError(progOptions, `unknown script element: ${scriptId}`); + } + shaders.push(shaderScript.text); + } + return createProgram(gl, shaders, progOptions); +} + +/** + * Creates a program from 2 sources. + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramFromSource(gl, [vs, fs], opt_options); + * twgl.createProgramFromSource(gl, [vs, fs], opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramFromSource(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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 or null if error or a callback was provided. + * @memberOf module:twgl/programs + */ +function createProgramFromSources( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + return createProgram(gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback); +} + +/** + * Returns true if attribute/uniform is a reserved/built in + * + * It makes no sense to me why GL returns these because it's + * illegal to call `gl.getUniformLocation` and `gl.getAttribLocation` + * with names that start with `gl_` (and `webgl_` in WebGL) + * + * I can only assume they are there because they might count + * when computing the number of uniforms/attributes used when you want to + * know if you are near the limit. That doesn't really make sense + * to me but the fact that these get returned are in the spec. + * + * @param {WebGLActiveInfo} info As returned from `gl.getActiveUniform` or + * `gl.getActiveAttrib`. + * @return {bool} true if it's reserved + * @private + */ +function isBuiltIn(info) { + const name = info.name; + return name.startsWith("gl_") || name.startsWith("webgl_"); +} + +const tokenRE = /(\.|\[|]|\w+)/g; +const isDigit = s => s >= '0' && s <= '9'; +function addSetterToUniformTree(fullPath, setter, node, uniformSetters) { + const tokens = fullPath.split(tokenRE).filter(s => s !== ''); + let tokenNdx = 0; + let path = ''; + + for (;;) { + const token = tokens[tokenNdx++]; // has to be name or number + path += token; + const isArrayIndex = isDigit(token[0]); + const accessor = isArrayIndex + ? parseInt(token) + : token; + if (isArrayIndex) { + path += tokens[tokenNdx++]; // skip ']' + } + const isLastToken = tokenNdx === tokens.length; + if (isLastToken) { + node[accessor] = setter; + break; + } else { + const token = tokens[tokenNdx++]; // has to be . or [ + const isArray = token === '['; + const child = node[accessor] || (isArray ? [] : {}); + node[accessor] = child; + node = child; + uniformSetters[path] = uniformSetters[path] || function(node) { + return function(value) { + setUniformTree(node, value); + }; + }(child); + path += token; + } + } +} + +/** + * Creates setter functions for all uniforms of a shader + * program. + * + * @see {@link module:twgl.setUniforms} + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @returns {Object.} an object with a setter by name for each uniform + * @memberOf module:twgl/programs + */ +function createUniformSetters(gl, program) { + let 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, location) { + const isArray = uniformInfo.name.endsWith("[0]"); + const type = uniformInfo.type; + const typeInfo = typeMap[type]; + if (!typeInfo) { + throw new Error(`unknown type: 0x${type.toString(16)}`); // we should never get here. + } + let setter; + if (typeInfo.bindPoint) { + // it's a sampler + const unit = textureUnit; + textureUnit += uniformInfo.size; + if (isArray) { + setter = typeInfo.arraySetter(gl, type, unit, location, uniformInfo.size); + } else { + setter = typeInfo.setter(gl, type, unit, location, uniformInfo.size); + } + } else { + if (typeInfo.arraySetter && isArray) { + setter = typeInfo.arraySetter(gl, location); + } else { + setter = typeInfo.setter(gl, location); + } + } + setter.location = location; + return setter; + } + + const uniformSetters = {}; + const uniformTree = {}; + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + + for (let ii = 0; ii < numUniforms; ++ii) { + const uniformInfo = gl.getActiveUniform(program, ii); + if (isBuiltIn(uniformInfo)) { + continue; + } + let name = uniformInfo.name; + // remove the array suffix. + if (name.endsWith("[0]")) { + name = name.substr(0, name.length - 3); + } + const location = gl.getUniformLocation(program, uniformInfo.name); + // the uniform will have no location if it's in a uniform block + if (location) { + const setter = createUniformSetter(program, uniformInfo, location); + uniformSetters[name] = setter; + addSetterToUniformTree(name, setter, uniformTree, uniformSetters); + } + } + + return uniformSetters; +} + +/** + * @typedef {Object} TransformFeedbackInfo + * @property {number} index index of transform feedback + * @property {number} type GL type + * @property {number} size 1 - 4 + * @memberOf module:twgl + */ + +/** + * Create TransformFeedbackInfo for passing to bindTransformFeedbackInfo. + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program an existing WebGLProgram. + * @return {Object} + * @memberOf module:twgl + */ +function createTransformFeedbackInfo(gl, program) { + const info = {}; + const numVaryings = gl.getProgramParameter(program, TRANSFORM_FEEDBACK_VARYINGS); + for (let ii = 0; ii < numVaryings; ++ii) { + const varying = gl.getTransformFeedbackVarying(program, ii); + info[varying.name] = { + index: ii, + type: varying.type, + size: varying.size, + }; + } + return info; +} + +/** + * Binds buffers for transform feedback. + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {(module:twgl.ProgramInfo|Object)} transformFeedbackInfo A ProgramInfo or TransformFeedbackInfo. + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @memberOf module:twgl + */ +function bindTransformFeedbackInfo(gl, transformFeedbackInfo, bufferInfo) { + if (transformFeedbackInfo.transformFeedbackInfo) { + transformFeedbackInfo = transformFeedbackInfo.transformFeedbackInfo; + } + if (bufferInfo.attribs) { + bufferInfo = bufferInfo.attribs; + } + for (const name in bufferInfo) { + const varying = transformFeedbackInfo[name]; + if (varying) { + const buf = bufferInfo[name]; + if (buf.offset) { + gl.bindBufferRange(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer, buf.offset, buf.size); + } else { + gl.bindBufferBase(TRANSFORM_FEEDBACK_BUFFER, varying.index, buf.buffer); + } + } + } +} + +/** + * Creates a transform feedback and sets the buffers + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @param {(module:twgl.BufferInfo|Object)} [bufferInfo] A BufferInfo or set of AttribInfos. + * @return {WebGLTransformFeedback} the created transform feedback + * @memberOf module:twgl + */ +function createTransformFeedback(gl, programInfo, bufferInfo) { + const tf = gl.createTransformFeedback(); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, tf); + gl.useProgram(programInfo.program); + bindTransformFeedbackInfo(gl, programInfo, bufferInfo); + gl.bindTransformFeedback(TRANSFORM_FEEDBACK, null); + return tf; +} + +/** + * @typedef {Object} UniformData + * @property {string} name The name of the uniform + * @property {number} type The WebGL type enum for this uniform + * @property {number} size The number of elements for this uniform + * @property {number} blockNdx The block index this uniform appears in + * @property {number} offset The byte offset in the block for this uniform's value + * @memberOf module:twgl + */ + +/** + * The specification for one UniformBlockObject + * + * @typedef {Object} BlockSpec + * @property {number} index The index of the block. + * @property {number} size The size in bytes needed for the block + * @property {number[]} uniformIndices The indices of the uniforms used by the block. These indices + * correspond to entries in a UniformData array in the {@link module:twgl.UniformBlockSpec}. + * @property {bool} usedByVertexShader Self explanatory + * @property {bool} usedByFragmentShader Self explanatory + * @property {bool} used Self explanatory + * @memberOf module:twgl + */ + +/** + * A `UniformBlockSpec` represents the data needed to create and bind + * UniformBlockObjects for a given program + * + * @typedef {Object} UniformBlockSpec + * @property {Object.} blockSpecs The BlockSpec for each block by block name + * @property {UniformData[]} uniformData An array of data for each uniform by uniform index. + * @memberOf module:twgl + */ + +/** + * Creates a UniformBlockSpec for the given program. + * + * A UniformBlockSpec represents the data needed to create and bind + * UniformBlockObjects + * + * @param {WebGL2RenderingContext} gl A WebGL2 Rendering Context + * @param {WebGLProgram} program A WebGLProgram for a successfully linked program + * @return {module:twgl.UniformBlockSpec} The created UniformBlockSpec + * @memberOf module:twgl/programs + */ +function createUniformBlockSpecFromProgram(gl, program) { + const numUniforms = gl.getProgramParameter(program, ACTIVE_UNIFORMS); + const uniformData = []; + const uniformIndices = []; + + for (let ii = 0; ii < numUniforms; ++ii) { + uniformIndices.push(ii); + uniformData.push({}); + const uniformInfo = gl.getActiveUniform(program, ii); + uniformData[ii].name = uniformInfo.name; + } + + [ + [ "UNIFORM_TYPE", "type" ], + [ "UNIFORM_SIZE", "size" ], // num elements + [ "UNIFORM_BLOCK_INDEX", "blockNdx" ], + [ "UNIFORM_OFFSET", "offset", ], + ].forEach(function(pair) { + const pname = pair[0]; + const key = pair[1]; + gl.getActiveUniforms(program, uniformIndices, gl[pname]).forEach(function(value, ndx) { + uniformData[ndx][key] = value; + }); + }); + + const blockSpecs = {}; + + const numUniformBlocks = gl.getProgramParameter(program, ACTIVE_UNIFORM_BLOCKS); + for (let ii = 0; ii < numUniformBlocks; ++ii) { + const name = gl.getActiveUniformBlockName(program, ii); + const blockSpec = { + index: gl.getUniformBlockIndex(program, name), + usedByVertexShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER), + usedByFragmentShader: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER), + size: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_DATA_SIZE), + uniformIndices: gl.getActiveUniformBlockParameter(program, ii, UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES), + }; + blockSpec.used = blockSpec.usedByVertexShader || blockSpec.usedByFragmentShader; + blockSpecs[name] = blockSpec; + } + + return { + blockSpecs: blockSpecs, + uniformData: uniformData, + }; +} + +const arraySuffixRE = /\[\d+\]\.$/; // better way to check? + +const pad = (v, padding) => ((v + (padding - 1)) / padding | 0) * padding; + +function createUniformBlockUniformSetter(view, isArray, rows, cols) { + if (isArray || rows) { + cols = cols || 1; + const numElements = view.length; + const totalRows = numElements / 4; + return function(value) { + let dst = 0; + let src = 0; + for (let row = 0; row < totalRows; ++row) { + for (let col = 0; col < cols; ++col) { + view[dst++] = value[src++]; + } + dst += 4 - cols; + } + }; + } else { + return function(value) { + if (value.length) { + view.set(value); + } else { + view[0] = value; + } + }; + } +} + +/** + * Represents a UniformBlockObject including an ArrayBuffer with all the uniform values + * and a corresponding WebGLBuffer to hold those values on the GPU + * + * @typedef {Object} UniformBlockInfo + * @property {string} name The name of the block + * @property {ArrayBuffer} array The array buffer that contains the uniform values + * @property {Float32Array} asFloat A float view on the array buffer. This is useful + * inspecting the contents of the buffer in the debugger. + * @property {Uint8Array} asUint8t A uint8 view on the array buffer. + * @property {WebGLBuffer} buffer A WebGL buffer that will hold a copy of the uniform values for rendering. + * @property {number} [offset] offset into buffer + * @property {Object} uniforms A uniform name to ArrayBufferView map. + * each Uniform has a correctly typed `ArrayBufferView` into array at the correct offset + * and length of that uniform. So for example a float uniform would have a 1 float `Float32Array` + * view. A single mat4 would have a 16 element `Float32Array` view. An ivec2 would have an + * `Int32Array` view, etc. + * @property {Object} setters A setter for this uniform. + * The reason to use setters is elements of arrays are padded to vec4 sizes which + * means if you want to set an array of 4 floats you'd need to set 16 values + * (or set elements 0, 4, 8, 12). In other words + * `someBlockInfo.uniforms.some4FloatArrayUniform.set([0, , , , 1, , , , 2, , , , 3])` + * where as the setter handles just passing in [0, 1, 2, 3] either directly as in + * `someBlockInfo.setter.some4FloatArrayUniform.set([0, 1, 2, 3])` (not recommended) + * or via {@link module:twgl.setBlockUniforms} + * @memberOf module:twgl + */ + +/** + * Options to allow createUniformBlockInfo to use an existing buffer and arrayBuffer at an offset + * @typedef {Object} UniformBlockInfoOptions + * @property {ArrayBuffer} [array] an existing array buffer to use for values + * @property {number} [offset] the offset in bytes to use in the array buffer (default = 0) + * @property {WebGLBuffer} [buffer] the buffer to use for this uniform block info + * @property {number} [bufferOffset] the offset in bytes in the buffer to use (default = use offset above) + */ + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {WebGLProgram} program A WebGLProgram + * @param {module:twgl.UniformBlockSpec} uniformBlockSpec. A UniformBlockSpec as returned + * from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfoFromProgram(gl, program, uniformBlockSpec, blockName, options = {}) { + const blockSpecs = uniformBlockSpec.blockSpecs; + const uniformData = uniformBlockSpec.uniformData; + const blockSpec = blockSpecs[blockName]; + if (!blockSpec) { + warn("no uniform block object named:", blockName); + return { + name: blockName, + uniforms: {}, + }; + } + const offset = options.offset ?? 0; + const array = options.array ?? new ArrayBuffer(blockSpec.size); + const buffer = options.buffer ?? gl.createBuffer(); + const uniformBufferIndex = blockSpec.index; + gl.bindBuffer(UNIFORM_BUFFER, buffer); + if (!options.buffer) { + gl.bufferData(UNIFORM_BUFFER, array.byteLength, DYNAMIC_DRAW); + } + gl.uniformBlockBinding(program, blockSpec.index, uniformBufferIndex); + + let prefix = blockName + "."; + if (arraySuffixRE.test(prefix)) { + prefix = prefix.replace(arraySuffixRE, "."); + } + const uniforms = {}; + const setters = {}; + const setterTree = {}; + blockSpec.uniformIndices.forEach(function(uniformNdx) { + const data = uniformData[uniformNdx]; + let name = data.name; + if (name.startsWith(prefix)) { + name = name.substr(prefix.length); + } + const isArray = name.endsWith('[0]'); + if (isArray) { + name = name.substr(0, name.length - 3); + } + const typeInfo = typeMap[data.type]; + const Type = typeInfo.Type; + const byteLength = isArray + ? pad(typeInfo.size, 16) * data.size + : typeInfo.size * data.size; + const uniformView = new Type(array, offset + data.offset, byteLength / Type.BYTES_PER_ELEMENT); + uniforms[name] = uniformView; + // Note: I'm not sure what to do here. The original + // idea was to create TypedArray views into each part + // of the block. This is useful, for example if you have + // a block with { mat4: model; mat4 view; mat4 projection; } + // you'll get a Float32Array for each one suitable for + // passing to most JS math libraries including twgl's and glMatrix.js. + // + // But, if you have a an array of structures, especially if that + // array is large, you get a whole bunch of TypedArray views. + // Every one of them has overhead and switching between them all + // is probably a cache miss. In that case it would really be better + // to just have one view (asFloat) and have all the setters + // just reference the correct portion. But, then you can't easily + // treat a matrix, or a vec4, as a standalone thing like you can + // with all the views. + // + // Another problem with the views is they are not shared. With + // uniforms you have one set of setters. With UniformBlockInfo + // you have a set of setters *pre block instance*. That's because + // TypedArray views can't be mapped to different buffers. + // + // My gut right now is if you really want the speed and compactness + // then you should probably roll your own solution. TWGL's goal + // here is ease of use as AFAICT there is no simple generic efficient + // solution. + const setter = createUniformBlockUniformSetter(uniformView, isArray, typeInfo.rows, typeInfo.cols); + setters[name] = setter; + addSetterToUniformTree(name, setter, setterTree, setters); + }); + return { + name: blockName, + array, + asFloat: new Float32Array(array), // for debugging + asUint8: new Uint8Array(array), // needed for gl.bufferSubData because it doesn't take an array buffer + buffer, + uniforms, + setters, + offset: options.bufferOffset ?? offset, + size: blockSpec.size, + }; +} + +/** + * Creates a `UniformBlockInfo` for the specified block + * + * Note: **If the blockName matches no existing blocks a warning is printed to the console and a dummy + * `UniformBlockInfo` is returned**. This is because when debugging GLSL + * it is common to comment out large portions of a shader or for example set + * the final output to a constant. When that happens blocks get optimized out. + * If this function did not create dummy blocks your code would crash when debugging. + * + * @param {WebGL2RenderingContext} gl A WebGL2RenderingContext + * @param {module:twgl.ProgramInfo} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} + * @param {string} blockName The name of the block. + * @param {module:twgl.UniformBlockInfoOptions} [options] Optional options for using existing an existing buffer and arrayBuffer + * @return {module:twgl.UniformBlockInfo} The created UniformBlockInfo + * @memberOf module:twgl/programs + */ +function createUniformBlockInfo(gl, programInfo, blockName, options = {}) { + return createUniformBlockInfoFromProgram(gl, programInfo.program, programInfo.uniformBlockSpec, blockName, options); +} + +/** + * Binds a uniform block to the matching uniform block point. + * Matches by blocks by name so blocks must have the same name not just the same + * structure. + * + * If you have changed any values and you upload the values into the corresponding WebGLBuffer + * call {@link module:twgl.setUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @return {bool} true if buffer was bound. If the programInfo has no block with the same block name + * no buffer is bound. + * @memberOf module:twgl/programs + */ +function bindUniformBlock(gl, programInfo, uniformBlockInfo) { + const uniformBlockSpec = programInfo.uniformBlockSpec || programInfo; + const blockSpec = uniformBlockSpec.blockSpecs[uniformBlockInfo.name]; + if (blockSpec) { + const bufferBindIndex = blockSpec.index; + gl.bindBufferRange(UNIFORM_BUFFER, bufferBindIndex, uniformBlockInfo.buffer, uniformBlockInfo.offset || 0, uniformBlockInfo.size ?? uniformBlockInfo.array.byteLength); + return true; + } + return false; +} + +/** + * Uploads the current uniform values to the corresponding WebGLBuffer + * and binds that buffer to the program's corresponding bind point for the uniform block object. + * + * If you haven't changed any values and you only need to bind the uniform block object + * call {@link module:twgl.bindUniformBlock} instead. + * + * @param {WebGL2RenderingContext} gl A WebGL 2 rendering context. + * @param {(module:twgl.ProgramInfo|module:twgl.UniformBlockSpec)} programInfo a `ProgramInfo` + * as returned from {@link module:twgl.createProgramInfo} or or `UniformBlockSpec` as + * returned from {@link module:twgl.createUniformBlockSpecFromProgram}. + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo a `UniformBlockInfo` as returned from + * {@link module:twgl.createUniformBlockInfo}. + * @memberOf module:twgl/programs + */ +function setUniformBlock(gl, programInfo, uniformBlockInfo) { + if (bindUniformBlock(gl, programInfo, uniformBlockInfo)) { + gl.bufferSubData(UNIFORM_BUFFER, 0, uniformBlockInfo.asUint8, uniformBlockInfo.offset || 0, uniformBlockInfo.size || 0); + } +} + +/** + * Sets values of a uniform block object + * + * @param {module:twgl.UniformBlockInfo} uniformBlockInfo A UniformBlockInfo as returned by {@link module:twgl.createUniformBlockInfo}. + * @param {Object.} values A uniform name to value map where the value is correct for the given + * type of uniform. So for example given a block like + * + * uniform SomeBlock { + * float someFloat; + * vec2 someVec2; + * vec3 someVec3Array[2]; + * int someInt; + * } + * + * You can set the values of the uniform block with + * + * twgl.setBlockUniforms(someBlockInfo, { + * someFloat: 12.3, + * someVec2: [1, 2], + * someVec3Array: [1, 2, 3, 4, 5, 6], + * someInt: 5, + * } + * + * Arrays can be JavaScript arrays or typed arrays + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Lights { + * Light lights[2]; + * }; + * + * // in JavaScript + * + * twgl.setBlockUniforms(someBlockInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setBlockUniforms(someBlockInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices. + * + * twgl.setBlockUniforms(someBlockInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * **IMPORTANT!**, packing in a UniformBlock is unintuitive. + * For example the actual layout of `someVec3Array` above in memory + * is `1, 2, 3, unused, 4, 5, 6, unused`. twgl takes in 6 values + * as shown about and copies them, skipping the padding. This might + * be confusing if you're already familiar with Uniform blocks. + * + * If you want to deal with the padding yourself you can access the array + * buffer views directly. eg: + * + * someBlockInfo.someVec3Array.set([1, 2, 3, 0, 4, 5, 6, 0]); + * + * Any name that doesn't match will be ignored + * @memberOf module:twgl/programs + */ +function setBlockUniforms(uniformBlockInfo, values) { + const setters = uniformBlockInfo.setters; + for (const name in values) { + const setter = setters[name]; + if (setter) { + const value = values[name]; + setter(value); + } + } +} + +function setUniformTree(tree, values) { + for (const name in values) { + const prop = tree[name]; + if (typeof prop === 'function') { + prop(values[name]); + } else { + setUniformTree(tree[name], values[name]); + } + } +} + +/** + * Set uniforms and binds related textures. + * + * example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"]); + * + * const tex1 = gl.createTexture(); + * const tex2 = gl.createTexture(); + * + * ... assume we setup the textures with data ... + * + * const 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(programInfo.program); + * + * This will automatically bind the textures AND set the + * uniforms. + * + * twgl.setUniforms(programInfo, uniforms); + * + * For the example above it is equivalent to + * + * let 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 + * + * const uniforms = { + * u_someSampler: tex1, + * u_someOtherSampler: tex2, + * }; + * + * const 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, + * ], + * }; + * + * twgl.setUniforms(programInfo, uniforms); + * twgl.setUniforms(programInfo, moreUniforms); + * + * You can also add WebGLSamplers to uniform samplers as in + * + * const uniforms = { + * u_someSampler: { + * texture: someWebGLTexture, + * sampler: someWebGLSampler, + * }, + * }; + * + * In which case both the sampler and texture will be bound to the + * same unit. + * + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * uniforms. + * You can pass multiple objects by putting them in an array or by calling with more arguments.For example + * + * const sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * const localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * twgl.setUniforms(programInfo, sharedUniforms, localUniforms); + * + * // is the same as + * + * twgl.setUniforms(programInfo, [sharedUniforms, localUniforms]); + * + * // is the same as + * + * twgl.setUniforms(programInfo, sharedUniforms); + * twgl.setUniforms(programInfo, localUniforms}; + * + * You can also fill out structure and array values either via + * shortcut. Example + * + * // -- in shader -- + * struct Light { + * float intensity; + * vec4 color; + * float nearFar[2]; + * }; + * uniform Light lights[2]; + * + * // in JavaScript + * + * twgl.setUniforms(programInfo, { + * lights: [ + * { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.1, 10] }, + * { intensity: 2.0, color: [0, 0, 1, 1], nearFar[0.2, 15] }, + * ], + * }); + * + * or the more traditional way + * + * twgl.setUniforms(programInfo, { + * "lights[0].intensity": 5.0, + * "lights[0].color": [1, 0, 0, 1], + * "lights[0].nearFar": [0.1, 10], + * "lights[1].intensity": 2.0, + * "lights[1].color": [0, 0, 1, 1], + * "lights[1].nearFar": [0.2, 15], + * }); + * + * You can also specify partial paths + * + * twgl.setUniforms(programInfo, { + * 'lights[1]': { intensity: 5.0, color: [1, 0, 0, 1], nearFar[0.2, 15] }, + * }); + * + * But you can not specify leaf array indices + * + * twgl.setUniforms(programInfo, { + * 'lights[1].nearFar[1]': 15, // BAD! nearFar is a leaf + * 'lights[1].nearFar': [0.2, 15], // GOOD + * }); + * + * @memberOf module:twgl/programs + */ +function setUniforms(setters, ...args) { // eslint-disable-line + const actualSetters = setters.uniformSetters || setters; + const numArgs = args.length; + for (let aNdx = 0; aNdx < numArgs; ++aNdx) { + const values = args[aNdx]; + if (Array.isArray(values)) { + const numValues = values.length; + for (let ii = 0; ii < numValues; ++ii) { + setUniforms(actualSetters, values[ii]); + } + } else { + for (const name in values) { + const setter = actualSetters[name]; + if (setter) { + setter(values[name]); + } + } + } + } +} + +/** + * Alias for `setUniforms` + * @function + * @param {(module:twgl.ProgramInfo|Object.)} setters a `ProgramInfo` as returned from `createProgramInfo` or the setters returned from + * `createUniformSetters`. + * @param {Object.} values an object with values for the + * @memberOf module:twgl/programs + */ +const setUniformsAndBindTextures = setUniforms; + +/** + * Creates setter functions for all attributes of a shader + * program. You can pass this to {@link module:twgl.setBuffersAndAttributes} to set all your buffers and attributes. + * + * @see {@link module:twgl.setAttributes} for example + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {WebGLProgram} program the program to create setters for. + * @return {Object.} an object with a setter for each attribute by name. + * @memberOf module:twgl/programs + */ +function createAttributeSetters(gl, program) { + const attribSetters = { + }; + + const numAttribs = gl.getProgramParameter(program, ACTIVE_ATTRIBUTES); + for (let ii = 0; ii < numAttribs; ++ii) { + const attribInfo = gl.getActiveAttrib(program, ii); + if (isBuiltIn(attribInfo)) { + continue; + } + const index = gl.getAttribLocation(program, attribInfo.name); + const typeInfo = attrTypeMap[attribInfo.type]; + const setter = typeInfo.setter(gl, index, typeInfo); + setter.location = index; + attribSetters[attribInfo.name] = setter; + } + + return attribSetters; +} + +/** + * Sets attributes and binds buffers (deprecated... use {@link module:twgl.setBuffersAndAttributes}) + * + * Example: + * + * const program = createProgramFromScripts( + * gl, ["some-vs", "some-fs"); + * + * const attribSetters = createAttributeSetters(program); + * + * const positionBuffer = gl.createBuffer(); + * const texcoordBuffer = gl.createBuffer(); + * + * const 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 + * * divisor: the divisor for instances. Default = undefined + * + * 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 + * + * const 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.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} buffers AttribInfos mapped by attribute name. + * @memberOf module:twgl/programs + * @deprecated use {@link module:twgl.setBuffersAndAttributes} + * @private + */ +function setAttributes(setters, buffers) { + for (const name in buffers) { + const setter = setters[name]; + if (setter) { + setter(buffers[name]); + } + } +} + +/** + * Sets attributes and buffers including the `ELEMENT_ARRAY_BUFFER` if appropriate + * + * Example: + * + * const programInfo = createProgramInfo( + * gl, ["some-vs", "some-fs"); + * + * const 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], }, + * }; + * + * const bufferInfo = createBufferInfoFromArrays(gl, arrays); + * + * gl.useProgram(programInfo.program); + * + * This will automatically bind the buffers AND set the + * attributes. + * + * setBuffersAndAttributes(gl, programInfo, bufferInfo); + * + * For the example above it is equivalent 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 {(module:twgl.ProgramInfo|Object.)} setters A `ProgramInfo` as returned from {@link module:twgl.createProgramInfo} or Attribute setters as returned from {@link module:twgl.createAttributeSetters} + * @param {(module:twgl.BufferInfo|module:twgl.VertexArrayInfo)} buffers a `BufferInfo` as returned from {@link module:twgl.createBufferInfoFromArrays}. + * or a `VertexArrayInfo` as returned from {@link module:twgl.createVertexArrayInfo} + * @memberOf module:twgl/programs + */ +function setBuffersAndAttributes(gl, programInfo, buffers) { + if (buffers.vertexArrayObject) { + gl.bindVertexArray(buffers.vertexArrayObject); + } else { + setAttributes(programInfo.attribSetters || programInfo, buffers.attribs); + if (buffers.indices) { + gl.bindBuffer(ELEMENT_ARRAY_BUFFER$1, buffers.indices); + } + } +} + +/** + * @typedef {Object} ProgramInfo + * @property {WebGLProgram} program A shader program + * @property {Object} uniformLocations The uniform locations of each uniform + * @property {Object} attribLocations The locations of each attribute + * @property {Object} uniformSetters object of setters as returned from createUniformSetters, + * @property {Object} attribSetters object of setters as returned from createAttribSetters, + * @property {module:twgl.UniformBlockSpec} [uniformBlockSpec] a uniform block spec for making UniformBlockInfos with createUniformBlockInfo etc.. + * @property {Object} [transformFeedbackInfo] info for transform feedbacks + * @memberOf module:twgl + */ + +/** + * Creates a ProgramInfo from an existing program. + * + * 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 {WebGLProgram} program an existing WebGLProgram. + * @return {module:twgl.ProgramInfo} The created ProgramInfo. + * @memberOf module:twgl/programs + */ +function createProgramInfoFromProgram(gl, program) { + const uniformSetters = createUniformSetters(gl, program); + const attribSetters = createAttributeSetters(gl, program); + const programInfo = { + program, + uniformSetters, + attribSetters, + uniformLocations: Object.fromEntries(Object.entries(uniformSetters).map(([k, v]) => [k, v.location])), + attribLocations: Object.fromEntries(Object.entries(attribSetters).map(([k, v]) => [k, v.location])), + }; + + if (isWebGL2(gl)) { + programInfo.uniformBlockSpec = createUniformBlockSpecFromProgram(gl, program); + programInfo.transformFeedbackInfo = createTransformFeedbackInfo(gl, program); + } + + return programInfo; +} + +const notIdRE = /\s|{|}|;/; + +/** + * 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, + * } + * + * NOTE: There are 4 signatures for this function + * + * twgl.createProgramInfo(gl, [vs, fs], options); + * twgl.createProgramInfo(gl, [vs, fs], opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_errFunc); + * twgl.createProgramInfo(gl, [vs, fs], opt_attribs, opt_locations, opt_errFunc); + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext + * to use. + * @param {string[]} shaderSources Array of sources for the + * shaders or ids. The first is assumed to be the vertex shader, + * the second the fragment shader. + * @param {module:twgl.ProgramOptions|string[]|module:twgl.ErrorCallback} [opt_attribs] Options for the program or an array of attribs names or an error callback. Locations will be assigned by index if not passed in + * @param {number[]|module:twgl.ErrorCallback} [opt_locations] The locations for the. A parallel array to opt_attribs letting you assign locations or an error callback. + * @param {module:twgl.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:twgl.ProgramInfo?} The created ProgramInfo or null if it failed to link or compile + * @memberOf module:twgl/programs + */ +function createProgramInfo( + gl, shaderSources, opt_attribs, opt_locations, opt_errorCallback) { + const progOptions = getProgramOptions(opt_attribs, opt_locations, opt_errorCallback); + const errors = []; + shaderSources = shaderSources.map(function(source) { + // Lets assume if there is no \n it's an id + if (!notIdRE.test(source)) { + const script = getElementById(source); + if (!script) { + const err = `no element with id: ${source}`; + progOptions.errorCallback(err); + errors.push(err); + } else { + source = script.text; + } + } + return source; + }); + + if (errors.length) { + return reportError(progOptions, ''); + } + + const origCallback = progOptions.callback; + if (origCallback) { + progOptions.callback = (err, program) => { + origCallback(err, err ? undefined : createProgramInfoFromProgram(gl, program)); + }; + } + + const program = createProgramFromSources(gl, shaderSources, progOptions); + if (!program) { + return null; + } + + return createProgramInfoFromProgram(gl, program); +} + +function checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions) { + // check errors for everything. + for (const [name, program] of Object.entries(programs)) { + const options = {...programOptions}; + const spec = programSpecs[name]; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + const errors = getProgramErrors(gl, program, options.errorCallback); + if (errors) { + // delete everything we created + for (const program of Object.values(programs)) { + const shaders = gl.getAttachedShaders(program); + gl.deleteProgram(program); + for (const shader of shaders) { + // Don't delete it if we didn't create it. + if (!noDeleteShadersSet.has(shader)) { + gl.deleteShader(shader); + } + } + } + return errors; + } + } + + return undefined; +} + +/** + * Creates multiple programs + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgram} + * + * Example: + * + * const programs = twgl.createPrograms(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createPrograms(gl, programSpecs, programOptions = {}) { + // Remember existing shaders so that if there is an error we don't delete them + const noDeleteShadersSet = new Set(); + + // compile and link everything + const programs = Object.fromEntries(Object.entries(programSpecs).map(([name, spec]) => { + const options = {...programOptions}; + const shaders = Array.isArray(spec) ? spec : spec.shaders; + if (!Array.isArray(spec)) { + Object.assign(options, spec); + } + shaders.forEach(noDeleteShadersSet.add, noDeleteShadersSet); + return [name, createProgramNoCheck(gl, shaders, options)]; + })); + + if (programOptions.callback) { + waitForAllProgramsLinkCompletionAsync(gl, programs).then(() => { + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + programOptions.callback(errors, errors ? undefined : programs); + }); + return undefined; + } + + const errors = checkAllPrograms(gl, programs, programSpecs, noDeleteShadersSet, programOptions); + return errors ? undefined : programs; +} + +/** + * Creates multiple programInfos + * + * Note: the reason this function exists is because the fastest way to create multiple + * programs in WebGL is to create and compile all shaders and link all programs and only + * afterwards check if they succeeded. In that way, giving all your shaders + * + * @see {@link module:twgl.createProgramInfo} + * + * Examples: + * + * const programInfos = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * or + * + * const {lambert, phong, particles} = twgl.createProgramInfos(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +function createProgramInfos(gl, programSpecs, programOptions) { + programOptions = getProgramOptions(programOptions); + + function createProgramInfosForPrograms(gl, programs) { + return Object.fromEntries(Object.entries(programs).map(([name, program]) => + [name, createProgramInfoFromProgram(gl, program)] + )); + } + + const origCallback = programOptions.callback; + if (origCallback) { + programOptions.callback = (err, programs) => { + origCallback(err, err ? undefined : createProgramInfosForPrograms(gl, programs)); + }; + } + + const programs = createPrograms(gl, programSpecs, programOptions); + if (origCallback || !programs) { + return undefined; + } + + return createProgramInfosForPrograms(gl, programs); +} + +/** + * Creates multiple programs asynchronously + * + * @see {@link module:twgl.createProgramAsync} + * + * Example: + * + * const programs = await twgl.createProgramsAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Object.?} the created programInfos by name + */ +const createProgramsAsync = wrapCallbackFnToAsyncFn(createPrograms); + +/** + * Creates multiple programInfos asynchronously + * + * @see {@link module:twgl.createProgramInfoAsync} + * + * Example: + * + * const programInfos = await twgl.createProgramInfosAsync(gl, { + * lambert: [lambertVS, lambertFS], + * phong: [phongVS, phoneFS], + * particles: { + * shaders: [particlesVS, particlesFS], + * transformFeedbackVaryings: ['position', 'velocity'], + * }, + * }); + * + * @function + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {Object.} programSpecs An object of ProgramSpecs, one per program. + * @param {module:twgl.ProgramOptions} [programOptions] options to apply to all programs + * @return {Promise>} the created programInfos by name + */ +const createProgramInfosAsync = wrapCallbackFnToAsyncFn(createProgramInfos); + +var programs = /*#__PURE__*/Object.freeze({ + __proto__: null, + createAttributeSetters: createAttributeSetters, + createProgram: createProgram, + createProgramAsync: createProgramAsync, + createPrograms: createPrograms, + createProgramsAsync: createProgramsAsync, + createProgramFromScripts: createProgramFromScripts, + createProgramFromSources: createProgramFromSources, + createProgramInfo: createProgramInfo, + createProgramInfoAsync: createProgramInfoAsync, + createProgramInfos: createProgramInfos, + createProgramInfosAsync: createProgramInfosAsync, + createProgramInfoFromProgram: createProgramInfoFromProgram, + createUniformSetters: createUniformSetters, + createUniformBlockSpecFromProgram: createUniformBlockSpecFromProgram, + createUniformBlockInfoFromProgram: createUniformBlockInfoFromProgram, + createUniformBlockInfo: createUniformBlockInfo, + createTransformFeedback: createTransformFeedback, + createTransformFeedbackInfo: createTransformFeedbackInfo, + bindTransformFeedbackInfo: bindTransformFeedbackInfo, + setAttributes: setAttributes, + setBuffersAndAttributes: setBuffersAndAttributes, + setUniforms: setUniforms, + setUniformsAndBindTextures: setUniformsAndBindTextures, + setUniformBlock: setUniformBlock, + setBlockUniforms: setBlockUniforms, + bindUniformBlock: bindUniformBlock +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const TRIANGLES = 0x0004; +const UNSIGNED_SHORT = 0x1403; + +/** + * Drawing related functions + * + * For backward compatibility they are available at both `twgl.draw` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/draw + */ + +/** + * 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:twgl.BufferInfo|module:twgl.VertexArrayInfo)} bufferInfo A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} or + * a VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @param {number} [type] eg (gl.TRIANGLES, gl.LINES, gl.POINTS, gl.TRIANGLE_STRIP, ...). Defaults to `gl.TRIANGLES` + * @param {number} [count] An optional count. Defaults to bufferInfo.numElements + * @param {number} [offset] An optional offset. Defaults to 0. + * @param {number} [instanceCount] An optional instanceCount. if set then `drawArraysInstanced` or `drawElementsInstanced` will be called + * @memberOf module:twgl/draw + */ +function drawBufferInfo(gl, bufferInfo, type, count, offset, instanceCount) { + type = type === undefined ? TRIANGLES : type; + const indices = bufferInfo.indices; + const elementType = bufferInfo.elementType; + const numElements = count === undefined ? bufferInfo.numElements : count; + offset = offset === undefined ? 0 : offset; + if (elementType || indices) { + if (instanceCount !== undefined) { + gl.drawElementsInstanced(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset, instanceCount); + } else { + gl.drawElements(type, numElements, elementType === undefined ? UNSIGNED_SHORT : bufferInfo.elementType, offset); + } + } else { + if (instanceCount !== undefined) { + gl.drawArraysInstanced(type, offset, numElements, instanceCount); + } else { + gl.drawArrays(type, offset, numElements); + } + } +} + +/** + * A DrawObject is useful for putting objects in to an array and passing them to {@link module:twgl.drawObjectList}. + * + * You need either a `BufferInfo` or a `VertexArrayInfo`. + * + * @typedef {Object} DrawObject + * @property {boolean} [active] whether or not to draw. Default = `true` (must be `false` to be not true). In other words `undefined` = `true` + * @property {number} [type] type to draw eg. `gl.TRIANGLES`, `gl.LINES`, etc... + * @property {module:twgl.ProgramInfo} programInfo A ProgramInfo as returned from {@link module:twgl.createProgramInfo} + * @property {module:twgl.BufferInfo} [bufferInfo] A BufferInfo as returned from {@link module:twgl.createBufferInfoFromArrays} + * @property {module:twgl.VertexArrayInfo} [vertexArrayInfo] A VertexArrayInfo as returned from {@link module:twgl.createVertexArrayInfo} + * @property {Object} uniforms The values for the uniforms. + * You can pass multiple objects by putting them in an array. For example + * + * var sharedUniforms = { + * u_fogNear: 10, + * u_projection: ... + * ... + * }; + * + * var localUniforms = { + * u_world: ... + * u_diffuseColor: ... + * }; + * + * var drawObj = { + * ... + * uniforms: [sharedUniforms, localUniforms], + * }; + * + * @property {number} [offset] the offset to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to 0. + * @property {number} [count] the count to pass to `gl.drawArrays` or `gl.drawElements`. Defaults to bufferInfo.numElements. + * @property {number} [instanceCount] the number of instances. Defaults to undefined. + * @memberOf module:twgl + */ + +/** + * Draws a list of objects + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {DrawObject[]} objectsToDraw an array of objects to draw. + * @memberOf module:twgl/draw + */ +function drawObjectList(gl, objectsToDraw) { + let lastUsedProgramInfo = null; + let lastUsedBufferInfo = null; + + objectsToDraw.forEach(function(object) { + if (object.active === false) { + return; + } + + const programInfo = object.programInfo; + const bufferInfo = object.vertexArrayInfo || object.bufferInfo; + let bindBuffers = false; + const type = object.type === undefined ? TRIANGLES : object.type; + + if (programInfo !== lastUsedProgramInfo) { + lastUsedProgramInfo = programInfo; + gl.useProgram(programInfo.program); + + // We have to rebind buffers when changing programs because we + // only bind buffers the program uses. So if 2 programs use the same + // bufferInfo but the 1st one uses only positions the when the + // we switch to the 2nd one some of the attributes will not be on. + bindBuffers = true; + } + + // Setup all the needed attributes. + if (bindBuffers || bufferInfo !== lastUsedBufferInfo) { + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject && !bufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } + lastUsedBufferInfo = bufferInfo; + setBuffersAndAttributes(gl, programInfo, bufferInfo); + } + + // Set the uniforms. + setUniforms(programInfo, object.uniforms); + + // Draw + drawBufferInfo(gl, bufferInfo, type, object.count, object.offset, object.instanceCount); + }); + + if (lastUsedBufferInfo && lastUsedBufferInfo.vertexArrayObject) { + gl.bindVertexArray(null); + } +} + +var draw = /*#__PURE__*/Object.freeze({ + __proto__: null, + drawBufferInfo: drawBufferInfo, + drawObjectList: drawObjectList +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +const FRAMEBUFFER = 0x8d40; +const RENDERBUFFER = 0x8d41; +const TEXTURE_2D = 0x0de1; + +const UNSIGNED_BYTE = 0x1401; + +/* PixelFormat */ +const DEPTH_COMPONENT = 0x1902; +const RGBA = 0x1908; +const DEPTH_COMPONENT24 = 0x81a6; +const DEPTH_COMPONENT32F = 0x8cac; +const DEPTH24_STENCIL8 = 0x88f0; +const DEPTH32F_STENCIL8 = 0x8cad; + +/* Framebuffer Object. */ +const RGBA4 = 0x8056; +const RGB5_A1 = 0x8057; +const RGB565 = 0x8D62; +const DEPTH_COMPONENT16 = 0x81A5; +const STENCIL_INDEX = 0x1901; +const STENCIL_INDEX8 = 0x8D48; +const DEPTH_STENCIL = 0x84F9; +const COLOR_ATTACHMENT0 = 0x8CE0; +const DEPTH_ATTACHMENT = 0x8D00; +const STENCIL_ATTACHMENT = 0x8D20; +const DEPTH_STENCIL_ATTACHMENT = 0x821A; + +/* TextureWrapMode */ +const CLAMP_TO_EDGE = 0x812F; + +/* TextureMagFilter */ +const LINEAR = 0x2601; + +/** + * The options for a framebuffer attachment. + * + * Note: For a `format` that is a texture include all the texture + * options from {@link module:twgl.TextureOptions} for example + * `min`, `mag`, `clamp`, etc... Note that unlike {@link module:twgl.TextureOptions} + * `auto` defaults to `false` for attachment textures but `min` and `mag` default + * to `gl.LINEAR` and `wrap` defaults to `CLAMP_TO_EDGE` + * + * @typedef {Object} AttachmentOptions + * @property {number} [attachmentPoint] The attachment point. Defaults + * to `gl.COLOR_ATTACHMENT0 + ndx` unless type is a depth or stencil type + * then it's gl.DEPTH_ATTACHMENT or `gl.DEPTH_STENCIL_ATTACHMENT` depending + * on the format or attachment type. + * @property {number} [format] The format. If one of `gl.RGBA4`, + * `gl.RGB565`, `gl.RGB5_A1`, `gl.DEPTH_COMPONENT16`, + * `gl.STENCIL_INDEX8` or `gl.DEPTH_STENCIL` then will create a + * renderbuffer. Otherwise will create a texture. Default = `gl.RGBA` + * @property {number} [type] The type. Used for texture. Default = `gl.UNSIGNED_BYTE`. + * @property {number} [target] The texture target for `gl.framebufferTexture2D`. + * Defaults to `gl.TEXTURE_2D`. Set to appropriate face for cube maps. + * @property {number} [samples] The number of samples. Default = 1 + * @property {number} [level] level for `gl.framebufferTexture2D`. Defaults to 0. + * @property {number} [layer] layer for `gl.framebufferTextureLayer`. Defaults to undefined. + * If set then `gl.framebufferTextureLayer` is called, if not then `gl.framebufferTexture2D` + * @property {(WebGLRenderbuffer | WebGLTexture)} [attachment] An existing renderbuffer or texture. + * If provided will attach this Object. This allows you to share + * attachments across framebuffers. + * @memberOf module:twgl + * @mixes module:twgl.TextureOptions + */ + +const defaultAttachments = [ + { format: RGBA, type: UNSIGNED_BYTE, min: LINEAR, wrap: CLAMP_TO_EDGE, }, + { format: DEPTH_STENCIL, }, +]; + +const attachmentsByFormat = {}; +attachmentsByFormat[DEPTH_STENCIL] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX] = STENCIL_ATTACHMENT; +attachmentsByFormat[STENCIL_INDEX8] = STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT16] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT24] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH_COMPONENT32F] = DEPTH_ATTACHMENT; +attachmentsByFormat[DEPTH24_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; +attachmentsByFormat[DEPTH32F_STENCIL8] = DEPTH_STENCIL_ATTACHMENT; + +function getAttachmentPointForFormat(format, internalFormat) { + return attachmentsByFormat[format] || attachmentsByFormat[internalFormat]; +} + +const renderbufferFormats = {}; +renderbufferFormats[RGBA4] = true; +renderbufferFormats[RGB5_A1] = true; +renderbufferFormats[RGB565] = true; +renderbufferFormats[DEPTH_STENCIL] = true; +renderbufferFormats[DEPTH_COMPONENT16] = true; +renderbufferFormats[STENCIL_INDEX] = true; +renderbufferFormats[STENCIL_INDEX8] = true; + +function isRenderbufferFormat(format) { + return renderbufferFormats[format]; +} + +const MAX_COLOR_ATTACHMENT_POINTS = 32; // even an 3090 only supports 8 but WebGL/OpenGL ES define constants for 32 + +function isColorAttachmentPoint(attachmentPoint) { + return attachmentPoint >= COLOR_ATTACHMENT0 && attachmentPoint < COLOR_ATTACHMENT0 + MAX_COLOR_ATTACHMENT_POINTS; +} + +/** + * @typedef {Object} FramebufferInfo + * @property {WebGLFramebuffer} framebuffer The WebGLFramebuffer for this framebufferInfo + * @property {Array.<(WebGLRenderbuffer | WebGLTexture)>} attachments The created attachments in the same order as passed in to {@link module:twgl.createFramebufferInfo}. + * @property {number} width The width of the framebuffer and its attachments + * @property {number} height The width of the framebuffer and its attachments + * @memberOf module:twgl + */ + +/** + * Creates a framebuffer and attachments. + * + * This returns a {@link module:twgl.FramebufferInfo} because it needs to return the attachments as well as the framebuffer. + * It also leaves the framebuffer it just created as the currently bound `FRAMEBUFFER`. + * Note: If this is WebGL2 or if you called {@link module:twgl.addExtensionsToContext} then it will set the drawBuffers + * to `[COLOR_ATTACHMENT0, COLOR_ATTACHMENT1, ...]` for how ever many color attachments were created. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * Passing in a specific size + * + * const width = 256; + * const height = 256; + * const fbi = twgl.createFramebufferInfo(gl, attachments, width, height); + * + * **Note!!** It is up to you to check if the framebuffer is renderable by calling `gl.checkFramebufferStatus`. + * [WebGL1 only guarantees 3 combinations of attachments work](https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.6). + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.AttachmentOptions[]} [attachments] which attachments to create. If not provided the default is a framebuffer with an + * `RGBA`, `UNSIGNED_BYTE` texture `COLOR_ATTACHMENT0` and a `DEPTH_STENCIL` renderbuffer `DEPTH_STENCIL_ATTACHMENT`. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @return {module:twgl.FramebufferInfo} the framebuffer and attachments. + * @memberOf module:twgl/framebuffers + */ +function createFramebufferInfo(gl, attachments, width, height) { + const target = FRAMEBUFFER; + const fb = gl.createFramebuffer(); + gl.bindFramebuffer(target, fb); + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + attachments = attachments || defaultAttachments; + const usedColorAttachmentsPoints = []; + const framebufferInfo = { + framebuffer: fb, + attachments: [], + width: width, + height: height, + }; + + attachments.forEach(function(attachmentOptions, i) { + let attachment = attachmentOptions.attachment; + const samples = attachmentOptions.samples; + const format = attachmentOptions.format; + let attachmentPoint = attachmentOptions.attachmentPoint || getAttachmentPointForFormat(format, attachmentOptions.internalFormat); + if (!attachmentPoint) { + attachmentPoint = COLOR_ATTACHMENT0 + i; + } + if (isColorAttachmentPoint(attachmentPoint)) { + usedColorAttachmentsPoints.push(attachmentPoint); + } + if (!attachment) { + if (samples !== undefined || isRenderbufferFormat(format)) { + attachment = gl.createRenderbuffer(); + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else { + const textureOptions = Object.assign({}, attachmentOptions); + textureOptions.width = width; + textureOptions.height = height; + if (textureOptions.auto === undefined) { + textureOptions.auto = false; + textureOptions.min = textureOptions.min || textureOptions.minMag || LINEAR; + textureOptions.mag = textureOptions.mag || textureOptions.minMag || LINEAR; + textureOptions.wrapS = textureOptions.wrapS || textureOptions.wrap || CLAMP_TO_EDGE; + textureOptions.wrapT = textureOptions.wrapT || textureOptions.wrap || CLAMP_TO_EDGE; + } + attachment = createTexture(gl, textureOptions); + } + } + if (isRenderbuffer(gl, attachment)) { + gl.framebufferRenderbuffer(target, attachmentPoint, RENDERBUFFER, attachment); + } else if (isTexture(gl, attachment)) { + if (attachmentOptions.layer !== undefined) { + gl.framebufferTextureLayer( + target, + attachmentPoint, + attachment, + attachmentOptions.level || 0, + attachmentOptions.layer); + } else { + gl.framebufferTexture2D( + target, + attachmentPoint, + attachmentOptions.target || TEXTURE_2D, + attachment, + attachmentOptions.level || 0); + } + } else { + throw new Error('unknown attachment type'); + } + framebufferInfo.attachments.push(attachment); + }); + if (gl.drawBuffers) { + gl.drawBuffers(usedColorAttachmentsPoints); + } + return framebufferInfo; +} + +/** + * Resizes the attachments of a framebuffer. + * + * You need to pass in the same `attachments` as you passed in {@link module:twgl.createFramebufferInfo} + * because TWGL has no idea the format/type of each attachment. + * + * The simplest usage + * + * // create an RGBA/UNSIGNED_BYTE texture and DEPTH_STENCIL renderbuffer + * const fbi = twgl.createFramebufferInfo(gl); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments + * twgl.resizeFramebufferInfo(gl, fbi); + * } + * + * More complex usage + * + * // create an RGB565 renderbuffer and a STENCIL_INDEX8 renderbuffer + * const attachments = [ + * { format: RGB565, mag: NEAREST }, + * { format: STENCIL_INDEX8 }, + * ] + * const fbi = twgl.createFramebufferInfo(gl, attachments); + * + * ... + * + * function render() { + * if (twgl.resizeCanvasToDisplaySize(gl.canvas)) { + * // resize the attachments to match + * twgl.resizeFramebufferInfo(gl, fbi, attachments); + * } + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo} framebufferInfo a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * @param {module:twgl.AttachmentOptions[]} [attachments] the same attachments options as passed to {@link module:twgl.createFramebufferInfo}. + * @param {number} [width] the width for the attachments. Default = size of drawingBuffer + * @param {number} [height] the height for the attachments. Default = size of drawingBuffer + * @memberOf module:twgl/framebuffers + */ +function resizeFramebufferInfo(gl, framebufferInfo, attachments, width, height) { + width = width || gl.drawingBufferWidth; + height = height || gl.drawingBufferHeight; + framebufferInfo.width = width; + framebufferInfo.height = height; + attachments = attachments || defaultAttachments; + attachments.forEach(function(attachmentOptions, ndx) { + const attachment = framebufferInfo.attachments[ndx]; + const format = attachmentOptions.format; + const samples = attachmentOptions.samples; + if (samples !== undefined || isRenderbuffer(gl, attachment)) { + gl.bindRenderbuffer(RENDERBUFFER, attachment); + if (samples > 1) { + gl.renderbufferStorageMultisample(RENDERBUFFER, samples, format, width, height); + } else { + gl.renderbufferStorage(RENDERBUFFER, format, width, height); + } + } else if (isTexture(gl, attachment)) { + resizeTexture(gl, attachment, attachmentOptions, width, height); + } else { + throw new Error('unknown attachment type'); + } + }); +} + +/** + * Binds a framebuffer + * + * This function pretty much solely exists because I spent hours + * trying to figure out why something I wrote wasn't working only + * to realize I forget to set the viewport dimensions. + * My hope is this function will fix that. + * + * It is effectively the same as + * + * gl.bindFramebuffer(gl.FRAMEBUFFER, someFramebufferInfo.framebuffer); + * gl.viewport(0, 0, someFramebufferInfo.width, someFramebufferInfo.height); + * + * @param {WebGLRenderingContext} gl the WebGLRenderingContext + * @param {module:twgl.FramebufferInfo|null} [framebufferInfo] a framebufferInfo as returned from {@link module:twgl.createFramebufferInfo}. + * If falsy will bind the canvas. + * @param {number} [target] The target. If not passed `gl.FRAMEBUFFER` will be used. + * @memberOf module:twgl/framebuffers + */ + +function bindFramebufferInfo(gl, framebufferInfo, target) { + target = target || FRAMEBUFFER; + if (framebufferInfo) { + gl.bindFramebuffer(target, framebufferInfo.framebuffer); + gl.viewport(0, 0, framebufferInfo.width, framebufferInfo.height); + } else { + gl.bindFramebuffer(target, null); + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + } +} + +var framebuffers = /*#__PURE__*/Object.freeze({ + __proto__: null, + bindFramebufferInfo: bindFramebufferInfo, + createFramebufferInfo: createFramebufferInfo, + resizeFramebufferInfo: resizeFramebufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * vertex array object related functions + * + * You should generally not need to use these functions. They are provided + * for those cases where you're doing something out of the ordinary + * and you need lower level access. + * + * For backward compatibility they are available at both `twgl.attributes` and `twgl` + * itself + * + * See {@link module:twgl} for core functions + * + * @module twgl/vertexArrays + */ + +const ELEMENT_ARRAY_BUFFER = 0x8893; + +/** + * @typedef {Object} VertexArrayInfo + * @property {number} numElements The number of elements to pass to `gl.drawArrays` or `gl.drawElements`. + * @property {number} [elementType] The type of indices `UNSIGNED_BYTE`, `UNSIGNED_SHORT` etc.. + * @property {WebGLVertexArrayObject} [vertexArrayObject] a vertex array object + * @memberOf module:twgl + */ + +/** + * Creates a VertexArrayInfo from a BufferInfo and one or more ProgramInfos + * + * This can be passed to {@link module:twgl.setBuffersAndAttributes} and to + * {@link module:twgl:drawBufferInfo}. + * + * > **IMPORTANT:** Vertex Array Objects are **not** a direct analog for a BufferInfo. Vertex Array Objects + * assign buffers to specific attributes at creation time. That means they can only be used with programs + * who's attributes use the same attribute locations for the same purposes. + * + * > Bind your attribute locations by passing an array of attribute names to {@link module:twgl.createProgramInfo} + * or use WebGL 2's GLSL ES 3's `layout(location = )` to make sure locations match. + * + * also + * + * > **IMPORTANT:** After calling twgl.setBuffersAndAttribute with a BufferInfo that uses a Vertex Array Object + * that Vertex Array Object will be bound. That means **ANY MANIPULATION OF ELEMENT_ARRAY_BUFFER or ATTRIBUTES** + * will affect the Vertex Array Object state. + * + * > Call `gl.bindVertexArray(null)` to get back manipulating the global attributes and ELEMENT_ARRAY_BUFFER. + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @param {module:twgl.ProgramInfo|module:twgl.ProgramInfo[]} programInfo a programInfo or array of programInfos + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * + * You need to make sure every attribute that will be used is bound. So for example assume shader 1 + * uses attributes A, B, C and shader 2 uses attributes A, B, D. If you only pass in the programInfo + * for shader 1 then only attributes A, B, and C will have their attributes set because TWGL doesn't + * now attribute D's location. + * + * So, you can pass in both shader 1 and shader 2's programInfo + * + * @return {module:twgl.VertexArrayInfo} The created VertexArrayInfo + * + * @memberOf module:twgl/vertexArrays + */ +function createVertexArrayInfo(gl, programInfos, bufferInfo) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + if (!programInfos.length) { + programInfos = [programInfos]; + } + programInfos.forEach(function(programInfo) { + setBuffersAndAttributes(gl, programInfo, bufferInfo); + }); + gl.bindVertexArray(null); + return { + numElements: bufferInfo.numElements, + elementType: bufferInfo.elementType, + vertexArrayObject: vao, + }; +} + +/** + * Creates a vertex array object and then sets the attributes on it + * + * @param {WebGLRenderingContext} gl The WebGLRenderingContext to use. + * @param {Object.} setters Attribute setters as returned from createAttributeSetters + * @param {Object.} attribs AttribInfos mapped by attribute name. + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOAndSetAttributes(gl, setters, attribs, indices) { + const vao = gl.createVertexArray(); + gl.bindVertexArray(vao); + setAttributes(setters, attribs); + if (indices) { + gl.bindBuffer(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.| module:twgl.ProgramInfo} programInfo as returned from createProgramInfo or Attribute setters as returned from createAttributeSetters + * @param {module:twgl.BufferInfo} bufferInfo BufferInfo as returned from createBufferInfoFromArrays etc... + * @param {WebGLBuffer} [indices] an optional ELEMENT_ARRAY_BUFFER of indices + * + * @return {WebGLVertexArrayObject|null} The created WebGLVertexArrayObject + * + * @memberOf module:twgl/vertexArrays + */ +function createVAOFromBufferInfo(gl, programInfo, bufferInfo) { + return createVAOAndSetAttributes(gl, programInfo.attribSetters || programInfo, bufferInfo.attribs, bufferInfo.indices); +} + +var vertexArrays = /*#__PURE__*/Object.freeze({ + __proto__: null, + createVertexArrayInfo: createVertexArrayInfo, + createVAOAndSetAttributes: createVAOAndSetAttributes, + createVAOFromBufferInfo: createVAOFromBufferInfo +}); + +/* + * Copyright 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ +const defaults = { + addExtensionsToContext: true, +}; + +/** + * Various default settings for twgl. + * + * Note: You can call this any number of times. Example: + * + * twgl.setDefaults({ textureColor: [1, 0, 0, 1] }); + * twgl.setDefaults({ attribPrefix: 'a_' }); + * + * is equivalent to + * + * twgl.setDefaults({ + * textureColor: [1, 0, 0, 1], + * attribPrefix: 'a_', + * }); + * + * @typedef {Object} Defaults + * @property {string} [attribPrefix] The prefix to stick on attributes + * + * When writing shaders I prefer to name attributes with `a_`, uniforms with `u_` and varyings with `v_` + * as it makes it clear where they came from. But, when building geometry I prefer using un-prefixed names. + * + * In other words I'll create arrays of geometry like this + * + * const arrays = { + * position: ... + * normal: ... + * texcoord: ... + * }; + * + * But need those mapped to attributes and my attributes start with `a_`. + * + * Default: `""` + * + * @property {number[]} [textureColor] Array of 4 values in the range 0 to 1 + * + * The default texture color is used when loading textures from + * urls. Because the URL will be loaded async we'd like to be + * able to use the texture immediately. By putting a 1x1 pixel + * color in the texture we can start using the texture before + * the URL has loaded. + * + * Default: `[0.5, 0.75, 1, 1]` + * + * @property {string} [crossOrigin] + * + * If not undefined sets the crossOrigin attribute on images + * that twgl creates when downloading images for textures. + * + * Also see {@link module:twgl.TextureOptions}. + * + * @property {bool} [addExtensionsToContext] + * + * If true, then, when twgl will try to add any supported WebGL extensions + * directly to the context under their normal GL names. For example + * if ANGLE_instances_arrays exists then twgl would enable it, + * add the functions `vertexAttribDivisor`, `drawArraysInstanced`, + * `drawElementsInstanced`, and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` + * to the `WebGLRenderingContext`. + * + * @memberOf module:twgl + */ + +/** + * Sets various defaults for twgl. + * + * In the interest of terseness which is kind of the point + * of twgl I've integrated a few of the older functions here + * + * @param {module:twgl.Defaults} newDefaults The default settings. + * @memberOf module:twgl + */ +function setDefaults(newDefaults) { + copyExistingProperties(newDefaults, defaults); + setDefaults$2(newDefaults); // eslint-disable-line + setDefaults$1(newDefaults); // eslint-disable-line +} + +const prefixRE = /^(.*?)_/; +function addExtensionToContext(gl, extensionName) { + glEnumToString(gl, 0); + const ext = gl.getExtension(extensionName); + if (ext) { + const enums = {}; + const fnSuffix = prefixRE.exec(extensionName)[1]; + const enumSuffix = '_' + fnSuffix; + for (const key in ext) { + const value = ext[key]; + const isFunc = typeof (value) === 'function'; + const suffix = isFunc ? fnSuffix : enumSuffix; + let name = key; + // examples of where this is not true are WEBGL_compressed_texture_s3tc + // and WEBGL_compressed_texture_pvrtc + if (key.endsWith(suffix)) { + name = key.substring(0, key.length - suffix.length); + } + if (gl[name] !== undefined) { + if (!isFunc && gl[name] !== value) { + warn$1(name, gl[name], value, key); + } + } else { + if (isFunc) { + gl[name] = function(origFn) { + return function() { + return origFn.apply(ext, arguments); + }; + }(value); + } else { + gl[name] = value; + enums[name] = value; + } + } + } + // pass the modified enums to glEnumToString + enums.constructor = { + name: ext.constructor.name, + }; + glEnumToString(enums, 0); + } + return ext; +} + +/* + * If you're wondering why the code doesn't just iterate + * over all extensions using `gl.getExtensions` is that it's possible + * some future extension is incompatible with this code. Rather than + * have thing suddenly break it seems better to manually add to this + * list. + * + */ +const supportedExtensions = [ + 'ANGLE_instanced_arrays', + 'EXT_blend_minmax', + 'EXT_color_buffer_float', + 'EXT_color_buffer_half_float', + 'EXT_disjoint_timer_query', + 'EXT_disjoint_timer_query_webgl2', + 'EXT_frag_depth', + 'EXT_sRGB', + 'EXT_shader_texture_lod', + 'EXT_texture_filter_anisotropic', + 'OES_element_index_uint', + 'OES_standard_derivatives', + 'OES_texture_float', + 'OES_texture_float_linear', + 'OES_texture_half_float', + 'OES_texture_half_float_linear', + 'OES_vertex_array_object', + 'WEBGL_color_buffer_float', + 'WEBGL_compressed_texture_atc', + 'WEBGL_compressed_texture_etc1', + 'WEBGL_compressed_texture_pvrtc', + 'WEBGL_compressed_texture_s3tc', + 'WEBGL_compressed_texture_s3tc_srgb', + 'WEBGL_depth_texture', + 'WEBGL_draw_buffers', +]; + +/** + * Attempts to enable all of the following extensions + * and add their functions and constants to the + * `WebGLRenderingContext` using their normal non-extension like names. + * + * ANGLE_instanced_arrays + * EXT_blend_minmax + * EXT_color_buffer_float + * EXT_color_buffer_half_float + * EXT_disjoint_timer_query + * EXT_disjoint_timer_query_webgl2 + * EXT_frag_depth + * EXT_sRGB + * EXT_shader_texture_lod + * EXT_texture_filter_anisotropic + * OES_element_index_uint + * OES_standard_derivatives + * OES_texture_float + * OES_texture_float_linear + * OES_texture_half_float + * OES_texture_half_float_linear + * OES_vertex_array_object + * WEBGL_color_buffer_float + * WEBGL_compressed_texture_atc + * WEBGL_compressed_texture_etc1 + * WEBGL_compressed_texture_pvrtc + * WEBGL_compressed_texture_s3tc + * WEBGL_compressed_texture_s3tc_srgb + * WEBGL_depth_texture + * WEBGL_draw_buffers + * + * For example if `ANGLE_instanced_arrays` exists then the functions + * `drawArraysInstanced`, `drawElementsInstanced`, `vertexAttribDivisor` + * and the constant `VERTEX_ATTRIB_ARRAY_DIVISOR` are added to the + * `WebGLRenderingContext`. + * + * Note that if you want to know if the extension exists you should + * probably call `gl.getExtension` for each extension. Alternatively + * you can check for the existence of the functions or constants that + * are expected to be added. For example + * + * if (gl.drawBuffers) { + * // Either WEBGL_draw_buffers was enabled OR you're running in WebGL2 + * .... + * + * @param {WebGLRenderingContext} gl A WebGLRenderingContext + * @memberOf module:twgl + */ +function addExtensionsToContext(gl) { + for (let ii = 0; ii < supportedExtensions.length; ++ii) { + addExtensionToContext(gl, supportedExtensions[ii]); + } +} + +/** + * Creates a webgl context. + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + * @private + */ +function create3DContext(canvas, opt_attribs) { + const names = ["webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL1 context. + * + * Note: Will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + * @deprecated + * @private + */ +function getWebGLContext(canvas, opt_attribs) { + const gl = create3DContext(canvas, opt_attribs); + return gl; +} + +/** + * Creates a webgl context. + * + * Will return a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * twgl.isWebGL2(gl); + * + * @param {HTMLCanvasElement} canvas The canvas tag to get + * context from. If one is not passed in one will be + * created. + * @return {WebGLRenderingContext} The created context. + */ +function createContext(canvas, opt_attribs) { + const names = ["webgl2", "webgl", "experimental-webgl"]; + let context = null; + for (let ii = 0; ii < names.length; ++ii) { + context = canvas.getContext(names[ii], opt_attribs); + if (context) { + if (defaults.addExtensionsToContext) { + addExtensionsToContext(context); + } + break; + } + } + return context; +} + +/** + * Gets a WebGL context. Will create a WebGL2 context if possible. + * + * You can check if it's WebGL2 with + * + * function isWebGL2(gl) { + * return gl.getParameter(gl.VERSION).indexOf("WebGL 2.0 ") == 0; + * } + * + * Note: For a WebGL1 context will attempt to enable Vertex Array Objects + * and add WebGL2 entry points. (unless you first set defaults with + * `twgl.setDefaults({enableVertexArrayObjects: false})`; + * + * @param {HTMLCanvasElement} canvas a canvas element. + * @param {WebGLContextAttributes} [opt_attribs] optional webgl context creation attributes + * @return {WebGLRenderingContext} The created context. + * @memberOf module:twgl + */ +function getContext(canvas, opt_attribs) { + const gl = createContext(canvas, opt_attribs); + return gl; +} + +/** + * Resize a canvas to match the size it's displayed. + * @param {HTMLCanvasElement} canvas The canvas to resize. + * @param {number} [multiplier] So you can pass in `window.devicePixelRatio` or other scale value if you want to. + * @return {boolean} true if the canvas was resized. + * @memberOf module:twgl + */ +function resizeCanvasToDisplaySize(canvas, multiplier) { + multiplier = multiplier || 1; + multiplier = Math.max(0, multiplier); + const width = canvas.clientWidth * multiplier | 0; + const height = canvas.clientHeight * multiplier | 0; + if (canvas.width !== width || canvas.height !== height) { + canvas.width = width; + canvas.height = height; + return true; + } + return false; +} + +export { addExtensionsToContext, attributes, bindFramebufferInfo, bindTransformFeedbackInfo, bindUniformBlock, canFilter, canGenerateMipmap, createAttribsFromArrays, createAttributeSetters, createBufferFromArray, createBufferFromTypedArray, createBufferInfoFromArrays, createBuffersFromArrays, createFramebufferInfo, createProgram, createProgramAsync, createProgramFromScripts, createProgramFromSources, createProgramInfo, createProgramInfoAsync, createProgramInfoFromProgram, createProgramInfos, createProgramInfosAsync, createPrograms, createProgramsAsync, createSampler, createSamplers, createTexture, createTextures, createTransformFeedback, createTransformFeedbackInfo, createUniformBlockInfo, createUniformBlockInfoFromProgram, createUniformBlockSpecFromProgram, createUniformSetters, createVAOAndSetAttributes, createVAOFromBufferInfo, createVertexArrayInfo, draw, drawBufferInfo, drawObjectList, framebuffers, getArray as getArray_, getBytesPerElementForInternalFormat, getContext, getFormatAndTypeForInternalFormat, getGLTypeForTypedArray, getGLTypeForTypedArrayType, getNumComponentsForFormat, getNumComponents as getNumComponents_, getTypedArrayTypeForGLType, getWebGLContext, glEnumToString, isArrayBuffer$1 as isArrayBuffer, isWebGL1, isWebGL2, loadTextureFromUrl, programs, resizeCanvasToDisplaySize, resizeFramebufferInfo, resizeTexture, setAttribInfoBufferFromArray, setDefaults$2 as setAttributeDefaults_, setAttributePrefix, setAttributes, setBlockUniforms, setBuffersAndAttributes, setDefaultTextureColor, setDefaults, setEmptyTexture, setSamplerParameters, setDefaults$1 as setTextureDefaults_, setTextureFilteringForSize, setTextureFromArray, setTextureFromElement, setTextureParameters, setUniformBlock, setUniforms, setUniformsAndBindTextures, textures, typedarrays, utils, vertexArrays }; diff --git a/npm/base/package.json b/npm/base/package.json index e8d86a4c..c6cda7de 100644 --- a/npm/base/package.json +++ b/npm/base/package.json @@ -1,6 +1,6 @@ { "name": "twgl-base.js", - "version": "5.6.0", + "version": "6.0.0", "description": "A Tiny WebGL helper library", "main": "dist/6.x/twgl.js", "types": "dist/6.x/twgl-full.d.ts",