From 5b6062fce4a672b5e89bcd7ff560ab3fd185d619 Mon Sep 17 00:00:00 2001 From: Rezmason Date: Tue, 2 Aug 2022 03:35:55 -0700 Subject: [PATCH] Update regl to support uniform arrays --- lib/regl.js | 7972 ++++++++++++++++++++++++++--------------------- lib/regl.min.js | 322 +- 2 files changed, 4586 insertions(+), 3708 deletions(-) diff --git a/lib/regl.js b/lib/regl.js index 8aea96c..105828e 100644 --- a/lib/regl.js +++ b/lib/regl.js @@ -1,7 +1,7 @@ (function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.createREGL = factory()); + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.createREGL = factory()); }(this, (function () { 'use strict'; var isTypedArray = function (x) { @@ -16,15 +16,15 @@ var isTypedArray = function (x) { x instanceof Float64Array || x instanceof Uint8ClampedArray ) -}; +} var extend = function (base, opts) { - var keys = Object.keys(opts); + var keys = Object.keys(opts) for (var i = 0; i < keys.length; ++i) { - base[keys[i]] = opts[keys[i]]; + base[keys[i]] = opts[keys[i]] } return base -}; +} // Error checking and parameter validation. // @@ -32,7 +32,7 @@ var extend = function (base, opts) { // a browserify transform for optimized/minified bundles. // /* globals atob */ -var endl = '\n'; +var endl = '\n' // only used for extracting shader names. if atob not present, then errors // will be slightly crappier @@ -44,14 +44,14 @@ function decodeB64 (str) { } function raise (message) { - var error = new Error('(regl) ' + message); - console.error(error); + var error = new Error('(regl) ' + message) + console.error(error) throw error } function check (pred, message) { if (!pred) { - raise(message); + raise(message) } } @@ -65,7 +65,7 @@ function encolon (message) { function checkParameter (param, possibilities, message) { if (!(param in possibilities)) { raise('unknown parameter (' + param + ')' + encolon(message) + - '. possible values: ' + Object.keys(possibilities).join()); + '. possible values: ' + Object.keys(possibilities).join()) } } @@ -73,15 +73,27 @@ function checkIsTypedArray (data, message) { if (!isTypedArray(data)) { raise( 'invalid parameter type' + encolon(message) + - '. must be a typed array'); + '. must be a typed array') + } +} + +function standardTypeEh (value, type) { + switch (type) { + case 'number': return typeof value === 'number' + case 'object': return typeof value === 'object' + case 'string': return typeof value === 'string' + case 'boolean': return typeof value === 'boolean' + case 'function': return typeof value === 'function' + case 'undefined': return typeof value === 'undefined' + case 'symbol': return typeof value === 'symbol' } } function checkTypeOf (value, type, message) { - if (typeof value !== type) { + if (!standardTypeEh(value, type)) { raise( 'invalid parameter type' + encolon(message) + - '. expected ' + type + ', got ' + (typeof value)); + '. expected ' + type + ', got ' + (typeof value)) } } @@ -89,13 +101,13 @@ function checkNonNegativeInt (value, message) { if (!((value >= 0) && ((value | 0) === value))) { raise('invalid parameter type, (' + value + ')' + encolon(message) + - '. must be a nonnegative integer'); + '. must be a nonnegative integer') } } function checkOneOf (value, list, message) { if (list.indexOf(value) < 0) { - raise('invalid value' + encolon(message) + '. must be one of: ' + list); + raise('invalid value' + encolon(message) + '. must be one of: ' + list) } } @@ -109,51 +121,51 @@ var constructorKeys = [ 'optionalExtensions', 'profile', 'onDone' -]; +] function checkConstructor (obj) { Object.keys(obj).forEach(function (key) { if (constructorKeys.indexOf(key) < 0) { - raise('invalid regl constructor argument "' + key + '". must be one of ' + constructorKeys); + raise('invalid regl constructor argument "' + key + '". must be one of ' + constructorKeys) } - }); + }) } function leftPad (str, n) { - str = str + ''; + str = str + '' while (str.length < n) { - str = ' ' + str; + str = ' ' + str } return str } function ShaderFile () { - this.name = 'unknown'; - this.lines = []; - this.index = {}; - this.hasErrors = false; + this.name = 'unknown' + this.lines = [] + this.index = {} + this.hasErrors = false } function ShaderLine (number, line) { - this.number = number; - this.line = line; - this.errors = []; + this.number = number + this.line = line + this.errors = [] } function ShaderError (fileNumber, lineNumber, message) { - this.file = fileNumber; - this.line = lineNumber; - this.message = message; + this.file = fileNumber + this.line = lineNumber + this.message = message } function guessCommand () { - var error = new Error(); - var stack = (error.stack || error).toString(); - var pat = /compileProcedure.*\n\s*at.*\((.*)\)/.exec(stack); + var error = new Error() + var stack = (error.stack || error).toString() + var pat = /compileProcedure.*\n\s*at.*\((.*)\)/.exec(stack) if (pat) { return pat[1] } - var pat2 = /compileProcedure.*\n\s*at\s+(.*)(\n|$)/.exec(stack); + var pat2 = /compileProcedure.*\n\s*at\s+(.*)(\n|$)/.exec(stack) if (pat2) { return pat2[1] } @@ -161,13 +173,13 @@ function guessCommand () { } function guessCallSite () { - var error = new Error(); - var stack = (error.stack || error).toString(); - var pat = /at REGLCommand.*\n\s+at.*\((.*)\)/.exec(stack); + var error = new Error() + var stack = (error.stack || error).toString() + var pat = /at REGLCommand.*\n\s+at.*\((.*)\)/.exec(stack) if (pat) { return pat[1] } - var pat2 = /at REGLCommand.*\n\s+at\s+(.*)\n/.exec(stack); + var pat2 = /at REGLCommand.*\n\s+at\s+(.*)\n/.exec(stack) if (pat2) { return pat2[1] } @@ -175,185 +187,185 @@ function guessCallSite () { } function parseSource (source, command) { - var lines = source.split('\n'); - var lineNumber = 1; - var fileNumber = 0; + var lines = source.split('\n') + var lineNumber = 1 + var fileNumber = 0 var files = { unknown: new ShaderFile(), 0: new ShaderFile() - }; - files.unknown.name = files[0].name = command || guessCommand(); - files.unknown.lines.push(new ShaderLine(0, '')); + } + files.unknown.name = files[0].name = command || guessCommand() + files.unknown.lines.push(new ShaderLine(0, '')) for (var i = 0; i < lines.length; ++i) { - var line = lines[i]; - var parts = /^\s*\#\s*(\w+)\s+(.+)\s*$/.exec(line); + var line = lines[i] + var parts = /^\s*#\s*(\w+)\s+(.+)\s*$/.exec(line) if (parts) { switch (parts[1]) { case 'line': - var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2]); + var lineNumberInfo = /(\d+)(\s+\d+)?/.exec(parts[2]) if (lineNumberInfo) { - lineNumber = lineNumberInfo[1] | 0; + lineNumber = lineNumberInfo[1] | 0 if (lineNumberInfo[2]) { - fileNumber = lineNumberInfo[2] | 0; + fileNumber = lineNumberInfo[2] | 0 if (!(fileNumber in files)) { - files[fileNumber] = new ShaderFile(); + files[fileNumber] = new ShaderFile() } } } break case 'define': - var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2]); + var nameInfo = /SHADER_NAME(_B64)?\s+(.*)$/.exec(parts[2]) if (nameInfo) { files[fileNumber].name = (nameInfo[1] - ? decodeB64(nameInfo[2]) - : nameInfo[2]); + ? decodeB64(nameInfo[2]) + : nameInfo[2]) } break } } - files[fileNumber].lines.push(new ShaderLine(lineNumber++, line)); + files[fileNumber].lines.push(new ShaderLine(lineNumber++, line)) } Object.keys(files).forEach(function (fileNumber) { - var file = files[fileNumber]; + var file = files[fileNumber] file.lines.forEach(function (line) { - file.index[line.number] = line; - }); - }); + file.index[line.number] = line + }) + }) return files } function parseErrorLog (errLog) { - var result = []; + var result = [] errLog.split('\n').forEach(function (errMsg) { if (errMsg.length < 5) { return } - var parts = /^ERROR\:\s+(\d+)\:(\d+)\:\s*(.*)$/.exec(errMsg); + var parts = /^ERROR:\s+(\d+):(\d+):\s*(.*)$/.exec(errMsg) if (parts) { result.push(new ShaderError( parts[1] | 0, parts[2] | 0, - parts[3].trim())); + parts[3].trim())) } else if (errMsg.length > 0) { - result.push(new ShaderError('unknown', 0, errMsg)); + result.push(new ShaderError('unknown', 0, errMsg)) } - }); + }) return result } function annotateFiles (files, errors) { errors.forEach(function (error) { - var file = files[error.file]; + var file = files[error.file] if (file) { - var line = file.index[error.line]; + var line = file.index[error.line] if (line) { - line.errors.push(error); - file.hasErrors = true; + line.errors.push(error) + file.hasErrors = true return } } - files.unknown.hasErrors = true; - files.unknown.lines[0].errors.push(error); - }); + files.unknown.hasErrors = true + files.unknown.lines[0].errors.push(error) + }) } function checkShaderError (gl, shader, source, type, command) { if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - var errLog = gl.getShaderInfoLog(shader); - var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex'; - checkCommandType(source, 'string', typeName + ' shader source must be a string', command); - var files = parseSource(source, command); - var errors = parseErrorLog(errLog); - annotateFiles(files, errors); + var errLog = gl.getShaderInfoLog(shader) + var typeName = type === gl.FRAGMENT_SHADER ? 'fragment' : 'vertex' + checkCommandType(source, 'string', typeName + ' shader source must be a string', command) + var files = parseSource(source, command) + var errors = parseErrorLog(errLog) + annotateFiles(files, errors) Object.keys(files).forEach(function (fileNumber) { - var file = files[fileNumber]; + var file = files[fileNumber] if (!file.hasErrors) { return } - var strings = ['']; - var styles = ['']; + var strings = [''] + var styles = [''] function push (str, style) { - strings.push(str); - styles.push(style || ''); + strings.push(str) + styles.push(style || '') } - push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold'); + push('file number ' + fileNumber + ': ' + file.name + '\n', 'color:red;text-decoration:underline;font-weight:bold') file.lines.forEach(function (line) { if (line.errors.length > 0) { - push(leftPad(line.number, 4) + '| ', 'background-color:yellow; font-weight:bold'); - push(line.line + endl, 'color:red; background-color:yellow; font-weight:bold'); + push(leftPad(line.number, 4) + '| ', 'background-color:yellow; font-weight:bold') + push(line.line + endl, 'color:red; background-color:yellow; font-weight:bold') // try to guess token - var offset = 0; + var offset = 0 line.errors.forEach(function (error) { - var message = error.message; - var token = /^\s*\'(.*)\'\s*\:\s*(.*)$/.exec(message); + var message = error.message + var token = /^\s*'(.*)'\s*:\s*(.*)$/.exec(message) if (token) { - var tokenPat = token[1]; - message = token[2]; + var tokenPat = token[1] + message = token[2] switch (tokenPat) { case 'assign': - tokenPat = '='; + tokenPat = '=' break } - offset = Math.max(line.line.indexOf(tokenPat, offset), 0); + offset = Math.max(line.line.indexOf(tokenPat, offset), 0) } else { - offset = 0; + offset = 0 } - push(leftPad('| ', 6)); - push(leftPad('^^^', offset + 3) + endl, 'font-weight:bold'); - push(leftPad('| ', 6)); - push(message + endl, 'font-weight:bold'); - }); - push(leftPad('| ', 6) + endl); + push(leftPad('| ', 6)) + push(leftPad('^^^', offset + 3) + endl, 'font-weight:bold') + push(leftPad('| ', 6)) + push(message + endl, 'font-weight:bold') + }) + push(leftPad('| ', 6) + endl) } else { - push(leftPad(line.number, 4) + '| '); - push(line.line + endl, 'color:red'); + push(leftPad(line.number, 4) + '| ') + push(line.line + endl, 'color:red') } - }); + }) if (typeof document !== 'undefined' && !window.chrome) { - styles[0] = strings.join('%c'); - console.log.apply(console, styles); + styles[0] = strings.join('%c') + console.log.apply(console, styles) } else { - console.log(strings.join('')); + console.log(strings.join('')) } - }); + }) - check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name); + check.raise('Error compiling ' + typeName + ' shader, ' + files[0].name) } } function checkLinkError (gl, program, fragShader, vertShader, command) { if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - var errLog = gl.getProgramInfoLog(program); - var fragParse = parseSource(fragShader, command); - var vertParse = parseSource(vertShader, command); + var errLog = gl.getProgramInfoLog(program) + var fragParse = parseSource(fragShader, command) + var vertParse = parseSource(vertShader, command) var header = 'Error linking program with vertex shader, "' + - vertParse[0].name + '", and fragment shader "' + fragParse[0].name + '"'; + vertParse[0].name + '", and fragment shader "' + fragParse[0].name + '"' if (typeof document !== 'undefined') { console.log('%c' + header + endl + '%c' + errLog, 'color:red;text-decoration:underline;font-weight:bold', - 'color:red'); + 'color:red') } else { - console.log(header + endl + errLog); + console.log(header + endl + errLog) } - check.raise(header); + check.raise(header) } } function saveCommandRef (object) { - object._commandRef = guessCommand(); + object._commandRef = guessCommand() } function saveDrawCommandInfo (opts, uniforms, attributes, stringStore) { - saveCommandRef(opts); + saveCommandRef(opts) function id (str) { if (str) { @@ -361,40 +373,40 @@ function saveDrawCommandInfo (opts, uniforms, attributes, stringStore) { } return 0 } - opts._fragId = id(opts.static.frag); - opts._vertId = id(opts.static.vert); + opts._fragId = id(opts.static.frag) + opts._vertId = id(opts.static.vert) function addProps (dict, set) { Object.keys(set).forEach(function (u) { - dict[stringStore.id(u)] = true; - }); + dict[stringStore.id(u)] = true + }) } - var uniformSet = opts._uniformSet = {}; - addProps(uniformSet, uniforms.static); - addProps(uniformSet, uniforms.dynamic); + var uniformSet = opts._uniformSet = {} + addProps(uniformSet, uniforms.static) + addProps(uniformSet, uniforms.dynamic) - var attributeSet = opts._attributeSet = {}; - addProps(attributeSet, attributes.static); - addProps(attributeSet, attributes.dynamic); + var attributeSet = opts._attributeSet = {} + addProps(attributeSet, attributes.static) + addProps(attributeSet, attributes.dynamic) opts._hasCount = ( 'count' in opts.static || 'count' in opts.dynamic || 'elements' in opts.static || - 'elements' in opts.dynamic); + 'elements' in opts.dynamic) } function commandRaise (message, command) { - var callSite = guessCallSite(); + var callSite = guessCallSite() raise(message + ' in command ' + (command || guessCommand()) + - (callSite === 'unknown' ? '' : ' called from ' + callSite)); + (callSite === 'unknown' ? '' : ' called from ' + callSite)) } function checkCommand (pred, message, command) { if (!pred) { - commandRaise(message, command || guessCommand()); + commandRaise(message, command || guessCommand()) } } @@ -403,21 +415,21 @@ function checkParameterCommand (param, possibilities, message, command) { commandRaise( 'unknown parameter (' + param + ')' + encolon(message) + '. possible values: ' + Object.keys(possibilities).join(), - command || guessCommand()); + command || guessCommand()) } } function checkCommandType (value, type, message, command) { - if (typeof value !== type) { + if (!standardTypeEh(value, type)) { commandRaise( 'invalid parameter type' + encolon(message) + '. expected ' + type + ', got ' + (typeof value), - command || guessCommand()); + command || guessCommand()) } } function checkOptional (block) { - block(); + block() } function checkFramebufferFormat (attachment, texFormats, rbFormats) { @@ -425,54 +437,54 @@ function checkFramebufferFormat (attachment, texFormats, rbFormats) { checkOneOf( attachment.texture._texture.internalformat, texFormats, - 'unsupported texture format for attachment'); + 'unsupported texture format for attachment') } else { checkOneOf( attachment.renderbuffer._renderbuffer.format, rbFormats, - 'unsupported renderbuffer format for attachment'); + 'unsupported renderbuffer format for attachment') } } -var GL_CLAMP_TO_EDGE = 0x812F; +var GL_CLAMP_TO_EDGE = 0x812F -var GL_NEAREST = 0x2600; -var GL_NEAREST_MIPMAP_NEAREST = 0x2700; -var GL_LINEAR_MIPMAP_NEAREST = 0x2701; -var GL_NEAREST_MIPMAP_LINEAR = 0x2702; -var GL_LINEAR_MIPMAP_LINEAR = 0x2703; +var GL_NEAREST = 0x2600 +var GL_NEAREST_MIPMAP_NEAREST = 0x2700 +var GL_LINEAR_MIPMAP_NEAREST = 0x2701 +var GL_NEAREST_MIPMAP_LINEAR = 0x2702 +var GL_LINEAR_MIPMAP_LINEAR = 0x2703 -var GL_BYTE = 5120; -var GL_UNSIGNED_BYTE = 5121; -var GL_SHORT = 5122; -var GL_UNSIGNED_SHORT = 5123; -var GL_INT = 5124; -var GL_UNSIGNED_INT = 5125; -var GL_FLOAT = 5126; +var GL_BYTE = 5120 +var GL_UNSIGNED_BYTE = 5121 +var GL_SHORT = 5122 +var GL_UNSIGNED_SHORT = 5123 +var GL_INT = 5124 +var GL_UNSIGNED_INT = 5125 +var GL_FLOAT = 5126 -var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033; -var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034; -var GL_UNSIGNED_SHORT_5_6_5 = 0x8363; -var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA; +var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033 +var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034 +var GL_UNSIGNED_SHORT_5_6_5 = 0x8363 +var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA -var GL_HALF_FLOAT_OES = 0x8D61; +var GL_HALF_FLOAT_OES = 0x8D61 -var TYPE_SIZE = {}; +var TYPE_SIZE = {} TYPE_SIZE[GL_BYTE] = -TYPE_SIZE[GL_UNSIGNED_BYTE] = 1; +TYPE_SIZE[GL_UNSIGNED_BYTE] = 1 TYPE_SIZE[GL_SHORT] = TYPE_SIZE[GL_UNSIGNED_SHORT] = TYPE_SIZE[GL_HALF_FLOAT_OES] = TYPE_SIZE[GL_UNSIGNED_SHORT_5_6_5] = TYPE_SIZE[GL_UNSIGNED_SHORT_4_4_4_4] = -TYPE_SIZE[GL_UNSIGNED_SHORT_5_5_5_1] = 2; +TYPE_SIZE[GL_UNSIGNED_SHORT_5_5_5_1] = 2 TYPE_SIZE[GL_INT] = TYPE_SIZE[GL_UNSIGNED_INT] = TYPE_SIZE[GL_FLOAT] = -TYPE_SIZE[GL_UNSIGNED_INT_24_8_WEBGL] = 4; +TYPE_SIZE[GL_UNSIGNED_INT_24_8_WEBGL] = 4 function pixelSize (type, channels) { if (type === GL_UNSIGNED_SHORT_5_5_5_1 || @@ -491,20 +503,20 @@ function isPow2 (v) { } function checkTexture2D (info, mipData, limits) { - var i; - var w = mipData.width; - var h = mipData.height; - var c = mipData.channels; + var i + var w = mipData.width + var h = mipData.height + var c = mipData.channels // Check texture shape check(w > 0 && w <= limits.maxTextureSize && h > 0 && h <= limits.maxTextureSize, - 'invalid texture shape'); + 'invalid texture shape') // check wrap mode if (info.wrapS !== GL_CLAMP_TO_EDGE || info.wrapT !== GL_CLAMP_TO_EDGE) { check(isPow2(w) && isPow2(h), - 'incompatible wrap mode for texture, both width and height must be power of 2'); + 'incompatible wrap mode for texture, both width and height must be power of 2') } if (mipData.mipmask === 1) { @@ -514,124 +526,124 @@ function checkTexture2D (info, mipData, limits) { info.minFilter !== GL_NEAREST_MIPMAP_LINEAR && info.minFilter !== GL_LINEAR_MIPMAP_NEAREST && info.minFilter !== GL_LINEAR_MIPMAP_LINEAR, - 'min filter requires mipmap'); + 'min filter requires mipmap') } } else { // texture must be power of 2 check(isPow2(w) && isPow2(h), - 'texture must be a square power of 2 to support mipmapping'); + 'texture must be a square power of 2 to support mipmapping') check(mipData.mipmask === (w << 1) - 1, - 'missing or incomplete mipmap data'); + 'missing or incomplete mipmap data') } if (mipData.type === GL_FLOAT) { if (limits.extensions.indexOf('oes_texture_float_linear') < 0) { check(info.minFilter === GL_NEAREST && info.magFilter === GL_NEAREST, - 'filter not supported, must enable oes_texture_float_linear'); + 'filter not supported, must enable oes_texture_float_linear') } check(!info.genMipmaps, - 'mipmap generation not supported with float textures'); + 'mipmap generation not supported with float textures') } // check image complete - var mipimages = mipData.images; + var mipimages = mipData.images for (i = 0; i < 16; ++i) { if (mipimages[i]) { - var mw = w >> i; - var mh = h >> i; - check(mipData.mipmask & (1 << i), 'missing mipmap data'); + var mw = w >> i + var mh = h >> i + check(mipData.mipmask & (1 << i), 'missing mipmap data') - var img = mipimages[i]; + var img = mipimages[i] check( img.width === mw && img.height === mh, - 'invalid shape for mip images'); + 'invalid shape for mip images') check( img.format === mipData.format && img.internalformat === mipData.internalformat && img.type === mipData.type, - 'incompatible type for mip image'); + 'incompatible type for mip image') if (img.compressed) { // TODO: check size for compressed images } else if (img.data) { // check(img.data.byteLength === mw * mh * // Math.max(pixelSize(img.type, c), img.unpackAlignment), - var rowSize = Math.ceil(pixelSize(img.type, c) * mw / img.unpackAlignment) * img.unpackAlignment; + var rowSize = Math.ceil(pixelSize(img.type, c) * mw / img.unpackAlignment) * img.unpackAlignment check(img.data.byteLength === rowSize * mh, - 'invalid data for image, buffer size is inconsistent with image format'); + 'invalid data for image, buffer size is inconsistent with image format') } else if (img.element) { // TODO: check element can be loaded } else if (img.copy) { // TODO: check compatible format and type } } else if (!info.genMipmaps) { - check((mipData.mipmask & (1 << i)) === 0, 'extra mipmap data'); + check((mipData.mipmask & (1 << i)) === 0, 'extra mipmap data') } } if (mipData.compressed) { check(!info.genMipmaps, - 'mipmap generation for compressed images not supported'); + 'mipmap generation for compressed images not supported') } } function checkTextureCube (texture, info, faces, limits) { - var w = texture.width; - var h = texture.height; - var c = texture.channels; + var w = texture.width + var h = texture.height + var c = texture.channels // Check texture shape check( w > 0 && w <= limits.maxTextureSize && h > 0 && h <= limits.maxTextureSize, - 'invalid texture shape'); + 'invalid texture shape') check( w === h, - 'cube map must be square'); + 'cube map must be square') check( info.wrapS === GL_CLAMP_TO_EDGE && info.wrapT === GL_CLAMP_TO_EDGE, - 'wrap mode not supported by cube map'); + 'wrap mode not supported by cube map') for (var i = 0; i < faces.length; ++i) { - var face = faces[i]; + var face = faces[i] check( face.width === w && face.height === h, - 'inconsistent cube map face shape'); + 'inconsistent cube map face shape') if (info.genMipmaps) { check(!face.compressed, - 'can not generate mipmap for compressed textures'); + 'can not generate mipmap for compressed textures') check(face.mipmask === 1, - 'can not specify mipmaps and generate mipmaps'); + 'can not specify mipmaps and generate mipmaps') } else { // TODO: check mip and filter mode } - var mipmaps = face.images; + var mipmaps = face.images for (var j = 0; j < 16; ++j) { - var img = mipmaps[j]; + var img = mipmaps[j] if (img) { - var mw = w >> j; - var mh = h >> j; - check(face.mipmask & (1 << j), 'missing mipmap data'); + var mw = w >> j + var mh = h >> j + check(face.mipmask & (1 << j), 'missing mipmap data') check( img.width === mw && img.height === mh, - 'invalid shape for mip images'); + 'invalid shape for mip images') check( img.format === texture.format && img.internalformat === texture.internalformat && img.type === texture.type, - 'incompatible type for mip image'); + 'incompatible type for mip image') if (img.compressed) { // TODO: check size for compressed images } else if (img.data) { check(img.data.byteLength === mw * mh * Math.max(pixelSize(img.type, c), img.unpackAlignment), - 'invalid data for image, buffer size is inconsistent with image format'); + 'invalid data for image, buffer size is inconsistent with image format') } else if (img.element) { // TODO: check element can be loaded } else if (img.copy) { @@ -666,14 +678,16 @@ var check$1 = extend(check, { textureCube: checkTextureCube }); -var VARIABLE_COUNTER = 0; +var VARIABLE_COUNTER = 0 -var DYN_FUNC = 0; +var DYN_FUNC = 0 +var DYN_CONSTANT = 5 +var DYN_ARRAY = 6 function DynamicVariable (type, data) { - this.id = (VARIABLE_COUNTER++); - this.type = type; - this.data = data; + this.id = (VARIABLE_COUNTER++) + this.type = type + this.data = data } function escapeStr (str) { @@ -685,8 +699,8 @@ function splitParts (str) { return [] } - var firstChar = str.charAt(0); - var lastChar = str.charAt(str.length - 1); + var firstChar = str.charAt(0) + var lastChar = str.charAt(str.length - 1) if (str.length > 1 && firstChar === lastChar && @@ -694,23 +708,23 @@ function splitParts (str) { return ['"' + escapeStr(str.substr(1, str.length - 2)) + '"'] } - var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str); + var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str) if (parts) { return ( splitParts(str.substr(0, parts.index)) - .concat(splitParts(parts[1])) - .concat(splitParts(str.substr(parts.index + parts[0].length))) + .concat(splitParts(parts[1])) + .concat(splitParts(str.substr(parts.index + parts[0].length))) ) } - var subparts = str.split('.'); + var subparts = str.split('.') if (subparts.length === 1) { return ['"' + escapeStr(str) + '"'] } - var result = []; + var result = [] for (var i = 0; i < subparts.length; ++i) { - result = result.concat(splitParts(subparts[i])); + result = result.concat(splitParts(subparts[i])) } return result } @@ -724,15 +738,20 @@ function defineDynamic (type, data) { } function isDynamic (x) { - return (typeof x === 'function' && !x._reglType) || - x instanceof DynamicVariable + return (typeof x === 'function' && !x._reglType) || (x instanceof DynamicVariable) } function unbox (x, path) { if (typeof x === 'function') { return new DynamicVariable(DYN_FUNC, x) + } else if (typeof x === 'number' || typeof x === 'boolean') { + return new DynamicVariable(DYN_CONSTANT, x) + } else if (Array.isArray(x)) { + return new DynamicVariable(DYN_ARRAY, x.map(function (y, i) { return unbox(y, path + '[' + i + ']') })) + } else if (x instanceof DynamicVariable) { + return x } - return x + check$1(false, 'invalid option type in uniform ' + path) } var dynamic = { @@ -755,20 +774,20 @@ var raf = { /* globals performance */ var clock = (typeof performance !== 'undefined' && performance.now) - ? function () { return performance.now() } - : function () { return +(new Date()) }; + ? function () { return performance.now() } + : function () { return +(new Date()) }; function createStringStore () { - var stringIds = {'': 0}; - var stringValues = ['']; + var stringIds = { '': 0 } + var stringValues = [''] return { id: function (str) { - var result = stringIds[str]; + var result = stringIds[str] if (result) { return result } - result = stringIds[str] = stringValues.length; - stringValues.push(str); + result = stringIds[str] = stringValues.length + stringValues.push(str) return result }, @@ -780,48 +799,61 @@ function createStringStore () { // Context and canvas creation helper functions function createCanvas (element, onDone, pixelRatio) { - var canvas = document.createElement('canvas'); + var canvas = document.createElement('canvas') extend(canvas.style, { border: 0, margin: 0, padding: 0, top: 0, - left: 0 - }); - element.appendChild(canvas); + left: 0, + width: '100%', + height: '100%' + }) + element.appendChild(canvas) if (element === document.body) { - canvas.style.position = 'absolute'; + canvas.style.position = 'absolute' extend(element.style, { margin: 0, padding: 0 - }); + }) } function resize () { - var w = window.innerWidth; - var h = window.innerHeight; + var w = window.innerWidth + var h = window.innerHeight if (element !== document.body) { - var bounds = element.getBoundingClientRect(); - w = bounds.right - bounds.left; - h = bounds.bottom - bounds.top; + var bounds = canvas.getBoundingClientRect() + w = bounds.right - bounds.left + h = bounds.bottom - bounds.top } - canvas.width = pixelRatio * w; - canvas.height = pixelRatio * h; - extend(canvas.style, { - width: w + 'px', - height: h + 'px' - }); + canvas.width = pixelRatio * w + canvas.height = pixelRatio * h } - window.addEventListener('resize', resize, false); + var resizeObserver + if (element !== document.body && typeof ResizeObserver === 'function') { + // ignore 'ResizeObserver' is not defined + // eslint-disable-next-line + resizeObserver = new ResizeObserver(function () { + // setTimeout to avoid flicker + setTimeout(resize) + }) + resizeObserver.observe(element) + } else { + window.addEventListener('resize', resize, false) + } function onDestroy () { - window.removeEventListener('resize', resize); - element.removeChild(canvas); + if (resizeObserver) { + resizeObserver.disconnect() + } else { + window.removeEventListener('resize', resize) + } + element.removeChild(canvas) } - resize(); + resize() return { canvas: canvas, @@ -863,86 +895,86 @@ function parseExtensions (input) { if (typeof input === 'string') { return input.split() } - check$1(Array.isArray(input), 'invalid extension array'); + check$1(Array.isArray(input), 'invalid extension array') return input } function getElement (desc) { if (typeof desc === 'string') { - check$1(typeof document !== 'undefined', 'not supported outside of DOM'); + check$1(typeof document !== 'undefined', 'not supported outside of DOM') return document.querySelector(desc) } return desc } function parseArgs (args_) { - var args = args_ || {}; - var element, container, canvas, gl; - var contextAttributes = {}; - var extensions = []; - var optionalExtensions = []; - var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio); - var profile = false; + var args = args_ || {} + var element, container, canvas, gl + var contextAttributes = {} + var extensions = [] + var optionalExtensions = [] + var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio) + var profile = false var onDone = function (err) { if (err) { - check$1.raise(err); + check$1.raise(err) } - }; - var onDestroy = function () {}; + } + var onDestroy = function () {} if (typeof args === 'string') { check$1( typeof document !== 'undefined', - 'selector queries only supported in DOM enviroments'); - element = document.querySelector(args); - check$1(element, 'invalid query string for element'); + 'selector queries only supported in DOM environments') + element = document.querySelector(args) + check$1(element, 'invalid query string for element') } else if (typeof args === 'object') { if (isHTMLElement(args)) { - element = args; + element = args } else if (isWebGLContext(args)) { - gl = args; - canvas = gl.canvas; + gl = args + canvas = gl.canvas } else { - check$1.constructor(args); + check$1.constructor(args) if ('gl' in args) { - gl = args.gl; + gl = args.gl } else if ('canvas' in args) { - canvas = getElement(args.canvas); + canvas = getElement(args.canvas) } else if ('container' in args) { - container = getElement(args.container); + container = getElement(args.container) } if ('attributes' in args) { - contextAttributes = args.attributes; - check$1.type(contextAttributes, 'object', 'invalid context attributes'); + contextAttributes = args.attributes + check$1.type(contextAttributes, 'object', 'invalid context attributes') } if ('extensions' in args) { - extensions = parseExtensions(args.extensions); + extensions = parseExtensions(args.extensions) } if ('optionalExtensions' in args) { - optionalExtensions = parseExtensions(args.optionalExtensions); + optionalExtensions = parseExtensions(args.optionalExtensions) } if ('onDone' in args) { check$1.type( args.onDone, 'function', - 'invalid or missing onDone callback'); - onDone = args.onDone; + 'invalid or missing onDone callback') + onDone = args.onDone } if ('profile' in args) { - profile = !!args.profile; + profile = !!args.profile } if ('pixelRatio' in args) { - pixelRatio = +args.pixelRatio; - check$1(pixelRatio > 0, 'invalid pixel ratio'); + pixelRatio = +args.pixelRatio + check$1(pixelRatio > 0, 'invalid pixel ratio') } } } else { - check$1.raise('invalid arguments to regl'); + check$1.raise('invalid arguments to regl') } if (element) { if (element.nodeName.toLowerCase() === 'canvas') { - canvas = element; + canvas = element } else { - container = element; + container = element } } @@ -950,20 +982,22 @@ function parseArgs (args_) { if (!canvas) { check$1( typeof document !== 'undefined', - 'must manually specify webgl context outside of DOM environments'); - var result = createCanvas(container || document.body, onDone, pixelRatio); + 'must manually specify webgl context outside of DOM environments') + var result = createCanvas(container || document.body, onDone, pixelRatio) if (!result) { return null } - canvas = result.canvas; - onDestroy = result.onDestroy; + canvas = result.canvas + onDestroy = result.onDestroy } - gl = createContext(canvas, contextAttributes); + // workaround for chromium bug, premultiplied alpha value is platform dependent + if (contextAttributes.premultipliedAlpha === undefined) contextAttributes.premultipliedAlpha = true + gl = createContext(canvas, contextAttributes) } if (!gl) { - onDestroy(); - onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org'); + onDestroy() + onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org') return null } @@ -981,28 +1015,28 @@ function parseArgs (args_) { } function createExtensionCache (gl, config) { - var extensions = {}; + var extensions = {} function tryLoadExtension (name_) { - check$1.type(name_, 'string', 'extension name must be string'); - var name = name_.toLowerCase(); - var ext; + check$1.type(name_, 'string', 'extension name must be string') + var name = name_.toLowerCase() + var ext try { - ext = extensions[name] = gl.getExtension(name); + ext = extensions[name] = gl.getExtension(name) } catch (e) {} return !!ext } for (var i = 0; i < config.extensions.length; ++i) { - var name = config.extensions[i]; + var name = config.extensions[i] if (!tryLoadExtension(name)) { - config.onDestroy(); - config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser'); + config.onDestroy() + config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser') return null } } - config.optionalExtensions.forEach(tryLoadExtension); + config.optionalExtensions.forEach(tryLoadExtension) return { extensions: extensions, @@ -1011,26 +1045,26 @@ function createExtensionCache (gl, config) { if (extensions[name] && !tryLoadExtension(name)) { throw new Error('(regl): error restoring extension ' + name) } - }); + }) } } } function loop (n, f) { - var result = Array(n); + var result = Array(n) for (var i = 0; i < n; ++i) { - result[i] = f(i); + result[i] = f(i) } return result } -var GL_BYTE$1 = 5120; -var GL_UNSIGNED_BYTE$2 = 5121; -var GL_SHORT$1 = 5122; -var GL_UNSIGNED_SHORT$1 = 5123; -var GL_INT$1 = 5124; -var GL_UNSIGNED_INT$1 = 5125; -var GL_FLOAT$2 = 5126; +var GL_BYTE$1 = 5120 +var GL_UNSIGNED_BYTE$2 = 5121 +var GL_SHORT$1 = 5122 +var GL_UNSIGNED_SHORT$1 = 5123 +var GL_INT$1 = 5124 +var GL_UNSIGNED_INT$1 = 5125 +var GL_FLOAT$2 = 5126 function nextPow16 (v) { for (var i = 16; i <= (1 << 28); i *= 16) { @@ -1042,26 +1076,26 @@ function nextPow16 (v) { } function log2 (v) { - var r, shift; - r = (v > 0xFFFF) << 4; - v >>>= r; - shift = (v > 0xFF) << 3; - v >>>= shift; r |= shift; - shift = (v > 0xF) << 2; - v >>>= shift; r |= shift; - shift = (v > 0x3) << 1; - v >>>= shift; r |= shift; + var r, shift + r = (v > 0xFFFF) << 4 + v >>>= r + shift = (v > 0xFF) << 3 + v >>>= shift; r |= shift + shift = (v > 0xF) << 2 + v >>>= shift; r |= shift + shift = (v > 0x3) << 1 + v >>>= shift; r |= shift return r | (v >> 1) } function createPool () { var bufferPool = loop(8, function () { return [] - }); + }) function alloc (n) { - var sz = nextPow16(n); - var bin = bufferPool[log2(sz) >> 2]; + var sz = nextPow16(n) + var bin = bufferPool[log2(sz) >> 2] if (bin.length > 0) { return bin.pop() } @@ -1069,32 +1103,32 @@ function createPool () { } function free (buf) { - bufferPool[log2(buf.byteLength) >> 2].push(buf); + bufferPool[log2(buf.byteLength) >> 2].push(buf) } function allocType (type, n) { - var result = null; + var result = null switch (type) { case GL_BYTE$1: - result = new Int8Array(alloc(n), 0, n); + result = new Int8Array(alloc(n), 0, n) break case GL_UNSIGNED_BYTE$2: - result = new Uint8Array(alloc(n), 0, n); + result = new Uint8Array(alloc(n), 0, n) break case GL_SHORT$1: - result = new Int16Array(alloc(2 * n), 0, n); + result = new Int16Array(alloc(2 * n), 0, n) break case GL_UNSIGNED_SHORT$1: - result = new Uint16Array(alloc(2 * n), 0, n); + result = new Uint16Array(alloc(2 * n), 0, n) break case GL_INT$1: - result = new Int32Array(alloc(4 * n), 0, n); + result = new Int32Array(alloc(4 * n), 0, n) break case GL_UNSIGNED_INT$1: - result = new Uint32Array(alloc(4 * n), 0, n); + result = new Uint32Array(alloc(4 * n), 0, n) break case GL_FLOAT$2: - result = new Float32Array(alloc(4 * n), 0, n); + result = new Float32Array(alloc(4 * n), 0, n) break default: return null @@ -1106,7 +1140,7 @@ function createPool () { } function freeType (array) { - free(array.buffer); + free(array.buffer) } return { @@ -1117,117 +1151,117 @@ function createPool () { } } -var pool = createPool(); +var pool = createPool() // zero pool for initial zero data -pool.zero = createPool(); +pool.zero = createPool() -var GL_SUBPIXEL_BITS = 0x0D50; -var GL_RED_BITS = 0x0D52; -var GL_GREEN_BITS = 0x0D53; -var GL_BLUE_BITS = 0x0D54; -var GL_ALPHA_BITS = 0x0D55; -var GL_DEPTH_BITS = 0x0D56; -var GL_STENCIL_BITS = 0x0D57; +var GL_SUBPIXEL_BITS = 0x0D50 +var GL_RED_BITS = 0x0D52 +var GL_GREEN_BITS = 0x0D53 +var GL_BLUE_BITS = 0x0D54 +var GL_ALPHA_BITS = 0x0D55 +var GL_DEPTH_BITS = 0x0D56 +var GL_STENCIL_BITS = 0x0D57 -var GL_ALIASED_POINT_SIZE_RANGE = 0x846D; -var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E; +var GL_ALIASED_POINT_SIZE_RANGE = 0x846D +var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E -var GL_MAX_TEXTURE_SIZE = 0x0D33; -var GL_MAX_VIEWPORT_DIMS = 0x0D3A; -var GL_MAX_VERTEX_ATTRIBS = 0x8869; -var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB; -var GL_MAX_VARYING_VECTORS = 0x8DFC; -var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D; -var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C; -var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872; -var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD; -var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C; -var GL_MAX_RENDERBUFFER_SIZE = 0x84E8; +var GL_MAX_TEXTURE_SIZE = 0x0D33 +var GL_MAX_VIEWPORT_DIMS = 0x0D3A +var GL_MAX_VERTEX_ATTRIBS = 0x8869 +var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB +var GL_MAX_VARYING_VECTORS = 0x8DFC +var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D +var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C +var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872 +var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD +var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C +var GL_MAX_RENDERBUFFER_SIZE = 0x84E8 -var GL_VENDOR = 0x1F00; -var GL_RENDERER = 0x1F01; -var GL_VERSION = 0x1F02; -var GL_SHADING_LANGUAGE_VERSION = 0x8B8C; +var GL_VENDOR = 0x1F00 +var GL_RENDERER = 0x1F01 +var GL_VERSION = 0x1F02 +var GL_SHADING_LANGUAGE_VERSION = 0x8B8C -var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF; +var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF -var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF; -var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824; +var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF +var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824 -var GL_TEXTURE_2D = 0x0DE1; -var GL_TEXTURE_CUBE_MAP = 0x8513; -var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515; -var GL_TEXTURE0 = 0x84C0; -var GL_RGBA = 0x1908; -var GL_FLOAT$1 = 0x1406; -var GL_UNSIGNED_BYTE$1 = 0x1401; -var GL_FRAMEBUFFER = 0x8D40; -var GL_FRAMEBUFFER_COMPLETE = 0x8CD5; -var GL_COLOR_ATTACHMENT0 = 0x8CE0; -var GL_COLOR_BUFFER_BIT$1 = 0x4000; +var GL_TEXTURE_2D = 0x0DE1 +var GL_TEXTURE_CUBE_MAP = 0x8513 +var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515 +var GL_TEXTURE0 = 0x84C0 +var GL_RGBA = 0x1908 +var GL_FLOAT$1 = 0x1406 +var GL_UNSIGNED_BYTE$1 = 0x1401 +var GL_FRAMEBUFFER = 0x8D40 +var GL_FRAMEBUFFER_COMPLETE = 0x8CD5 +var GL_COLOR_ATTACHMENT0 = 0x8CE0 +var GL_COLOR_BUFFER_BIT$1 = 0x4000 var wrapLimits = function (gl, extensions) { - var maxAnisotropic = 1; + var maxAnisotropic = 1 if (extensions.ext_texture_filter_anisotropic) { - maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT); + maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) } - var maxDrawbuffers = 1; - var maxColorAttachments = 1; + var maxDrawbuffers = 1 + var maxColorAttachments = 1 if (extensions.webgl_draw_buffers) { - maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL); - maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL); + maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL) + maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL) } // detect if reading float textures is available (Safari doesn't support) - var readFloat = !!extensions.oes_texture_float; + var readFloat = !!extensions.oes_texture_float if (readFloat) { - var readFloatTexture = gl.createTexture(); - gl.bindTexture(GL_TEXTURE_2D, readFloatTexture); - gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT$1, null); + var readFloatTexture = gl.createTexture() + gl.bindTexture(GL_TEXTURE_2D, readFloatTexture) + gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT$1, null) - var fbo = gl.createFramebuffer(); - gl.bindFramebuffer(GL_FRAMEBUFFER, fbo); - gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readFloatTexture, 0); - gl.bindTexture(GL_TEXTURE_2D, null); + var fbo = gl.createFramebuffer() + gl.bindFramebuffer(GL_FRAMEBUFFER, fbo) + gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readFloatTexture, 0) + gl.bindTexture(GL_TEXTURE_2D, null) - if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) !== GL_FRAMEBUFFER_COMPLETE) readFloat = false; + if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) !== GL_FRAMEBUFFER_COMPLETE) readFloat = false else { - gl.viewport(0, 0, 1, 1); - gl.clearColor(1.0, 0.0, 0.0, 1.0); - gl.clear(GL_COLOR_BUFFER_BIT$1); - var pixels = pool.allocType(GL_FLOAT$1, 4); - gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT$1, pixels); + gl.viewport(0, 0, 1, 1) + gl.clearColor(1.0, 0.0, 0.0, 1.0) + gl.clear(GL_COLOR_BUFFER_BIT$1) + var pixels = pool.allocType(GL_FLOAT$1, 4) + gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT$1, pixels) - if (gl.getError()) readFloat = false; + if (gl.getError()) readFloat = false else { - gl.deleteFramebuffer(fbo); - gl.deleteTexture(readFloatTexture); + gl.deleteFramebuffer(fbo) + gl.deleteTexture(readFloatTexture) - readFloat = pixels[0] === 1.0; + readFloat = pixels[0] === 1.0 } - pool.freeType(pixels); + pool.freeType(pixels) } } // detect non power of two cube textures support (IE doesn't support) - var isIE = typeof navigator !== 'undefined' && (/MSIE/.test(navigator.userAgent) || /Trident\//.test(navigator.appVersion) || /Edge/.test(navigator.userAgent)); + var isIE = typeof navigator !== 'undefined' && (/MSIE/.test(navigator.userAgent) || /Trident\//.test(navigator.appVersion) || /Edge/.test(navigator.userAgent)) - var npotTextureCube = true; + var npotTextureCube = true if (!isIE) { - var cubeTexture = gl.createTexture(); - var data = pool.allocType(GL_UNSIGNED_BYTE$1, 36); - gl.activeTexture(GL_TEXTURE0); - gl.bindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture); - gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE$1, data); - pool.freeType(data); - gl.bindTexture(GL_TEXTURE_CUBE_MAP, null); - gl.deleteTexture(cubeTexture); - npotTextureCube = !gl.getError(); + var cubeTexture = gl.createTexture() + var data = pool.allocType(GL_UNSIGNED_BYTE$1, 36) + gl.activeTexture(GL_TEXTURE0) + gl.bindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture) + gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE$1, data) + pool.freeType(data) + gl.bindTexture(GL_TEXTURE_CUBE_MAP, null) + gl.deleteTexture(cubeTexture) + npotTextureCube = !gl.getError() } return { @@ -1279,7 +1313,7 @@ var wrapLimits = function (gl, extensions) { readFloat: readFloat, npotTextureCube: npotTextureCube } -}; +} function isNDArrayLike (obj) { return ( @@ -1295,7 +1329,7 @@ function isNDArrayLike (obj) { var values = function (obj) { return Object.keys(obj).map(function (key) { return obj[key] }) -}; +} var flattenUtils = { shape: arrayShape$1, @@ -1304,92 +1338,92 @@ var flattenUtils = { function flatten1D (array, nx, out) { for (var i = 0; i < nx; ++i) { - out[i] = array[i]; + out[i] = array[i] } } function flatten2D (array, nx, ny, out) { - var ptr = 0; + var ptr = 0 for (var i = 0; i < nx; ++i) { - var row = array[i]; + var row = array[i] for (var j = 0; j < ny; ++j) { - out[ptr++] = row[j]; + out[ptr++] = row[j] } } } function flatten3D (array, nx, ny, nz, out, ptr_) { - var ptr = ptr_; + var ptr = ptr_ for (var i = 0; i < nx; ++i) { - var row = array[i]; + var row = array[i] for (var j = 0; j < ny; ++j) { - var col = row[j]; + var col = row[j] for (var k = 0; k < nz; ++k) { - out[ptr++] = col[k]; + out[ptr++] = col[k] } } } } function flattenRec (array, shape, level, out, ptr) { - var stride = 1; + var stride = 1 for (var i = level + 1; i < shape.length; ++i) { - stride *= shape[i]; + stride *= shape[i] } - var n = shape[level]; + var n = shape[level] if (shape.length - level === 4) { - var nx = shape[level + 1]; - var ny = shape[level + 2]; - var nz = shape[level + 3]; + var nx = shape[level + 1] + var ny = shape[level + 2] + var nz = shape[level + 3] for (i = 0; i < n; ++i) { - flatten3D(array[i], nx, ny, nz, out, ptr); - ptr += stride; + flatten3D(array[i], nx, ny, nz, out, ptr) + ptr += stride } } else { for (i = 0; i < n; ++i) { - flattenRec(array[i], shape, level + 1, out, ptr); - ptr += stride; + flattenRec(array[i], shape, level + 1, out, ptr) + ptr += stride } } } function flattenArray (array, shape, type, out_) { - var sz = 1; + var sz = 1 if (shape.length) { for (var i = 0; i < shape.length; ++i) { - sz *= shape[i]; + sz *= shape[i] } } else { - sz = 0; + sz = 0 } - var out = out_ || pool.allocType(type, sz); + var out = out_ || pool.allocType(type, sz) switch (shape.length) { case 0: break case 1: - flatten1D(array, shape[0], out); + flatten1D(array, shape[0], out) break case 2: - flatten2D(array, shape[0], shape[1], out); + flatten2D(array, shape[0], shape[1], out) break case 3: - flatten3D(array, shape[0], shape[1], shape[2], out, 0); + flatten3D(array, shape[0], shape[1], shape[2], out, 0) break default: - flattenRec(array, shape, 0, out, 0); + flattenRec(array, shape, 0, out, 0) } return out } function arrayShape$1 (array_) { - var shape = []; + var shape = [] for (var array = array_; array.length; array = array[0]) { - shape.push(array.length); + shape.push(array.length) } return shape } -var arrayTypes = { +var arrayTypes = { "[object Int8Array]": 5120, "[object Int16Array]": 5122, "[object Int32Array]": 5124, @@ -1429,23 +1463,23 @@ var usageTypes = { "static": 35044 }; -var arrayFlatten = flattenUtils.flatten; -var arrayShape = flattenUtils.shape; +var arrayFlatten = flattenUtils.flatten +var arrayShape = flattenUtils.shape -var GL_STATIC_DRAW = 0x88E4; -var GL_STREAM_DRAW = 0x88E0; +var GL_STATIC_DRAW = 0x88E4 +var GL_STREAM_DRAW = 0x88E0 -var GL_UNSIGNED_BYTE$3 = 5121; -var GL_FLOAT$3 = 5126; +var GL_UNSIGNED_BYTE$3 = 5121 +var GL_FLOAT$3 = 5126 -var DTYPES_SIZES = []; -DTYPES_SIZES[5120] = 1; // int8 -DTYPES_SIZES[5122] = 2; // int16 -DTYPES_SIZES[5124] = 4; // int32 -DTYPES_SIZES[5121] = 1; // uint8 -DTYPES_SIZES[5123] = 2; // uint16 -DTYPES_SIZES[5125] = 4; // uint32 -DTYPES_SIZES[5126] = 4; // float32 +var DTYPES_SIZES = [] +DTYPES_SIZES[5120] = 1 // int8 +DTYPES_SIZES[5122] = 2 // int16 +DTYPES_SIZES[5124] = 4 // int32 +DTYPES_SIZES[5121] = 1 // uint8 +DTYPES_SIZES[5123] = 2 // uint16 +DTYPES_SIZES[5125] = 4 // uint32 +DTYPES_SIZES[5126] = 4 // float32 function typedArrayCode (data) { return arrayTypes[Object.prototype.toString.call(data)] | 0 @@ -1453,215 +1487,210 @@ function typedArrayCode (data) { function copyArray (out, inp) { for (var i = 0; i < inp.length; ++i) { - out[i] = inp[i]; + out[i] = inp[i] } } function transpose ( result, data, shapeX, shapeY, strideX, strideY, offset) { - var ptr = 0; + var ptr = 0 for (var i = 0; i < shapeX; ++i) { for (var j = 0; j < shapeY; ++j) { - result[ptr++] = data[strideX * i + strideY * j + offset]; + result[ptr++] = data[strideX * i + strideY * j + offset] } } } -function wrapBufferState (gl, stats, config, attributeState) { - var bufferCount = 0; - var bufferSet = {}; +function wrapBufferState (gl, stats, config, destroyBuffer) { + var bufferCount = 0 + var bufferSet = {} function REGLBuffer (type) { - this.id = bufferCount++; - this.buffer = gl.createBuffer(); - this.type = type; - this.usage = GL_STATIC_DRAW; - this.byteLength = 0; - this.dimension = 1; - this.dtype = GL_UNSIGNED_BYTE$3; + this.id = bufferCount++ + this.buffer = gl.createBuffer() + this.type = type + this.usage = GL_STATIC_DRAW + this.byteLength = 0 + this.dimension = 1 + this.dtype = GL_UNSIGNED_BYTE$3 - this.persistentData = null; + this.persistentData = null if (config.profile) { - this.stats = {size: 0}; + this.stats = { size: 0 } } } REGLBuffer.prototype.bind = function () { - gl.bindBuffer(this.type, this.buffer); - }; + gl.bindBuffer(this.type, this.buffer) + } REGLBuffer.prototype.destroy = function () { - destroy(this); - }; + destroy(this) + } - var streamPool = []; + var streamPool = [] function createStream (type, data) { - var buffer = streamPool.pop(); + var buffer = streamPool.pop() if (!buffer) { - buffer = new REGLBuffer(type); + buffer = new REGLBuffer(type) } - buffer.bind(); - initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false); + buffer.bind() + initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false) return buffer } function destroyStream (stream$$1) { - streamPool.push(stream$$1); + streamPool.push(stream$$1) } function initBufferFromTypedArray (buffer, data, usage) { - buffer.byteLength = data.byteLength; - gl.bufferData(buffer.type, data, usage); + buffer.byteLength = data.byteLength + gl.bufferData(buffer.type, data, usage) } function initBufferFromData (buffer, data, usage, dtype, dimension, persist) { - var shape; - buffer.usage = usage; + var shape + buffer.usage = usage if (Array.isArray(data)) { - buffer.dtype = dtype || GL_FLOAT$3; + buffer.dtype = dtype || GL_FLOAT$3 if (data.length > 0) { - var flatData; + var flatData if (Array.isArray(data[0])) { - shape = arrayShape(data); - var dim = 1; + shape = arrayShape(data) + var dim = 1 for (var i = 1; i < shape.length; ++i) { - dim *= shape[i]; + dim *= shape[i] } - buffer.dimension = dim; - flatData = arrayFlatten(data, shape, buffer.dtype); - initBufferFromTypedArray(buffer, flatData, usage); + buffer.dimension = dim + flatData = arrayFlatten(data, shape, buffer.dtype) + initBufferFromTypedArray(buffer, flatData, usage) if (persist) { - buffer.persistentData = flatData; + buffer.persistentData = flatData } else { - pool.freeType(flatData); + pool.freeType(flatData) } } else if (typeof data[0] === 'number') { - buffer.dimension = dimension; - var typedData = pool.allocType(buffer.dtype, data.length); - copyArray(typedData, data); - initBufferFromTypedArray(buffer, typedData, usage); + buffer.dimension = dimension + var typedData = pool.allocType(buffer.dtype, data.length) + copyArray(typedData, data) + initBufferFromTypedArray(buffer, typedData, usage) if (persist) { - buffer.persistentData = typedData; + buffer.persistentData = typedData } else { - pool.freeType(typedData); + pool.freeType(typedData) } } else if (isTypedArray(data[0])) { - buffer.dimension = data[0].length; - buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$3; + buffer.dimension = data[0].length + buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$3 flatData = arrayFlatten( data, [data.length, data[0].length], - buffer.dtype); - initBufferFromTypedArray(buffer, flatData, usage); + buffer.dtype) + initBufferFromTypedArray(buffer, flatData, usage) if (persist) { - buffer.persistentData = flatData; + buffer.persistentData = flatData } else { - pool.freeType(flatData); + pool.freeType(flatData) } } else { - check$1.raise('invalid buffer data'); + check$1.raise('invalid buffer data') } } } else if (isTypedArray(data)) { - buffer.dtype = dtype || typedArrayCode(data); - buffer.dimension = dimension; - initBufferFromTypedArray(buffer, data, usage); + buffer.dtype = dtype || typedArrayCode(data) + buffer.dimension = dimension + initBufferFromTypedArray(buffer, data, usage) if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer)); + buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer)) } } else if (isNDArrayLike(data)) { - shape = data.shape; - var stride = data.stride; - var offset = data.offset; + shape = data.shape + var stride = data.stride + var offset = data.offset - var shapeX = 0; - var shapeY = 0; - var strideX = 0; - var strideY = 0; + var shapeX = 0 + var shapeY = 0 + var strideX = 0 + var strideY = 0 if (shape.length === 1) { - shapeX = shape[0]; - shapeY = 1; - strideX = stride[0]; - strideY = 0; + shapeX = shape[0] + shapeY = 1 + strideX = stride[0] + strideY = 0 } else if (shape.length === 2) { - shapeX = shape[0]; - shapeY = shape[1]; - strideX = stride[0]; - strideY = stride[1]; + shapeX = shape[0] + shapeY = shape[1] + strideX = stride[0] + strideY = stride[1] } else { - check$1.raise('invalid shape'); + check$1.raise('invalid shape') } - buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$3; - buffer.dimension = shapeY; + buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$3 + buffer.dimension = shapeY - var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY); + var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY) transpose(transposeData, data.data, shapeX, shapeY, strideX, strideY, - offset); - initBufferFromTypedArray(buffer, transposeData, usage); + offset) + initBufferFromTypedArray(buffer, transposeData, usage) if (persist) { - buffer.persistentData = transposeData; + buffer.persistentData = transposeData } else { - pool.freeType(transposeData); + pool.freeType(transposeData) } } else if (data instanceof ArrayBuffer) { - buffer.dtype = GL_UNSIGNED_BYTE$3; - buffer.dimension = dimension; - initBufferFromTypedArray(buffer, data, usage); + buffer.dtype = GL_UNSIGNED_BYTE$3 + buffer.dimension = dimension + initBufferFromTypedArray(buffer, data, usage) if (persist) { - buffer.persistentData = new Uint8Array(new Uint8Array(data)); + buffer.persistentData = new Uint8Array(new Uint8Array(data)) } } else { - check$1.raise('invalid buffer data'); + check$1.raise('invalid buffer data') } } function destroy (buffer) { - stats.bufferCount--; + stats.bufferCount-- - for (var i = 0; i < attributeState.state.length; ++i) { - var record = attributeState.state[i]; - if (record.buffer === buffer) { - gl.disableVertexAttribArray(i); - record.buffer = null; - } - } + // remove attribute link + destroyBuffer(buffer) - var handle = buffer.buffer; - check$1(handle, 'buffer must not be deleted already'); - gl.deleteBuffer(handle); - buffer.buffer = null; - delete bufferSet[buffer.id]; + var handle = buffer.buffer + check$1(handle, 'buffer must not be deleted already') + gl.deleteBuffer(handle) + buffer.buffer = null + delete bufferSet[buffer.id] } function createBuffer (options, type, deferInit, persistent) { - stats.bufferCount++; + stats.bufferCount++ - var buffer = new REGLBuffer(type); - bufferSet[buffer.id] = buffer; + var buffer = new REGLBuffer(type) + bufferSet[buffer.id] = buffer function reglBuffer (options) { - var usage = GL_STATIC_DRAW; - var data = null; - var byteLength = 0; - var dtype = 0; - var dimension = 1; + var usage = GL_STATIC_DRAW + var data = null + var byteLength = 0 + var dtype = 0 + var dimension = 1 if (Array.isArray(options) || isTypedArray(options) || isNDArrayLike(options) || options instanceof ArrayBuffer) { - data = options; + data = options } else if (typeof options === 'number') { - byteLength = options | 0; + byteLength = options | 0 } else if (options) { check$1.type( options, 'object', - 'buffer arguments must be an object, a number or an array'); + 'buffer arguments must be an object, a number or an array') if ('data' in options) { check$1( @@ -1669,45 +1698,45 @@ function wrapBufferState (gl, stats, config, attributeState) { Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data), - 'invalid data for buffer'); - data = options.data; + 'invalid data for buffer') + data = options.data } if ('usage' in options) { - check$1.parameter(options.usage, usageTypes, 'invalid buffer usage'); - usage = usageTypes[options.usage]; + check$1.parameter(options.usage, usageTypes, 'invalid buffer usage') + usage = usageTypes[options.usage] } if ('type' in options) { - check$1.parameter(options.type, glTypes, 'invalid buffer type'); - dtype = glTypes[options.type]; + check$1.parameter(options.type, glTypes, 'invalid buffer type') + dtype = glTypes[options.type] } if ('dimension' in options) { - check$1.type(options.dimension, 'number', 'invalid dimension'); - dimension = options.dimension | 0; + check$1.type(options.dimension, 'number', 'invalid dimension') + dimension = options.dimension | 0 } if ('length' in options) { - check$1.nni(byteLength, 'buffer length must be a nonnegative integer'); - byteLength = options.length | 0; + check$1.nni(byteLength, 'buffer length must be a nonnegative integer') + byteLength = options.length | 0 } } - buffer.bind(); + buffer.bind() if (!data) { // #475 - if (byteLength) gl.bufferData(buffer.type, byteLength, usage); - buffer.dtype = dtype || GL_UNSIGNED_BYTE$3; - buffer.usage = usage; - buffer.dimension = dimension; - buffer.byteLength = byteLength; + if (byteLength) gl.bufferData(buffer.type, byteLength, usage) + buffer.dtype = dtype || GL_UNSIGNED_BYTE$3 + buffer.usage = usage + buffer.dimension = dimension + buffer.byteLength = byteLength } else { - initBufferFromData(buffer, data, usage, dtype, dimension, persistent); + initBufferFromData(buffer, data, usage, dtype, dimension, persistent) } if (config.profile) { - buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype]; + buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype] } return reglBuffer @@ -1715,105 +1744,105 @@ function wrapBufferState (gl, stats, config, attributeState) { function setSubData (data, offset) { check$1(offset + data.byteLength <= buffer.byteLength, - 'invalid buffer subdata call, buffer is too small. ' + ' Can\'t write data of size ' + data.byteLength + ' starting from offset ' + offset + ' to a buffer of size ' + buffer.byteLength); + 'invalid buffer subdata call, buffer is too small. ' + ' Can\'t write data of size ' + data.byteLength + ' starting from offset ' + offset + ' to a buffer of size ' + buffer.byteLength) - gl.bufferSubData(buffer.type, offset, data); + gl.bufferSubData(buffer.type, offset, data) } function subdata (data, offset_) { - var offset = (offset_ || 0) | 0; - var shape; - buffer.bind(); + var offset = (offset_ || 0) | 0 + var shape + buffer.bind() if (isTypedArray(data) || data instanceof ArrayBuffer) { - setSubData(data, offset); + setSubData(data, offset) } else if (Array.isArray(data)) { if (data.length > 0) { if (typeof data[0] === 'number') { - var converted = pool.allocType(buffer.dtype, data.length); - copyArray(converted, data); - setSubData(converted, offset); - pool.freeType(converted); + var converted = pool.allocType(buffer.dtype, data.length) + copyArray(converted, data) + setSubData(converted, offset) + pool.freeType(converted) } else if (Array.isArray(data[0]) || isTypedArray(data[0])) { - shape = arrayShape(data); - var flatData = arrayFlatten(data, shape, buffer.dtype); - setSubData(flatData, offset); - pool.freeType(flatData); + shape = arrayShape(data) + var flatData = arrayFlatten(data, shape, buffer.dtype) + setSubData(flatData, offset) + pool.freeType(flatData) } else { - check$1.raise('invalid buffer data'); + check$1.raise('invalid buffer data') } } } else if (isNDArrayLike(data)) { - shape = data.shape; - var stride = data.stride; + shape = data.shape + var stride = data.stride - var shapeX = 0; - var shapeY = 0; - var strideX = 0; - var strideY = 0; + var shapeX = 0 + var shapeY = 0 + var strideX = 0 + var strideY = 0 if (shape.length === 1) { - shapeX = shape[0]; - shapeY = 1; - strideX = stride[0]; - strideY = 0; + shapeX = shape[0] + shapeY = 1 + strideX = stride[0] + strideY = 0 } else if (shape.length === 2) { - shapeX = shape[0]; - shapeY = shape[1]; - strideX = stride[0]; - strideY = stride[1]; + shapeX = shape[0] + shapeY = shape[1] + strideX = stride[0] + strideY = stride[1] } else { - check$1.raise('invalid shape'); + check$1.raise('invalid shape') } var dtype = Array.isArray(data.data) ? buffer.dtype - : typedArrayCode(data.data); + : typedArrayCode(data.data) - var transposeData = pool.allocType(dtype, shapeX * shapeY); + var transposeData = pool.allocType(dtype, shapeX * shapeY) transpose(transposeData, data.data, shapeX, shapeY, strideX, strideY, - data.offset); - setSubData(transposeData, offset); - pool.freeType(transposeData); + data.offset) + setSubData(transposeData, offset) + pool.freeType(transposeData) } else { - check$1.raise('invalid data for buffer subdata'); + check$1.raise('invalid data for buffer subdata') } return reglBuffer } if (!deferInit) { - reglBuffer(options); + reglBuffer(options) } - reglBuffer._reglType = 'buffer'; - reglBuffer._buffer = buffer; - reglBuffer.subdata = subdata; + reglBuffer._reglType = 'buffer' + reglBuffer._buffer = buffer + reglBuffer.subdata = subdata if (config.profile) { - reglBuffer.stats = buffer.stats; + reglBuffer.stats = buffer.stats } - reglBuffer.destroy = function () { destroy(buffer); }; + reglBuffer.destroy = function () { destroy(buffer) } return reglBuffer } function restoreBuffers () { values(bufferSet).forEach(function (buffer) { - buffer.buffer = gl.createBuffer(); - gl.bindBuffer(buffer.type, buffer.buffer); + buffer.buffer = gl.createBuffer() + gl.bindBuffer(buffer.type, buffer.buffer) gl.bufferData( - buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage); - }); + buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage) + }) } if (config.profile) { stats.getTotalBufferSize = function () { - var total = 0; + var total = 0 // TODO: Right now, the streams are not part of the total count. Object.keys(bufferSet).forEach(function (key) { - total += bufferSet[key].stats.size; - }); + total += bufferSet[key].stats.size + }) return total - }; + } } return { @@ -1823,8 +1852,8 @@ function wrapBufferState (gl, stats, config, attributeState) { destroyStream: destroyStream, clear: function () { - values(bufferSet).forEach(destroy); - streamPool.forEach(destroy); + values(bufferSet).forEach(destroy) + streamPool.forEach(destroy) }, getBuffer: function (wrapper) { @@ -1859,65 +1888,65 @@ var primTypes = { "triangle fan": 6 }; -var GL_POINTS = 0; -var GL_LINES = 1; -var GL_TRIANGLES = 4; +var GL_POINTS = 0 +var GL_LINES = 1 +var GL_TRIANGLES = 4 -var GL_BYTE$2 = 5120; -var GL_UNSIGNED_BYTE$4 = 5121; -var GL_SHORT$2 = 5122; -var GL_UNSIGNED_SHORT$2 = 5123; -var GL_INT$2 = 5124; -var GL_UNSIGNED_INT$2 = 5125; +var GL_BYTE$2 = 5120 +var GL_UNSIGNED_BYTE$4 = 5121 +var GL_SHORT$2 = 5122 +var GL_UNSIGNED_SHORT$2 = 5123 +var GL_INT$2 = 5124 +var GL_UNSIGNED_INT$2 = 5125 -var GL_ELEMENT_ARRAY_BUFFER = 34963; +var GL_ELEMENT_ARRAY_BUFFER = 34963 -var GL_STREAM_DRAW$1 = 0x88E0; -var GL_STATIC_DRAW$1 = 0x88E4; +var GL_STREAM_DRAW$1 = 0x88E0 +var GL_STATIC_DRAW$1 = 0x88E4 function wrapElementsState (gl, extensions, bufferState, stats) { - var elementSet = {}; - var elementCount = 0; + var elementSet = {} + var elementCount = 0 var elementTypes = { 'uint8': GL_UNSIGNED_BYTE$4, 'uint16': GL_UNSIGNED_SHORT$2 - }; + } if (extensions.oes_element_index_uint) { - elementTypes.uint32 = GL_UNSIGNED_INT$2; + elementTypes.uint32 = GL_UNSIGNED_INT$2 } function REGLElementBuffer (buffer) { - this.id = elementCount++; - elementSet[this.id] = this; - this.buffer = buffer; - this.primType = GL_TRIANGLES; - this.vertCount = 0; - this.type = 0; + this.id = elementCount++ + elementSet[this.id] = this + this.buffer = buffer + this.primType = GL_TRIANGLES + this.vertCount = 0 + this.type = 0 } REGLElementBuffer.prototype.bind = function () { - this.buffer.bind(); - }; + this.buffer.bind() + } - var bufferPool = []; + var bufferPool = [] function createElementStream (data) { - var result = bufferPool.pop(); + var result = bufferPool.pop() if (!result) { result = new REGLElementBuffer(bufferState.create( null, GL_ELEMENT_ARRAY_BUFFER, true, - false)._buffer); + false)._buffer) } - initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0); + initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0) return result } function destroyElementStream (elements) { - bufferPool.push(elements); + bufferPool.push(elements) } function initElements ( @@ -1928,166 +1957,167 @@ function wrapElementsState (gl, extensions, bufferState, stats) { count, byteLength, type) { - elements.buffer.bind(); + elements.buffer.bind() + var dtype if (data) { - var predictedType = type; + var predictedType = type if (!type && ( - !isTypedArray(data) || + !isTypedArray(data) || (isNDArrayLike(data) && !isTypedArray(data.data)))) { predictedType = extensions.oes_element_index_uint ? GL_UNSIGNED_INT$2 - : GL_UNSIGNED_SHORT$2; + : GL_UNSIGNED_SHORT$2 } bufferState._initBuffer( elements.buffer, data, usage, predictedType, - 3); + 3) } else { - gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage); - elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$4; - elements.buffer.usage = usage; - elements.buffer.dimension = 3; - elements.buffer.byteLength = byteLength; + gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage) + elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$4 + elements.buffer.usage = usage + elements.buffer.dimension = 3 + elements.buffer.byteLength = byteLength } - var dtype = type; + dtype = type if (!type) { switch (elements.buffer.dtype) { case GL_UNSIGNED_BYTE$4: case GL_BYTE$2: - dtype = GL_UNSIGNED_BYTE$4; + dtype = GL_UNSIGNED_BYTE$4 break case GL_UNSIGNED_SHORT$2: case GL_SHORT$2: - dtype = GL_UNSIGNED_SHORT$2; + dtype = GL_UNSIGNED_SHORT$2 break case GL_UNSIGNED_INT$2: case GL_INT$2: - dtype = GL_UNSIGNED_INT$2; + dtype = GL_UNSIGNED_INT$2 break default: - check$1.raise('unsupported type for element array'); + check$1.raise('unsupported type for element array') } - elements.buffer.dtype = dtype; + elements.buffer.dtype = dtype } - elements.type = dtype; + elements.type = dtype // Check oes_element_index_uint extension check$1( dtype !== GL_UNSIGNED_INT$2 || !!extensions.oes_element_index_uint, - '32 bit element buffers not supported, enable oes_element_index_uint first'); + '32 bit element buffers not supported, enable oes_element_index_uint first') // try to guess default primitive type and arguments - var vertCount = count; + var vertCount = count if (vertCount < 0) { - vertCount = elements.buffer.byteLength; + vertCount = elements.buffer.byteLength if (dtype === GL_UNSIGNED_SHORT$2) { - vertCount >>= 1; + vertCount >>= 1 } else if (dtype === GL_UNSIGNED_INT$2) { - vertCount >>= 2; + vertCount >>= 2 } } - elements.vertCount = vertCount; + elements.vertCount = vertCount // try to guess primitive type from cell dimension - var primType = prim; + var primType = prim if (prim < 0) { - primType = GL_TRIANGLES; - var dimension = elements.buffer.dimension; - if (dimension === 1) primType = GL_POINTS; - if (dimension === 2) primType = GL_LINES; - if (dimension === 3) primType = GL_TRIANGLES; + primType = GL_TRIANGLES + var dimension = elements.buffer.dimension + if (dimension === 1) primType = GL_POINTS + if (dimension === 2) primType = GL_LINES + if (dimension === 3) primType = GL_TRIANGLES } - elements.primType = primType; + elements.primType = primType } function destroyElements (elements) { - stats.elementsCount--; + stats.elementsCount-- - check$1(elements.buffer !== null, 'must not double destroy elements'); - delete elementSet[elements.id]; - elements.buffer.destroy(); - elements.buffer = null; + check$1(elements.buffer !== null, 'must not double destroy elements') + delete elementSet[elements.id] + elements.buffer.destroy() + elements.buffer = null } function createElements (options, persistent) { - var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true); - var elements = new REGLElementBuffer(buffer._buffer); - stats.elementsCount++; + var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true) + var elements = new REGLElementBuffer(buffer._buffer) + stats.elementsCount++ function reglElements (options) { if (!options) { - buffer(); - elements.primType = GL_TRIANGLES; - elements.vertCount = 0; - elements.type = GL_UNSIGNED_BYTE$4; + buffer() + elements.primType = GL_TRIANGLES + elements.vertCount = 0 + elements.type = GL_UNSIGNED_BYTE$4 } else if (typeof options === 'number') { - buffer(options); - elements.primType = GL_TRIANGLES; - elements.vertCount = options | 0; - elements.type = GL_UNSIGNED_BYTE$4; + buffer(options) + elements.primType = GL_TRIANGLES + elements.vertCount = options | 0 + elements.type = GL_UNSIGNED_BYTE$4 } else { - var data = null; - var usage = GL_STATIC_DRAW$1; - var primType = -1; - var vertCount = -1; - var byteLength = 0; - var dtype = 0; + var data = null + var usage = GL_STATIC_DRAW$1 + var primType = -1 + var vertCount = -1 + var byteLength = 0 + var dtype = 0 if (Array.isArray(options) || isTypedArray(options) || isNDArrayLike(options)) { - data = options; + data = options } else { - check$1.type(options, 'object', 'invalid arguments for elements'); + check$1.type(options, 'object', 'invalid arguments for elements') if ('data' in options) { - data = options.data; + data = options.data check$1( - Array.isArray(data) || + Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data), - 'invalid data for element buffer'); + 'invalid data for element buffer') } if ('usage' in options) { check$1.parameter( options.usage, usageTypes, - 'invalid element buffer usage'); - usage = usageTypes[options.usage]; + 'invalid element buffer usage') + usage = usageTypes[options.usage] } if ('primitive' in options) { check$1.parameter( options.primitive, primTypes, - 'invalid element buffer primitive'); - primType = primTypes[options.primitive]; + 'invalid element buffer primitive') + primType = primTypes[options.primitive] } if ('count' in options) { check$1( typeof options.count === 'number' && options.count >= 0, - 'invalid vertex count for elements'); - vertCount = options.count | 0; + 'invalid vertex count for elements') + vertCount = options.count | 0 } if ('type' in options) { check$1.parameter( options.type, elementTypes, - 'invalid buffer type'); - dtype = elementTypes[options.type]; + 'invalid buffer type') + dtype = elementTypes[options.type] } if ('length' in options) { - byteLength = options.length | 0; + byteLength = options.length | 0 } else { - byteLength = vertCount; + byteLength = vertCount if (dtype === GL_UNSIGNED_SHORT$2 || dtype === GL_SHORT$2) { - byteLength *= 2; + byteLength *= 2 } else if (dtype === GL_UNSIGNED_INT$2 || dtype === GL_INT$2) { - byteLength *= 4; + byteLength *= 4 } } } @@ -2098,23 +2128,23 @@ function wrapElementsState (gl, extensions, bufferState, stats) { primType, vertCount, byteLength, - dtype); + dtype) } return reglElements } - reglElements(options); + reglElements(options) - reglElements._reglType = 'elements'; - reglElements._elements = elements; + reglElements._reglType = 'elements' + reglElements._elements = elements reglElements.subdata = function (data, offset) { - buffer.subdata(data, offset); + buffer.subdata(data, offset) return reglElements - }; + } reglElements.destroy = function () { - destroyElements(elements); - }; + destroyElements(elements) + } return reglElements } @@ -2131,47 +2161,47 @@ function wrapElementsState (gl, extensions, bufferState, stats) { return null }, clear: function () { - values(elementSet).forEach(destroyElements); + values(elementSet).forEach(destroyElements) } } } -var FLOAT = new Float32Array(1); -var INT = new Uint32Array(FLOAT.buffer); +var FLOAT = new Float32Array(1) +var INT = new Uint32Array(FLOAT.buffer) -var GL_UNSIGNED_SHORT$4 = 5123; +var GL_UNSIGNED_SHORT$4 = 5123 function convertToHalfFloat (array) { - var ushorts = pool.allocType(GL_UNSIGNED_SHORT$4, array.length); + var ushorts = pool.allocType(GL_UNSIGNED_SHORT$4, array.length) for (var i = 0; i < array.length; ++i) { if (isNaN(array[i])) { - ushorts[i] = 0xffff; + ushorts[i] = 0xffff } else if (array[i] === Infinity) { - ushorts[i] = 0x7c00; + ushorts[i] = 0x7c00 } else if (array[i] === -Infinity) { - ushorts[i] = 0xfc00; + ushorts[i] = 0xfc00 } else { - FLOAT[0] = array[i]; - var x = INT[0]; + FLOAT[0] = array[i] + var x = INT[0] - var sgn = (x >>> 31) << 15; - var exp = ((x << 1) >>> 24) - 127; - var frac = (x >> 13) & ((1 << 10) - 1); + var sgn = (x >>> 31) << 15 + var exp = ((x << 1) >>> 24) - 127 + var frac = (x >> 13) & ((1 << 10) - 1) if (exp < -24) { // round non-representable denormals to 0 - ushorts[i] = sgn; + ushorts[i] = sgn } else if (exp < -14) { // handle denormals - var s = -14 - exp; - ushorts[i] = sgn + ((frac + (1 << 10)) >> s); + var s = -14 - exp + ushorts[i] = sgn + ((frac + (1 << 10)) >> s) } else if (exp > 15) { // round overflow to +/- Infinity - ushorts[i] = sgn + 0x7c00; + ushorts[i] = sgn + 0x7c00 } else { // otherwise convert directly - ushorts[i] = sgn + ((exp + 15) << 10) + frac; + ushorts[i] = sgn + ((exp + 15) << 10) + frac } } } @@ -2185,97 +2215,97 @@ function isArrayLike (s) { var isPow2$1 = function (v) { return !(v & (v - 1)) && (!!v) -}; +} -var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3; +var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3 -var GL_TEXTURE_2D$1 = 0x0DE1; -var GL_TEXTURE_CUBE_MAP$1 = 0x8513; -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515; +var GL_TEXTURE_2D$1 = 0x0DE1 +var GL_TEXTURE_CUBE_MAP$1 = 0x8513 +var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515 -var GL_RGBA$1 = 0x1908; -var GL_ALPHA = 0x1906; -var GL_RGB = 0x1907; -var GL_LUMINANCE = 0x1909; -var GL_LUMINANCE_ALPHA = 0x190A; +var GL_RGBA$1 = 0x1908 +var GL_ALPHA = 0x1906 +var GL_RGB = 0x1907 +var GL_LUMINANCE = 0x1909 +var GL_LUMINANCE_ALPHA = 0x190A -var GL_RGBA4 = 0x8056; -var GL_RGB5_A1 = 0x8057; -var GL_RGB565 = 0x8D62; +var GL_RGBA4 = 0x8056 +var GL_RGB5_A1 = 0x8057 +var GL_RGB565 = 0x8D62 -var GL_UNSIGNED_SHORT_4_4_4_4$1 = 0x8033; -var GL_UNSIGNED_SHORT_5_5_5_1$1 = 0x8034; -var GL_UNSIGNED_SHORT_5_6_5$1 = 0x8363; -var GL_UNSIGNED_INT_24_8_WEBGL$1 = 0x84FA; +var GL_UNSIGNED_SHORT_4_4_4_4$1 = 0x8033 +var GL_UNSIGNED_SHORT_5_5_5_1$1 = 0x8034 +var GL_UNSIGNED_SHORT_5_6_5$1 = 0x8363 +var GL_UNSIGNED_INT_24_8_WEBGL$1 = 0x84FA -var GL_DEPTH_COMPONENT = 0x1902; -var GL_DEPTH_STENCIL = 0x84F9; +var GL_DEPTH_COMPONENT = 0x1902 +var GL_DEPTH_STENCIL = 0x84F9 -var GL_SRGB_EXT = 0x8C40; -var GL_SRGB_ALPHA_EXT = 0x8C42; +var GL_SRGB_EXT = 0x8C40 +var GL_SRGB_ALPHA_EXT = 0x8C42 -var GL_HALF_FLOAT_OES$1 = 0x8D61; +var GL_HALF_FLOAT_OES$1 = 0x8D61 -var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0; -var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1; -var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2; -var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3; +var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0 +var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1 +var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2 +var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3 -var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92; -var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93; -var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE; +var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92 +var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93 +var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE -var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00; -var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01; -var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02; -var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03; +var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00 +var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01 +var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02 +var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03 -var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64; +var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64 -var GL_UNSIGNED_BYTE$5 = 0x1401; -var GL_UNSIGNED_SHORT$3 = 0x1403; -var GL_UNSIGNED_INT$3 = 0x1405; -var GL_FLOAT$4 = 0x1406; +var GL_UNSIGNED_BYTE$5 = 0x1401 +var GL_UNSIGNED_SHORT$3 = 0x1403 +var GL_UNSIGNED_INT$3 = 0x1405 +var GL_FLOAT$4 = 0x1406 -var GL_TEXTURE_WRAP_S = 0x2802; -var GL_TEXTURE_WRAP_T = 0x2803; +var GL_TEXTURE_WRAP_S = 0x2802 +var GL_TEXTURE_WRAP_T = 0x2803 -var GL_REPEAT = 0x2901; -var GL_CLAMP_TO_EDGE$1 = 0x812F; -var GL_MIRRORED_REPEAT = 0x8370; +var GL_REPEAT = 0x2901 +var GL_CLAMP_TO_EDGE$1 = 0x812F +var GL_MIRRORED_REPEAT = 0x8370 -var GL_TEXTURE_MAG_FILTER = 0x2800; -var GL_TEXTURE_MIN_FILTER = 0x2801; +var GL_TEXTURE_MAG_FILTER = 0x2800 +var GL_TEXTURE_MIN_FILTER = 0x2801 -var GL_NEAREST$1 = 0x2600; -var GL_LINEAR = 0x2601; -var GL_NEAREST_MIPMAP_NEAREST$1 = 0x2700; -var GL_LINEAR_MIPMAP_NEAREST$1 = 0x2701; -var GL_NEAREST_MIPMAP_LINEAR$1 = 0x2702; -var GL_LINEAR_MIPMAP_LINEAR$1 = 0x2703; +var GL_NEAREST$1 = 0x2600 +var GL_LINEAR = 0x2601 +var GL_NEAREST_MIPMAP_NEAREST$1 = 0x2700 +var GL_LINEAR_MIPMAP_NEAREST$1 = 0x2701 +var GL_NEAREST_MIPMAP_LINEAR$1 = 0x2702 +var GL_LINEAR_MIPMAP_LINEAR$1 = 0x2703 -var GL_GENERATE_MIPMAP_HINT = 0x8192; -var GL_DONT_CARE = 0x1100; -var GL_FASTEST = 0x1101; -var GL_NICEST = 0x1102; +var GL_GENERATE_MIPMAP_HINT = 0x8192 +var GL_DONT_CARE = 0x1100 +var GL_FASTEST = 0x1101 +var GL_NICEST = 0x1102 -var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE; +var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE -var GL_UNPACK_ALIGNMENT = 0x0CF5; -var GL_UNPACK_FLIP_Y_WEBGL = 0x9240; -var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241; -var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243; +var GL_UNPACK_ALIGNMENT = 0x0CF5 +var GL_UNPACK_FLIP_Y_WEBGL = 0x9240 +var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241 +var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243 -var GL_BROWSER_DEFAULT_WEBGL = 0x9244; +var GL_BROWSER_DEFAULT_WEBGL = 0x9244 -var GL_TEXTURE0$1 = 0x84C0; +var GL_TEXTURE0$1 = 0x84C0 var MIPMAP_FILTERS = [ GL_NEAREST_MIPMAP_NEAREST$1, GL_NEAREST_MIPMAP_LINEAR$1, GL_LINEAR_MIPMAP_NEAREST$1, GL_LINEAR_MIPMAP_LINEAR$1 -]; +] var CHANNELS_FORMAT = [ 0, @@ -2283,68 +2313,70 @@ var CHANNELS_FORMAT = [ GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA$1 -]; +] -var FORMAT_CHANNELS = {}; +var FORMAT_CHANNELS = {} FORMAT_CHANNELS[GL_LUMINANCE] = FORMAT_CHANNELS[GL_ALPHA] = -FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1; +FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1 FORMAT_CHANNELS[GL_DEPTH_STENCIL] = -FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2; +FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2 FORMAT_CHANNELS[GL_RGB] = -FORMAT_CHANNELS[GL_SRGB_EXT] = 3; +FORMAT_CHANNELS[GL_SRGB_EXT] = 3 FORMAT_CHANNELS[GL_RGBA$1] = -FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4; +FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4 function objectName (str) { return '[object ' + str + ']' } -var CANVAS_CLASS = objectName('HTMLCanvasElement'); -var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D'); -var BITMAP_CLASS = objectName('ImageBitmap'); -var IMAGE_CLASS = objectName('HTMLImageElement'); -var VIDEO_CLASS = objectName('HTMLVideoElement'); +var CANVAS_CLASS = objectName('HTMLCanvasElement') +var OFFSCREENCANVAS_CLASS = objectName('OffscreenCanvas') +var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D') +var BITMAP_CLASS = objectName('ImageBitmap') +var IMAGE_CLASS = objectName('HTMLImageElement') +var VIDEO_CLASS = objectName('HTMLVideoElement') var PIXEL_CLASSES = Object.keys(arrayTypes).concat([ CANVAS_CLASS, + OFFSCREENCANVAS_CLASS, CONTEXT2D_CLASS, BITMAP_CLASS, IMAGE_CLASS, VIDEO_CLASS -]); +]) // for every texture type, store // the size in bytes. -var TYPE_SIZES = []; -TYPE_SIZES[GL_UNSIGNED_BYTE$5] = 1; -TYPE_SIZES[GL_FLOAT$4] = 4; -TYPE_SIZES[GL_HALF_FLOAT_OES$1] = 2; +var TYPE_SIZES = [] +TYPE_SIZES[GL_UNSIGNED_BYTE$5] = 1 +TYPE_SIZES[GL_FLOAT$4] = 4 +TYPE_SIZES[GL_HALF_FLOAT_OES$1] = 2 -TYPE_SIZES[GL_UNSIGNED_SHORT$3] = 2; -TYPE_SIZES[GL_UNSIGNED_INT$3] = 4; +TYPE_SIZES[GL_UNSIGNED_SHORT$3] = 2 +TYPE_SIZES[GL_UNSIGNED_INT$3] = 4 -var FORMAT_SIZES_SPECIAL = []; -FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2; -FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2; -FORMAT_SIZES_SPECIAL[GL_RGB565] = 2; -FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4; +var FORMAT_SIZES_SPECIAL = [] +FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2 +FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2 +FORMAT_SIZES_SPECIAL[GL_RGB565] = 2 +FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1; +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1; +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5; -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25; +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5 +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25 -FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5; +FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5 function isNumericArray (arr) { return ( @@ -2357,7 +2389,7 @@ function isRectArray (arr) { if (!Array.isArray(arr)) { return false } - var width = arr.length; + var width = arr.length if (width === 0 || !isArrayLike(arr[0])) { return false } @@ -2372,6 +2404,10 @@ function isCanvasElement (object) { return classString(object) === CANVAS_CLASS } +function isOffscreenCanvas (object) { + return classString(object) === OFFSCREENCANVAS_CLASS +} + function isContext2D (object) { return classString(object) === CONTEXT2D_CLASS } @@ -2392,7 +2428,7 @@ function isPixelData (object) { if (!object) { return false } - var className = classString(object); + var className = classString(object) if (PIXEL_CLASSES.indexOf(className) >= 0) { return true } @@ -2407,23 +2443,23 @@ function typedArrayCode$1 (data) { } function convertData (result, data) { - var n = data.length; + var n = data.length switch (result.type) { case GL_UNSIGNED_BYTE$5: case GL_UNSIGNED_SHORT$3: case GL_UNSIGNED_INT$3: case GL_FLOAT$4: - var converted = pool.allocType(result.type, n); - converted.set(data); - result.data = converted; + var converted = pool.allocType(result.type, n) + converted.set(data) + result.data = converted break case GL_HALF_FLOAT_OES$1: - result.data = convertToHalfFloat(data); + result.data = convertToHalfFloat(data) break default: - check$1.raise('unsupported texture type, must specify a typed array'); + check$1.raise('unsupported texture type, must specify a typed array') } } @@ -2436,55 +2472,55 @@ function preConvert (image, n) { function postConvert (image, data) { if (image.type === GL_HALF_FLOAT_OES$1) { - image.data = convertToHalfFloat(data); - pool.freeType(data); + image.data = convertToHalfFloat(data) + pool.freeType(data) } else { - image.data = data; + image.data = data } } function transposeData (image, array, strideX, strideY, strideC, offset) { - var w = image.width; - var h = image.height; - var c = image.channels; - var n = w * h * c; - var data = preConvert(image, n); + var w = image.width + var h = image.height + var c = image.channels + var n = w * h * c + var data = preConvert(image, n) - var p = 0; + var p = 0 for (var i = 0; i < h; ++i) { for (var j = 0; j < w; ++j) { for (var k = 0; k < c; ++k) { - data[p++] = array[strideX * j + strideY * i + strideC * k + offset]; + data[p++] = array[strideX * j + strideY * i + strideC * k + offset] } } } - postConvert(image, data); + postConvert(image, data) } function getTextureSize (format, type, width, height, isMipmap, isCube) { - var s; + var s if (typeof FORMAT_SIZES_SPECIAL[format] !== 'undefined') { // we have a special array for dealing with weird color formats such as RGB5A1 - s = FORMAT_SIZES_SPECIAL[format]; + s = FORMAT_SIZES_SPECIAL[format] } else { - s = FORMAT_CHANNELS[format] * TYPE_SIZES[type]; + s = FORMAT_CHANNELS[format] * TYPE_SIZES[type] } if (isCube) { - s *= 6; + s *= 6 } if (isMipmap) { // compute the total size of all the mipmaps. - var total = 0; + var total = 0 - var w = width; + var w = width while (w >= 1) { // we can only use mipmaps on a square image, // so we can simply use the width and ignore the height: - total += s * w * w; - w /= 2; + total += s * w * w + w /= 2 } return total } else { @@ -2502,18 +2538,18 @@ function createTextureSet ( 'dont care': GL_DONT_CARE, 'nice': GL_NICEST, 'fast': GL_FASTEST - }; + } var wrapModes = { 'repeat': GL_REPEAT, 'clamp': GL_CLAMP_TO_EDGE$1, 'mirror': GL_MIRRORED_REPEAT - }; + } var magFilters = { 'nearest': GL_NEAREST$1, 'linear': GL_LINEAR - }; + } var minFilters = extend({ 'mipmap': GL_LINEAR_MIPMAP_LINEAR$1, @@ -2521,19 +2557,19 @@ function createTextureSet ( 'linear mipmap nearest': GL_LINEAR_MIPMAP_NEAREST$1, 'nearest mipmap linear': GL_NEAREST_MIPMAP_LINEAR$1, 'linear mipmap linear': GL_LINEAR_MIPMAP_LINEAR$1 - }, magFilters); + }, magFilters) var colorSpace = { 'none': 0, 'browser': GL_BROWSER_DEFAULT_WEBGL - }; + } var textureTypes = { 'uint8': GL_UNSIGNED_BYTE$5, 'rgba4': GL_UNSIGNED_SHORT_4_4_4_4$1, 'rgb565': GL_UNSIGNED_SHORT_5_6_5$1, 'rgb5 a1': GL_UNSIGNED_SHORT_5_5_5_1$1 - }; + } var textureFormats = { 'alpha': GL_ALPHA, @@ -2544,34 +2580,34 @@ function createTextureSet ( 'rgba4': GL_RGBA4, 'rgb5 a1': GL_RGB5_A1, 'rgb565': GL_RGB565 - }; + } - var compressedTextureFormats = {}; + var compressedTextureFormats = {} if (extensions.ext_srgb) { - textureFormats.srgb = GL_SRGB_EXT; - textureFormats.srgba = GL_SRGB_ALPHA_EXT; + textureFormats.srgb = GL_SRGB_EXT + textureFormats.srgba = GL_SRGB_ALPHA_EXT } if (extensions.oes_texture_float) { - textureTypes.float32 = textureTypes.float = GL_FLOAT$4; + textureTypes.float32 = textureTypes.float = GL_FLOAT$4 } if (extensions.oes_texture_half_float) { - textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES$1; + textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES$1 } if (extensions.webgl_depth_texture) { extend(textureFormats, { 'depth': GL_DEPTH_COMPONENT, 'depth stencil': GL_DEPTH_STENCIL - }); + }) extend(textureTypes, { 'uint16': GL_UNSIGNED_SHORT$3, 'uint32': GL_UNSIGNED_INT$3, 'depth stencil': GL_UNSIGNED_INT_24_8_WEBGL$1 - }); + }) } if (extensions.webgl_compressed_texture_s3tc) { @@ -2580,7 +2616,7 @@ function createTextureSet ( 'rgba s3tc dxt1': GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 'rgba s3tc dxt3': GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 'rgba s3tc dxt5': GL_COMPRESSED_RGBA_S3TC_DXT5_EXT - }); + }) } if (extensions.webgl_compressed_texture_atc) { @@ -2588,7 +2624,7 @@ function createTextureSet ( 'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL, 'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL, 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL - }); + }) } if (extensions.webgl_compressed_texture_pvrtc) { @@ -2597,112 +2633,115 @@ function createTextureSet ( 'rgb pvrtc 2bppv1': GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 'rgba pvrtc 4bppv1': GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 'rgba pvrtc 2bppv1': GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG - }); + }) } if (extensions.webgl_compressed_texture_etc1) { - compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL; + compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL } // Copy over all texture formats var supportedCompressedFormats = Array.prototype.slice.call( - gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS)); + gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS)) Object.keys(compressedTextureFormats).forEach(function (name) { - var format = compressedTextureFormats[name]; + var format = compressedTextureFormats[name] if (supportedCompressedFormats.indexOf(format) >= 0) { - textureFormats[name] = format; + textureFormats[name] = format } - }); + }) - var supportedFormats = Object.keys(textureFormats); - limits.textureFormats = supportedFormats; + var supportedFormats = Object.keys(textureFormats) + limits.textureFormats = supportedFormats // associate with every format string its // corresponding GL-value. - var textureFormatsInvert = []; + var textureFormatsInvert = [] Object.keys(textureFormats).forEach(function (key) { - var val = textureFormats[key]; - textureFormatsInvert[val] = key; - }); + var val = textureFormats[key] + textureFormatsInvert[val] = key + }) // associate with every type string its // corresponding GL-value. - var textureTypesInvert = []; + var textureTypesInvert = [] Object.keys(textureTypes).forEach(function (key) { - var val = textureTypes[key]; - textureTypesInvert[val] = key; - }); + var val = textureTypes[key] + textureTypesInvert[val] = key + }) - var magFiltersInvert = []; + var magFiltersInvert = [] Object.keys(magFilters).forEach(function (key) { - var val = magFilters[key]; - magFiltersInvert[val] = key; - }); + var val = magFilters[key] + magFiltersInvert[val] = key + }) - var minFiltersInvert = []; + var minFiltersInvert = [] Object.keys(minFilters).forEach(function (key) { - var val = minFilters[key]; - minFiltersInvert[val] = key; - }); + var val = minFilters[key] + minFiltersInvert[val] = key + }) - var wrapModesInvert = []; + var wrapModesInvert = [] Object.keys(wrapModes).forEach(function (key) { - var val = wrapModes[key]; - wrapModesInvert[val] = key; - }); + var val = wrapModes[key] + wrapModesInvert[val] = key + }) // colorFormats[] gives the format (channels) associated to an // internalformat var colorFormats = supportedFormats.reduce(function (color, key) { - var glenum = textureFormats[key]; + var glenum = textureFormats[key] if (glenum === GL_LUMINANCE || glenum === GL_ALPHA || glenum === GL_LUMINANCE || glenum === GL_LUMINANCE_ALPHA || glenum === GL_DEPTH_COMPONENT || - glenum === GL_DEPTH_STENCIL) { - color[glenum] = glenum; + glenum === GL_DEPTH_STENCIL || + (extensions.ext_srgb && + (glenum === GL_SRGB_EXT || + glenum === GL_SRGB_ALPHA_EXT))) { + color[glenum] = glenum } else if (glenum === GL_RGB5_A1 || key.indexOf('rgba') >= 0) { - color[glenum] = GL_RGBA$1; + color[glenum] = GL_RGBA$1 } else { - color[glenum] = GL_RGB; + color[glenum] = GL_RGB } return color - }, {}); + }, {}) function TexFlags () { // format info - this.internalformat = GL_RGBA$1; - this.format = GL_RGBA$1; - this.type = GL_UNSIGNED_BYTE$5; - this.compressed = false; + this.internalformat = GL_RGBA$1 + this.format = GL_RGBA$1 + this.type = GL_UNSIGNED_BYTE$5 + this.compressed = false // pixel storage - this.premultiplyAlpha = false; - this.flipY = false; - this.unpackAlignment = 1; - this.colorSpace = GL_BROWSER_DEFAULT_WEBGL; + this.premultiplyAlpha = false + this.flipY = false + this.unpackAlignment = 1 + this.colorSpace = GL_BROWSER_DEFAULT_WEBGL // shape info - this.width = 0; - this.height = 0; - this.channels = 0; + this.width = 0 + this.height = 0 + this.channels = 0 } function copyFlags (result, other) { - result.internalformat = other.internalformat; - result.format = other.format; - result.type = other.type; - result.compressed = other.compressed; + result.internalformat = other.internalformat + result.format = other.format + result.type = other.type + result.compressed = other.compressed - result.premultiplyAlpha = other.premultiplyAlpha; - result.flipY = other.flipY; - result.unpackAlignment = other.unpackAlignment; - result.colorSpace = other.colorSpace; + result.premultiplyAlpha = other.premultiplyAlpha + result.flipY = other.flipY + result.unpackAlignment = other.unpackAlignment + result.colorSpace = other.colorSpace - result.width = other.width; - result.height = other.height; - result.channels = other.channels; + result.width = other.width + result.height = other.height + result.channels = other.channels } function parseFlags (flags, options) { @@ -2712,345 +2751,335 @@ function createTextureSet ( if ('premultiplyAlpha' in options) { check$1.type(options.premultiplyAlpha, 'boolean', - 'invalid premultiplyAlpha'); - flags.premultiplyAlpha = options.premultiplyAlpha; + 'invalid premultiplyAlpha') + flags.premultiplyAlpha = options.premultiplyAlpha } if ('flipY' in options) { check$1.type(options.flipY, 'boolean', - 'invalid texture flip'); - flags.flipY = options.flipY; + 'invalid texture flip') + flags.flipY = options.flipY } if ('alignment' in options) { check$1.oneOf(options.alignment, [1, 2, 4, 8], - 'invalid texture unpack alignment'); - flags.unpackAlignment = options.alignment; + 'invalid texture unpack alignment') + flags.unpackAlignment = options.alignment } if ('colorSpace' in options) { check$1.parameter(options.colorSpace, colorSpace, - 'invalid colorSpace'); - flags.colorSpace = colorSpace[options.colorSpace]; + 'invalid colorSpace') + flags.colorSpace = colorSpace[options.colorSpace] } if ('type' in options) { - var type = options.type; + var type = options.type check$1(extensions.oes_texture_float || !(type === 'float' || type === 'float32'), - 'you must enable the OES_texture_float extension in order to use floating point textures.'); + 'you must enable the OES_texture_float extension in order to use floating point textures.') check$1(extensions.oes_texture_half_float || !(type === 'half float' || type === 'float16'), - 'you must enable the OES_texture_half_float extension in order to use 16-bit floating point textures.'); + 'you must enable the OES_texture_half_float extension in order to use 16-bit floating point textures.') check$1(extensions.webgl_depth_texture || !(type === 'uint16' || type === 'uint32' || type === 'depth stencil'), - 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.'); + 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.') check$1.parameter(type, textureTypes, - 'invalid texture type'); - flags.type = textureTypes[type]; + 'invalid texture type') + flags.type = textureTypes[type] } - var w = flags.width; - var h = flags.height; - var c = flags.channels; - var hasChannels = false; + var w = flags.width + var h = flags.height + var c = flags.channels + var hasChannels = false if ('shape' in options) { check$1(Array.isArray(options.shape) && options.shape.length >= 2, - 'shape must be an array'); - w = options.shape[0]; - h = options.shape[1]; + 'shape must be an array') + w = options.shape[0] + h = options.shape[1] if (options.shape.length === 3) { - c = options.shape[2]; - check$1(c > 0 && c <= 4, 'invalid number of channels'); - hasChannels = true; + c = options.shape[2] + check$1(c > 0 && c <= 4, 'invalid number of channels') + hasChannels = true } - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width'); - check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height'); + check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width') + check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height') } else { if ('radius' in options) { - w = h = options.radius; - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid radius'); + w = h = options.radius + check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid radius') } if ('width' in options) { - w = options.width; - check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width'); + w = options.width + check$1(w >= 0 && w <= limits.maxTextureSize, 'invalid width') } if ('height' in options) { - h = options.height; - check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height'); + h = options.height + check$1(h >= 0 && h <= limits.maxTextureSize, 'invalid height') } if ('channels' in options) { - c = options.channels; - check$1(c > 0 && c <= 4, 'invalid number of channels'); - hasChannels = true; + c = options.channels + check$1(c > 0 && c <= 4, 'invalid number of channels') + hasChannels = true } } - flags.width = w | 0; - flags.height = h | 0; - flags.channels = c | 0; + flags.width = w | 0 + flags.height = h | 0 + flags.channels = c | 0 - var hasFormat = false; + var hasFormat = false if ('format' in options) { - var formatStr = options.format; + var formatStr = options.format check$1(extensions.webgl_depth_texture || !(formatStr === 'depth' || formatStr === 'depth stencil'), - 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.'); + 'you must enable the WEBGL_depth_texture extension in order to use depth/stencil textures.') check$1.parameter(formatStr, textureFormats, - 'invalid texture format'); - var internalformat = flags.internalformat = textureFormats[formatStr]; - flags.format = colorFormats[internalformat]; + 'invalid texture format') + var internalformat = flags.internalformat = textureFormats[formatStr] + flags.format = colorFormats[internalformat] if (formatStr in textureTypes) { if (!('type' in options)) { - flags.type = textureTypes[formatStr]; + flags.type = textureTypes[formatStr] } } if (formatStr in compressedTextureFormats) { - flags.compressed = true; + flags.compressed = true } - hasFormat = true; + hasFormat = true } // Reconcile channels and format if (!hasChannels && hasFormat) { - flags.channels = FORMAT_CHANNELS[flags.format]; + flags.channels = FORMAT_CHANNELS[flags.format] } else if (hasChannels && !hasFormat) { if (flags.channels !== CHANNELS_FORMAT[flags.format]) { - flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels]; + flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels] } } else if (hasFormat && hasChannels) { check$1( flags.channels === FORMAT_CHANNELS[flags.format], - 'number of channels inconsistent with specified format'); + 'number of channels inconsistent with specified format') } } function setFlags (flags) { - gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY); - gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha); - gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace); - gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment); + gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY) + gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha) + gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace) + gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment) } // ------------------------------------------------------- // Tex image data // ------------------------------------------------------- function TexImage () { - TexFlags.call(this); + TexFlags.call(this) - this.xOffset = 0; - this.yOffset = 0; + this.xOffset = 0 + this.yOffset = 0 // data - this.data = null; - this.needsFree = false; + this.data = null + this.needsFree = false // html element - this.element = null; + this.element = null // copyTexImage info - this.needsCopy = false; + this.needsCopy = false } function parseImage (image, options) { - var data = null; + var data = null if (isPixelData(options)) { - data = options; + data = options } else if (options) { - check$1.type(options, 'object', 'invalid pixel data type'); - parseFlags(image, options); + check$1.type(options, 'object', 'invalid pixel data type') + parseFlags(image, options) if ('x' in options) { - image.xOffset = options.x | 0; + image.xOffset = options.x | 0 } if ('y' in options) { - image.yOffset = options.y | 0; + image.yOffset = options.y | 0 } if (isPixelData(options.data)) { - data = options.data; + data = options.data } } check$1( !image.compressed || data instanceof Uint8Array, - 'compressed texture data must be stored in a uint8array'); + 'compressed texture data must be stored in a uint8array') if (options.copy) { - check$1(!data, 'can not specify copy and data field for the same texture'); - var viewW = contextState.viewportWidth; - var viewH = contextState.viewportHeight; - image.width = image.width || (viewW - image.xOffset); - image.height = image.height || (viewH - image.yOffset); - image.needsCopy = true; + check$1(!data, 'can not specify copy and data field for the same texture') + var viewW = contextState.viewportWidth + var viewH = contextState.viewportHeight + image.width = image.width || (viewW - image.xOffset) + image.height = image.height || (viewH - image.yOffset) + image.needsCopy = true check$1(image.xOffset >= 0 && image.xOffset < viewW && image.yOffset >= 0 && image.yOffset < viewH && image.width > 0 && image.width <= viewW && image.height > 0 && image.height <= viewH, - 'copy texture read out of bounds'); + 'copy texture read out of bounds') } else if (!data) { - image.width = image.width || 1; - image.height = image.height || 1; - image.channels = image.channels || 4; + image.width = image.width || 1 + image.height = image.height || 1 + image.channels = image.channels || 4 } else if (isTypedArray(data)) { - image.channels = image.channels || 4; - image.data = data; + image.channels = image.channels || 4 + image.data = data if (!('type' in options) && image.type === GL_UNSIGNED_BYTE$5) { - image.type = typedArrayCode$1(data); + image.type = typedArrayCode$1(data) } } else if (isNumericArray(data)) { - image.channels = image.channels || 4; - convertData(image, data); - image.alignment = 1; - image.needsFree = true; + image.channels = image.channels || 4 + convertData(image, data) + image.alignment = 1 + image.needsFree = true } else if (isNDArrayLike(data)) { - var array = data.data; + var array = data.data if (!Array.isArray(array) && image.type === GL_UNSIGNED_BYTE$5) { - image.type = typedArrayCode$1(array); + image.type = typedArrayCode$1(array) } - var shape = data.shape; - var stride = data.stride; - var shapeX, shapeY, shapeC, strideX, strideY, strideC; + var shape = data.shape + var stride = data.stride + var shapeX, shapeY, shapeC, strideX, strideY, strideC if (shape.length === 3) { - shapeC = shape[2]; - strideC = stride[2]; + shapeC = shape[2] + strideC = stride[2] } else { - check$1(shape.length === 2, 'invalid ndarray pixel data, must be 2 or 3D'); - shapeC = 1; - strideC = 1; + check$1(shape.length === 2, 'invalid ndarray pixel data, must be 2 or 3D') + shapeC = 1 + strideC = 1 } - shapeX = shape[0]; - shapeY = shape[1]; - strideX = stride[0]; - strideY = stride[1]; - image.alignment = 1; - image.width = shapeX; - image.height = shapeY; - image.channels = shapeC; - image.format = image.internalformat = CHANNELS_FORMAT[shapeC]; - image.needsFree = true; - transposeData(image, array, strideX, strideY, strideC, data.offset); - } else if (isCanvasElement(data) || isContext2D(data)) { - if (isCanvasElement(data)) { - image.element = data; + shapeX = shape[0] + shapeY = shape[1] + strideX = stride[0] + strideY = stride[1] + image.alignment = 1 + image.width = shapeX + image.height = shapeY + image.channels = shapeC + image.format = image.internalformat = CHANNELS_FORMAT[shapeC] + image.needsFree = true + transposeData(image, array, strideX, strideY, strideC, data.offset) + } else if (isCanvasElement(data) || isOffscreenCanvas(data) || isContext2D(data)) { + if (isCanvasElement(data) || isOffscreenCanvas(data)) { + image.element = data } else { - image.element = data.canvas; + image.element = data.canvas } - image.width = image.element.width; - image.height = image.element.height; - image.channels = 4; + image.width = image.element.width + image.height = image.element.height + image.channels = 4 } else if (isBitmap(data)) { - image.element = data; - image.width = data.width; - image.height = data.height; - image.channels = 4; + image.element = data + image.width = data.width + image.height = data.height + image.channels = 4 } else if (isImageElement(data)) { - image.element = data; - image.width = data.naturalWidth; - image.height = data.naturalHeight; - image.channels = 4; + image.element = data + image.width = data.naturalWidth + image.height = data.naturalHeight + image.channels = 4 } else if (isVideoElement(data)) { - image.element = data; - image.width = data.videoWidth; - image.height = data.videoHeight; - image.channels = 4; + image.element = data + image.width = data.videoWidth + image.height = data.videoHeight + image.channels = 4 } else if (isRectArray(data)) { - var w = image.width || data[0].length; - var h = image.height || data.length; - var c = image.channels; + var w = image.width || data[0].length + var h = image.height || data.length + var c = image.channels if (isArrayLike(data[0][0])) { - c = c || data[0][0].length; + c = c || data[0][0].length } else { - c = c || 1; + c = c || 1 } - var arrayShape = flattenUtils.shape(data); - var n = 1; + var arrayShape = flattenUtils.shape(data) + var n = 1 for (var dd = 0; dd < arrayShape.length; ++dd) { - n *= arrayShape[dd]; + n *= arrayShape[dd] } - var allocData = preConvert(image, n); - flattenUtils.flatten(data, arrayShape, '', allocData); - postConvert(image, allocData); - image.alignment = 1; - image.width = w; - image.height = h; - image.channels = c; - image.format = image.internalformat = CHANNELS_FORMAT[c]; - image.needsFree = true; + var allocData = preConvert(image, n) + flattenUtils.flatten(data, arrayShape, '', allocData) + postConvert(image, allocData) + image.alignment = 1 + image.width = w + image.height = h + image.channels = c + image.format = image.internalformat = CHANNELS_FORMAT[c] + image.needsFree = true } if (image.type === GL_FLOAT$4) { check$1(limits.extensions.indexOf('oes_texture_float') >= 0, - 'oes_texture_float extension not enabled'); + 'oes_texture_float extension not enabled') } else if (image.type === GL_HALF_FLOAT_OES$1) { check$1(limits.extensions.indexOf('oes_texture_half_float') >= 0, - 'oes_texture_half_float extension not enabled'); + 'oes_texture_half_float extension not enabled') } // do compressed texture validation here. } function setImage (info, target, miplevel) { - var element = info.element; - var data = info.data; - var internalformat = info.internalformat; - var format = info.format; - var type = info.type; - var width = info.width; - var height = info.height; - var channels = info.channels; + var element = info.element + var data = info.data + var internalformat = info.internalformat + var format = info.format + var type = info.type + var width = info.width + var height = info.height - setFlags(info); + setFlags(info) if (element) { - gl.texImage2D(target, miplevel, format, format, type, element); + gl.texImage2D(target, miplevel, format, format, type, element) } else if (info.compressed) { - gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data); + gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data) } else if (info.needsCopy) { - reglPoll(); + reglPoll() gl.copyTexImage2D( - target, miplevel, format, info.xOffset, info.yOffset, width, height, 0); + target, miplevel, format, info.xOffset, info.yOffset, width, height, 0) } else { - var nullData = !data; - if (nullData) { - data = pool.zero.allocType(type, width * height * channels); - } - - gl.texImage2D(target, miplevel, format, width, height, 0, format, type, data); - - if (nullData && data) { - pool.zero.freeType(data); - } + gl.texImage2D(target, miplevel, format, width, height, 0, format, type, data || null) } } function setSubImage (info, target, x, y, miplevel) { - var element = info.element; - var data = info.data; - var internalformat = info.internalformat; - var format = info.format; - var type = info.type; - var width = info.width; - var height = info.height; + var element = info.element + var data = info.data + var internalformat = info.internalformat + var format = info.format + var type = info.type + var width = info.width + var height = info.height - setFlags(info); + setFlags(info) if (element) { gl.texSubImage2D( - target, miplevel, x, y, format, type, element); + target, miplevel, x, y, format, type, element) } else if (info.compressed) { gl.compressedTexSubImage2D( - target, miplevel, x, y, internalformat, width, height, data); + target, miplevel, x, y, internalformat, width, height, data) } else if (info.needsCopy) { - reglPoll(); + reglPoll() gl.copyTexSubImage2D( - target, miplevel, x, y, info.xOffset, info.yOffset, width, height); + target, miplevel, x, y, info.xOffset, info.yOffset, width, height) } else { gl.texSubImage2D( - target, miplevel, x, y, width, height, format, type, data); + target, miplevel, x, y, width, height, format, type, data) } } // texImage pool - var imagePool = []; + var imagePool = [] function allocImage () { return imagePool.pop() || new TexImage() @@ -3058,59 +3087,59 @@ function createTextureSet ( function freeImage (image) { if (image.needsFree) { - pool.freeType(image.data); + pool.freeType(image.data) } - TexImage.call(image); - imagePool.push(image); + TexImage.call(image) + imagePool.push(image) } // ------------------------------------------------------- // Mip map // ------------------------------------------------------- function MipMap () { - TexFlags.call(this); + TexFlags.call(this) - this.genMipmaps = false; - this.mipmapHint = GL_DONT_CARE; - this.mipmask = 0; - this.images = Array(16); + this.genMipmaps = false + this.mipmapHint = GL_DONT_CARE + this.mipmask = 0 + this.images = Array(16) } function parseMipMapFromShape (mipmap, width, height) { - var img = mipmap.images[0] = allocImage(); - mipmap.mipmask = 1; - img.width = mipmap.width = width; - img.height = mipmap.height = height; - img.channels = mipmap.channels = 4; + var img = mipmap.images[0] = allocImage() + mipmap.mipmask = 1 + img.width = mipmap.width = width + img.height = mipmap.height = height + img.channels = mipmap.channels = 4 } function parseMipMapFromObject (mipmap, options) { - var imgData = null; + var imgData = null if (isPixelData(options)) { - imgData = mipmap.images[0] = allocImage(); - copyFlags(imgData, mipmap); - parseImage(imgData, options); - mipmap.mipmask = 1; + imgData = mipmap.images[0] = allocImage() + copyFlags(imgData, mipmap) + parseImage(imgData, options) + mipmap.mipmask = 1 } else { - parseFlags(mipmap, options); + parseFlags(mipmap, options) if (Array.isArray(options.mipmap)) { - var mipData = options.mipmap; + var mipData = options.mipmap for (var i = 0; i < mipData.length; ++i) { - imgData = mipmap.images[i] = allocImage(); - copyFlags(imgData, mipmap); - imgData.width >>= i; - imgData.height >>= i; - parseImage(imgData, mipData[i]); - mipmap.mipmask |= (1 << i); + imgData = mipmap.images[i] = allocImage() + copyFlags(imgData, mipmap) + imgData.width >>= i + imgData.height >>= i + parseImage(imgData, mipData[i]) + mipmap.mipmask |= (1 << i) } } else { - imgData = mipmap.images[0] = allocImage(); - copyFlags(imgData, mipmap); - parseImage(imgData, options); - mipmap.mipmask = 1; + imgData = mipmap.images[0] = allocImage() + copyFlags(imgData, mipmap) + parseImage(imgData, options) + mipmap.mipmask = 1 } } - copyFlags(mipmap, mipmap.images[0]); + copyFlags(mipmap, mipmap.images[0]) // For textures of the compressed format WEBGL_compressed_texture_s3tc // we must have that @@ -3121,313 +3150,316 @@ function createTextureSet ( // but we do not yet support having multiple mipmap levels for compressed textures, // so we only test for level zero. - if (mipmap.compressed && - (mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT) || - (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || - (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || - (mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) { - check$1(mipmap.width % 4 === 0 && - mipmap.height % 4 === 0, - 'for compressed texture formats, mipmap level 0 must have width and height that are a multiple of 4'); + if ( + mipmap.compressed && + ( + mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT || + mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || + mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || + mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT + ) + ) { + check$1(mipmap.width % 4 === 0 && mipmap.height % 4 === 0, + 'for compressed texture formats, mipmap level 0 must have width and height that are a multiple of 4') } } function setMipMap (mipmap, target) { - var images = mipmap.images; + var images = mipmap.images for (var i = 0; i < images.length; ++i) { if (!images[i]) { return } - setImage(images[i], target, i); + setImage(images[i], target, i) } } - var mipPool = []; + var mipPool = [] function allocMipMap () { - var result = mipPool.pop() || new MipMap(); - TexFlags.call(result); - result.mipmask = 0; + var result = mipPool.pop() || new MipMap() + TexFlags.call(result) + result.mipmask = 0 for (var i = 0; i < 16; ++i) { - result.images[i] = null; + result.images[i] = null } return result } function freeMipMap (mipmap) { - var images = mipmap.images; + var images = mipmap.images for (var i = 0; i < images.length; ++i) { if (images[i]) { - freeImage(images[i]); + freeImage(images[i]) } - images[i] = null; + images[i] = null } - mipPool.push(mipmap); + mipPool.push(mipmap) } // ------------------------------------------------------- // Tex info // ------------------------------------------------------- function TexInfo () { - this.minFilter = GL_NEAREST$1; - this.magFilter = GL_NEAREST$1; + this.minFilter = GL_NEAREST$1 + this.magFilter = GL_NEAREST$1 - this.wrapS = GL_CLAMP_TO_EDGE$1; - this.wrapT = GL_CLAMP_TO_EDGE$1; + this.wrapS = GL_CLAMP_TO_EDGE$1 + this.wrapT = GL_CLAMP_TO_EDGE$1 - this.anisotropic = 1; + this.anisotropic = 1 - this.genMipmaps = false; - this.mipmapHint = GL_DONT_CARE; + this.genMipmaps = false + this.mipmapHint = GL_DONT_CARE } function parseTexInfo (info, options) { if ('min' in options) { - var minFilter = options.min; - check$1.parameter(minFilter, minFilters); - info.minFilter = minFilters[minFilter]; + var minFilter = options.min + check$1.parameter(minFilter, minFilters) + info.minFilter = minFilters[minFilter] if (MIPMAP_FILTERS.indexOf(info.minFilter) >= 0 && !('faces' in options)) { - info.genMipmaps = true; + info.genMipmaps = true } } if ('mag' in options) { - var magFilter = options.mag; - check$1.parameter(magFilter, magFilters); - info.magFilter = magFilters[magFilter]; + var magFilter = options.mag + check$1.parameter(magFilter, magFilters) + info.magFilter = magFilters[magFilter] } - var wrapS = info.wrapS; - var wrapT = info.wrapT; + var wrapS = info.wrapS + var wrapT = info.wrapT if ('wrap' in options) { - var wrap = options.wrap; + var wrap = options.wrap if (typeof wrap === 'string') { - check$1.parameter(wrap, wrapModes); - wrapS = wrapT = wrapModes[wrap]; + check$1.parameter(wrap, wrapModes) + wrapS = wrapT = wrapModes[wrap] } else if (Array.isArray(wrap)) { - check$1.parameter(wrap[0], wrapModes); - check$1.parameter(wrap[1], wrapModes); - wrapS = wrapModes[wrap[0]]; - wrapT = wrapModes[wrap[1]]; + check$1.parameter(wrap[0], wrapModes) + check$1.parameter(wrap[1], wrapModes) + wrapS = wrapModes[wrap[0]] + wrapT = wrapModes[wrap[1]] } } else { if ('wrapS' in options) { - var optWrapS = options.wrapS; - check$1.parameter(optWrapS, wrapModes); - wrapS = wrapModes[optWrapS]; + var optWrapS = options.wrapS + check$1.parameter(optWrapS, wrapModes) + wrapS = wrapModes[optWrapS] } if ('wrapT' in options) { - var optWrapT = options.wrapT; - check$1.parameter(optWrapT, wrapModes); - wrapT = wrapModes[optWrapT]; + var optWrapT = options.wrapT + check$1.parameter(optWrapT, wrapModes) + wrapT = wrapModes[optWrapT] } } - info.wrapS = wrapS; - info.wrapT = wrapT; + info.wrapS = wrapS + info.wrapT = wrapT if ('anisotropic' in options) { - var anisotropic = options.anisotropic; + var anisotropic = options.anisotropic check$1(typeof anisotropic === 'number' && anisotropic >= 1 && anisotropic <= limits.maxAnisotropic, - 'aniso samples must be between 1 and '); - info.anisotropic = options.anisotropic; + 'aniso samples must be between 1 and ') + info.anisotropic = options.anisotropic } if ('mipmap' in options) { - var hasMipMap = false; + var hasMipMap = false switch (typeof options.mipmap) { case 'string': check$1.parameter(options.mipmap, mipmapHint, - 'invalid mipmap hint'); - info.mipmapHint = mipmapHint[options.mipmap]; - info.genMipmaps = true; - hasMipMap = true; + 'invalid mipmap hint') + info.mipmapHint = mipmapHint[options.mipmap] + info.genMipmaps = true + hasMipMap = true break case 'boolean': - hasMipMap = info.genMipmaps = options.mipmap; + hasMipMap = info.genMipmaps = options.mipmap break case 'object': - check$1(Array.isArray(options.mipmap), 'invalid mipmap type'); - info.genMipmaps = false; - hasMipMap = true; + check$1(Array.isArray(options.mipmap), 'invalid mipmap type') + info.genMipmaps = false + hasMipMap = true break default: - check$1.raise('invalid mipmap type'); + check$1.raise('invalid mipmap type') } if (hasMipMap && !('min' in options)) { - info.minFilter = GL_NEAREST_MIPMAP_NEAREST$1; + info.minFilter = GL_NEAREST_MIPMAP_NEAREST$1 } } } function setTexInfo (info, target) { - gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter); - gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter); - gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS); - gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT); + gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter) + gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter) + gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS) + gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT) if (extensions.ext_texture_filter_anisotropic) { - gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic); + gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic) } if (info.genMipmaps) { - gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint); - gl.generateMipmap(target); + gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint) + gl.generateMipmap(target) } } // ------------------------------------------------------- // Full texture object // ------------------------------------------------------- - var textureCount = 0; - var textureSet = {}; - var numTexUnits = limits.maxTextureUnits; + var textureCount = 0 + var textureSet = {} + var numTexUnits = limits.maxTextureUnits var textureUnits = Array(numTexUnits).map(function () { return null - }); + }) function REGLTexture (target) { - TexFlags.call(this); - this.mipmask = 0; - this.internalformat = GL_RGBA$1; + TexFlags.call(this) + this.mipmask = 0 + this.internalformat = GL_RGBA$1 - this.id = textureCount++; + this.id = textureCount++ - this.refCount = 1; + this.refCount = 1 - this.target = target; - this.texture = gl.createTexture(); + this.target = target + this.texture = gl.createTexture() - this.unit = -1; - this.bindCount = 0; + this.unit = -1 + this.bindCount = 0 - this.texInfo = new TexInfo(); + this.texInfo = new TexInfo() if (config.profile) { - this.stats = {size: 0}; + this.stats = { size: 0 } } } function tempBind (texture) { - gl.activeTexture(GL_TEXTURE0$1); - gl.bindTexture(texture.target, texture.texture); + gl.activeTexture(GL_TEXTURE0$1) + gl.bindTexture(texture.target, texture.texture) } function tempRestore () { - var prev = textureUnits[0]; + var prev = textureUnits[0] if (prev) { - gl.bindTexture(prev.target, prev.texture); + gl.bindTexture(prev.target, prev.texture) } else { - gl.bindTexture(GL_TEXTURE_2D$1, null); + gl.bindTexture(GL_TEXTURE_2D$1, null) } } function destroy (texture) { - var handle = texture.texture; - check$1(handle, 'must not double destroy texture'); - var unit = texture.unit; - var target = texture.target; + var handle = texture.texture + check$1(handle, 'must not double destroy texture') + var unit = texture.unit + var target = texture.target if (unit >= 0) { - gl.activeTexture(GL_TEXTURE0$1 + unit); - gl.bindTexture(target, null); - textureUnits[unit] = null; + gl.activeTexture(GL_TEXTURE0$1 + unit) + gl.bindTexture(target, null) + textureUnits[unit] = null } - gl.deleteTexture(handle); - texture.texture = null; - texture.params = null; - texture.pixels = null; - texture.refCount = 0; - delete textureSet[texture.id]; - stats.textureCount--; + gl.deleteTexture(handle) + texture.texture = null + texture.params = null + texture.pixels = null + texture.refCount = 0 + delete textureSet[texture.id] + stats.textureCount-- } extend(REGLTexture.prototype, { bind: function () { - var texture = this; - texture.bindCount += 1; - var unit = texture.unit; + var texture = this + texture.bindCount += 1 + var unit = texture.unit if (unit < 0) { for (var i = 0; i < numTexUnits; ++i) { - var other = textureUnits[i]; + var other = textureUnits[i] if (other) { if (other.bindCount > 0) { continue } - other.unit = -1; + other.unit = -1 } - textureUnits[i] = texture; - unit = i; + textureUnits[i] = texture + unit = i break } if (unit >= numTexUnits) { - check$1.raise('insufficient number of texture units'); + check$1.raise('insufficient number of texture units') } if (config.profile && stats.maxTextureUnits < (unit + 1)) { - stats.maxTextureUnits = unit + 1; // +1, since the units are zero-based + stats.maxTextureUnits = unit + 1 // +1, since the units are zero-based } - texture.unit = unit; - gl.activeTexture(GL_TEXTURE0$1 + unit); - gl.bindTexture(texture.target, texture.texture); + texture.unit = unit + gl.activeTexture(GL_TEXTURE0$1 + unit) + gl.bindTexture(texture.target, texture.texture) } return unit }, unbind: function () { - this.bindCount -= 1; + this.bindCount -= 1 }, decRef: function () { if (--this.refCount <= 0) { - destroy(this); + destroy(this) } } - }); + }) function createTexture2D (a, b) { - var texture = new REGLTexture(GL_TEXTURE_2D$1); - textureSet[texture.id] = texture; - stats.textureCount++; + var texture = new REGLTexture(GL_TEXTURE_2D$1) + textureSet[texture.id] = texture + stats.textureCount++ function reglTexture2D (a, b) { - var texInfo = texture.texInfo; - TexInfo.call(texInfo); - var mipData = allocMipMap(); + var texInfo = texture.texInfo + TexInfo.call(texInfo) + var mipData = allocMipMap() if (typeof a === 'number') { if (typeof b === 'number') { - parseMipMapFromShape(mipData, a | 0, b | 0); + parseMipMapFromShape(mipData, a | 0, b | 0) } else { - parseMipMapFromShape(mipData, a | 0, a | 0); + parseMipMapFromShape(mipData, a | 0, a | 0) } } else if (a) { - check$1.type(a, 'object', 'invalid arguments to regl.texture'); - parseTexInfo(texInfo, a); - parseMipMapFromObject(mipData, a); + check$1.type(a, 'object', 'invalid arguments to regl.texture') + parseTexInfo(texInfo, a) + parseMipMapFromObject(mipData, a) } else { // empty textures get assigned a default shape of 1x1 - parseMipMapFromShape(mipData, 1, 1); + parseMipMapFromShape(mipData, 1, 1) } if (texInfo.genMipmaps) { - mipData.mipmask = (mipData.width << 1) - 1; + mipData.mipmask = (mipData.width << 1) - 1 } - texture.mipmask = mipData.mipmask; + texture.mipmask = mipData.mipmask - copyFlags(texture, mipData); + copyFlags(texture, mipData) - check$1.texture2D(texInfo, mipData, limits); - texture.internalformat = mipData.internalformat; + check$1.texture2D(texInfo, mipData, limits) + texture.internalformat = mipData.internalformat - reglTexture2D.width = mipData.width; - reglTexture2D.height = mipData.height; + reglTexture2D.width = mipData.width + reglTexture2D.height = mipData.height - tempBind(texture); - setMipMap(mipData, GL_TEXTURE_2D$1); - setTexInfo(texInfo, GL_TEXTURE_2D$1); - tempRestore(); + tempBind(texture) + setMipMap(mipData, GL_TEXTURE_2D$1) + setTexInfo(texInfo, GL_TEXTURE_2D$1) + tempRestore() - freeMipMap(mipData); + freeMipMap(mipData) if (config.profile) { texture.stats.size = getTextureSize( @@ -3436,82 +3468,77 @@ function createTextureSet ( mipData.width, mipData.height, texInfo.genMipmaps, - false); + false) } - reglTexture2D.format = textureFormatsInvert[texture.internalformat]; - reglTexture2D.type = textureTypesInvert[texture.type]; + reglTexture2D.format = textureFormatsInvert[texture.internalformat] + reglTexture2D.type = textureTypesInvert[texture.type] - reglTexture2D.mag = magFiltersInvert[texInfo.magFilter]; - reglTexture2D.min = minFiltersInvert[texInfo.minFilter]; + reglTexture2D.mag = magFiltersInvert[texInfo.magFilter] + reglTexture2D.min = minFiltersInvert[texInfo.minFilter] - reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS]; - reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT]; + reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS] + reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT] return reglTexture2D } function subimage (image, x_, y_, level_) { - check$1(!!image, 'must specify image data'); + check$1(!!image, 'must specify image data') - var x = x_ | 0; - var y = y_ | 0; - var level = level_ | 0; + var x = x_ | 0 + var y = y_ | 0 + var level = level_ | 0 - var imageData = allocImage(); - copyFlags(imageData, texture); - imageData.width = 0; - imageData.height = 0; - parseImage(imageData, image); - imageData.width = imageData.width || ((texture.width >> level) - x); - imageData.height = imageData.height || ((texture.height >> level) - y); + var imageData = allocImage() + copyFlags(imageData, texture) + imageData.width = 0 + imageData.height = 0 + parseImage(imageData, image) + imageData.width = imageData.width || ((texture.width >> level) - x) + imageData.height = imageData.height || ((texture.height >> level) - y) check$1( texture.type === imageData.type && texture.format === imageData.format && texture.internalformat === imageData.internalformat, - 'incompatible format for texture.subimage'); + 'incompatible format for texture.subimage') check$1( x >= 0 && y >= 0 && x + imageData.width <= texture.width && y + imageData.height <= texture.height, - 'texture.subimage write out of bounds'); + 'texture.subimage write out of bounds') check$1( texture.mipmask & (1 << level), - 'missing mipmap data'); + 'missing mipmap data') check$1( imageData.data || imageData.element || imageData.needsCopy, - 'missing image data'); + 'missing image data') - tempBind(texture); - setSubImage(imageData, GL_TEXTURE_2D$1, x, y, level); - tempRestore(); + tempBind(texture) + setSubImage(imageData, GL_TEXTURE_2D$1, x, y, level) + tempRestore() - freeImage(imageData); + freeImage(imageData) return reglTexture2D } function resize (w_, h_) { - var w = w_ | 0; - var h = (h_ | 0) || w; + var w = w_ | 0 + var h = (h_ | 0) || w if (w === texture.width && h === texture.height) { return reglTexture2D } - reglTexture2D.width = texture.width = w; - reglTexture2D.height = texture.height = h; + reglTexture2D.width = texture.width = w + reglTexture2D.height = texture.height = h - tempBind(texture); - - var data; - var channels = texture.channels; - var type = texture.type; + tempBind(texture) for (var i = 0; texture.mipmask >> i; ++i) { - var _w = w >> i; - var _h = h >> i; + var _w = w >> i + var _h = h >> i if (!_w || !_h) break - data = pool.zero.allocType(type, _w * _h * channels); gl.texImage2D( GL_TEXTURE_2D$1, i, @@ -3521,10 +3548,9 @@ function createTextureSet ( 0, texture.format, texture.type, - data); - if (data) pool.zero.freeType(data); + null) } - tempRestore(); + tempRestore() // also, recompute the texture size. if (config.profile) { @@ -3534,103 +3560,104 @@ function createTextureSet ( w, h, false, - false); + false) } return reglTexture2D } - reglTexture2D(a, b); + reglTexture2D(a, b) - reglTexture2D.subimage = subimage; - reglTexture2D.resize = resize; - reglTexture2D._reglType = 'texture2d'; - reglTexture2D._texture = texture; + reglTexture2D.subimage = subimage + reglTexture2D.resize = resize + reglTexture2D._reglType = 'texture2d' + reglTexture2D._texture = texture if (config.profile) { - reglTexture2D.stats = texture.stats; + reglTexture2D.stats = texture.stats } reglTexture2D.destroy = function () { - texture.decRef(); - }; + texture.decRef() + } return reglTexture2D } function createTextureCube (a0, a1, a2, a3, a4, a5) { - var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP$1); - textureSet[texture.id] = texture; - stats.cubeCount++; + var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP$1) + textureSet[texture.id] = texture + stats.cubeCount++ - var faces = new Array(6); + var faces = new Array(6) function reglTextureCube (a0, a1, a2, a3, a4, a5) { - var i; - var texInfo = texture.texInfo; - TexInfo.call(texInfo); + var i + var texInfo = texture.texInfo + TexInfo.call(texInfo) for (i = 0; i < 6; ++i) { - faces[i] = allocMipMap(); + faces[i] = allocMipMap() } if (typeof a0 === 'number' || !a0) { - var s = (a0 | 0) || 1; + var s = (a0 | 0) || 1 for (i = 0; i < 6; ++i) { - parseMipMapFromShape(faces[i], s, s); + parseMipMapFromShape(faces[i], s, s) } } else if (typeof a0 === 'object') { if (a1) { - parseMipMapFromObject(faces[0], a0); - parseMipMapFromObject(faces[1], a1); - parseMipMapFromObject(faces[2], a2); - parseMipMapFromObject(faces[3], a3); - parseMipMapFromObject(faces[4], a4); - parseMipMapFromObject(faces[5], a5); + parseMipMapFromObject(faces[0], a0) + parseMipMapFromObject(faces[1], a1) + parseMipMapFromObject(faces[2], a2) + parseMipMapFromObject(faces[3], a3) + parseMipMapFromObject(faces[4], a4) + parseMipMapFromObject(faces[5], a5) } else { - parseTexInfo(texInfo, a0); - parseFlags(texture, a0); + parseTexInfo(texInfo, a0) + parseFlags(texture, a0) if ('faces' in a0) { - var face_input = a0.faces; - check$1(Array.isArray(face_input) && face_input.length === 6, - 'cube faces must be a length 6 array'); + var faceInput = a0.faces + check$1(Array.isArray(faceInput) && faceInput.length === 6, + 'cube faces must be a length 6 array') for (i = 0; i < 6; ++i) { - check$1(typeof face_input[i] === 'object' && !!face_input[i], - 'invalid input for cube map face'); - copyFlags(faces[i], texture); - parseMipMapFromObject(faces[i], face_input[i]); + check$1(typeof faceInput[i] === 'object' && !!faceInput[i], + 'invalid input for cube map face') + copyFlags(faces[i], texture) + parseMipMapFromObject(faces[i], faceInput[i]) } } else { for (i = 0; i < 6; ++i) { - parseMipMapFromObject(faces[i], a0); + parseMipMapFromObject(faces[i], a0) } } } } else { - check$1.raise('invalid arguments to cube map'); + check$1.raise('invalid arguments to cube map') } - copyFlags(texture, faces[0]); - - if (!limits.npotTextureCube) { - check$1(isPow2$1(texture.width) && isPow2$1(texture.height), 'your browser does not support non power or two texture dimensions'); - } + copyFlags(texture, faces[0]) + check$1.optional(function () { + if (!limits.npotTextureCube) { + check$1(isPow2$1(texture.width) && isPow2$1(texture.height), 'your browser does not support non power or two texture dimensions') + } + }) if (texInfo.genMipmaps) { - texture.mipmask = (faces[0].width << 1) - 1; + texture.mipmask = (faces[0].width << 1) - 1 } else { - texture.mipmask = faces[0].mipmask; + texture.mipmask = faces[0].mipmask } - check$1.textureCube(texture, texInfo, faces, limits); - texture.internalformat = faces[0].internalformat; + check$1.textureCube(texture, texInfo, faces, limits) + texture.internalformat = faces[0].internalformat - reglTextureCube.width = faces[0].width; - reglTextureCube.height = faces[0].height; + reglTextureCube.width = faces[0].width + reglTextureCube.height = faces[0].height - tempBind(texture); + tempBind(texture) for (i = 0; i < 6; ++i) { - setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i); + setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i) } - setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP$1); - tempRestore(); + setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP$1) + tempRestore() if (config.profile) { texture.stats.size = getTextureSize( @@ -3639,78 +3666,78 @@ function createTextureSet ( reglTextureCube.width, reglTextureCube.height, texInfo.genMipmaps, - true); + true) } - reglTextureCube.format = textureFormatsInvert[texture.internalformat]; - reglTextureCube.type = textureTypesInvert[texture.type]; + reglTextureCube.format = textureFormatsInvert[texture.internalformat] + reglTextureCube.type = textureTypesInvert[texture.type] - reglTextureCube.mag = magFiltersInvert[texInfo.magFilter]; - reglTextureCube.min = minFiltersInvert[texInfo.minFilter]; + reglTextureCube.mag = magFiltersInvert[texInfo.magFilter] + reglTextureCube.min = minFiltersInvert[texInfo.minFilter] - reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS]; - reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT]; + reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS] + reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT] for (i = 0; i < 6; ++i) { - freeMipMap(faces[i]); + freeMipMap(faces[i]) } return reglTextureCube } function subimage (face, image, x_, y_, level_) { - check$1(!!image, 'must specify image data'); + check$1(!!image, 'must specify image data') check$1(typeof face === 'number' && face === (face | 0) && - face >= 0 && face < 6, 'invalid face'); + face >= 0 && face < 6, 'invalid face') - var x = x_ | 0; - var y = y_ | 0; - var level = level_ | 0; + var x = x_ | 0 + var y = y_ | 0 + var level = level_ | 0 - var imageData = allocImage(); - copyFlags(imageData, texture); - imageData.width = 0; - imageData.height = 0; - parseImage(imageData, image); - imageData.width = imageData.width || ((texture.width >> level) - x); - imageData.height = imageData.height || ((texture.height >> level) - y); + var imageData = allocImage() + copyFlags(imageData, texture) + imageData.width = 0 + imageData.height = 0 + parseImage(imageData, image) + imageData.width = imageData.width || ((texture.width >> level) - x) + imageData.height = imageData.height || ((texture.height >> level) - y) check$1( texture.type === imageData.type && texture.format === imageData.format && texture.internalformat === imageData.internalformat, - 'incompatible format for texture.subimage'); + 'incompatible format for texture.subimage') check$1( x >= 0 && y >= 0 && x + imageData.width <= texture.width && y + imageData.height <= texture.height, - 'texture.subimage write out of bounds'); + 'texture.subimage write out of bounds') check$1( texture.mipmask & (1 << level), - 'missing mipmap data'); + 'missing mipmap data') check$1( imageData.data || imageData.element || imageData.needsCopy, - 'missing image data'); + 'missing image data') - tempBind(texture); - setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + face, x, y, level); - tempRestore(); + tempBind(texture) + setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + face, x, y, level) + tempRestore() - freeImage(imageData); + freeImage(imageData) return reglTextureCube } function resize (radius_) { - var radius = radius_ | 0; + var radius = radius_ | 0 if (radius === texture.width) { return } - reglTextureCube.width = texture.width = radius; - reglTextureCube.height = texture.height = radius; + reglTextureCube.width = texture.width = radius + reglTextureCube.height = texture.height = radius - tempBind(texture); + tempBind(texture) for (var i = 0; i < 6; ++i) { for (var j = 0; texture.mipmask >> j; ++j) { gl.texImage2D( @@ -3722,10 +3749,10 @@ function createTextureSet ( 0, texture.format, texture.type, - null); + null) } } - tempRestore(); + tempRestore() if (config.profile) { texture.stats.size = getTextureSize( @@ -3734,24 +3761,24 @@ function createTextureSet ( reglTextureCube.width, reglTextureCube.height, false, - true); + true) } return reglTextureCube } - reglTextureCube(a0, a1, a2, a3, a4, a5); + reglTextureCube(a0, a1, a2, a3, a4, a5) - reglTextureCube.subimage = subimage; - reglTextureCube.resize = resize; - reglTextureCube._reglType = 'textureCube'; - reglTextureCube._texture = texture; + reglTextureCube.subimage = subimage + reglTextureCube.resize = resize + reglTextureCube._reglType = 'textureCube' + reglTextureCube._texture = texture if (config.profile) { - reglTextureCube.stats = texture.stats; + reglTextureCube.stats = texture.stats } reglTextureCube.destroy = function () { - texture.decRef(); - }; + texture.decRef() + } return reglTextureCube } @@ -3759,39 +3786,39 @@ function createTextureSet ( // Called when regl is destroyed function destroyTextures () { for (var i = 0; i < numTexUnits; ++i) { - gl.activeTexture(GL_TEXTURE0$1 + i); - gl.bindTexture(GL_TEXTURE_2D$1, null); - textureUnits[i] = null; + gl.activeTexture(GL_TEXTURE0$1 + i) + gl.bindTexture(GL_TEXTURE_2D$1, null) + textureUnits[i] = null } - values(textureSet).forEach(destroy); + values(textureSet).forEach(destroy) - stats.cubeCount = 0; - stats.textureCount = 0; + stats.cubeCount = 0 + stats.textureCount = 0 } if (config.profile) { stats.getTotalTextureSize = function () { - var total = 0; + var total = 0 Object.keys(textureSet).forEach(function (key) { - total += textureSet[key].stats.size; - }); + total += textureSet[key].stats.size + }) return total - }; + } } function restoreTextures () { for (var i = 0; i < numTexUnits; ++i) { - var tex = textureUnits[i]; + var tex = textureUnits[i] if (tex) { - tex.bindCount = 0; - tex.unit = -1; - textureUnits[i] = null; + tex.bindCount = 0 + tex.unit = -1 + textureUnits[i] = null } } values(textureSet).forEach(function (texture) { - texture.texture = gl.createTexture(); - gl.bindTexture(texture.target, texture.texture); + texture.texture = gl.createTexture() + gl.bindTexture(texture.target, texture.texture) for (var i = 0; i < 32; ++i) { if ((texture.mipmask & (1 << i)) === 0) { continue @@ -3805,7 +3832,7 @@ function createTextureSet ( 0, texture.internalformat, texture.type, - null); + null) } else { for (var j = 0; j < 6; ++j) { gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + j, @@ -3816,12 +3843,26 @@ function createTextureSet ( 0, texture.internalformat, texture.type, - null); + null) } } } - setTexInfo(texture.texInfo, texture.target); - }); + setTexInfo(texture.texInfo, texture.target) + }) + } + + function refreshTextures () { + for (var i = 0; i < numTexUnits; ++i) { + var tex = textureUnits[i] + if (tex) { + tex.bindCount = 0 + tex.unit = -1 + textureUnits[i] = null + } + gl.activeTexture(GL_TEXTURE0$1 + i) + gl.bindTexture(GL_TEXTURE_2D$1, null) + gl.bindTexture(GL_TEXTURE_CUBE_MAP$1, null) + } } return { @@ -3831,40 +3872,41 @@ function createTextureSet ( getTexture: function (wrapper) { return null }, - restore: restoreTextures + restore: restoreTextures, + refresh: refreshTextures } } -var GL_RENDERBUFFER = 0x8D41; +var GL_RENDERBUFFER = 0x8D41 -var GL_RGBA4$1 = 0x8056; -var GL_RGB5_A1$1 = 0x8057; -var GL_RGB565$1 = 0x8D62; -var GL_DEPTH_COMPONENT16 = 0x81A5; -var GL_STENCIL_INDEX8 = 0x8D48; -var GL_DEPTH_STENCIL$1 = 0x84F9; +var GL_RGBA4$1 = 0x8056 +var GL_RGB5_A1$1 = 0x8057 +var GL_RGB565$1 = 0x8D62 +var GL_DEPTH_COMPONENT16 = 0x81A5 +var GL_STENCIL_INDEX8 = 0x8D48 +var GL_DEPTH_STENCIL$1 = 0x84F9 -var GL_SRGB8_ALPHA8_EXT = 0x8C43; +var GL_SRGB8_ALPHA8_EXT = 0x8C43 -var GL_RGBA32F_EXT = 0x8814; +var GL_RGBA32F_EXT = 0x8814 -var GL_RGBA16F_EXT = 0x881A; -var GL_RGB16F_EXT = 0x881B; +var GL_RGBA16F_EXT = 0x881A +var GL_RGB16F_EXT = 0x881B -var FORMAT_SIZES = []; +var FORMAT_SIZES = [] -FORMAT_SIZES[GL_RGBA4$1] = 2; -FORMAT_SIZES[GL_RGB5_A1$1] = 2; -FORMAT_SIZES[GL_RGB565$1] = 2; +FORMAT_SIZES[GL_RGBA4$1] = 2 +FORMAT_SIZES[GL_RGB5_A1$1] = 2 +FORMAT_SIZES[GL_RGB565$1] = 2 -FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2; -FORMAT_SIZES[GL_STENCIL_INDEX8] = 1; -FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4; +FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2 +FORMAT_SIZES[GL_STENCIL_INDEX8] = 1 +FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4 -FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4; -FORMAT_SIZES[GL_RGBA32F_EXT] = 16; -FORMAT_SIZES[GL_RGBA16F_EXT] = 8; -FORMAT_SIZES[GL_RGB16F_EXT] = 6; +FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4 +FORMAT_SIZES[GL_RGBA32F_EXT] = 16 +FORMAT_SIZES[GL_RGBA16F_EXT] = 8 +FORMAT_SIZES[GL_RGB16F_EXT] = 6 function getRenderbufferSize (format, width, height) { return FORMAT_SIZES[format] * width * height @@ -3878,114 +3920,114 @@ var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { 'depth': GL_DEPTH_COMPONENT16, 'stencil': GL_STENCIL_INDEX8, 'depth stencil': GL_DEPTH_STENCIL$1 - }; + } if (extensions.ext_srgb) { - formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT; + formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT } if (extensions.ext_color_buffer_half_float) { - formatTypes['rgba16f'] = GL_RGBA16F_EXT; - formatTypes['rgb16f'] = GL_RGB16F_EXT; + formatTypes['rgba16f'] = GL_RGBA16F_EXT + formatTypes['rgb16f'] = GL_RGB16F_EXT } if (extensions.webgl_color_buffer_float) { - formatTypes['rgba32f'] = GL_RGBA32F_EXT; + formatTypes['rgba32f'] = GL_RGBA32F_EXT } - var formatTypesInvert = []; + var formatTypesInvert = [] Object.keys(formatTypes).forEach(function (key) { - var val = formatTypes[key]; - formatTypesInvert[val] = key; - }); + var val = formatTypes[key] + formatTypesInvert[val] = key + }) - var renderbufferCount = 0; - var renderbufferSet = {}; + var renderbufferCount = 0 + var renderbufferSet = {} function REGLRenderbuffer (renderbuffer) { - this.id = renderbufferCount++; - this.refCount = 1; + this.id = renderbufferCount++ + this.refCount = 1 - this.renderbuffer = renderbuffer; + this.renderbuffer = renderbuffer - this.format = GL_RGBA4$1; - this.width = 0; - this.height = 0; + this.format = GL_RGBA4$1 + this.width = 0 + this.height = 0 if (config.profile) { - this.stats = {size: 0}; + this.stats = { size: 0 } } } REGLRenderbuffer.prototype.decRef = function () { if (--this.refCount <= 0) { - destroy(this); + destroy(this) } - }; + } function destroy (rb) { - var handle = rb.renderbuffer; - check$1(handle, 'must not double destroy renderbuffer'); - gl.bindRenderbuffer(GL_RENDERBUFFER, null); - gl.deleteRenderbuffer(handle); - rb.renderbuffer = null; - rb.refCount = 0; - delete renderbufferSet[rb.id]; - stats.renderbufferCount--; + var handle = rb.renderbuffer + check$1(handle, 'must not double destroy renderbuffer') + gl.bindRenderbuffer(GL_RENDERBUFFER, null) + gl.deleteRenderbuffer(handle) + rb.renderbuffer = null + rb.refCount = 0 + delete renderbufferSet[rb.id] + stats.renderbufferCount-- } function createRenderbuffer (a, b) { - var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer()); - renderbufferSet[renderbuffer.id] = renderbuffer; - stats.renderbufferCount++; + var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer()) + renderbufferSet[renderbuffer.id] = renderbuffer + stats.renderbufferCount++ function reglRenderbuffer (a, b) { - var w = 0; - var h = 0; - var format = GL_RGBA4$1; + var w = 0 + var h = 0 + var format = GL_RGBA4$1 if (typeof a === 'object' && a) { - var options = a; + var options = a if ('shape' in options) { - var shape = options.shape; + var shape = options.shape check$1(Array.isArray(shape) && shape.length >= 2, - 'invalid renderbuffer shape'); - w = shape[0] | 0; - h = shape[1] | 0; + 'invalid renderbuffer shape') + w = shape[0] | 0 + h = shape[1] | 0 } else { if ('radius' in options) { - w = h = options.radius | 0; + w = h = options.radius | 0 } if ('width' in options) { - w = options.width | 0; + w = options.width | 0 } if ('height' in options) { - h = options.height | 0; + h = options.height | 0 } } if ('format' in options) { check$1.parameter(options.format, formatTypes, - 'invalid renderbuffer format'); - format = formatTypes[options.format]; + 'invalid renderbuffer format') + format = formatTypes[options.format] } } else if (typeof a === 'number') { - w = a | 0; + w = a | 0 if (typeof b === 'number') { - h = b | 0; + h = b | 0 } else { - h = w; + h = w } } else if (!a) { - w = h = 1; + w = h = 1 } else { - check$1.raise('invalid arguments to renderbuffer constructor'); + check$1.raise('invalid arguments to renderbuffer constructor') } // check shape check$1( w > 0 && h > 0 && w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, - 'invalid renderbuffer size'); + 'invalid renderbuffer size') if (w === renderbuffer.width && h === renderbuffer.height && @@ -3993,28 +4035,28 @@ var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { return } - reglRenderbuffer.width = renderbuffer.width = w; - reglRenderbuffer.height = renderbuffer.height = h; - renderbuffer.format = format; + reglRenderbuffer.width = renderbuffer.width = w + reglRenderbuffer.height = renderbuffer.height = h + renderbuffer.format = format - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer); - gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h); + gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) + gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h) check$1( gl.getError() === 0, - 'invalid render buffer format'); + 'invalid render buffer format') if (config.profile) { - renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height); + renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height) } - reglRenderbuffer.format = formatTypesInvert[renderbuffer.format]; + reglRenderbuffer.format = formatTypesInvert[renderbuffer.format] return reglRenderbuffer } function resize (w_, h_) { - var w = w_ | 0; - var h = (h_ | 0) || w; + var w = w_ | 0 + var h = (h_ | 0) || w if (w === renderbuffer.width && h === renderbuffer.height) { return reglRenderbuffer @@ -4024,128 +4066,128 @@ var wrapRenderbuffers = function (gl, extensions, limits, stats, config) { check$1( w > 0 && h > 0 && w <= limits.maxRenderbufferSize && h <= limits.maxRenderbufferSize, - 'invalid renderbuffer size'); + 'invalid renderbuffer size') - reglRenderbuffer.width = renderbuffer.width = w; - reglRenderbuffer.height = renderbuffer.height = h; + reglRenderbuffer.width = renderbuffer.width = w + reglRenderbuffer.height = renderbuffer.height = h - gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer); - gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h); + gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer) + gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h) check$1( gl.getError() === 0, - 'invalid render buffer format'); + 'invalid render buffer format') // also, recompute size. if (config.profile) { renderbuffer.stats.size = getRenderbufferSize( - renderbuffer.format, renderbuffer.width, renderbuffer.height); + renderbuffer.format, renderbuffer.width, renderbuffer.height) } return reglRenderbuffer } - reglRenderbuffer(a, b); + reglRenderbuffer(a, b) - reglRenderbuffer.resize = resize; - reglRenderbuffer._reglType = 'renderbuffer'; - reglRenderbuffer._renderbuffer = renderbuffer; + reglRenderbuffer.resize = resize + reglRenderbuffer._reglType = 'renderbuffer' + reglRenderbuffer._renderbuffer = renderbuffer if (config.profile) { - reglRenderbuffer.stats = renderbuffer.stats; + reglRenderbuffer.stats = renderbuffer.stats } reglRenderbuffer.destroy = function () { - renderbuffer.decRef(); - }; + renderbuffer.decRef() + } return reglRenderbuffer } if (config.profile) { stats.getTotalRenderbufferSize = function () { - var total = 0; + var total = 0 Object.keys(renderbufferSet).forEach(function (key) { - total += renderbufferSet[key].stats.size; - }); + total += renderbufferSet[key].stats.size + }) return total - }; + } } function restoreRenderbuffers () { values(renderbufferSet).forEach(function (rb) { - rb.renderbuffer = gl.createRenderbuffer(); - gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer); - gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height); - }); - gl.bindRenderbuffer(GL_RENDERBUFFER, null); + rb.renderbuffer = gl.createRenderbuffer() + gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer) + gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height) + }) + gl.bindRenderbuffer(GL_RENDERBUFFER, null) } return { create: createRenderbuffer, clear: function () { - values(renderbufferSet).forEach(destroy); + values(renderbufferSet).forEach(destroy) }, restore: restoreRenderbuffers } -}; +} // We store these constants so that the minifier can inline them -var GL_FRAMEBUFFER$1 = 0x8D40; -var GL_RENDERBUFFER$1 = 0x8D41; +var GL_FRAMEBUFFER$1 = 0x8D40 +var GL_RENDERBUFFER$1 = 0x8D41 -var GL_TEXTURE_2D$2 = 0x0DE1; -var GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 = 0x8515; +var GL_TEXTURE_2D$2 = 0x0DE1 +var GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 = 0x8515 -var GL_COLOR_ATTACHMENT0$1 = 0x8CE0; -var GL_DEPTH_ATTACHMENT = 0x8D00; -var GL_STENCIL_ATTACHMENT = 0x8D20; -var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A; +var GL_COLOR_ATTACHMENT0$1 = 0x8CE0 +var GL_DEPTH_ATTACHMENT = 0x8D00 +var GL_STENCIL_ATTACHMENT = 0x8D20 +var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A -var GL_FRAMEBUFFER_COMPLETE$1 = 0x8CD5; -var GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6; -var GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7; -var GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9; -var GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD; +var GL_FRAMEBUFFER_COMPLETE$1 = 0x8CD5 +var GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = 0x8CD6 +var GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7 +var GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS = 0x8CD9 +var GL_FRAMEBUFFER_UNSUPPORTED = 0x8CDD -var GL_HALF_FLOAT_OES$2 = 0x8D61; -var GL_UNSIGNED_BYTE$6 = 0x1401; -var GL_FLOAT$5 = 0x1406; +var GL_HALF_FLOAT_OES$2 = 0x8D61 +var GL_UNSIGNED_BYTE$6 = 0x1401 +var GL_FLOAT$5 = 0x1406 -var GL_RGB$1 = 0x1907; -var GL_RGBA$2 = 0x1908; +var GL_RGB$1 = 0x1907 +var GL_RGBA$2 = 0x1908 -var GL_DEPTH_COMPONENT$1 = 0x1902; +var GL_DEPTH_COMPONENT$1 = 0x1902 var colorTextureFormatEnums = [ GL_RGB$1, GL_RGBA$2 -]; +] // for every texture format, store // the number of channels -var textureFormatChannels = []; -textureFormatChannels[GL_RGBA$2] = 4; -textureFormatChannels[GL_RGB$1] = 3; +var textureFormatChannels = [] +textureFormatChannels[GL_RGBA$2] = 4 +textureFormatChannels[GL_RGB$1] = 3 // for every texture type, store // the size in bytes. -var textureTypeSizes = []; -textureTypeSizes[GL_UNSIGNED_BYTE$6] = 1; -textureTypeSizes[GL_FLOAT$5] = 4; -textureTypeSizes[GL_HALF_FLOAT_OES$2] = 2; +var textureTypeSizes = [] +textureTypeSizes[GL_UNSIGNED_BYTE$6] = 1 +textureTypeSizes[GL_FLOAT$5] = 4 +textureTypeSizes[GL_HALF_FLOAT_OES$2] = 2 -var GL_RGBA4$2 = 0x8056; -var GL_RGB5_A1$2 = 0x8057; -var GL_RGB565$2 = 0x8D62; -var GL_DEPTH_COMPONENT16$1 = 0x81A5; -var GL_STENCIL_INDEX8$1 = 0x8D48; -var GL_DEPTH_STENCIL$2 = 0x84F9; +var GL_RGBA4$2 = 0x8056 +var GL_RGB5_A1$2 = 0x8057 +var GL_RGB565$2 = 0x8D62 +var GL_DEPTH_COMPONENT16$1 = 0x81A5 +var GL_STENCIL_INDEX8$1 = 0x8D48 +var GL_DEPTH_STENCIL$2 = 0x84F9 -var GL_SRGB8_ALPHA8_EXT$1 = 0x8C43; +var GL_SRGB8_ALPHA8_EXT$1 = 0x8C43 -var GL_RGBA32F_EXT$1 = 0x8814; +var GL_RGBA32F_EXT$1 = 0x8814 -var GL_RGBA16F_EXT$1 = 0x881A; -var GL_RGB16F_EXT$1 = 0x881B; +var GL_RGBA16F_EXT$1 = 0x881A +var GL_RGB16F_EXT$1 = 0x881B var colorRenderbufferFormatEnums = [ GL_RGBA4$2, @@ -4155,14 +4197,14 @@ var colorRenderbufferFormatEnums = [ GL_RGBA16F_EXT$1, GL_RGB16F_EXT$1, GL_RGBA32F_EXT$1 -]; +] -var statusCode = {}; -statusCode[GL_FRAMEBUFFER_COMPLETE$1] = 'complete'; -statusCode[GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT] = 'incomplete attachment'; -statusCode[GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS] = 'incomplete dimensions'; -statusCode[GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT] = 'incomplete, missing attachment'; -statusCode[GL_FRAMEBUFFER_UNSUPPORTED] = 'unsupported'; +var statusCode = {} +statusCode[GL_FRAMEBUFFER_COMPLETE$1] = 'complete' +statusCode[GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT] = 'incomplete attachment' +statusCode[GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS] = 'incomplete dimensions' +statusCode[GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT] = 'incomplete, missing attachment' +statusCode[GL_FRAMEBUFFER_UNSUPPORTED] = 'unsupported' function wrapFBOState ( gl, @@ -4176,56 +4218,56 @@ function wrapFBOState ( next: null, dirty: false, setFBO: null - }; + } - var colorTextureFormats = ['rgba']; - var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1']; + var colorTextureFormats = ['rgba'] + var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1'] if (extensions.ext_srgb) { - colorRenderbufferFormats.push('srgba'); + colorRenderbufferFormats.push('srgba') } if (extensions.ext_color_buffer_half_float) { - colorRenderbufferFormats.push('rgba16f', 'rgb16f'); + colorRenderbufferFormats.push('rgba16f', 'rgb16f') } if (extensions.webgl_color_buffer_float) { - colorRenderbufferFormats.push('rgba32f'); + colorRenderbufferFormats.push('rgba32f') } - var colorTypes = ['uint8']; + var colorTypes = ['uint8'] if (extensions.oes_texture_half_float) { - colorTypes.push('half float', 'float16'); + colorTypes.push('half float', 'float16') } if (extensions.oes_texture_float) { - colorTypes.push('float', 'float32'); + colorTypes.push('float', 'float32') } function FramebufferAttachment (target, texture, renderbuffer) { - this.target = target; - this.texture = texture; - this.renderbuffer = renderbuffer; + this.target = target + this.texture = texture + this.renderbuffer = renderbuffer - var w = 0; - var h = 0; + var w = 0 + var h = 0 if (texture) { - w = texture.width; - h = texture.height; + w = texture.width + h = texture.height } else if (renderbuffer) { - w = renderbuffer.width; - h = renderbuffer.height; + w = renderbuffer.width + h = renderbuffer.height } - this.width = w; - this.height = h; + this.width = w + this.height = h } function decRef (attachment) { if (attachment) { if (attachment.texture) { - attachment.texture._texture.decRef(); + attachment.texture._texture.decRef() } if (attachment.renderbuffer) { - attachment.renderbuffer._renderbuffer.decRef(); + attachment.renderbuffer._renderbuffer.decRef() } } } @@ -4235,18 +4277,18 @@ function wrapFBOState ( return } if (attachment.texture) { - var texture = attachment.texture._texture; - var tw = Math.max(1, texture.width); - var th = Math.max(1, texture.height); + var texture = attachment.texture._texture + var tw = Math.max(1, texture.width) + var th = Math.max(1, texture.height) check$1(tw === width && th === height, - 'inconsistent width/height for supplied texture'); - texture.refCount += 1; + 'inconsistent width/height for supplied texture') + texture.refCount += 1 } else { - var renderbuffer = attachment.renderbuffer._renderbuffer; + var renderbuffer = attachment.renderbuffer._renderbuffer check$1( renderbuffer.width === width && renderbuffer.height === height, - 'inconsistent width/height for renderbuffer'); - renderbuffer.refCount += 1; + 'inconsistent width/height for renderbuffer') + renderbuffer.refCount += 1 } } @@ -4258,47 +4300,47 @@ function wrapFBOState ( location, attachment.target, attachment.texture._texture.texture, - 0); + 0) } else { gl.framebufferRenderbuffer( GL_FRAMEBUFFER$1, location, GL_RENDERBUFFER$1, - attachment.renderbuffer._renderbuffer.renderbuffer); + attachment.renderbuffer._renderbuffer.renderbuffer) } } } function parseAttachment (attachment) { - var target = GL_TEXTURE_2D$2; - var texture = null; - var renderbuffer = null; + var target = GL_TEXTURE_2D$2 + var texture = null + var renderbuffer = null - var data = attachment; + var data = attachment if (typeof attachment === 'object') { - data = attachment.data; + data = attachment.data if ('target' in attachment) { - target = attachment.target | 0; + target = attachment.target | 0 } } - check$1.type(data, 'function', 'invalid attachment data'); + check$1.type(data, 'function', 'invalid attachment data') - var type = data._reglType; + var type = data._reglType if (type === 'texture2d') { - texture = data; - check$1(target === GL_TEXTURE_2D$2); + texture = data + check$1(target === GL_TEXTURE_2D$2) } else if (type === 'textureCube') { - texture = data; + texture = data check$1( target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 && target < GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + 6, - 'invalid cube map target'); + 'invalid cube map target') } else if (type === 'renderbuffer') { - renderbuffer = data; - target = GL_RENDERBUFFER$1; + renderbuffer = data + target = GL_RENDERBUFFER$1 } else { - check$1.raise('invalid regl object for attachment'); + check$1.raise('invalid regl object for attachment') } return new FramebufferAttachment(target, texture, renderbuffer) @@ -4316,16 +4358,16 @@ function wrapFBOState ( height: height, format: format, type: type - }); - texture._texture.refCount = 0; + }) + texture._texture.refCount = 0 return new FramebufferAttachment(GL_TEXTURE_2D$2, texture, null) } else { var rb = renderbufferState.create({ width: width, height: height, format: format - }); - rb._renderbuffer.refCount = 0; + }) + rb._renderbuffer.refCount = 0 return new FramebufferAttachment(GL_RENDERBUFFER$1, null, rb) } } @@ -4337,55 +4379,55 @@ function wrapFBOState ( function resizeAttachment (attachment, w, h) { if (attachment) { if (attachment.texture) { - attachment.texture.resize(w, h); + attachment.texture.resize(w, h) } else if (attachment.renderbuffer) { - attachment.renderbuffer.resize(w, h); + attachment.renderbuffer.resize(w, h) } - attachment.width = w; - attachment.height = h; + attachment.width = w + attachment.height = h } } - var framebufferCount = 0; - var framebufferSet = {}; + var framebufferCount = 0 + var framebufferSet = {} function REGLFramebuffer () { - this.id = framebufferCount++; - framebufferSet[this.id] = this; + this.id = framebufferCount++ + framebufferSet[this.id] = this - this.framebuffer = gl.createFramebuffer(); - this.width = 0; - this.height = 0; + this.framebuffer = gl.createFramebuffer() + this.width = 0 + this.height = 0 - this.colorAttachments = []; - this.depthAttachment = null; - this.stencilAttachment = null; - this.depthStencilAttachment = null; + this.colorAttachments = [] + this.depthAttachment = null + this.stencilAttachment = null + this.depthStencilAttachment = null } function decFBORefs (framebuffer) { - framebuffer.colorAttachments.forEach(decRef); - decRef(framebuffer.depthAttachment); - decRef(framebuffer.stencilAttachment); - decRef(framebuffer.depthStencilAttachment); + framebuffer.colorAttachments.forEach(decRef) + decRef(framebuffer.depthAttachment) + decRef(framebuffer.stencilAttachment) + decRef(framebuffer.depthStencilAttachment) } function destroy (framebuffer) { - var handle = framebuffer.framebuffer; - check$1(handle, 'must not double destroy framebuffer'); - gl.deleteFramebuffer(handle); - framebuffer.framebuffer = null; - stats.framebufferCount--; - delete framebufferSet[framebuffer.id]; + var handle = framebuffer.framebuffer + check$1(handle, 'must not double destroy framebuffer') + gl.deleteFramebuffer(handle) + framebuffer.framebuffer = null + stats.framebufferCount-- + delete framebufferSet[framebuffer.id] } function updateFramebuffer (framebuffer) { - var i; + var i - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebuffer.framebuffer); - var colorAttachments = framebuffer.colorAttachments; + gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebuffer.framebuffer) + var colorAttachments = framebuffer.colorAttachments for (i = 0; i < colorAttachments.length; ++i) { - attach(GL_COLOR_ATTACHMENT0$1 + i, colorAttachments[i]); + attach(GL_COLOR_ATTACHMENT0$1 + i, colorAttachments[i]) } for (i = colorAttachments.length; i < limits.maxColorAttachments; ++i) { gl.framebufferTexture2D( @@ -4393,7 +4435,7 @@ function wrapFBOState ( GL_COLOR_ATTACHMENT0$1 + i, GL_TEXTURE_2D$2, null, - 0); + 0) } gl.framebufferTexture2D( @@ -4401,90 +4443,90 @@ function wrapFBOState ( GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D$2, null, - 0); + 0) gl.framebufferTexture2D( GL_FRAMEBUFFER$1, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D$2, null, - 0); + 0) gl.framebufferTexture2D( GL_FRAMEBUFFER$1, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D$2, null, - 0); + 0) - attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment); - attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment); - attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment); + attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment) + attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment) + attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment) // Check status code - var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER$1); + var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER$1) if (!gl.isContextLost() && status !== GL_FRAMEBUFFER_COMPLETE$1) { check$1.raise('framebuffer configuration not supported, status = ' + - statusCode[status]); + statusCode[status]) } - gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebufferState.next ? framebufferState.next.framebuffer : null); - framebufferState.cur = framebufferState.next; + gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebufferState.next ? framebufferState.next.framebuffer : null) + framebufferState.cur = framebufferState.next // FIXME: Clear error code here. This is a work around for a bug in // headless-gl - gl.getError(); + gl.getError() } function createFBO (a0, a1) { - var framebuffer = new REGLFramebuffer(); - stats.framebufferCount++; + var framebuffer = new REGLFramebuffer() + stats.framebufferCount++ function reglFramebuffer (a, b) { - var i; + var i check$1(framebufferState.next !== framebuffer, - 'can not update framebuffer which is currently in use'); + 'can not update framebuffer which is currently in use') - var width = 0; - var height = 0; + var width = 0 + var height = 0 - var needsDepth = true; - var needsStencil = true; + var needsDepth = true + var needsStencil = true - var colorBuffer = null; - var colorTexture = true; - var colorFormat = 'rgba'; - var colorType = 'uint8'; - var colorCount = 1; + var colorBuffer = null + var colorTexture = true + var colorFormat = 'rgba' + var colorType = 'uint8' + var colorCount = 1 - var depthBuffer = null; - var stencilBuffer = null; - var depthStencilBuffer = null; - var depthStencilTexture = false; + var depthBuffer = null + var stencilBuffer = null + var depthStencilBuffer = null + var depthStencilTexture = false if (typeof a === 'number') { - width = a | 0; - height = (b | 0) || width; + width = a | 0 + height = (b | 0) || width } else if (!a) { - width = height = 1; + width = height = 1 } else { - check$1.type(a, 'object', 'invalid arguments for framebuffer'); - var options = a; + check$1.type(a, 'object', 'invalid arguments for framebuffer') + var options = a if ('shape' in options) { - var shape = options.shape; + var shape = options.shape check$1(Array.isArray(shape) && shape.length >= 2, - 'invalid shape for framebuffer'); - width = shape[0]; - height = shape[1]; + 'invalid shape for framebuffer') + width = shape[0] + height = shape[1] } else { if ('radius' in options) { - width = height = options.radius; + width = height = options.radius } if ('width' in options) { - width = options.width; + width = options.width } if ('height' in options) { - height = options.height; + height = options.height } } @@ -4492,336 +4534,338 @@ function wrapFBOState ( 'colors' in options) { colorBuffer = options.color || - options.colors; + options.colors if (Array.isArray(colorBuffer)) { check$1( colorBuffer.length === 1 || extensions.webgl_draw_buffers, - 'multiple render targets not supported'); + 'multiple render targets not supported') } } if (!colorBuffer) { if ('colorCount' in options) { - colorCount = options.colorCount | 0; - check$1(colorCount > 0, 'invalid color buffer count'); + colorCount = options.colorCount | 0 + check$1(colorCount > 0, 'invalid color buffer count') } if ('colorTexture' in options) { - colorTexture = !!options.colorTexture; - colorFormat = 'rgba4'; + colorTexture = !!options.colorTexture + colorFormat = 'rgba4' } if ('colorType' in options) { - colorType = options.colorType; + colorType = options.colorType if (!colorTexture) { if (colorType === 'half float' || colorType === 'float16') { check$1(extensions.ext_color_buffer_half_float, - 'you must enable EXT_color_buffer_half_float to use 16-bit render buffers'); - colorFormat = 'rgba16f'; + 'you must enable EXT_color_buffer_half_float to use 16-bit render buffers') + colorFormat = 'rgba16f' } else if (colorType === 'float' || colorType === 'float32') { check$1(extensions.webgl_color_buffer_float, - 'you must enable WEBGL_color_buffer_float in order to use 32-bit floating point renderbuffers'); - colorFormat = 'rgba32f'; + 'you must enable WEBGL_color_buffer_float in order to use 32-bit floating point renderbuffers') + colorFormat = 'rgba32f' } } else { check$1(extensions.oes_texture_float || !(colorType === 'float' || colorType === 'float32'), - 'you must enable OES_texture_float in order to use floating point framebuffer objects'); + 'you must enable OES_texture_float in order to use floating point framebuffer objects') check$1(extensions.oes_texture_half_float || !(colorType === 'half float' || colorType === 'float16'), - 'you must enable OES_texture_half_float in order to use 16-bit floating point framebuffer objects'); + 'you must enable OES_texture_half_float in order to use 16-bit floating point framebuffer objects') } - check$1.oneOf(colorType, colorTypes, 'invalid color type'); + check$1.oneOf(colorType, colorTypes, 'invalid color type') } if ('colorFormat' in options) { - colorFormat = options.colorFormat; + colorFormat = options.colorFormat if (colorTextureFormats.indexOf(colorFormat) >= 0) { - colorTexture = true; + colorTexture = true } else if (colorRenderbufferFormats.indexOf(colorFormat) >= 0) { - colorTexture = false; + colorTexture = false } else { - if (colorTexture) { - check$1.oneOf( - options.colorFormat, colorTextureFormats, - 'invalid color format for texture'); - } else { - check$1.oneOf( - options.colorFormat, colorRenderbufferFormats, - 'invalid color format for renderbuffer'); - } + check$1.optional(function () { + if (colorTexture) { + check$1.oneOf( + options.colorFormat, colorTextureFormats, + 'invalid color format for texture') + } else { + check$1.oneOf( + options.colorFormat, colorRenderbufferFormats, + 'invalid color format for renderbuffer') + } + }) } } } if ('depthTexture' in options || 'depthStencilTexture' in options) { depthStencilTexture = !!(options.depthTexture || - options.depthStencilTexture); + options.depthStencilTexture) check$1(!depthStencilTexture || extensions.webgl_depth_texture, - 'webgl_depth_texture extension not supported'); + 'webgl_depth_texture extension not supported') } if ('depth' in options) { if (typeof options.depth === 'boolean') { - needsDepth = options.depth; + needsDepth = options.depth } else { - depthBuffer = options.depth; - needsStencil = false; + depthBuffer = options.depth + needsStencil = false } } if ('stencil' in options) { if (typeof options.stencil === 'boolean') { - needsStencil = options.stencil; + needsStencil = options.stencil } else { - stencilBuffer = options.stencil; - needsDepth = false; + stencilBuffer = options.stencil + needsDepth = false } } if ('depthStencil' in options) { if (typeof options.depthStencil === 'boolean') { - needsDepth = needsStencil = options.depthStencil; + needsDepth = needsStencil = options.depthStencil } else { - depthStencilBuffer = options.depthStencil; - needsDepth = false; - needsStencil = false; + depthStencilBuffer = options.depthStencil + needsDepth = false + needsStencil = false } } } // parse attachments - var colorAttachments = null; - var depthAttachment = null; - var stencilAttachment = null; - var depthStencilAttachment = null; + var colorAttachments = null + var depthAttachment = null + var stencilAttachment = null + var depthStencilAttachment = null // Set up color attachments if (Array.isArray(colorBuffer)) { - colorAttachments = colorBuffer.map(parseAttachment); + colorAttachments = colorBuffer.map(parseAttachment) } else if (colorBuffer) { - colorAttachments = [parseAttachment(colorBuffer)]; + colorAttachments = [parseAttachment(colorBuffer)] } else { - colorAttachments = new Array(colorCount); + colorAttachments = new Array(colorCount) for (i = 0; i < colorCount; ++i) { colorAttachments[i] = allocAttachment( width, height, colorTexture, colorFormat, - colorType); + colorType) } } check$1(extensions.webgl_draw_buffers || colorAttachments.length <= 1, - 'you must enable the WEBGL_draw_buffers extension in order to use multiple color buffers.'); + 'you must enable the WEBGL_draw_buffers extension in order to use multiple color buffers.') check$1(colorAttachments.length <= limits.maxColorAttachments, - 'too many color attachments, not supported'); + 'too many color attachments, not supported') - width = width || colorAttachments[0].width; - height = height || colorAttachments[0].height; + width = width || colorAttachments[0].width + height = height || colorAttachments[0].height if (depthBuffer) { - depthAttachment = parseAttachment(depthBuffer); + depthAttachment = parseAttachment(depthBuffer) } else if (needsDepth && !needsStencil) { depthAttachment = allocAttachment( width, height, depthStencilTexture, 'depth', - 'uint32'); + 'uint32') } if (stencilBuffer) { - stencilAttachment = parseAttachment(stencilBuffer); + stencilAttachment = parseAttachment(stencilBuffer) } else if (needsStencil && !needsDepth) { stencilAttachment = allocAttachment( width, height, false, 'stencil', - 'uint8'); + 'uint8') } if (depthStencilBuffer) { - depthStencilAttachment = parseAttachment(depthStencilBuffer); + depthStencilAttachment = parseAttachment(depthStencilBuffer) } else if (!depthBuffer && !stencilBuffer && needsStencil && needsDepth) { depthStencilAttachment = allocAttachment( width, height, depthStencilTexture, 'depth stencil', - 'depth stencil'); + 'depth stencil') } check$1( (!!depthBuffer) + (!!stencilBuffer) + (!!depthStencilBuffer) <= 1, - 'invalid framebuffer configuration, can specify exactly one depth/stencil attachment'); + 'invalid framebuffer configuration, can specify exactly one depth/stencil attachment') - var commonColorAttachmentSize = null; + var commonColorAttachmentSize = null for (i = 0; i < colorAttachments.length; ++i) { - incRefAndCheckShape(colorAttachments[i], width, height); + incRefAndCheckShape(colorAttachments[i], width, height) check$1(!colorAttachments[i] || (colorAttachments[i].texture && colorTextureFormatEnums.indexOf(colorAttachments[i].texture._texture.format) >= 0) || (colorAttachments[i].renderbuffer && colorRenderbufferFormatEnums.indexOf(colorAttachments[i].renderbuffer._renderbuffer.format) >= 0), - 'framebuffer color attachment ' + i + ' is invalid'); + 'framebuffer color attachment ' + i + ' is invalid') if (colorAttachments[i] && colorAttachments[i].texture) { var colorAttachmentSize = textureFormatChannels[colorAttachments[i].texture._texture.format] * - textureTypeSizes[colorAttachments[i].texture._texture.type]; + textureTypeSizes[colorAttachments[i].texture._texture.type] if (commonColorAttachmentSize === null) { - commonColorAttachmentSize = colorAttachmentSize; + commonColorAttachmentSize = colorAttachmentSize } else { // We need to make sure that all color attachments have the same number of bitplanes // (that is, the same numer of bits per pixel) // This is required by the GLES2.0 standard. See the beginning of Chapter 4 in that document. check$1(commonColorAttachmentSize === colorAttachmentSize, - 'all color attachments much have the same number of bits per pixel.'); + 'all color attachments much have the same number of bits per pixel.') } } } - incRefAndCheckShape(depthAttachment, width, height); + incRefAndCheckShape(depthAttachment, width, height) check$1(!depthAttachment || (depthAttachment.texture && depthAttachment.texture._texture.format === GL_DEPTH_COMPONENT$1) || (depthAttachment.renderbuffer && depthAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_COMPONENT16$1), - 'invalid depth attachment for framebuffer object'); - incRefAndCheckShape(stencilAttachment, width, height); + 'invalid depth attachment for framebuffer object') + incRefAndCheckShape(stencilAttachment, width, height) check$1(!stencilAttachment || (stencilAttachment.renderbuffer && stencilAttachment.renderbuffer._renderbuffer.format === GL_STENCIL_INDEX8$1), - 'invalid stencil attachment for framebuffer object'); - incRefAndCheckShape(depthStencilAttachment, width, height); + 'invalid stencil attachment for framebuffer object') + incRefAndCheckShape(depthStencilAttachment, width, height) check$1(!depthStencilAttachment || (depthStencilAttachment.texture && depthStencilAttachment.texture._texture.format === GL_DEPTH_STENCIL$2) || (depthStencilAttachment.renderbuffer && depthStencilAttachment.renderbuffer._renderbuffer.format === GL_DEPTH_STENCIL$2), - 'invalid depth-stencil attachment for framebuffer object'); + 'invalid depth-stencil attachment for framebuffer object') // decrement references - decFBORefs(framebuffer); + decFBORefs(framebuffer) - framebuffer.width = width; - framebuffer.height = height; + framebuffer.width = width + framebuffer.height = height - framebuffer.colorAttachments = colorAttachments; - framebuffer.depthAttachment = depthAttachment; - framebuffer.stencilAttachment = stencilAttachment; - framebuffer.depthStencilAttachment = depthStencilAttachment; + framebuffer.colorAttachments = colorAttachments + framebuffer.depthAttachment = depthAttachment + framebuffer.stencilAttachment = stencilAttachment + framebuffer.depthStencilAttachment = depthStencilAttachment - reglFramebuffer.color = colorAttachments.map(unwrapAttachment); - reglFramebuffer.depth = unwrapAttachment(depthAttachment); - reglFramebuffer.stencil = unwrapAttachment(stencilAttachment); - reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment); + reglFramebuffer.color = colorAttachments.map(unwrapAttachment) + reglFramebuffer.depth = unwrapAttachment(depthAttachment) + reglFramebuffer.stencil = unwrapAttachment(stencilAttachment) + reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment) - reglFramebuffer.width = framebuffer.width; - reglFramebuffer.height = framebuffer.height; + reglFramebuffer.width = framebuffer.width + reglFramebuffer.height = framebuffer.height - updateFramebuffer(framebuffer); + updateFramebuffer(framebuffer) return reglFramebuffer } function resize (w_, h_) { check$1(framebufferState.next !== framebuffer, - 'can not resize a framebuffer which is currently in use'); + 'can not resize a framebuffer which is currently in use') - var w = Math.max(w_ | 0, 1); - var h = Math.max((h_ | 0) || w, 1); + var w = Math.max(w_ | 0, 1) + var h = Math.max((h_ | 0) || w, 1) if (w === framebuffer.width && h === framebuffer.height) { return reglFramebuffer } // resize all buffers - var colorAttachments = framebuffer.colorAttachments; + var colorAttachments = framebuffer.colorAttachments for (var i = 0; i < colorAttachments.length; ++i) { - resizeAttachment(colorAttachments[i], w, h); + resizeAttachment(colorAttachments[i], w, h) } - resizeAttachment(framebuffer.depthAttachment, w, h); - resizeAttachment(framebuffer.stencilAttachment, w, h); - resizeAttachment(framebuffer.depthStencilAttachment, w, h); + resizeAttachment(framebuffer.depthAttachment, w, h) + resizeAttachment(framebuffer.stencilAttachment, w, h) + resizeAttachment(framebuffer.depthStencilAttachment, w, h) - framebuffer.width = reglFramebuffer.width = w; - framebuffer.height = reglFramebuffer.height = h; + framebuffer.width = reglFramebuffer.width = w + framebuffer.height = reglFramebuffer.height = h - updateFramebuffer(framebuffer); + updateFramebuffer(framebuffer) return reglFramebuffer } - reglFramebuffer(a0, a1); + reglFramebuffer(a0, a1) return extend(reglFramebuffer, { resize: resize, _reglType: 'framebuffer', _framebuffer: framebuffer, destroy: function () { - destroy(framebuffer); - decFBORefs(framebuffer); + destroy(framebuffer) + decFBORefs(framebuffer) }, use: function (block) { framebufferState.setFBO({ framebuffer: reglFramebuffer - }, block); + }, block) } }) } function createCubeFBO (options) { - var faces = Array(6); + var faces = Array(6) function reglFramebufferCube (a) { - var i; + var i check$1(faces.indexOf(framebufferState.next) < 0, - 'can not update framebuffer which is currently in use'); + 'can not update framebuffer which is currently in use') var params = { color: null - }; + } - var radius = 0; + var radius = 0 - var colorBuffer = null; - var colorFormat = 'rgba'; - var colorType = 'uint8'; - var colorCount = 1; + var colorBuffer = null + var colorFormat = 'rgba' + var colorType = 'uint8' + var colorCount = 1 if (typeof a === 'number') { - radius = a | 0; + radius = a | 0 } else if (!a) { - radius = 1; + radius = 1 } else { - check$1.type(a, 'object', 'invalid arguments for framebuffer'); - var options = a; + check$1.type(a, 'object', 'invalid arguments for framebuffer') + var options = a if ('shape' in options) { - var shape = options.shape; + var shape = options.shape check$1( Array.isArray(shape) && shape.length >= 2, - 'invalid shape for framebuffer'); + 'invalid shape for framebuffer') check$1( shape[0] === shape[1], - 'cube framebuffer must be square'); - radius = shape[0]; + 'cube framebuffer must be square') + radius = shape[0] } else { if ('radius' in options) { - radius = options.radius | 0; + radius = options.radius | 0 } if ('width' in options) { - radius = options.width | 0; + radius = options.width | 0 if ('height' in options) { - check$1(options.height === radius, 'must be square'); + check$1(options.height === radius, 'must be square') } } else if ('height' in options) { - radius = options.height | 0; + radius = options.height | 0 } } @@ -4829,101 +4873,101 @@ function wrapFBOState ( 'colors' in options) { colorBuffer = options.color || - options.colors; + options.colors if (Array.isArray(colorBuffer)) { check$1( colorBuffer.length === 1 || extensions.webgl_draw_buffers, - 'multiple render targets not supported'); + 'multiple render targets not supported') } } if (!colorBuffer) { if ('colorCount' in options) { - colorCount = options.colorCount | 0; - check$1(colorCount > 0, 'invalid color buffer count'); + colorCount = options.colorCount | 0 + check$1(colorCount > 0, 'invalid color buffer count') } if ('colorType' in options) { check$1.oneOf( options.colorType, colorTypes, - 'invalid color type'); - colorType = options.colorType; + 'invalid color type') + colorType = options.colorType } if ('colorFormat' in options) { - colorFormat = options.colorFormat; + colorFormat = options.colorFormat check$1.oneOf( options.colorFormat, colorTextureFormats, - 'invalid color format for texture'); + 'invalid color format for texture') } } if ('depth' in options) { - params.depth = options.depth; + params.depth = options.depth } if ('stencil' in options) { - params.stencil = options.stencil; + params.stencil = options.stencil } if ('depthStencil' in options) { - params.depthStencil = options.depthStencil; + params.depthStencil = options.depthStencil } } - var colorCubes; + var colorCubes if (colorBuffer) { if (Array.isArray(colorBuffer)) { - colorCubes = []; + colorCubes = [] for (i = 0; i < colorBuffer.length; ++i) { - colorCubes[i] = colorBuffer[i]; + colorCubes[i] = colorBuffer[i] } } else { - colorCubes = [ colorBuffer ]; + colorCubes = [ colorBuffer ] } } else { - colorCubes = Array(colorCount); + colorCubes = Array(colorCount) var cubeMapParams = { radius: radius, format: colorFormat, type: colorType - }; + } for (i = 0; i < colorCount; ++i) { - colorCubes[i] = textureState.createCube(cubeMapParams); + colorCubes[i] = textureState.createCube(cubeMapParams) } } // Check color cubes - params.color = Array(colorCubes.length); + params.color = Array(colorCubes.length) for (i = 0; i < colorCubes.length; ++i) { - var cube = colorCubes[i]; + var cube = colorCubes[i] check$1( typeof cube === 'function' && cube._reglType === 'textureCube', - 'invalid cube map'); - radius = radius || cube.width; + 'invalid cube map') + radius = radius || cube.width check$1( cube.width === radius && cube.height === radius, - 'invalid cube map shape'); + 'invalid cube map shape') params.color[i] = { target: GL_TEXTURE_CUBE_MAP_POSITIVE_X$2, data: colorCubes[i] - }; + } } for (i = 0; i < 6; ++i) { for (var j = 0; j < colorCubes.length; ++j) { - params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + i; + params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + i } // reuse depth-stencil attachments across all cube maps if (i > 0) { - params.depth = faces[0].depth; - params.stencil = faces[0].stencil; - params.depthStencil = faces[0].depthStencil; + params.depth = faces[0].depth + params.stencil = faces[0].stencil + params.depthStencil = faces[0].depthStencil } if (faces[i]) { - (faces[i])(params); + (faces[i])(params) } else { - faces[i] = createFBO(params); + faces[i] = createFBO(params) } } @@ -4935,30 +4979,30 @@ function wrapFBOState ( } function resize (radius_) { - var i; - var radius = radius_ | 0; + var i + var radius = radius_ | 0 check$1(radius > 0 && radius <= limits.maxCubeMapSize, - 'invalid radius for cube fbo'); + 'invalid radius for cube fbo') if (radius === reglFramebufferCube.width) { return reglFramebufferCube } - var colors = reglFramebufferCube.color; + var colors = reglFramebufferCube.color for (i = 0; i < colors.length; ++i) { - colors[i].resize(radius); + colors[i].resize(radius) } for (i = 0; i < 6; ++i) { - faces[i].resize(radius); + faces[i].resize(radius) } - reglFramebufferCube.width = reglFramebufferCube.height = radius; + reglFramebufferCube.width = reglFramebufferCube.height = radius return reglFramebufferCube } - reglFramebufferCube(options); + reglFramebufferCube(options) return extend(reglFramebufferCube, { faces: faces, @@ -4966,26 +5010,26 @@ function wrapFBOState ( _reglType: 'framebufferCube', destroy: function () { faces.forEach(function (f) { - f.destroy(); - }); + f.destroy() + }) } }) } function restoreFramebuffers () { - framebufferState.cur = null; - framebufferState.next = null; - framebufferState.dirty = true; + framebufferState.cur = null + framebufferState.next = null + framebufferState.dirty = true values(framebufferSet).forEach(function (fb) { - fb.framebuffer = gl.createFramebuffer(); - updateFramebuffer(fb); - }); + fb.framebuffer = gl.createFramebuffer() + updateFramebuffer(fb) + }) } return extend(framebufferState, { getFramebuffer: function (object) { if (typeof object === 'function' && object._reglType === 'framebuffer') { - var fbo = object._framebuffer; + var fbo = object._framebuffer if (fbo instanceof REGLFramebuffer) { return fbo } @@ -4995,90 +5039,465 @@ function wrapFBOState ( create: createFBO, createCube: createCubeFBO, clear: function () { - values(framebufferSet).forEach(destroy); + values(framebufferSet).forEach(destroy) }, restore: restoreFramebuffers }) } -var GL_FLOAT$6 = 5126; +var GL_FLOAT$6 = 5126 +var GL_ARRAY_BUFFER$1 = 34962 +var GL_ELEMENT_ARRAY_BUFFER$1 = 34963 + +var VAO_OPTIONS = [ + 'attributes', + 'elements', + 'offset', + 'count', + 'primitive', + 'instances' +] function AttributeRecord () { - this.state = 0; + this.state = 0 - this.x = 0.0; - this.y = 0.0; - this.z = 0.0; - this.w = 0.0; + this.x = 0.0 + this.y = 0.0 + this.z = 0.0 + this.w = 0.0 - this.buffer = null; - this.size = 0; - this.normalized = false; - this.type = GL_FLOAT$6; - this.offset = 0; - this.stride = 0; - this.divisor = 0; + this.buffer = null + this.size = 0 + this.normalized = false + this.type = GL_FLOAT$6 + this.offset = 0 + this.stride = 0 + this.divisor = 0 } function wrapAttributeState ( gl, extensions, limits, - stringStore) { - var NUM_ATTRIBUTES = limits.maxAttributes; - var attributeBindings = new Array(NUM_ATTRIBUTES); + stats, + bufferState, + elementState, + drawState) { + var NUM_ATTRIBUTES = limits.maxAttributes + var attributeBindings = new Array(NUM_ATTRIBUTES) for (var i = 0; i < NUM_ATTRIBUTES; ++i) { - attributeBindings[i] = new AttributeRecord(); + attributeBindings[i] = new AttributeRecord() } + var vaoCount = 0 + var vaoSet = {} - return { + var state = { Record: AttributeRecord, scope: {}, - state: attributeBindings + state: attributeBindings, + currentVAO: null, + targetVAO: null, + restore: extVAO() ? restoreVAO : function () {}, + createVAO: createVAO, + getVAO: getVAO, + destroyBuffer: destroyBuffer, + setVAO: extVAO() ? setVAOEXT : setVAOEmulated, + clear: extVAO() ? destroyVAOEXT : function () {} } + + function destroyBuffer (buffer) { + for (var i = 0; i < attributeBindings.length; ++i) { + var record = attributeBindings[i] + if (record.buffer === buffer) { + gl.disableVertexAttribArray(i) + record.buffer = null + } + } + } + + function extVAO () { + return extensions.oes_vertex_array_object + } + + function extInstanced () { + return extensions.angle_instanced_arrays + } + + function getVAO (vao) { + if (typeof vao === 'function' && vao._vao) { + return vao._vao + } + return null + } + + function setVAOEXT (vao) { + if (vao === state.currentVAO) { + return + } + var ext = extVAO() + if (vao) { + ext.bindVertexArrayOES(vao.vao) + } else { + ext.bindVertexArrayOES(null) + } + state.currentVAO = vao + } + + function setVAOEmulated (vao) { + if (vao === state.currentVAO) { + return + } + if (vao) { + vao.bindAttrs() + } else { + var exti = extInstanced() + for (var i = 0; i < attributeBindings.length; ++i) { + var binding = attributeBindings[i] + if (binding.buffer) { + gl.enableVertexAttribArray(i) + binding.buffer.bind() + gl.vertexAttribPointer(i, binding.size, binding.type, binding.normalized, binding.stride, binding.offfset) + if (exti && binding.divisor) { + exti.vertexAttribDivisorANGLE(i, binding.divisor) + } + } else { + gl.disableVertexAttribArray(i) + gl.vertexAttrib4f(i, binding.x, binding.y, binding.z, binding.w) + } + } + if (drawState.elements) { + gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, drawState.elements.buffer.buffer) + } else { + gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) + } + } + state.currentVAO = vao + } + + function destroyVAOEXT () { + values(vaoSet).forEach(function (vao) { + vao.destroy() + }) + } + + function REGLVAO () { + this.id = ++vaoCount + this.attributes = [] + this.elements = null + this.ownsElements = false + this.count = 0 + this.offset = 0 + this.instances = -1 + this.primitive = 4 + var extension = extVAO() + if (extension) { + this.vao = extension.createVertexArrayOES() + } else { + this.vao = null + } + vaoSet[this.id] = this + this.buffers = [] + } + + REGLVAO.prototype.bindAttrs = function () { + var exti = extInstanced() + var attributes = this.attributes + for (var i = 0; i < attributes.length; ++i) { + var attr = attributes[i] + if (attr.buffer) { + gl.enableVertexAttribArray(i) + gl.bindBuffer(GL_ARRAY_BUFFER$1, attr.buffer.buffer) + gl.vertexAttribPointer(i, attr.size, attr.type, attr.normalized, attr.stride, attr.offset) + if (exti && attr.divisor) { + exti.vertexAttribDivisorANGLE(i, attr.divisor) + } + } else { + gl.disableVertexAttribArray(i) + gl.vertexAttrib4f(i, attr.x, attr.y, attr.z, attr.w) + } + } + for (var j = attributes.length; j < NUM_ATTRIBUTES; ++j) { + gl.disableVertexAttribArray(j) + } + var elements = elementState.getElements(this.elements) + if (elements) { + gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, elements.buffer.buffer) + } else { + gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER$1, null) + } + } + + REGLVAO.prototype.refresh = function () { + var ext = extVAO() + if (ext) { + ext.bindVertexArrayOES(this.vao) + this.bindAttrs() + state.currentVAO = null + ext.bindVertexArrayOES(null) + } + } + + REGLVAO.prototype.destroy = function () { + if (this.vao) { + var extension = extVAO() + if (this === state.currentVAO) { + state.currentVAO = null + extension.bindVertexArrayOES(null) + } + extension.deleteVertexArrayOES(this.vao) + this.vao = null + } + if (this.ownsElements) { + this.elements.destroy() + this.elements = null + this.ownsElements = false + } + if (vaoSet[this.id]) { + delete vaoSet[this.id] + stats.vaoCount -= 1 + } + } + + function restoreVAO () { + var ext = extVAO() + if (ext) { + values(vaoSet).forEach(function (vao) { + vao.refresh() + }) + } + } + + function createVAO (_attr) { + var vao = new REGLVAO() + stats.vaoCount += 1 + + function updateVAO (options) { + var attributes + if (Array.isArray(options)) { + attributes = options + if (vao.elements && vao.ownsElements) { + vao.elements.destroy() + } + vao.elements = null + vao.ownsElements = false + vao.offset = 0 + vao.count = 0 + vao.instances = -1 + vao.primitive = 4 + } else { + check$1(typeof options === 'object', 'invalid arguments for create vao') + check$1('attributes' in options, 'must specify attributes for vao') + if (options.elements) { + var elements = options.elements + if (vao.ownsElements) { + if (typeof elements === 'function' && elements._reglType === 'elements') { + vao.elements.destroy() + vao.ownsElements = false + } else { + vao.elements(elements) + vao.ownsElements = false + } + } else if (elementState.getElements(options.elements)) { + vao.elements = options.elements + vao.ownsElements = false + } else { + vao.elements = elementState.create(options.elements) + vao.ownsElements = true + } + } else { + vao.elements = null + vao.ownsElements = false + } + attributes = options.attributes + + // set default vao + vao.offset = 0 + vao.count = -1 + vao.instances = -1 + vao.primitive = 4 + + // copy element properties + if (vao.elements) { + vao.count = vao.elements._elements.vertCount + vao.primitive = vao.elements._elements.primType + } + + if ('offset' in options) { + vao.offset = options.offset | 0 + } + if ('count' in options) { + vao.count = options.count | 0 + } + if ('instances' in options) { + vao.instances = options.instances | 0 + } + if ('primitive' in options) { + check$1(options.primitive in primTypes, 'bad primitive type: ' + options.primitive) + vao.primitive = primTypes[options.primitive] + } + + check$1.optional(() => { + var keys = Object.keys(options) + for (var i = 0; i < keys.length; ++i) { + check$1(VAO_OPTIONS.indexOf(keys[i]) >= 0, 'invalid option for vao: "' + keys[i] + '" valid options are ' + VAO_OPTIONS) + } + }) + check$1(Array.isArray(attributes), 'attributes must be an array') + } + + check$1(attributes.length < NUM_ATTRIBUTES, 'too many attributes') + check$1(attributes.length > 0, 'must specify at least one attribute') + + var bufUpdated = {} + var nattributes = vao.attributes + nattributes.length = attributes.length + for (var i = 0; i < attributes.length; ++i) { + var spec = attributes[i] + var rec = nattributes[i] = new AttributeRecord() + var data = spec.data || spec + if (Array.isArray(data) || isTypedArray(data) || isNDArrayLike(data)) { + var buf + if (vao.buffers[i]) { + buf = vao.buffers[i] + if (isTypedArray(data) && buf._buffer.byteLength >= data.byteLength) { + buf.subdata(data) + } else { + buf.destroy() + vao.buffers[i] = null + } + } + if (!vao.buffers[i]) { + buf = vao.buffers[i] = bufferState.create(spec, GL_ARRAY_BUFFER$1, false, true) + } + rec.buffer = bufferState.getBuffer(buf) + rec.size = rec.buffer.dimension | 0 + rec.normalized = false + rec.type = rec.buffer.dtype + rec.offset = 0 + rec.stride = 0 + rec.divisor = 0 + rec.state = 1 + bufUpdated[i] = 1 + } else if (bufferState.getBuffer(spec)) { + rec.buffer = bufferState.getBuffer(spec) + rec.size = rec.buffer.dimension | 0 + rec.normalized = false + rec.type = rec.buffer.dtype + rec.offset = 0 + rec.stride = 0 + rec.divisor = 0 + rec.state = 1 + } else if (bufferState.getBuffer(spec.buffer)) { + rec.buffer = bufferState.getBuffer(spec.buffer) + rec.size = ((+spec.size) || rec.buffer.dimension) | 0 + rec.normalized = !!spec.normalized || false + if ('type' in spec) { + check$1.parameter(spec.type, glTypes, 'invalid buffer type') + rec.type = glTypes[spec.type] + } else { + rec.type = rec.buffer.dtype + } + rec.offset = (spec.offset || 0) | 0 + rec.stride = (spec.stride || 0) | 0 + rec.divisor = (spec.divisor || 0) | 0 + rec.state = 1 + + check$1(rec.size >= 1 && rec.size <= 4, 'size must be between 1 and 4') + check$1(rec.offset >= 0, 'invalid offset') + check$1(rec.stride >= 0 && rec.stride <= 255, 'stride must be between 0 and 255') + check$1(rec.divisor >= 0, 'divisor must be positive') + check$1(!rec.divisor || !!extensions.angle_instanced_arrays, 'ANGLE_instanced_arrays must be enabled to use divisor') + } else if ('x' in spec) { + check$1(i > 0, 'first attribute must not be a constant') + rec.x = +spec.x || 0 + rec.y = +spec.y || 0 + rec.z = +spec.z || 0 + rec.w = +spec.w || 0 + rec.state = 2 + } else { + check$1(false, 'invalid attribute spec for location ' + i) + } + } + + // retire unused buffers + for (var j = 0; j < vao.buffers.length; ++j) { + if (!bufUpdated[j] && vao.buffers[j]) { + vao.buffers[j].destroy() + vao.buffers[j] = null + } + } + + vao.refresh() + return updateVAO + } + + updateVAO.destroy = function () { + for (var j = 0; j < vao.buffers.length; ++j) { + if (vao.buffers[j]) { + vao.buffers[j].destroy() + } + } + vao.buffers.length = 0 + + if (vao.ownsElements) { + vao.elements.destroy() + vao.elements = null + vao.ownsElements = false + } + + vao.destroy() + } + + updateVAO._vao = vao + updateVAO._reglType = 'vao' + + return updateVAO(_attr) + } + + return state } -var GL_FRAGMENT_SHADER = 35632; -var GL_VERTEX_SHADER = 35633; +var GL_FRAGMENT_SHADER = 35632 +var GL_VERTEX_SHADER = 35633 -var GL_ACTIVE_UNIFORMS = 0x8B86; -var GL_ACTIVE_ATTRIBUTES = 0x8B89; +var GL_ACTIVE_UNIFORMS = 0x8B86 +var GL_ACTIVE_ATTRIBUTES = 0x8B89 function wrapShaderState (gl, stringStore, stats, config) { // =================================================== // glsl compilation and linking // =================================================== - var fragShaders = {}; - var vertShaders = {}; + var fragShaders = {} + var vertShaders = {} function ActiveInfo (name, id, location, info) { - this.name = name; - this.id = id; - this.location = location; - this.info = info; + this.name = name + this.id = id + this.location = location + this.info = info } function insertActiveInfo (list, info) { for (var i = 0; i < list.length; ++i) { if (list[i].id === info.id) { - list[i].location = info.location; + list[i].location = info.location return } } - list.push(info); + list.push(info) } function getShader (type, id, command) { - var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders; - var shader = cache[id]; + var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders + var shader = cache[id] if (!shader) { - var source = stringStore.str(id); - shader = gl.createShader(type); - gl.shaderSource(shader, source); - gl.compileShader(shader); - check$1.shaderError(gl, shader, source, type, command); - cache[id] = shader; + var source = stringStore.str(id) + shader = gl.createShader(type) + gl.shaderSource(shader, source) + gl.compileShader(shader) + check$1.shaderError(gl, shader, source, type, command) + cache[id] = shader } return shader @@ -5087,163 +5506,203 @@ function wrapShaderState (gl, stringStore, stats, config) { // =================================================== // program linking // =================================================== - var programCache = {}; - var programList = []; + var programCache = {} + var programList = [] - var PROGRAM_COUNTER = 0; + var PROGRAM_COUNTER = 0 function REGLProgram (fragId, vertId) { - this.id = PROGRAM_COUNTER++; - this.fragId = fragId; - this.vertId = vertId; - this.program = null; - this.uniforms = []; - this.attributes = []; + this.id = PROGRAM_COUNTER++ + this.fragId = fragId + this.vertId = vertId + this.program = null + this.uniforms = [] + this.attributes = [] + this.refCount = 1 if (config.profile) { this.stats = { uniformsCount: 0, attributesCount: 0 - }; + } } } - function linkProgram (desc, command) { - var i, info; + function linkProgram (desc, command, attributeLocations) { + var i, info // ------------------------------- // compile & link // ------------------------------- - var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId); - var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId); + var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId) + var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId) - var program = desc.program = gl.createProgram(); - gl.attachShader(program, fragShader); - gl.attachShader(program, vertShader); - gl.linkProgram(program); + var program = desc.program = gl.createProgram() + gl.attachShader(program, fragShader) + gl.attachShader(program, vertShader) + if (attributeLocations) { + for (i = 0; i < attributeLocations.length; ++i) { + var binding = attributeLocations[i] + gl.bindAttribLocation(program, binding[0], binding[1]) + } + } + + gl.linkProgram(program) check$1.linkError( gl, program, stringStore.str(desc.fragId), stringStore.str(desc.vertId), - command); + command) // ------------------------------- // grab uniforms // ------------------------------- - var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS); + var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS) if (config.profile) { - desc.stats.uniformsCount = numUniforms; + desc.stats.uniformsCount = numUniforms } - var uniforms = desc.uniforms; + var uniforms = desc.uniforms for (i = 0; i < numUniforms; ++i) { - info = gl.getActiveUniform(program, i); + info = gl.getActiveUniform(program, i) if (info) { if (info.size > 1) { for (var j = 0; j < info.size; ++j) { - var name = info.name.replace('[0]', '[' + j + ']'); + var name = info.name.replace('[0]', '[' + j + ']') insertActiveInfo(uniforms, new ActiveInfo( name, stringStore.id(name), gl.getUniformLocation(program, name), - info)); + info)) } - } else { - insertActiveInfo(uniforms, new ActiveInfo( - info.name, - stringStore.id(info.name), - gl.getUniformLocation(program, info.name), - info)); } + var uniName = info.name + if (info.size > 1) { + uniName = uniName.replace('[0]', '') + } + insertActiveInfo(uniforms, new ActiveInfo( + uniName, + stringStore.id(uniName), + gl.getUniformLocation(program, uniName), + info)) } } // ------------------------------- // grab attributes // ------------------------------- - var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES); + var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES) if (config.profile) { - desc.stats.attributesCount = numAttributes; + desc.stats.attributesCount = numAttributes } - var attributes = desc.attributes; + var attributes = desc.attributes for (i = 0; i < numAttributes; ++i) { - info = gl.getActiveAttrib(program, i); + info = gl.getActiveAttrib(program, i) if (info) { insertActiveInfo(attributes, new ActiveInfo( info.name, stringStore.id(info.name), gl.getAttribLocation(program, info.name), - info)); + info)) } } } if (config.profile) { stats.getMaxUniformsCount = function () { - var m = 0; + var m = 0 programList.forEach(function (desc) { if (desc.stats.uniformsCount > m) { - m = desc.stats.uniformsCount; + m = desc.stats.uniformsCount } - }); + }) return m - }; + } stats.getMaxAttributesCount = function () { - var m = 0; + var m = 0 programList.forEach(function (desc) { if (desc.stats.attributesCount > m) { - m = desc.stats.attributesCount; + m = desc.stats.attributesCount } - }); + }) return m - }; + } } function restoreShaders () { - fragShaders = {}; - vertShaders = {}; + fragShaders = {} + vertShaders = {} for (var i = 0; i < programList.length; ++i) { - linkProgram(programList[i]); + linkProgram(programList[i], null, programList[i].attributes.map(function (info) { + return [info.location, info.name] + })) } } return { clear: function () { - var deleteShader = gl.deleteShader.bind(gl); - values(fragShaders).forEach(deleteShader); - fragShaders = {}; - values(vertShaders).forEach(deleteShader); - vertShaders = {}; + var deleteShader = gl.deleteShader.bind(gl) + values(fragShaders).forEach(deleteShader) + fragShaders = {} + values(vertShaders).forEach(deleteShader) + vertShaders = {} programList.forEach(function (desc) { - gl.deleteProgram(desc.program); - }); - programList.length = 0; - programCache = {}; + gl.deleteProgram(desc.program) + }) + programList.length = 0 + programCache = {} - stats.shaderCount = 0; + stats.shaderCount = 0 }, - program: function (vertId, fragId, command) { - check$1.command(vertId >= 0, 'missing vertex shader', command); - check$1.command(fragId >= 0, 'missing fragment shader', command); + program: function (vertId, fragId, command, attribLocations) { + check$1.command(vertId >= 0, 'missing vertex shader', command) + check$1.command(fragId >= 0, 'missing fragment shader', command) - var cache = programCache[fragId]; + var cache = programCache[fragId] if (!cache) { - cache = programCache[fragId] = {}; + cache = programCache[fragId] = {} } - var program = cache[vertId]; - if (!program) { - program = new REGLProgram(fragId, vertId); - stats.shaderCount++; - - linkProgram(program, command); - cache[vertId] = program; - programList.push(program); + var prevProgram = cache[vertId] + if (prevProgram) { + prevProgram.refCount++ + if (!attribLocations) { + return prevProgram + } } - return program + var program = new REGLProgram(fragId, vertId) + stats.shaderCount++ + linkProgram(program, command, attribLocations) + if (!prevProgram) { + cache[vertId] = program + } + programList.push(program) + return extend(program, { + destroy: function () { + program.refCount-- + if (program.refCount <= 0) { + gl.deleteProgram(program.program) + var idx = programList.indexOf(program) + programList.splice(idx, 1) + stats.shaderCount-- + } + // no program is linked to this vert anymore + if (cache[program.vertId].refCount <= 0) { + gl.deleteShader(vertShaders[program.vertId]) + delete vertShaders[program.vertId] + delete programCache[program.fragId][program.vertId] + } + // no program is linked to this frag anymore + if (!Object.keys(programCache[program.fragId]).length) { + gl.deleteShader(fragShaders[program.fragId]) + delete fragShaders[program.fragId] + delete programCache[program.fragId] + } + } + }) }, restore: restoreShaders, @@ -5255,10 +5714,10 @@ function wrapShaderState (gl, stringStore, stats, config) { } } -var GL_RGBA$3 = 6408; -var GL_UNSIGNED_BYTE$7 = 5121; -var GL_PACK_ALIGNMENT = 0x0D05; -var GL_FLOAT$7 = 0x1406; // 5126 +var GL_RGBA$3 = 6408 +var GL_UNSIGNED_BYTE$7 = 5121 +var GL_PACK_ALIGNMENT = 0x0D05 +var GL_FLOAT$7 = 0x1406 // 5126 function wrapReadPixels ( gl, @@ -5269,54 +5728,56 @@ function wrapReadPixels ( extensions, limits) { function readPixelsImpl (input) { - var type; + var type if (framebufferState.next === null) { check$1( glAttributes.preserveDrawingBuffer, - 'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer'); - type = GL_UNSIGNED_BYTE$7; + 'you must create a webgl context with "preserveDrawingBuffer":true in order to read pixels from the drawing buffer') + type = GL_UNSIGNED_BYTE$7 } else { check$1( framebufferState.next.colorAttachments[0].texture !== null, - 'You cannot read from a renderbuffer'); - type = framebufferState.next.colorAttachments[0].texture._texture.type; + 'You cannot read from a renderbuffer') + type = framebufferState.next.colorAttachments[0].texture._texture.type - if (extensions.oes_texture_float) { - check$1( - type === GL_UNSIGNED_BYTE$7 || type === GL_FLOAT$7, - 'Reading from a framebuffer is only allowed for the types \'uint8\' and \'float\''); + check$1.optional(function () { + if (extensions.oes_texture_float) { + check$1( + type === GL_UNSIGNED_BYTE$7 || type === GL_FLOAT$7, + 'Reading from a framebuffer is only allowed for the types \'uint8\' and \'float\'') - if (type === GL_FLOAT$7) { - check$1(limits.readFloat, 'Reading \'float\' values is not permitted in your browser. For a fallback, please see: https://www.npmjs.com/package/glsl-read-float'); + if (type === GL_FLOAT$7) { + check$1(limits.readFloat, 'Reading \'float\' values is not permitted in your browser. For a fallback, please see: https://www.npmjs.com/package/glsl-read-float') + } + } else { + check$1( + type === GL_UNSIGNED_BYTE$7, + 'Reading from a framebuffer is only allowed for the type \'uint8\'') } - } else { - check$1( - type === GL_UNSIGNED_BYTE$7, - 'Reading from a framebuffer is only allowed for the type \'uint8\''); - } + }) } - var x = 0; - var y = 0; - var width = context.framebufferWidth; - var height = context.framebufferHeight; - var data = null; + var x = 0 + var y = 0 + var width = context.framebufferWidth + var height = context.framebufferHeight + var data = null if (isTypedArray(input)) { - data = input; + data = input } else if (input) { - check$1.type(input, 'object', 'invalid arguments to regl.read()'); - x = input.x | 0; - y = input.y | 0; + check$1.type(input, 'object', 'invalid arguments to regl.read()') + x = input.x | 0 + y = input.y | 0 check$1( x >= 0 && x < context.framebufferWidth, - 'invalid x offset for regl.read'); + 'invalid x offset for regl.read') check$1( y >= 0 && y < context.framebufferHeight, - 'invalid y offset for regl.read'); - width = (input.width || (context.framebufferWidth - x)) | 0; - height = (input.height || (context.framebufferHeight - y)) | 0; - data = input.data || null; + 'invalid y offset for regl.read') + width = (input.width || (context.framebufferWidth - x)) | 0 + height = (input.height || (context.framebufferHeight - y)) | 0 + data = input.data || null } // sanity check input.data @@ -5324,56 +5785,56 @@ function wrapReadPixels ( if (type === GL_UNSIGNED_BYTE$7) { check$1( data instanceof Uint8Array, - 'buffer must be \'Uint8Array\' when reading from a framebuffer of type \'uint8\''); + 'buffer must be \'Uint8Array\' when reading from a framebuffer of type \'uint8\'') } else if (type === GL_FLOAT$7) { check$1( data instanceof Float32Array, - 'buffer must be \'Float32Array\' when reading from a framebuffer of type \'float\''); + 'buffer must be \'Float32Array\' when reading from a framebuffer of type \'float\'') } } check$1( width > 0 && width + x <= context.framebufferWidth, - 'invalid width for read pixels'); + 'invalid width for read pixels') check$1( height > 0 && height + y <= context.framebufferHeight, - 'invalid height for read pixels'); + 'invalid height for read pixels') // Update WebGL state - reglPoll(); + reglPoll() // Compute size - var size = width * height * 4; + var size = width * height * 4 // Allocate data if (!data) { if (type === GL_UNSIGNED_BYTE$7) { - data = new Uint8Array(size); + data = new Uint8Array(size) } else if (type === GL_FLOAT$7) { - data = data || new Float32Array(size); + data = data || new Float32Array(size) } } // Type check - check$1.isTypedArray(data, 'data buffer for regl.read() must be a typedarray'); - check$1(data.byteLength >= size, 'data buffer for regl.read() too small'); + check$1.isTypedArray(data, 'data buffer for regl.read() must be a typedarray') + check$1(data.byteLength >= size, 'data buffer for regl.read() too small') // Run read pixels - gl.pixelStorei(GL_PACK_ALIGNMENT, 4); + gl.pixelStorei(GL_PACK_ALIGNMENT, 4) gl.readPixels(x, y, width, height, GL_RGBA$3, - type, - data); + type, + data) return data } function readPixelsFBO (options) { - var result; + var result framebufferState.setFBO({ framebuffer: options.framebuffer }, function () { - result = readPixelsImpl(options); - }); + result = readPixelsImpl(options) + }) return result } @@ -5398,13 +5859,13 @@ function join (x) { function createEnvironment () { // Unique variable id counter - var varCounter = 0; + var varCounter = 0 // Linked values are passed from this scope into the generated code block // Calling link() passes a value into the generated scope and returns // the variable name which it is bound to - var linkedNames = []; - var linkedValues = []; + var linkedNames = [] + var linkedValues = [] function link (value) { for (var i = 0; i < linkedValues.length; ++i) { if (linkedValues[i] === value) { @@ -5412,28 +5873,28 @@ function createEnvironment () { } } - var name = 'g' + (varCounter++); - linkedNames.push(name); - linkedValues.push(value); + var name = 'g' + (varCounter++) + linkedNames.push(name) + linkedValues.push(value) return name } // create a code block function block () { - var code = []; + var code = [] function push () { - code.push.apply(code, slice(arguments)); + code.push.apply(code, slice(arguments)) } - var vars = []; + var vars = [] function def () { - var name = 'v' + (varCounter++); - vars.push(name); + var name = 'v' + (varCounter++) + vars.push(name) if (arguments.length > 0) { - code.push(name, '='); - code.push.apply(code, slice(arguments)); - code.push(';'); + code.push(name, '=') + code.push.apply(code, slice(arguments)) + code.push(';') } return name @@ -5451,26 +5912,26 @@ function createEnvironment () { } function scope () { - var entry = block(); - var exit = block(); + var entry = block() + var exit = block() - var entryToString = entry.toString; - var exitToString = exit.toString; + var entryToString = entry.toString + var exitToString = exit.toString function save (object, prop) { - exit(object, prop, '=', entry.def(object, prop), ';'); + exit(object, prop, '=', entry.def(object, prop), ';') } return extend(function () { - entry.apply(entry, slice(arguments)); + entry.apply(entry, slice(arguments)) }, { def: entry.def, entry: entry, exit: exit, save: save, set: function (object, prop, value) { - save(object, prop); - entry(object, prop, '=', value, ';'); + save(object, prop) + entry(object, prop, '=', value, ';') }, toString: function () { return entryToString() + exitToString() @@ -5479,26 +5940,26 @@ function createEnvironment () { } function conditional () { - var pred = join(arguments); - var thenBlock = scope(); - var elseBlock = scope(); + var pred = join(arguments) + var thenBlock = scope() + var elseBlock = scope() - var thenToString = thenBlock.toString; - var elseToString = elseBlock.toString; + var thenToString = thenBlock.toString + var elseToString = elseBlock.toString return extend(thenBlock, { then: function () { - thenBlock.apply(thenBlock, slice(arguments)); + thenBlock.apply(thenBlock, slice(arguments)) return this }, else: function () { - elseBlock.apply(elseBlock, slice(arguments)); + elseBlock.apply(elseBlock, slice(arguments)) return this }, toString: function () { - var elseClause = elseToString(); + var elseClause = elseToString() if (elseClause) { - elseClause = 'else{' + elseClause + '}'; + elseClause = 'else{' + elseClause + '}' } return join([ 'if(', pred, '){', @@ -5510,23 +5971,23 @@ function createEnvironment () { } // procedure list - var globalBlock = block(); - var procedures = {}; + var globalBlock = block() + var procedures = {} function proc (name, count) { - var args = []; + var args = [] function arg () { - var name = 'a' + args.length; - args.push(name); + var name = 'a' + args.length + args.push(name) return name } - count = count || 0; + count = count || 0 for (var i = 0; i < count; ++i) { - arg(); + arg() } - var body = scope(); - var bodyToString = body.toString; + var body = scope() + var bodyToString = body.toString var result = procedures[name] = extend(body, { arg: arg, @@ -5537,7 +5998,7 @@ function createEnvironment () { '}' ]) } - }); + }) return result } @@ -5545,16 +6006,16 @@ function createEnvironment () { function compile () { var code = ['"use strict";', globalBlock, - 'return {']; + 'return {'] Object.keys(procedures).forEach(function (name) { - code.push('"', name, '":', procedures[name].toString(), ','); - }); - code.push('}'); + code.push('"', name, '":', procedures[name].toString(), ',') + }) + code.push('}') var src = join(code) .replace(/;/g, ';\n') .replace(/}/g, '}\n') - .replace(/{/g, '{\n'); - var proc = Function.apply(null, linkedNames.concat(src)); + .replace(/{/g, '{\n') + var proc = Function.apply(null, linkedNames.concat(src)) return proc.apply(null, linkedValues) } @@ -5570,68 +6031,71 @@ function createEnvironment () { } // "cute" names for vector components -var CUTE_COMPONENTS = 'xyzw'.split(''); +var CUTE_COMPONENTS = 'xyzw'.split('') -var GL_UNSIGNED_BYTE$8 = 5121; +var GL_UNSIGNED_BYTE$8 = 5121 -var ATTRIB_STATE_POINTER = 1; -var ATTRIB_STATE_CONSTANT = 2; +var ATTRIB_STATE_POINTER = 1 +var ATTRIB_STATE_CONSTANT = 2 -var DYN_FUNC$1 = 0; -var DYN_PROP$1 = 1; -var DYN_CONTEXT$1 = 2; -var DYN_STATE$1 = 3; -var DYN_THUNK = 4; +var DYN_FUNC$1 = 0 +var DYN_PROP$1 = 1 +var DYN_CONTEXT$1 = 2 +var DYN_STATE$1 = 3 +var DYN_THUNK = 4 +var DYN_CONSTANT$1 = 5 +var DYN_ARRAY$1 = 6 -var S_DITHER = 'dither'; -var S_BLEND_ENABLE = 'blend.enable'; -var S_BLEND_COLOR = 'blend.color'; -var S_BLEND_EQUATION = 'blend.equation'; -var S_BLEND_FUNC = 'blend.func'; -var S_DEPTH_ENABLE = 'depth.enable'; -var S_DEPTH_FUNC = 'depth.func'; -var S_DEPTH_RANGE = 'depth.range'; -var S_DEPTH_MASK = 'depth.mask'; -var S_COLOR_MASK = 'colorMask'; -var S_CULL_ENABLE = 'cull.enable'; -var S_CULL_FACE = 'cull.face'; -var S_FRONT_FACE = 'frontFace'; -var S_LINE_WIDTH = 'lineWidth'; -var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable'; -var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset'; -var S_SAMPLE_ALPHA = 'sample.alpha'; -var S_SAMPLE_ENABLE = 'sample.enable'; -var S_SAMPLE_COVERAGE = 'sample.coverage'; -var S_STENCIL_ENABLE = 'stencil.enable'; -var S_STENCIL_MASK = 'stencil.mask'; -var S_STENCIL_FUNC = 'stencil.func'; -var S_STENCIL_OPFRONT = 'stencil.opFront'; -var S_STENCIL_OPBACK = 'stencil.opBack'; -var S_SCISSOR_ENABLE = 'scissor.enable'; -var S_SCISSOR_BOX = 'scissor.box'; -var S_VIEWPORT = 'viewport'; +var S_DITHER = 'dither' +var S_BLEND_ENABLE = 'blend.enable' +var S_BLEND_COLOR = 'blend.color' +var S_BLEND_EQUATION = 'blend.equation' +var S_BLEND_FUNC = 'blend.func' +var S_DEPTH_ENABLE = 'depth.enable' +var S_DEPTH_FUNC = 'depth.func' +var S_DEPTH_RANGE = 'depth.range' +var S_DEPTH_MASK = 'depth.mask' +var S_COLOR_MASK = 'colorMask' +var S_CULL_ENABLE = 'cull.enable' +var S_CULL_FACE = 'cull.face' +var S_FRONT_FACE = 'frontFace' +var S_LINE_WIDTH = 'lineWidth' +var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable' +var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset' +var S_SAMPLE_ALPHA = 'sample.alpha' +var S_SAMPLE_ENABLE = 'sample.enable' +var S_SAMPLE_COVERAGE = 'sample.coverage' +var S_STENCIL_ENABLE = 'stencil.enable' +var S_STENCIL_MASK = 'stencil.mask' +var S_STENCIL_FUNC = 'stencil.func' +var S_STENCIL_OPFRONT = 'stencil.opFront' +var S_STENCIL_OPBACK = 'stencil.opBack' +var S_SCISSOR_ENABLE = 'scissor.enable' +var S_SCISSOR_BOX = 'scissor.box' +var S_VIEWPORT = 'viewport' -var S_PROFILE = 'profile'; +var S_PROFILE = 'profile' -var S_FRAMEBUFFER = 'framebuffer'; -var S_VERT = 'vert'; -var S_FRAG = 'frag'; -var S_ELEMENTS = 'elements'; -var S_PRIMITIVE = 'primitive'; -var S_COUNT = 'count'; -var S_OFFSET = 'offset'; -var S_INSTANCES = 'instances'; +var S_FRAMEBUFFER = 'framebuffer' +var S_VERT = 'vert' +var S_FRAG = 'frag' +var S_ELEMENTS = 'elements' +var S_PRIMITIVE = 'primitive' +var S_COUNT = 'count' +var S_OFFSET = 'offset' +var S_INSTANCES = 'instances' +var S_VAO = 'vao' -var SUFFIX_WIDTH = 'Width'; -var SUFFIX_HEIGHT = 'Height'; +var SUFFIX_WIDTH = 'Width' +var SUFFIX_HEIGHT = 'Height' -var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH; -var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT; -var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH; -var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT; -var S_DRAWINGBUFFER = 'drawingBuffer'; -var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH; -var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT; +var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH +var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT +var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH +var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT +var S_DRAWINGBUFFER = 'drawingBuffer' +var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH +var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT var NESTED_OPTIONS = [ S_BLEND_FUNC, @@ -5643,62 +6107,62 @@ var NESTED_OPTIONS = [ S_VIEWPORT, S_SCISSOR_BOX, S_POLYGON_OFFSET_OFFSET -]; +] -var GL_ARRAY_BUFFER$1 = 34962; -var GL_ELEMENT_ARRAY_BUFFER$1 = 34963; +var GL_ARRAY_BUFFER$2 = 34962 +var GL_ELEMENT_ARRAY_BUFFER$2 = 34963 -var GL_FRAGMENT_SHADER$1 = 35632; -var GL_VERTEX_SHADER$1 = 35633; +var GL_FRAGMENT_SHADER$1 = 35632 +var GL_VERTEX_SHADER$1 = 35633 -var GL_TEXTURE_2D$3 = 0x0DE1; -var GL_TEXTURE_CUBE_MAP$2 = 0x8513; +var GL_TEXTURE_2D$3 = 0x0DE1 +var GL_TEXTURE_CUBE_MAP$2 = 0x8513 -var GL_CULL_FACE = 0x0B44; -var GL_BLEND = 0x0BE2; -var GL_DITHER = 0x0BD0; -var GL_STENCIL_TEST = 0x0B90; -var GL_DEPTH_TEST = 0x0B71; -var GL_SCISSOR_TEST = 0x0C11; -var GL_POLYGON_OFFSET_FILL = 0x8037; -var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E; -var GL_SAMPLE_COVERAGE = 0x80A0; +var GL_CULL_FACE = 0x0B44 +var GL_BLEND = 0x0BE2 +var GL_DITHER = 0x0BD0 +var GL_STENCIL_TEST = 0x0B90 +var GL_DEPTH_TEST = 0x0B71 +var GL_SCISSOR_TEST = 0x0C11 +var GL_POLYGON_OFFSET_FILL = 0x8037 +var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E +var GL_SAMPLE_COVERAGE = 0x80A0 -var GL_FLOAT$8 = 5126; -var GL_FLOAT_VEC2 = 35664; -var GL_FLOAT_VEC3 = 35665; -var GL_FLOAT_VEC4 = 35666; -var GL_INT$3 = 5124; -var GL_INT_VEC2 = 35667; -var GL_INT_VEC3 = 35668; -var GL_INT_VEC4 = 35669; -var GL_BOOL = 35670; -var GL_BOOL_VEC2 = 35671; -var GL_BOOL_VEC3 = 35672; -var GL_BOOL_VEC4 = 35673; -var GL_FLOAT_MAT2 = 35674; -var GL_FLOAT_MAT3 = 35675; -var GL_FLOAT_MAT4 = 35676; -var GL_SAMPLER_2D = 35678; -var GL_SAMPLER_CUBE = 35680; +var GL_FLOAT$8 = 5126 +var GL_FLOAT_VEC2 = 35664 +var GL_FLOAT_VEC3 = 35665 +var GL_FLOAT_VEC4 = 35666 +var GL_INT$3 = 5124 +var GL_INT_VEC2 = 35667 +var GL_INT_VEC3 = 35668 +var GL_INT_VEC4 = 35669 +var GL_BOOL = 35670 +var GL_BOOL_VEC2 = 35671 +var GL_BOOL_VEC3 = 35672 +var GL_BOOL_VEC4 = 35673 +var GL_FLOAT_MAT2 = 35674 +var GL_FLOAT_MAT3 = 35675 +var GL_FLOAT_MAT4 = 35676 +var GL_SAMPLER_2D = 35678 +var GL_SAMPLER_CUBE = 35680 -var GL_TRIANGLES$1 = 4; +var GL_TRIANGLES$1 = 4 -var GL_FRONT = 1028; -var GL_BACK = 1029; -var GL_CW = 0x0900; -var GL_CCW = 0x0901; -var GL_MIN_EXT = 0x8007; -var GL_MAX_EXT = 0x8008; -var GL_ALWAYS = 519; -var GL_KEEP = 7680; -var GL_ZERO = 0; -var GL_ONE = 1; -var GL_FUNC_ADD = 0x8006; -var GL_LESS = 513; +var GL_FRONT = 1028 +var GL_BACK = 1029 +var GL_CW = 0x0900 +var GL_CCW = 0x0901 +var GL_MIN_EXT = 0x8007 +var GL_MAX_EXT = 0x8008 +var GL_ALWAYS = 519 +var GL_KEEP = 7680 +var GL_ZERO = 0 +var GL_ONE = 1 +var GL_FUNC_ADD = 0x8006 +var GL_LESS = 513 -var GL_FRAMEBUFFER$2 = 0x8D40; -var GL_COLOR_ATTACHMENT0$2 = 0x8CE0; +var GL_FRAMEBUFFER$2 = 0x8D40 +var GL_COLOR_ATTACHMENT0$2 = 0x8CE0 var blendFuncs = { '0': 0, @@ -5718,7 +6182,7 @@ var blendFuncs = { 'constant alpha': 32771, 'one minus constant alpha': 32772, 'src alpha saturate': 776 -}; +} // There are invalid values for srcRGB and dstRGB. See: // https://www.khronos.org/registry/webgl/specs/1.0/#6.13 @@ -5732,7 +6196,7 @@ var invalidBlendCombinations = [ 'constant alpha, one minus constant color', 'one minus constant alpha, constant color', 'one minus constant alpha, one minus constant color' -]; +] var compareFuncs = { 'never': 512, @@ -5752,7 +6216,7 @@ var compareFuncs = { 'gequal': 518, '>=': 518, 'always': 519 -}; +} var stencilOps = { '0': 0, @@ -5764,17 +6228,17 @@ var stencilOps = { 'increment wrap': 34055, 'decrement wrap': 34056, 'invert': 5386 -}; +} var shaderType = { 'frag': GL_FRAGMENT_SHADER$1, 'vert': GL_VERTEX_SHADER$1 -}; +} var orientationType = { 'cw': GL_CW, 'ccw': GL_CCW -}; +} function isBufferArgs (x) { return Array.isArray(x) || @@ -5795,10 +6259,10 @@ function sortState (state) { } function Declaration (thisDep, contextDep, propDep, append) { - this.thisDep = thisDep; - this.contextDep = contextDep; - this.propDep = propDep; - this.append = append; + this.thisDep = thisDep + this.contextDep = contextDep + this.propDep = propDep + this.append = append } function isStatic (decl) { @@ -5810,21 +6274,59 @@ function createStaticDecl (append) { } function createDynamicDecl (dyn, append) { - var type = dyn.type; + var type = dyn.type if (type === DYN_FUNC$1) { - var numArgs = dyn.data.length; + var numArgs = dyn.data.length return new Declaration( true, numArgs >= 1, numArgs >= 2, append) } else if (type === DYN_THUNK) { - var data = dyn.data; + var data = dyn.data return new Declaration( data.thisDep, data.contextDep, data.propDep, append) + } else if (type === DYN_CONSTANT$1) { + return new Declaration( + false, + false, + false, + append) + } else if (type === DYN_ARRAY$1) { + var thisDep = false + var contextDep = false + var propDep = false + for (var i = 0; i < dyn.data.length; ++i) { + var subDyn = dyn.data[i] + if (subDyn.type === DYN_PROP$1) { + propDep = true + } else if (subDyn.type === DYN_CONTEXT$1) { + contextDep = true + } else if (subDyn.type === DYN_STATE$1) { + thisDep = true + } else if (subDyn.type === DYN_FUNC$1) { + thisDep = true + var subArgs = subDyn.data + if (subArgs >= 1) { + contextDep = true + } + if (subArgs >= 2) { + propDep = true + } + } else if (subDyn.type === DYN_THUNK) { + thisDep = thisDep || subDyn.data.thisDep + contextDep = contextDep || subDyn.data.contextDep + propDep = propDep || subDyn.data.propDep + } + } + return new Declaration( + thisDep, + contextDep, + propDep, + append) } else { return new Declaration( type === DYN_STATE$1, @@ -5834,7 +6336,7 @@ function createDynamicDecl (dyn, append) { } } -var SCOPE_DECL = new Declaration(false, false, false, function () {}); +var SCOPE_DECL = new Declaration(false, false, false, function () {}) function reglCore ( gl, @@ -5852,20 +6354,21 @@ function reglCore ( contextState, timer, config) { - var AttributeRecord = attributeState.Record; + var AttributeRecord = attributeState.Record var blendEquations = { 'add': 32774, 'subtract': 32778, 'reverse subtract': 32779 - }; + } if (extensions.ext_blend_minmax) { - blendEquations.min = GL_MIN_EXT; - blendEquations.max = GL_MAX_EXT; + blendEquations.min = GL_MIN_EXT + blendEquations.max = GL_MAX_EXT } - var extInstancing = extensions.angle_instanced_arrays; - var extDrawBuffers = extensions.webgl_draw_buffers; + var extInstancing = extensions.angle_instanced_arrays + var extDrawBuffers = extensions.webgl_draw_buffers + var extVertexArrays = extensions.oes_vertex_array_object // =================================================== // =================================================== @@ -5875,91 +6378,91 @@ function reglCore ( var currentState = { dirty: true, profile: config.profile - }; - var nextState = {}; - var GL_STATE_NAMES = []; - var GL_FLAGS = {}; - var GL_VARIABLES = {}; + } + var nextState = {} + var GL_STATE_NAMES = [] + var GL_FLAGS = {} + var GL_VARIABLES = {} function propName (name) { return name.replace('.', '_') } function stateFlag (sname, cap, init) { - var name = propName(sname); - GL_STATE_NAMES.push(sname); - nextState[name] = currentState[name] = !!init; - GL_FLAGS[name] = cap; + var name = propName(sname) + GL_STATE_NAMES.push(sname) + nextState[name] = currentState[name] = !!init + GL_FLAGS[name] = cap } function stateVariable (sname, func, init) { - var name = propName(sname); - GL_STATE_NAMES.push(sname); + var name = propName(sname) + GL_STATE_NAMES.push(sname) if (Array.isArray(init)) { - currentState[name] = init.slice(); - nextState[name] = init.slice(); + currentState[name] = init.slice() + nextState[name] = init.slice() } else { - currentState[name] = nextState[name] = init; + currentState[name] = nextState[name] = init } - GL_VARIABLES[name] = func; + GL_VARIABLES[name] = func } // Dithering - stateFlag(S_DITHER, GL_DITHER); + stateFlag(S_DITHER, GL_DITHER) // Blending - stateFlag(S_BLEND_ENABLE, GL_BLEND); - stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0]); + stateFlag(S_BLEND_ENABLE, GL_BLEND) + stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0]) stateVariable(S_BLEND_EQUATION, 'blendEquationSeparate', - [GL_FUNC_ADD, GL_FUNC_ADD]); + [GL_FUNC_ADD, GL_FUNC_ADD]) stateVariable(S_BLEND_FUNC, 'blendFuncSeparate', - [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO]); + [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO]) // Depth - stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true); - stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS); - stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1]); - stateVariable(S_DEPTH_MASK, 'depthMask', true); + stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true) + stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS) + stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1]) + stateVariable(S_DEPTH_MASK, 'depthMask', true) // Color mask - stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true]); + stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true]) // Face culling - stateFlag(S_CULL_ENABLE, GL_CULL_FACE); - stateVariable(S_CULL_FACE, 'cullFace', GL_BACK); + stateFlag(S_CULL_ENABLE, GL_CULL_FACE) + stateVariable(S_CULL_FACE, 'cullFace', GL_BACK) // Front face orientation - stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW); + stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW) // Line width - stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1); + stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1) // Polygon offset - stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL); - stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0]); + stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL) + stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0]) // Sample coverage - stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE); - stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE); - stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false]); + stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE) + stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE) + stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false]) // Stencil - stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST); - stateVariable(S_STENCIL_MASK, 'stencilMask', -1); - stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1]); + stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST) + stateVariable(S_STENCIL_MASK, 'stencilMask', -1) + stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1]) stateVariable(S_STENCIL_OPFRONT, 'stencilOpSeparate', - [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP]); + [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP]) stateVariable(S_STENCIL_OPBACK, 'stencilOpSeparate', - [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP]); + [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP]) // Scissor - stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST); + stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST) stateVariable(S_SCISSOR_BOX, 'scissor', - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]); + [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) // Viewport stateVariable(S_VIEWPORT, S_VIEWPORT, - [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]); + [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]) // =================================================== // =================================================== @@ -5977,13 +6480,14 @@ function reglCore ( buffer: bufferState, shader: shaderState, attributes: attributeState.state, + vao: attributeState, uniforms: uniformState, framebuffer: framebufferState, extensions: extensions, timer: timer, isBufferArgs: isBufferArgs - }; + } var sharedConstants = { primTypes: primTypes, @@ -5993,14 +6497,14 @@ function reglCore ( stencilOps: stencilOps, glTypes: glTypes, orientationType: orientationType - }; + } check$1.optional(function () { - sharedState.isArrayLike = isArrayLike; - }); + sharedState.isArrayLike = isArrayLike + }) if (extDrawBuffers) { - sharedConstants.backBuffer = [GL_BACK]; + sharedConstants.backBuffer = [GL_BACK] sharedConstants.drawBuffer = loop(limits.maxDrawbuffers, function (i) { if (i === 0) { return [0] @@ -6008,56 +6512,56 @@ function reglCore ( return loop(i, function (j) { return GL_COLOR_ATTACHMENT0$2 + j }) - }); + }) } - var drawCallCounter = 0; + var drawCallCounter = 0 function createREGLEnvironment () { - var env = createEnvironment(); - var link = env.link; - var global = env.global; - env.id = drawCallCounter++; + var env = createEnvironment() + var link = env.link + var global = env.global + env.id = drawCallCounter++ - env.batchId = '0'; + env.batchId = '0' // link shared state - var SHARED = link(sharedState); + var SHARED = link(sharedState) var shared = env.shared = { props: 'a0' - }; + } Object.keys(sharedState).forEach(function (prop) { - shared[prop] = global.def(SHARED, '.', prop); - }); + shared[prop] = global.def(SHARED, '.', prop) + }) // Inject runtime assertion stuff for debug builds check$1.optional(function () { - env.CHECK = link(check$1); - env.commandStr = check$1.guessCommand(); - env.command = link(env.commandStr); + env.CHECK = link(check$1) + env.commandStr = check$1.guessCommand() + env.command = link(env.commandStr) env.assert = function (block, pred, message) { block( 'if(!(', pred, '))', - this.CHECK, '.commandRaise(', link(message), ',', this.command, ');'); - }; + this.CHECK, '.commandRaise(', link(message), ',', this.command, ');') + } - sharedConstants.invalidBlendCombinations = invalidBlendCombinations; - }); + sharedConstants.invalidBlendCombinations = invalidBlendCombinations + }) // Copy GL state variables over - var nextVars = env.next = {}; - var currentVars = env.current = {}; + var nextVars = env.next = {} + var currentVars = env.current = {} Object.keys(GL_VARIABLES).forEach(function (variable) { if (Array.isArray(currentState[variable])) { - nextVars[variable] = global.def(shared.next, '.', variable); - currentVars[variable] = global.def(shared.current, '.', variable); + nextVars[variable] = global.def(shared.next, '.', variable) + currentVars[variable] = global.def(shared.current, '.', variable) } - }); + }) // Initialize shared constants - var constants = env.constants = {}; + var constants = env.constants = {} Object.keys(sharedConstants).forEach(function (name) { - constants[name] = global.def(JSON.stringify(sharedConstants[name])); - }); + constants[name] = global.def(JSON.stringify(sharedConstants[name])) + }) // Helper function for calling a block env.invoke = function (block, x) { @@ -6068,11 +6572,11 @@ function reglCore ( shared.context, shared.props, env.batchId - ]; + ] return block.def( link(x.data), '.call(', - argList.slice(0, Math.max(x.data.length + 1, 4)), - ')') + argList.slice(0, Math.max(x.data.length + 1, 4)), + ')') case DYN_PROP$1: return block.def(shared.props, x.data) case DYN_CONTEXT$1: @@ -6080,26 +6584,32 @@ function reglCore ( case DYN_STATE$1: return block.def('this', x.data) case DYN_THUNK: - x.data.append(env, block); + x.data.append(env, block) return x.data.ref + case DYN_CONSTANT$1: + return x.data.toString() + case DYN_ARRAY$1: + return x.data.map(function (y) { + return env.invoke(block, y) + }) } - }; + } - env.attribCache = {}; + env.attribCache = {} - var scopeAttribs = {}; + var scopeAttribs = {} env.scopeAttrib = function (name) { - var id = stringStore.id(name); + var id = stringStore.id(name) if (id in scopeAttribs) { return scopeAttribs[id] } - var binding = attributeState.scope[id]; + var binding = attributeState.scope[id] if (!binding) { - binding = attributeState.scope[id] = new AttributeRecord(); + binding = attributeState.scope[id] = new AttributeRecord() } - var result = scopeAttribs[id] = link(binding); + var result = scopeAttribs[id] = link(binding) return result - }; + } return env } @@ -6110,103 +6620,103 @@ function reglCore ( // =================================================== // =================================================== function parseProfile (options) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic - var profileEnable; + var profileEnable if (S_PROFILE in staticOptions) { - var value = !!staticOptions[S_PROFILE]; + var value = !!staticOptions[S_PROFILE] profileEnable = createStaticDecl(function (env, scope) { return value - }); - profileEnable.enable = value; + }) + profileEnable.enable = value } else if (S_PROFILE in dynamicOptions) { - var dyn = dynamicOptions[S_PROFILE]; + var dyn = dynamicOptions[S_PROFILE] profileEnable = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) - }); + }) } return profileEnable } function parseFramebuffer (options, env) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic if (S_FRAMEBUFFER in staticOptions) { - var framebuffer = staticOptions[S_FRAMEBUFFER]; + var framebuffer = staticOptions[S_FRAMEBUFFER] if (framebuffer) { - framebuffer = framebufferState.getFramebuffer(framebuffer); - check$1.command(framebuffer, 'invalid framebuffer object'); + framebuffer = framebufferState.getFramebuffer(framebuffer) + check$1.command(framebuffer, 'invalid framebuffer object') return createStaticDecl(function (env, block) { - var FRAMEBUFFER = env.link(framebuffer); - var shared = env.shared; + var FRAMEBUFFER = env.link(framebuffer) + var shared = env.shared block.set( shared.framebuffer, '.next', - FRAMEBUFFER); - var CONTEXT = shared.context; + FRAMEBUFFER) + var CONTEXT = shared.context block.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, - FRAMEBUFFER + '.width'); + FRAMEBUFFER + '.width') block.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, - FRAMEBUFFER + '.height'); + FRAMEBUFFER + '.height') return FRAMEBUFFER }) } else { return createStaticDecl(function (env, scope) { - var shared = env.shared; + var shared = env.shared scope.set( shared.framebuffer, '.next', - 'null'); - var CONTEXT = shared.context; + 'null') + var CONTEXT = shared.context scope.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH); + CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) scope.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT); + CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) return 'null' }) } } else if (S_FRAMEBUFFER in dynamicOptions) { - var dyn = dynamicOptions[S_FRAMEBUFFER]; + var dyn = dynamicOptions[S_FRAMEBUFFER] return createDynamicDecl(dyn, function (env, scope) { - var FRAMEBUFFER_FUNC = env.invoke(scope, dyn); - var shared = env.shared; - var FRAMEBUFFER_STATE = shared.framebuffer; + var FRAMEBUFFER_FUNC = env.invoke(scope, dyn) + var shared = env.shared + var FRAMEBUFFER_STATE = shared.framebuffer var FRAMEBUFFER = scope.def( - FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')'); + FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')') check$1.optional(function () { env.assert(scope, '!' + FRAMEBUFFER_FUNC + '||' + FRAMEBUFFER, - 'invalid framebuffer object'); - }); + 'invalid framebuffer object') + }) scope.set( FRAMEBUFFER_STATE, '.next', - FRAMEBUFFER); - var CONTEXT = shared.context; + FRAMEBUFFER) + var CONTEXT = shared.context scope.set( CONTEXT, '.' + S_FRAMEBUFFER_WIDTH, FRAMEBUFFER + '?' + FRAMEBUFFER + '.width:' + - CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH); + CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH) scope.set( CONTEXT, '.' + S_FRAMEBUFFER_HEIGHT, FRAMEBUFFER + '?' + FRAMEBUFFER + '.height:' + - CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT); + CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT) return FRAMEBUFFER }) } else { @@ -6215,29 +6725,29 @@ function reglCore ( } function parseViewportScissor (options, framebuffer, env) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic function parseBox (param) { if (param in staticOptions) { - var box = staticOptions[param]; - check$1.commandType(box, 'object', 'invalid ' + param, env.commandStr); + var box = staticOptions[param] + check$1.commandType(box, 'object', 'invalid ' + param, env.commandStr) - var isStatic = true; - var x = box.x | 0; - var y = box.y | 0; - var w, h; + var isStatic = true + var x = box.x | 0 + var y = box.y | 0 + var w, h if ('width' in box) { - w = box.width | 0; - check$1.command(w >= 0, 'invalid ' + param, env.commandStr); + w = box.width | 0 + check$1.command(w >= 0, 'invalid ' + param, env.commandStr) } else { - isStatic = false; + isStatic = false } if ('height' in box) { - h = box.height | 0; - check$1.command(h >= 0, 'invalid ' + param, env.commandStr); + h = box.height | 0 + check$1.command(h >= 0, 'invalid ' + param, env.commandStr) } else { - isStatic = false; + isStatic = false } return new Declaration( @@ -6245,51 +6755,51 @@ function reglCore ( !isStatic && framebuffer && framebuffer.contextDep, !isStatic && framebuffer && framebuffer.propDep, function (env, scope) { - var CONTEXT = env.shared.context; - var BOX_W = w; + var CONTEXT = env.shared.context + var BOX_W = w if (!('width' in box)) { - BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x); + BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x) } - var BOX_H = h; + var BOX_H = h if (!('height' in box)) { - BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y); + BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y) } return [x, y, BOX_W, BOX_H] }) } else if (param in dynamicOptions) { - var dynBox = dynamicOptions[param]; + var dynBox = dynamicOptions[param] var result = createDynamicDecl(dynBox, function (env, scope) { - var BOX = env.invoke(scope, dynBox); + var BOX = env.invoke(scope, dynBox) check$1.optional(function () { env.assert(scope, BOX + '&&typeof ' + BOX + '==="object"', - 'invalid ' + param); - }); + 'invalid ' + param) + }) - var CONTEXT = env.shared.context; - var BOX_X = scope.def(BOX, '.x|0'); - var BOX_Y = scope.def(BOX, '.y|0'); + var CONTEXT = env.shared.context + var BOX_X = scope.def(BOX, '.x|0') + var BOX_Y = scope.def(BOX, '.y|0') var BOX_W = scope.def( '"width" in ', BOX, '?', BOX, '.width|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')'); + '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')') var BOX_H = scope.def( '"height" in ', BOX, '?', BOX, '.height|0:', - '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')'); + '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')') check$1.optional(function () { env.assert(scope, BOX_W + '>=0&&' + BOX_H + '>=0', - 'invalid ' + param); - }); + 'invalid ' + param) + }) return [BOX_X, BOX_Y, BOX_W, BOX_H] - }); + }) if (framebuffer) { - result.thisDep = result.thisDep || framebuffer.thisDep; - result.contextDep = result.contextDep || framebuffer.contextDep; - result.propDep = result.propDep || framebuffer.propDep; + result.thisDep = result.thisDep || framebuffer.thisDep + result.contextDep = result.contextDep || framebuffer.contextDep + result.propDep = result.propDep || framebuffer.propDep } return result } else if (framebuffer) { @@ -6298,7 +6808,7 @@ function reglCore ( framebuffer.contextDep, framebuffer.propDep, function (env, scope) { - var CONTEXT = env.shared.context; + var CONTEXT = env.shared.context return [ 0, 0, scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH), @@ -6309,27 +6819,27 @@ function reglCore ( } } - var viewport = parseBox(S_VIEWPORT); + var viewport = parseBox(S_VIEWPORT) if (viewport) { - var prevViewport = viewport; + var prevViewport = viewport viewport = new Declaration( viewport.thisDep, viewport.contextDep, viewport.propDep, function (env, scope) { - var VIEWPORT = prevViewport.append(env, scope); - var CONTEXT = env.shared.context; + var VIEWPORT = prevViewport.append(env, scope) + var CONTEXT = env.shared.context scope.set( CONTEXT, '.' + S_VIEWPORT_WIDTH, - VIEWPORT[2]); + VIEWPORT[2]) scope.set( CONTEXT, '.' + S_VIEWPORT_HEIGHT, - VIEWPORT[3]); + VIEWPORT[3]) return VIEWPORT - }); + }) } return { @@ -6338,74 +6848,97 @@ function reglCore ( } } - function parseProgram (options) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + function parseAttribLocations (options, attributes) { + var staticOptions = options.static + var staticProgram = + typeof staticOptions[S_FRAG] === 'string' && + typeof staticOptions[S_VERT] === 'string' + if (staticProgram) { + if (Object.keys(attributes.dynamic).length > 0) { + return null + } + var staticAttributes = attributes.static + var sAttributes = Object.keys(staticAttributes) + if (sAttributes.length > 0 && typeof staticAttributes[sAttributes[0]] === 'number') { + var bindings = [] + for (var i = 0; i < sAttributes.length; ++i) { + check$1(typeof staticAttributes[sAttributes[i]] === 'number', 'must specify all vertex attribute locations when using vaos') + bindings.push([staticAttributes[sAttributes[i]] | 0, sAttributes[i]]) + } + return bindings + } + } + return null + } + + function parseProgram (options, env, attribLocations) { + var staticOptions = options.static + var dynamicOptions = options.dynamic function parseShader (name) { if (name in staticOptions) { - var id = stringStore.id(staticOptions[name]); + var id = stringStore.id(staticOptions[name]) check$1.optional(function () { - shaderState.shader(shaderType[name], id, check$1.guessCommand()); - }); + shaderState.shader(shaderType[name], id, check$1.guessCommand()) + }) var result = createStaticDecl(function () { return id - }); - result.id = id; + }) + result.id = id return result } else if (name in dynamicOptions) { - var dyn = dynamicOptions[name]; + var dyn = dynamicOptions[name] return createDynamicDecl(dyn, function (env, scope) { - var str = env.invoke(scope, dyn); - var id = scope.def(env.shared.strings, '.id(', str, ')'); + var str = env.invoke(scope, dyn) + var id = scope.def(env.shared.strings, '.id(', str, ')') check$1.optional(function () { scope( env.shared.shader, '.shader(', shaderType[name], ',', id, ',', - env.command, ');'); - }); + env.command, ');') + }) return id }) } return null } - var frag = parseShader(S_FRAG); - var vert = parseShader(S_VERT); + var frag = parseShader(S_FRAG) + var vert = parseShader(S_VERT) - var program = null; - var progVar; + var program = null + var progVar if (isStatic(frag) && isStatic(vert)) { - program = shaderState.program(vert.id, frag.id); + program = shaderState.program(vert.id, frag.id, null, attribLocations) progVar = createStaticDecl(function (env, scope) { return env.link(program) - }); + }) } else { progVar = new Declaration( (frag && frag.thisDep) || (vert && vert.thisDep), (frag && frag.contextDep) || (vert && vert.contextDep), (frag && frag.propDep) || (vert && vert.propDep), function (env, scope) { - var SHADER_STATE = env.shared.shader; - var fragId; + var SHADER_STATE = env.shared.shader + var fragId if (frag) { - fragId = frag.append(env, scope); + fragId = frag.append(env, scope) } else { - fragId = scope.def(SHADER_STATE, '.', S_FRAG); + fragId = scope.def(SHADER_STATE, '.', S_FRAG) } - var vertId; + var vertId if (vert) { - vertId = vert.append(env, scope); + vertId = vert.append(env, scope) } else { - vertId = scope.def(SHADER_STATE, '.', S_VERT); + vertId = scope.def(SHADER_STATE, '.', S_VERT) } - var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId; + var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId check$1.optional(function () { - progDef += ',' + env.command; - }); + progDef += ',' + env.command + }) return scope.def(progDef + ')') - }); + }) } return { @@ -6417,87 +6950,141 @@ function reglCore ( } function parseDraw (options, env) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic + + // TODO: should use VAO to get default values for offset properties + // should move vao parse into here and out of the old stuff + + var staticDraw = {} + var vaoActive = false + + function parseVAO () { + if (S_VAO in staticOptions) { + var vao = staticOptions[S_VAO] + if (vao !== null && attributeState.getVAO(vao) === null) { + vao = attributeState.createVAO(vao) + } + + vaoActive = true + staticDraw.vao = vao + + return createStaticDecl(function (env) { + var vaoRef = attributeState.getVAO(vao) + if (vaoRef) { + return env.link(vaoRef) + } else { + return 'null' + } + }) + } else if (S_VAO in dynamicOptions) { + vaoActive = true + var dyn = dynamicOptions[S_VAO] + return createDynamicDecl(dyn, function (env, scope) { + var vaoRef = env.invoke(scope, dyn) + return scope.def(env.shared.vao + '.getVAO(' + vaoRef + ')') + }) + } + return null + } + + var vao = parseVAO() + + var elementsActive = false function parseElements () { if (S_ELEMENTS in staticOptions) { - var elements = staticOptions[S_ELEMENTS]; + var elements = staticOptions[S_ELEMENTS] + staticDraw.elements = elements if (isBufferArgs(elements)) { - elements = elementState.getElements(elementState.create(elements, true)); + var e = staticDraw.elements = elementState.create(elements, true) + elements = elementState.getElements(e) + elementsActive = true } else if (elements) { - elements = elementState.getElements(elements); - check$1.command(elements, 'invalid elements', env.commandStr); + elements = elementState.getElements(elements) + elementsActive = true + check$1.command(elements, 'invalid elements', env.commandStr) } + var result = createStaticDecl(function (env, scope) { if (elements) { - var result = env.link(elements); - env.ELEMENTS = result; + var result = env.link(elements) + env.ELEMENTS = result return result } - env.ELEMENTS = null; + env.ELEMENTS = null return null - }); - result.value = elements; + }) + result.value = elements return result } else if (S_ELEMENTS in dynamicOptions) { - var dyn = dynamicOptions[S_ELEMENTS]; + elementsActive = true + + var dyn = dynamicOptions[S_ELEMENTS] return createDynamicDecl(dyn, function (env, scope) { - var shared = env.shared; + var shared = env.shared - var IS_BUFFER_ARGS = shared.isBufferArgs; - var ELEMENT_STATE = shared.elements; + var IS_BUFFER_ARGS = shared.isBufferArgs + var ELEMENT_STATE = shared.elements - var elementDefn = env.invoke(scope, dyn); - var elements = scope.def('null'); - var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')'); + var elementDefn = env.invoke(scope, dyn) + var elements = scope.def('null') + var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')') var ifte = env.cond(elementStream) .then(elements, '=', ELEMENT_STATE, '.createStream(', elementDefn, ');') - .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');'); + .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');') check$1.optional(function () { env.assert(ifte.else, '!' + elementDefn + '||' + elements, - 'invalid elements'); - }); + 'invalid elements') + }) - scope.entry(ifte); + scope.entry(ifte) scope.exit( env.cond(elementStream) - .then(ELEMENT_STATE, '.destroyStream(', elements, ');')); + .then(ELEMENT_STATE, '.destroyStream(', elements, ');')) - env.ELEMENTS = elements; + env.ELEMENTS = elements return elements }) + } else if (vaoActive) { + return new Declaration( + vao.thisDep, + vao.contextDep, + vao.propDep, + function (env, scope) { + return scope.def(env.shared.vao + '.currentVAO?' + env.shared.elements + '.getElements(' + env.shared.vao + '.currentVAO.elements):null') + }) } - return null } - var elements = parseElements(); + var elements = parseElements() function parsePrimitive () { if (S_PRIMITIVE in staticOptions) { - var primitive = staticOptions[S_PRIMITIVE]; - check$1.commandParameter(primitive, primTypes, 'invalid primitve', env.commandStr); + var primitive = staticOptions[S_PRIMITIVE] + staticDraw.primitive = primitive + check$1.commandParameter(primitive, primTypes, 'invalid primitve', env.commandStr) return createStaticDecl(function (env, scope) { return primTypes[primitive] }) } else if (S_PRIMITIVE in dynamicOptions) { - var dynPrimitive = dynamicOptions[S_PRIMITIVE]; + var dynPrimitive = dynamicOptions[S_PRIMITIVE] return createDynamicDecl(dynPrimitive, function (env, scope) { - var PRIM_TYPES = env.constants.primTypes; - var prim = env.invoke(scope, dynPrimitive); + var PRIM_TYPES = env.constants.primTypes + var prim = env.invoke(scope, dynPrimitive) check$1.optional(function () { env.assert(scope, prim + ' in ' + PRIM_TYPES, - 'invalid primitive, must be one of ' + Object.keys(primTypes)); - }); + 'invalid primitive, must be one of ' + Object.keys(primTypes)) + }) return scope.def(PRIM_TYPES, '[', prim, ']') }) - } else if (elements) { + } else if (elementsActive) { if (isStatic(elements)) { if (elements.value) { return createStaticDecl(function (env, scope) { @@ -6514,71 +7101,103 @@ function reglCore ( elements.contextDep, elements.propDep, function (env, scope) { - var elements = env.ELEMENTS; + var elements = env.ELEMENTS return scope.def(elements, '?', elements, '.primType:', GL_TRIANGLES$1) }) } + } else if (vaoActive) { + return new Declaration( + vao.thisDep, + vao.contextDep, + vao.propDep, + function (env, scope) { + return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.primitive:' + GL_TRIANGLES$1) + }) } return null } function parseParam (param, isOffset) { if (param in staticOptions) { - var value = staticOptions[param] | 0; - check$1.command(!isOffset || value >= 0, 'invalid ' + param, env.commandStr); + var value = staticOptions[param] | 0 + if (isOffset) { + staticDraw.offset = value + } else { + staticDraw.instances = value + } + check$1.command(!isOffset || value >= 0, 'invalid ' + param, env.commandStr) return createStaticDecl(function (env, scope) { if (isOffset) { - env.OFFSET = value; + env.OFFSET = value } return value }) } else if (param in dynamicOptions) { - var dynValue = dynamicOptions[param]; + var dynValue = dynamicOptions[param] return createDynamicDecl(dynValue, function (env, scope) { - var result = env.invoke(scope, dynValue); + var result = env.invoke(scope, dynValue) if (isOffset) { - env.OFFSET = result; + env.OFFSET = result check$1.optional(function () { env.assert(scope, result + '>=0', - 'invalid ' + param); - }); + 'invalid ' + param) + }) } return result }) - } else if (isOffset && elements) { - return createStaticDecl(function (env, scope) { - env.OFFSET = '0'; - return 0 - }) + } else if (isOffset) { + if (elementsActive) { + return createStaticDecl(function (env, scope) { + env.OFFSET = 0 + return 0 + }) + } else if (vaoActive) { + return new Declaration( + vao.thisDep, + vao.contextDep, + vao.propDep, + function (env, scope) { + return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.offset:0') + }) + } + } else if (vaoActive) { + return new Declaration( + vao.thisDep, + vao.contextDep, + vao.propDep, + function (env, scope) { + return scope.def(env.shared.vao + '.currentVAO?' + env.shared.vao + '.currentVAO.instances:-1') + }) } return null } - var OFFSET = parseParam(S_OFFSET, true); + var OFFSET = parseParam(S_OFFSET, true) function parseVertCount () { if (S_COUNT in staticOptions) { - var count = staticOptions[S_COUNT] | 0; + var count = staticOptions[S_COUNT] | 0 + staticDraw.count = count check$1.command( - typeof count === 'number' && count >= 0, 'invalid vertex count', env.commandStr); + typeof count === 'number' && count >= 0, 'invalid vertex count', env.commandStr) return createStaticDecl(function () { return count }) } else if (S_COUNT in dynamicOptions) { - var dynCount = dynamicOptions[S_COUNT]; + var dynCount = dynamicOptions[S_COUNT] return createDynamicDecl(dynCount, function (env, scope) { - var result = env.invoke(scope, dynCount); + var result = env.invoke(scope, dynCount) check$1.optional(function () { env.assert(scope, 'typeof ' + result + '==="number"&&' + result + '>=0&&' + result + '===(' + result + '|0)', - 'invalid vertex count'); - }); + 'invalid vertex count') + }) return result }) - } else if (elements) { + } else if (elementsActive) { if (isStatic(elements)) { if (elements) { if (OFFSET) { @@ -6588,13 +7207,13 @@ function reglCore ( OFFSET.propDep, function (env, scope) { var result = scope.def( - env.ELEMENTS, '.vertCount-', env.OFFSET); + env.ELEMENTS, '.vertCount-', env.OFFSET) check$1.optional(function () { env.assert(scope, result + '>=0', - 'invalid vertex offset/element buffer too small'); - }); + 'invalid vertex offset/element buffer too small') + }) return result }) @@ -6606,10 +7225,10 @@ function reglCore ( } else { var result = createStaticDecl(function () { return -1 - }); + }) check$1.optional(function () { - result.MISSING = true; - }); + result.MISSING = true + }) return result } } else { @@ -6618,51 +7237,71 @@ function reglCore ( elements.contextDep || OFFSET.contextDep, elements.propDep || OFFSET.propDep, function (env, scope) { - var elements = env.ELEMENTS; + var elements = env.ELEMENTS if (env.OFFSET) { return scope.def(elements, '?', elements, '.vertCount-', env.OFFSET, ':-1') } return scope.def(elements, '?', elements, '.vertCount:-1') - }); + }) check$1.optional(function () { - variable.DYNAMIC = true; - }); + variable.DYNAMIC = true + }) return variable } + } else if (vaoActive) { + var countVariable = new Declaration( + vao.thisDep, + vao.contextDep, + vao.propDep, + function (env, scope) { + return scope.def(env.shared.vao, '.currentVAO?', env.shared.vao, '.currentVAO.count:-1') + }) + return countVariable } return null } + var primitive = parsePrimitive() + var count = parseVertCount() + var instances = parseParam(S_INSTANCES, false) + return { elements: elements, - primitive: parsePrimitive(), - count: parseVertCount(), - instances: parseParam(S_INSTANCES, false), - offset: OFFSET + primitive: primitive, + count: count, + instances: instances, + offset: OFFSET, + vao: vao, + + vaoActive: vaoActive, + elementsActive: elementsActive, + + // static draw props + static: staticDraw } } function parseGLState (options, env) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic - var STATE = {}; + var STATE = {} GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop); + var param = propName(prop) function parseParam (parseStatic, parseDynamic) { if (prop in staticOptions) { - var value = parseStatic(staticOptions[prop]); + var value = parseStatic(staticOptions[prop]) STATE[param] = createStaticDecl(function () { return value - }); + }) } else if (prop in dynamicOptions) { - var dyn = dynamicOptions[prop]; + var dyn = dynamicOptions[prop] STATE[param] = createDynamicDecl(dyn, function (env, scope) { return parseDynamic(env, scope, env.invoke(scope, dyn)) - }); + }) } } @@ -6679,31 +7318,31 @@ function reglCore ( case S_DEPTH_MASK: return parseParam( function (value) { - check$1.commandType(value, 'boolean', prop, env.commandStr); + check$1.commandType(value, 'boolean', prop, env.commandStr) return value }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, 'typeof ' + value + '==="boolean"', - 'invalid flag ' + prop, env.commandStr); - }); + 'invalid flag ' + prop, env.commandStr) + }) return value }) case S_DEPTH_FUNC: return parseParam( function (value) { - check$1.commandParameter(value, compareFuncs, 'invalid ' + prop, env.commandStr); + check$1.commandParameter(value, compareFuncs, 'invalid ' + prop, env.commandStr) return compareFuncs[value] }, function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs; + var COMPARE_FUNCS = env.constants.compareFuncs check$1.optional(function () { env.assert(scope, value + ' in ' + COMPARE_FUNCS, - 'invalid ' + prop + ', must be one of ' + Object.keys(compareFuncs)); - }); + 'invalid ' + prop + ', must be one of ' + Object.keys(compareFuncs)) + }) return scope.def(COMPARE_FUNCS, '[', value, ']') }) @@ -6717,7 +7356,7 @@ function reglCore ( typeof value[1] === 'number' && value[0] <= value[1], 'depth range is 2d array', - env.commandStr); + env.commandStr) return value }, function (env, scope, value) { @@ -6728,30 +7367,30 @@ function reglCore ( 'typeof ' + value + '[0]==="number"&&' + 'typeof ' + value + '[1]==="number"&&' + value + '[0]<=' + value + '[1]', - 'depth range must be a 2d array'); - }); + 'depth range must be a 2d array') + }) - var Z_NEAR = scope.def('+', value, '[0]'); - var Z_FAR = scope.def('+', value, '[1]'); + var Z_NEAR = scope.def('+', value, '[0]') + var Z_FAR = scope.def('+', value, '[1]') return [Z_NEAR, Z_FAR] }) case S_BLEND_FUNC: return parseParam( function (value) { - check$1.commandType(value, 'object', 'blend.func', env.commandStr); - var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src); - var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src); - var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst); - var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst); - check$1.commandParameter(srcRGB, blendFuncs, param + '.srcRGB', env.commandStr); - check$1.commandParameter(srcAlpha, blendFuncs, param + '.srcAlpha', env.commandStr); - check$1.commandParameter(dstRGB, blendFuncs, param + '.dstRGB', env.commandStr); - check$1.commandParameter(dstAlpha, blendFuncs, param + '.dstAlpha', env.commandStr); + check$1.commandType(value, 'object', 'blend.func', env.commandStr) + var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src) + var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src) + var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst) + var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst) + check$1.commandParameter(srcRGB, blendFuncs, param + '.srcRGB', env.commandStr) + check$1.commandParameter(srcAlpha, blendFuncs, param + '.srcAlpha', env.commandStr) + check$1.commandParameter(dstRGB, blendFuncs, param + '.dstRGB', env.commandStr) + check$1.commandParameter(dstAlpha, blendFuncs, param + '.dstAlpha', env.commandStr) check$1.command( (invalidBlendCombinations.indexOf(srcRGB + ', ' + dstRGB) === -1), - 'unallowed blending combination (srcRGB, dstRGB) = (' + srcRGB + ', ' + dstRGB + ')', env.commandStr); + 'unallowed blending combination (srcRGB, dstRGB) = (' + srcRGB + ', ' + dstRGB + ')', env.commandStr) return [ blendFuncs[srcRGB], @@ -6761,46 +7400,46 @@ function reglCore ( ] }, function (env, scope, value) { - var BLEND_FUNCS = env.constants.blendFuncs; + var BLEND_FUNCS = env.constants.blendFuncs check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', - 'invalid blend func, must be an object'); - }); + 'invalid blend func, must be an object') + }) function read (prefix, suffix) { var func = scope.def( '"', prefix, suffix, '" in ', value, '?', value, '.', prefix, suffix, - ':', value, '.', prefix); + ':', value, '.', prefix) check$1.optional(function () { env.assert(scope, func + ' in ' + BLEND_FUNCS, - 'invalid ' + prop + '.' + prefix + suffix + ', must be one of ' + Object.keys(blendFuncs)); - }); + 'invalid ' + prop + '.' + prefix + suffix + ', must be one of ' + Object.keys(blendFuncs)) + }) return func } - var srcRGB = read('src', 'RGB'); - var dstRGB = read('dst', 'RGB'); + var srcRGB = read('src', 'RGB') + var dstRGB = read('dst', 'RGB') check$1.optional(function () { - var INVALID_BLEND_COMBINATIONS = env.constants.invalidBlendCombinations; + var INVALID_BLEND_COMBINATIONS = env.constants.invalidBlendCombinations env.assert(scope, - INVALID_BLEND_COMBINATIONS + + INVALID_BLEND_COMBINATIONS + '.indexOf(' + srcRGB + '+", "+' + dstRGB + ') === -1 ', - 'unallowed blending combination for (srcRGB, dstRGB)' - ); - }); + 'unallowed blending combination for (srcRGB, dstRGB)' + ) + }) - var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']'); - var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']'); - var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']'); - var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']'); + var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']') + var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']') + var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']') + var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']') return [SRC_RGB, DST_RGB, SRC_ALPHA, DST_ALPHA] }) @@ -6809,54 +7448,54 @@ function reglCore ( return parseParam( function (value) { if (typeof value === 'string') { - check$1.commandParameter(value, blendEquations, 'invalid ' + prop, env.commandStr); + check$1.commandParameter(value, blendEquations, 'invalid ' + prop, env.commandStr) return [ blendEquations[value], blendEquations[value] ] } else if (typeof value === 'object') { check$1.commandParameter( - value.rgb, blendEquations, prop + '.rgb', env.commandStr); + value.rgb, blendEquations, prop + '.rgb', env.commandStr) check$1.commandParameter( - value.alpha, blendEquations, prop + '.alpha', env.commandStr); + value.alpha, blendEquations, prop + '.alpha', env.commandStr) return [ blendEquations[value.rgb], blendEquations[value.alpha] ] } else { - check$1.commandRaise('invalid blend.equation', env.commandStr); + check$1.commandRaise('invalid blend.equation', env.commandStr) } }, function (env, scope, value) { - var BLEND_EQUATIONS = env.constants.blendEquations; + var BLEND_EQUATIONS = env.constants.blendEquations - var RGB = scope.def(); - var ALPHA = scope.def(); + var RGB = scope.def() + var ALPHA = scope.def() - var ifte = env.cond('typeof ', value, '==="string"'); + var ifte = env.cond('typeof ', value, '==="string"') check$1.optional(function () { function checkProp (block, name, value) { env.assert(block, value + ' in ' + BLEND_EQUATIONS, - 'invalid ' + name + ', must be one of ' + Object.keys(blendEquations)); + 'invalid ' + name + ', must be one of ' + Object.keys(blendEquations)) } - checkProp(ifte.then, prop, value); + checkProp(ifte.then, prop, value) env.assert(ifte.else, value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop); - checkProp(ifte.else, prop + '.rgb', value + '.rgb'); - checkProp(ifte.else, prop + '.alpha', value + '.alpha'); - }); + 'invalid ' + prop) + checkProp(ifte.else, prop + '.rgb', value + '.rgb') + checkProp(ifte.else, prop + '.alpha', value + '.alpha') + }) ifte.then( - RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];'); + RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];') ifte.else( RGB, '=', BLEND_EQUATIONS, '[', value, '.rgb];', - ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];'); + ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];') - scope(ifte); + scope(ifte) return [RGB, ALPHA] }) @@ -6867,7 +7506,7 @@ function reglCore ( check$1.command( isArrayLike(value) && value.length === 4, - 'blend.color must be a 4d array', env.commandStr); + 'blend.color must be a 4d array', env.commandStr) return loop(4, function (i) { return +value[i] }) @@ -6877,8 +7516,8 @@ function reglCore ( env.assert(scope, env.shared.isArrayLike + '(' + value + ')&&' + value + '.length===4', - 'blend.color must be a 4d array'); - }); + 'blend.color must be a 4d array') + }) return loop(4, function (i) { return scope.def('+', value, '[', i, ']') }) @@ -6887,28 +7526,28 @@ function reglCore ( case S_STENCIL_MASK: return parseParam( function (value) { - check$1.commandType(value, 'number', param, env.commandStr); + check$1.commandType(value, 'number', param, env.commandStr) return value | 0 }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, 'typeof ' + value + '==="number"', - 'invalid stencil.mask'); - }); + 'invalid stencil.mask') + }) return scope.def(value, '|0') }) case S_STENCIL_FUNC: return parseParam( function (value) { - check$1.commandType(value, 'object', param, env.commandStr); - var cmp = value.cmp || 'keep'; - var ref = value.ref || 0; - var mask = 'mask' in value ? value.mask : -1; - check$1.commandParameter(cmp, compareFuncs, prop + '.cmp', env.commandStr); - check$1.commandType(ref, 'number', prop + '.ref', env.commandStr); - check$1.commandType(mask, 'number', prop + '.mask', env.commandStr); + check$1.commandType(value, 'object', param, env.commandStr) + var cmp = value.cmp || 'keep' + var ref = value.ref || 0 + var mask = 'mask' in value ? value.mask : -1 + check$1.commandParameter(cmp, compareFuncs, prop + '.cmp', env.commandStr) + check$1.commandType(ref, 'number', prop + '.ref', env.commandStr) + check$1.commandType(mask, 'number', prop + '.mask', env.commandStr) return [ compareFuncs[cmp], ref, @@ -6916,25 +7555,25 @@ function reglCore ( ] }, function (env, scope, value) { - var COMPARE_FUNCS = env.constants.compareFuncs; + var COMPARE_FUNCS = env.constants.compareFuncs check$1.optional(function () { function assert () { env.assert(scope, Array.prototype.join.call(arguments, ''), - 'invalid stencil.func'); + 'invalid stencil.func') } - assert(value + '&&typeof ', value, '==="object"'); + assert(value + '&&typeof ', value, '==="object"') assert('!("cmp" in ', value, ')||(', - value, '.cmp in ', COMPARE_FUNCS, ')'); - }); + value, '.cmp in ', COMPARE_FUNCS, ')') + }) var cmp = scope.def( '"cmp" in ', value, '?', COMPARE_FUNCS, '[', value, '.cmp]', - ':', GL_KEEP); - var ref = scope.def(value, '.ref|0'); + ':', GL_KEEP) + var ref = scope.def(value, '.ref|0') var mask = scope.def( '"mask" in ', value, - '?', value, '.mask|0:-1'); + '?', value, '.mask|0:-1') return [cmp, ref, mask] }) @@ -6942,13 +7581,13 @@ function reglCore ( case S_STENCIL_OPBACK: return parseParam( function (value) { - check$1.commandType(value, 'object', param, env.commandStr); - var fail = value.fail || 'keep'; - var zfail = value.zfail || 'keep'; - var zpass = value.zpass || 'keep'; - check$1.commandParameter(fail, stencilOps, prop + '.fail', env.commandStr); - check$1.commandParameter(zfail, stencilOps, prop + '.zfail', env.commandStr); - check$1.commandParameter(zpass, stencilOps, prop + '.zpass', env.commandStr); + check$1.commandType(value, 'object', param, env.commandStr) + var fail = value.fail || 'keep' + var zfail = value.zfail || 'keep' + var zpass = value.zpass || 'keep' + check$1.commandParameter(fail, stencilOps, prop + '.fail', env.commandStr) + check$1.commandParameter(zfail, stencilOps, prop + '.zfail', env.commandStr) + check$1.commandParameter(zpass, stencilOps, prop + '.zpass', env.commandStr) return [ prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT, stencilOps[fail], @@ -6957,21 +7596,21 @@ function reglCore ( ] }, function (env, scope, value) { - var STENCIL_OPS = env.constants.stencilOps; + var STENCIL_OPS = env.constants.stencilOps check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop); - }); + 'invalid ' + prop) + }) function read (name) { check$1.optional(function () { env.assert(scope, '!("' + name + '" in ' + value + ')||' + '(' + value + '.' + name + ' in ' + STENCIL_OPS + ')', - 'invalid ' + prop + '.' + name + ', must be one of ' + Object.keys(stencilOps)); - }); + 'invalid ' + prop + '.' + name + ', must be one of ' + Object.keys(stencilOps)) + }) return scope.def( '"', name, '" in ', value, @@ -6990,22 +7629,22 @@ function reglCore ( case S_POLYGON_OFFSET_OFFSET: return parseParam( function (value) { - check$1.commandType(value, 'object', param, env.commandStr); - var factor = value.factor | 0; - var units = value.units | 0; - check$1.commandType(factor, 'number', param + '.factor', env.commandStr); - check$1.commandType(units, 'number', param + '.units', env.commandStr); + check$1.commandType(value, 'object', param, env.commandStr) + var factor = value.factor | 0 + var units = value.units | 0 + check$1.commandType(factor, 'number', param + '.factor', env.commandStr) + check$1.commandType(units, 'number', param + '.units', env.commandStr) return [factor, units] }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', - 'invalid ' + prop); - }); + 'invalid ' + prop) + }) - var FACTOR = scope.def(value, '.factor|0'); - var UNITS = scope.def(value, '.units|0'); + var FACTOR = scope.def(value, '.factor|0') + var UNITS = scope.def(value, '.units|0') return [FACTOR, UNITS] }) @@ -7013,13 +7652,13 @@ function reglCore ( case S_CULL_FACE: return parseParam( function (value) { - var face = 0; + var face = 0 if (value === 'front') { - face = GL_FRONT; + face = GL_FRONT } else if (value === 'back') { - face = GL_BACK; + face = GL_BACK } - check$1.command(!!face, param, env.commandStr); + check$1.command(!!face, param, env.commandStr) return face }, function (env, scope, value) { @@ -7027,8 +7666,8 @@ function reglCore ( env.assert(scope, value + '==="front"||' + value + '==="back"', - 'invalid cull.face'); - }); + 'invalid cull.face') + }) return scope.def(value, '==="front"?', GL_FRONT, ':', GL_BACK) }) @@ -7040,7 +7679,7 @@ function reglCore ( value >= limits.lineWidthDims[0] && value <= limits.lineWidthDims[1], 'invalid line width, must be a positive number between ' + - limits.lineWidthDims[0] + ' and ' + limits.lineWidthDims[1], env.commandStr); + limits.lineWidthDims[0] + ' and ' + limits.lineWidthDims[1], env.commandStr) return value }, function (env, scope, value) { @@ -7049,8 +7688,8 @@ function reglCore ( 'typeof ' + value + '==="number"&&' + value + '>=' + limits.lineWidthDims[0] + '&&' + value + '<=' + limits.lineWidthDims[1], - 'invalid line width'); - }); + 'invalid line width') + }) return value }) @@ -7058,7 +7697,7 @@ function reglCore ( case S_FRONT_FACE: return parseParam( function (value) { - check$1.commandParameter(value, orientationType, param, env.commandStr); + check$1.commandParameter(value, orientationType, param, env.commandStr) return orientationType[value] }, function (env, scope, value) { @@ -7066,8 +7705,8 @@ function reglCore ( env.assert(scope, value + '==="cw"||' + value + '==="ccw"', - 'invalid frontFace, must be one of cw,ccw'); - }); + 'invalid frontFace, must be one of cw,ccw') + }) return scope.def(value + '==="cw"?' + GL_CW + ':' + GL_CCW) }) @@ -7076,7 +7715,7 @@ function reglCore ( function (value) { check$1.command( isArrayLike(value) && value.length === 4, - 'color.mask must be length 4 array', env.commandStr); + 'color.mask must be length 4 array', env.commandStr) return value.map(function (v) { return !!v }) }, function (env, scope, value) { @@ -7084,8 +7723,8 @@ function reglCore ( env.assert(scope, env.shared.isArrayLike + '(' + value + ')&&' + value + '.length===4', - 'invalid color.mask'); - }); + 'invalid color.mask') + }) return loop(4, function (i) { return '!!' + value + '[' + i + ']' }) @@ -7094,62 +7733,62 @@ function reglCore ( case S_SAMPLE_COVERAGE: return parseParam( function (value) { - check$1.command(typeof value === 'object' && value, param, env.commandStr); - var sampleValue = 'value' in value ? value.value : 1; - var sampleInvert = !!value.invert; + check$1.command(typeof value === 'object' && value, param, env.commandStr) + var sampleValue = 'value' in value ? value.value : 1 + var sampleInvert = !!value.invert check$1.command( typeof sampleValue === 'number' && sampleValue >= 0 && sampleValue <= 1, - 'sample.coverage.value must be a number between 0 and 1', env.commandStr); + 'sample.coverage.value must be a number between 0 and 1', env.commandStr) return [sampleValue, sampleInvert] }, function (env, scope, value) { check$1.optional(function () { env.assert(scope, value + '&&typeof ' + value + '==="object"', - 'invalid sample.coverage'); - }); + 'invalid sample.coverage') + }) var VALUE = scope.def( - '"value" in ', value, '?+', value, '.value:1'); - var INVERT = scope.def('!!', value, '.invert'); + '"value" in ', value, '?+', value, '.value:1') + var INVERT = scope.def('!!', value, '.invert') return [VALUE, INVERT] }) } - }); + }) return STATE } function parseUniforms (uniforms, env) { - var staticUniforms = uniforms.static; - var dynamicUniforms = uniforms.dynamic; + var staticUniforms = uniforms.static + var dynamicUniforms = uniforms.dynamic - var UNIFORMS = {}; + var UNIFORMS = {} Object.keys(staticUniforms).forEach(function (name) { - var value = staticUniforms[name]; - var result; + var value = staticUniforms[name] + var result if (typeof value === 'number' || typeof value === 'boolean') { result = createStaticDecl(function () { return value - }); + }) } else if (typeof value === 'function') { - var reglType = value._reglType; + var reglType = value._reglType if (reglType === 'texture2d' || reglType === 'textureCube') { result = createStaticDecl(function (env) { return env.link(value) - }); + }) } else if (reglType === 'framebuffer' || reglType === 'framebufferCube') { check$1.command(value.color.length > 0, - 'missing color attachment for framebuffer sent to uniform "' + name + '"', env.commandStr); + 'missing color attachment for framebuffer sent to uniform "' + name + '"', env.commandStr) result = createStaticDecl(function (env) { return env.link(value.color[0]) - }); + }) } else { - check$1.commandRaise('invalid data for uniform "' + name + '"', env.commandStr); + check$1.commandRaise('invalid data for uniform "' + name + '"', env.commandStr) } } else if (isArrayLike(value)) { result = createStaticDecl(function (env) { @@ -7158,112 +7797,112 @@ function reglCore ( check$1.command( typeof value[i] === 'number' || typeof value[i] === 'boolean', - 'invalid uniform ' + name, env.commandStr); + 'invalid uniform ' + name, env.commandStr) return value[i] - }), ']'); + }), ']') return ITEM - }); + }) } else { - check$1.commandRaise('invalid or missing data for uniform "' + name + '"', env.commandStr); + check$1.commandRaise('invalid or missing data for uniform "' + name + '"', env.commandStr) } - result.value = value; - UNIFORMS[name] = result; - }); + result.value = value + UNIFORMS[name] = result + }) Object.keys(dynamicUniforms).forEach(function (key) { - var dyn = dynamicUniforms[key]; + var dyn = dynamicUniforms[key] UNIFORMS[key] = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) - }); - }); + }) + }) return UNIFORMS } function parseAttributes (attributes, env) { - var staticAttributes = attributes.static; - var dynamicAttributes = attributes.dynamic; + var staticAttributes = attributes.static + var dynamicAttributes = attributes.dynamic - var attributeDefs = {}; + var attributeDefs = {} Object.keys(staticAttributes).forEach(function (attribute) { - var value = staticAttributes[attribute]; - var id = stringStore.id(attribute); + var value = staticAttributes[attribute] + var id = stringStore.id(attribute) - var record = new AttributeRecord(); + var record = new AttributeRecord() if (isBufferArgs(value)) { - record.state = ATTRIB_STATE_POINTER; + record.state = ATTRIB_STATE_POINTER record.buffer = bufferState.getBuffer( - bufferState.create(value, GL_ARRAY_BUFFER$1, false, true)); - record.type = 0; + bufferState.create(value, GL_ARRAY_BUFFER$2, false, true)) + record.type = 0 } else { - var buffer = bufferState.getBuffer(value); + var buffer = bufferState.getBuffer(value) if (buffer) { - record.state = ATTRIB_STATE_POINTER; - record.buffer = buffer; - record.type = 0; + record.state = ATTRIB_STATE_POINTER + record.buffer = buffer + record.type = 0 } else { check$1.command(typeof value === 'object' && value, - 'invalid data for attribute ' + attribute, env.commandStr); + 'invalid data for attribute ' + attribute, env.commandStr) if ('constant' in value) { - var constant = value.constant; - record.buffer = 'null'; - record.state = ATTRIB_STATE_CONSTANT; + var constant = value.constant + record.buffer = 'null' + record.state = ATTRIB_STATE_CONSTANT if (typeof constant === 'number') { - record.x = constant; + record.x = constant } else { check$1.command( isArrayLike(constant) && constant.length > 0 && constant.length <= 4, - 'invalid constant for attribute ' + attribute, env.commandStr); + 'invalid constant for attribute ' + attribute, env.commandStr) CUTE_COMPONENTS.forEach(function (c, i) { if (i < constant.length) { - record[c] = constant[i]; + record[c] = constant[i] } - }); + }) } } else { if (isBufferArgs(value.buffer)) { buffer = bufferState.getBuffer( - bufferState.create(value.buffer, GL_ARRAY_BUFFER$1, false, true)); + bufferState.create(value.buffer, GL_ARRAY_BUFFER$2, false, true)) } else { - buffer = bufferState.getBuffer(value.buffer); + buffer = bufferState.getBuffer(value.buffer) } - check$1.command(!!buffer, 'missing buffer for attribute "' + attribute + '"', env.commandStr); + check$1.command(!!buffer, 'missing buffer for attribute "' + attribute + '"', env.commandStr) - var offset = value.offset | 0; + var offset = value.offset | 0 check$1.command(offset >= 0, - 'invalid offset for attribute "' + attribute + '"', env.commandStr); + 'invalid offset for attribute "' + attribute + '"', env.commandStr) - var stride = value.stride | 0; + var stride = value.stride | 0 check$1.command(stride >= 0 && stride < 256, - 'invalid stride for attribute "' + attribute + '", must be integer betweeen [0, 255]', env.commandStr); + 'invalid stride for attribute "' + attribute + '", must be integer betweeen [0, 255]', env.commandStr) - var size = value.size | 0; + var size = value.size | 0 check$1.command(!('size' in value) || (size > 0 && size <= 4), - 'invalid size for attribute "' + attribute + '", must be 1,2,3,4', env.commandStr); + 'invalid size for attribute "' + attribute + '", must be 1,2,3,4', env.commandStr) - var normalized = !!value.normalized; + var normalized = !!value.normalized - var type = 0; + var type = 0 if ('type' in value) { check$1.commandParameter( value.type, glTypes, - 'invalid type for attribute ' + attribute, env.commandStr); - type = glTypes[value.type]; - } - - var divisor = value.divisor | 0; - if ('divisor' in value) { - check$1.command(divisor === 0 || extInstancing, - 'cannot specify divisor for attribute "' + attribute + '", instancing not supported', env.commandStr); - check$1.command(divisor >= 0, - 'invalid divisor for attribute "' + attribute + '"', env.commandStr); + 'invalid type for attribute ' + attribute, env.commandStr) + type = glTypes[value.type] } + var divisor = value.divisor | 0 check$1.optional(function () { - var command = env.commandStr; + if ('divisor' in value) { + check$1.command(divisor === 0 || extInstancing, + 'cannot specify divisor for attribute "' + attribute + '", instancing not supported', env.commandStr) + check$1.command(divisor >= 0, + 'invalid divisor for attribute "' + attribute + '"', env.commandStr) + } + + var command = env.commandStr var VALID_KEYS = [ 'buffer', @@ -7273,59 +7912,59 @@ function reglCore ( 'type', 'size', 'stride' - ]; + ] Object.keys(value).forEach(function (prop) { check$1.command( VALID_KEYS.indexOf(prop) >= 0, 'unknown parameter "' + prop + '" for attribute pointer "' + attribute + '" (valid parameters are ' + VALID_KEYS + ')', - command); - }); - }); + command) + }) + }) - record.buffer = buffer; - record.state = ATTRIB_STATE_POINTER; - record.size = size; - record.normalized = normalized; - record.type = type || buffer.dtype; - record.offset = offset; - record.stride = stride; - record.divisor = divisor; + record.buffer = buffer + record.state = ATTRIB_STATE_POINTER + record.size = size + record.normalized = normalized + record.type = type || buffer.dtype + record.offset = offset + record.stride = stride + record.divisor = divisor } } } attributeDefs[attribute] = createStaticDecl(function (env, scope) { - var cache = env.attribCache; + var cache = env.attribCache if (id in cache) { return cache[id] } var result = { isStream: false - }; - Object.keys(record).forEach(function (key) { - result[key] = record[key]; - }); - if (record.buffer) { - result.buffer = env.link(record.buffer); - result.type = result.type || (result.buffer + '.dtype'); } - cache[id] = result; + Object.keys(record).forEach(function (key) { + result[key] = record[key] + }) + if (record.buffer) { + result.buffer = env.link(record.buffer) + result.type = result.type || (result.buffer + '.dtype') + } + cache[id] = result return result - }); - }); + }) + }) Object.keys(dynamicAttributes).forEach(function (attribute) { - var dyn = dynamicAttributes[attribute]; + var dyn = dynamicAttributes[attribute] function appendAttributeCode (env, block) { - var VALUE = env.invoke(block, dyn); + var VALUE = env.invoke(block, dyn) - var shared = env.shared; - var constants = env.constants; + var shared = env.shared + var constants = env.constants - var IS_BUFFER_ARGS = shared.isBufferArgs; - var BUFFER_STATE = shared.buffer; + var IS_BUFFER_ARGS = shared.isBufferArgs + var BUFFER_STATE = shared.buffer // Perform validation on attribute check$1.optional(function () { @@ -7339,25 +7978,25 @@ function reglCore ( '("constant" in ' + VALUE + '&&(typeof ' + VALUE + '.constant==="number"||' + shared.isArrayLike + '(' + VALUE + '.constant))))', - 'invalid dynamic attribute "' + attribute + '"'); - }); + 'invalid dynamic attribute "' + attribute + '"') + }) // allocate names for result var result = { isStream: block.def(false) - }; - var defaultRecord = new AttributeRecord(); - defaultRecord.state = ATTRIB_STATE_POINTER; + } + var defaultRecord = new AttributeRecord() + defaultRecord.state = ATTRIB_STATE_POINTER Object.keys(defaultRecord).forEach(function (key) { - result[key] = block.def('' + defaultRecord[key]); - }); + result[key] = block.def('' + defaultRecord[key]) + }) - var BUFFER = result.buffer; - var TYPE = result.type; + var BUFFER = result.buffer + var TYPE = result.type block( 'if(', IS_BUFFER_ARGS, '(', VALUE, ')){', result.isStream, '=true;', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$1, ',', VALUE, ');', + BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, ');', TYPE, '=', BUFFER, '.dtype;', '}else{', BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, ');', @@ -7379,66 +8018,66 @@ function reglCore ( }).join(''), '}}else{', 'if(', IS_BUFFER_ARGS, '(', VALUE, '.buffer)){', - BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$1, ',', VALUE, '.buffer);', + BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, '.buffer);', '}else{', BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, '.buffer);', '}', TYPE, '="type" in ', VALUE, '?', constants.glTypes, '[', VALUE, '.type]:', BUFFER, '.dtype;', - result.normalized, '=!!', VALUE, '.normalized;'); + result.normalized, '=!!', VALUE, '.normalized;') function emitReadRecord (name) { - block(result[name], '=', VALUE, '.', name, '|0;'); + block(result[name], '=', VALUE, '.', name, '|0;') } - emitReadRecord('size'); - emitReadRecord('offset'); - emitReadRecord('stride'); - emitReadRecord('divisor'); + emitReadRecord('size') + emitReadRecord('offset') + emitReadRecord('stride') + emitReadRecord('divisor') - block('}}'); + block('}}') block.exit( 'if(', result.isStream, '){', BUFFER_STATE, '.destroyStream(', BUFFER, ');', - '}'); + '}') return result } - attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode); - }); + attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode) + }) return attributeDefs } function parseContext (context) { - var staticContext = context.static; - var dynamicContext = context.dynamic; - var result = {}; + var staticContext = context.static + var dynamicContext = context.dynamic + var result = {} Object.keys(staticContext).forEach(function (name) { - var value = staticContext[name]; + var value = staticContext[name] result[name] = createStaticDecl(function (env, scope) { if (typeof value === 'number' || typeof value === 'boolean') { return '' + value } else { return env.link(value) } - }); - }); + }) + }) Object.keys(dynamicContext).forEach(function (name) { - var dyn = dynamicContext[name]; + var dyn = dynamicContext[name] result[name] = createDynamicDecl(dyn, function (env, scope) { return env.invoke(scope, dyn) - }); - }); + }) + }) return result } function parseArguments (options, attributes, uniforms, context, env) { - var staticOptions = options.static; - var dynamicOptions = options.dynamic; + var staticOptions = options.static + var dynamicOptions = options.dynamic check$1.optional(function () { var KEY_NAMES = [ @@ -7450,51 +8089,86 @@ function reglCore ( S_OFFSET, S_COUNT, S_INSTANCES, - S_PROFILE - ].concat(GL_STATE_NAMES); + S_PROFILE, + S_VAO + ].concat(GL_STATE_NAMES) function checkKeys (dict) { Object.keys(dict).forEach(function (key) { check$1.command( KEY_NAMES.indexOf(key) >= 0, 'unknown parameter "' + key + '"', - env.commandStr); - }); + env.commandStr) + }) } - checkKeys(staticOptions); - checkKeys(dynamicOptions); - }); + checkKeys(staticOptions) + checkKeys(dynamicOptions) + }) - var framebuffer = parseFramebuffer(options, env); - var viewportAndScissor = parseViewportScissor(options, framebuffer, env); - var draw = parseDraw(options, env); - var state = parseGLState(options, env); - var shader = parseProgram(options, env); + var attribLocations = parseAttribLocations(options, attributes) + + var framebuffer = parseFramebuffer(options, env) + var viewportAndScissor = parseViewportScissor(options, framebuffer, env) + var draw = parseDraw(options, env) + var state = parseGLState(options, env) + var shader = parseProgram(options, env, attribLocations) function copyBox (name) { - var defn = viewportAndScissor[name]; + var defn = viewportAndScissor[name] if (defn) { - state[name] = defn; + state[name] = defn } } - copyBox(S_VIEWPORT); - copyBox(propName(S_SCISSOR_BOX)); + copyBox(S_VIEWPORT) + copyBox(propName(S_SCISSOR_BOX)) - var dirty = Object.keys(state).length > 0; + var dirty = Object.keys(state).length > 0 var result = { framebuffer: framebuffer, draw: draw, shader: shader, state: state, - dirty: dirty - }; + dirty: dirty, + scopeVAO: null, + drawVAO: null, + useVAO: false, + attributes: {} + } - result.profile = parseProfile(options, env); - result.uniforms = parseUniforms(uniforms, env); - result.attributes = parseAttributes(attributes, env); - result.context = parseContext(context, env); + result.profile = parseProfile(options, env) + result.uniforms = parseUniforms(uniforms, env) + result.drawVAO = result.scopeVAO = draw.vao + // special case: check if we can statically allocate a vertex array object for this program + if (!result.drawVAO && + shader.program && + !attribLocations && + extensions.angle_instanced_arrays && + draw.static.elements) { + var useVAO = true + var staticBindings = shader.program.attributes.map(function (attr) { + var binding = attributes.static[attr] + useVAO = useVAO && !!binding + return binding + }) + if (useVAO && staticBindings.length > 0) { + var vao = attributeState.getVAO(attributeState.createVAO({ + attributes: staticBindings, + elements: draw.static.elements + })) + result.drawVAO = new Declaration(null, null, null, function (env, scope) { + return env.link(vao) + }) + result.useVAO = true + } + } + if (attribLocations) { + result.useVAO = true + } else { + result.attributes = parseAttributes(attributes, env) + } + result.context = parseContext(context, env) return result } @@ -7504,18 +8178,23 @@ function reglCore ( // =================================================== // =================================================== function emitContext (env, scope, context) { - var shared = env.shared; - var CONTEXT = shared.context; + var shared = env.shared + var CONTEXT = shared.context - var contextEnter = env.scope(); + var contextEnter = env.scope() Object.keys(context).forEach(function (name) { - scope.save(CONTEXT, '.' + name); - var defn = context[name]; - contextEnter(CONTEXT, '.', name, '=', defn.append(env, scope), ';'); - }); + scope.save(CONTEXT, '.' + name) + var defn = context[name] + var value = defn.append(env, scope) + if (Array.isArray(value)) { + contextEnter(CONTEXT, '.', name, '=[', value.join(), '];') + } else { + contextEnter(CONTEXT, '.', name, '=', value, ';') + } + }) - scope(contextEnter); + scope(contextEnter) } // =================================================== @@ -7524,75 +8203,75 @@ function reglCore ( // =================================================== // =================================================== function emitPollFramebuffer (env, scope, framebuffer, skipCheck) { - var shared = env.shared; + var shared = env.shared - var GL = shared.gl; - var FRAMEBUFFER_STATE = shared.framebuffer; - var EXT_DRAW_BUFFERS; + var GL = shared.gl + var FRAMEBUFFER_STATE = shared.framebuffer + var EXT_DRAW_BUFFERS if (extDrawBuffers) { - EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers'); + EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers') } - var constants = env.constants; + var constants = env.constants - var DRAW_BUFFERS = constants.drawBuffer; - var BACK_BUFFER = constants.backBuffer; + var DRAW_BUFFERS = constants.drawBuffer + var BACK_BUFFER = constants.backBuffer - var NEXT; + var NEXT if (framebuffer) { - NEXT = framebuffer.append(env, scope); + NEXT = framebuffer.append(env, scope) } else { - NEXT = scope.def(FRAMEBUFFER_STATE, '.next'); + NEXT = scope.def(FRAMEBUFFER_STATE, '.next') } if (!skipCheck) { - scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){'); + scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){') } scope( 'if(', NEXT, '){', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',', NEXT, '.framebuffer);'); + GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',', NEXT, '.framebuffer);') if (extDrawBuffers) { scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', - DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);'); + DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);') } scope('}else{', - GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',null);'); + GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',null);') if (extDrawBuffers) { - scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');'); + scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');') } scope( '}', - FRAMEBUFFER_STATE, '.cur=', NEXT, ';'); + FRAMEBUFFER_STATE, '.cur=', NEXT, ';') if (!skipCheck) { - scope('}'); + scope('}') } } function emitPollState (env, scope, args) { - var shared = env.shared; + var shared = env.shared - var GL = shared.gl; + var GL = shared.gl - var CURRENT_VARS = env.current; - var NEXT_VARS = env.next; - var CURRENT_STATE = shared.current; - var NEXT_STATE = shared.next; + var CURRENT_VARS = env.current + var NEXT_VARS = env.next + var CURRENT_STATE = shared.current + var NEXT_STATE = shared.next - var block = env.cond(CURRENT_STATE, '.dirty'); + var block = env.cond(CURRENT_STATE, '.dirty') GL_STATE_NAMES.forEach(function (prop) { - var param = propName(prop); + var param = propName(prop) if (param in args.state) { return } - var NEXT, CURRENT; + var NEXT, CURRENT if (param in NEXT_VARS) { - NEXT = NEXT_VARS[param]; - CURRENT = CURRENT_VARS[param]; + NEXT = NEXT_VARS[param] + CURRENT = CURRENT_VARS[param] var parts = loop(currentState[param].length, function (i) { return block.def(NEXT, '[', i, ']') - }); + }) block(env.cond(parts.map(function (p, i) { return p + '!==' + CURRENT + '[' + i + ']' }).join('||')) @@ -7600,83 +8279,83 @@ function reglCore ( GL, '.', GL_VARIABLES[param], '(', parts, ');', parts.map(function (p, i) { return CURRENT + '[' + i + ']=' + p - }).join(';'), ';')); + }).join(';'), ';')) } else { - NEXT = block.def(NEXT_STATE, '.', param); - var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param); - block(ifte); + NEXT = block.def(NEXT_STATE, '.', param) + var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param) + block(ifte) if (param in GL_FLAGS) { ifte( env.cond(NEXT) - .then(GL, '.enable(', GL_FLAGS[param], ');') - .else(GL, '.disable(', GL_FLAGS[param], ');'), - CURRENT_STATE, '.', param, '=', NEXT, ';'); + .then(GL, '.enable(', GL_FLAGS[param], ');') + .else(GL, '.disable(', GL_FLAGS[param], ');'), + CURRENT_STATE, '.', param, '=', NEXT, ';') } else { ifte( GL, '.', GL_VARIABLES[param], '(', NEXT, ');', - CURRENT_STATE, '.', param, '=', NEXT, ';'); + CURRENT_STATE, '.', param, '=', NEXT, ';') } } - }); + }) if (Object.keys(args.state).length === 0) { - block(CURRENT_STATE, '.dirty=false;'); + block(CURRENT_STATE, '.dirty=false;') } - scope(block); + scope(block) } function emitSetOptions (env, scope, options, filter) { - var shared = env.shared; - var CURRENT_VARS = env.current; - var CURRENT_STATE = shared.current; - var GL = shared.gl; + var shared = env.shared + var CURRENT_VARS = env.current + var CURRENT_STATE = shared.current + var GL = shared.gl sortState(Object.keys(options)).forEach(function (param) { - var defn = options[param]; + var defn = options[param] if (filter && !filter(defn)) { return } - var variable = defn.append(env, scope); + var variable = defn.append(env, scope) if (GL_FLAGS[param]) { - var flag = GL_FLAGS[param]; + var flag = GL_FLAGS[param] if (isStatic(defn)) { if (variable) { - scope(GL, '.enable(', flag, ');'); + scope(GL, '.enable(', flag, ');') } else { - scope(GL, '.disable(', flag, ');'); + scope(GL, '.disable(', flag, ');') } } else { scope(env.cond(variable) .then(GL, '.enable(', flag, ');') - .else(GL, '.disable(', flag, ');')); + .else(GL, '.disable(', flag, ');')) } - scope(CURRENT_STATE, '.', param, '=', variable, ';'); + scope(CURRENT_STATE, '.', param, '=', variable, ';') } else if (isArrayLike(variable)) { - var CURRENT = CURRENT_VARS[param]; + var CURRENT = CURRENT_VARS[param] scope( GL, '.', GL_VARIABLES[param], '(', variable, ');', variable.map(function (v, i) { return CURRENT + '[' + i + ']=' + v - }).join(';'), ';'); + }).join(';'), ';') } else { scope( GL, '.', GL_VARIABLES[param], '(', variable, ');', - CURRENT_STATE, '.', param, '=', variable, ';'); + CURRENT_STATE, '.', param, '=', variable, ';') } - }); + }) } function injectExtensions (env, scope) { if (extInstancing) { env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays'); + env.shared.extensions, '.angle_instanced_arrays') } } function emitProfile (env, scope, args, useScope, incrementCounter) { - var shared = env.shared; - var STATS = env.stats; - var CURRENT_STATE = shared.current; - var TIMER = shared.timer; - var profileArg = args.profile; + var shared = env.shared + var STATS = env.stats + var CURRENT_STATE = shared.current + var TIMER = shared.timer + var profileArg = args.profile function perfCounter () { if (typeof performance === 'undefined') { @@ -7686,73 +8365,73 @@ function reglCore ( } } - var CPU_START, QUERY_COUNTER; + var CPU_START, QUERY_COUNTER function emitProfileStart (block) { - CPU_START = scope.def(); - block(CPU_START, '=', perfCounter(), ';'); + CPU_START = scope.def() + block(CPU_START, '=', perfCounter(), ';') if (typeof incrementCounter === 'string') { - block(STATS, '.count+=', incrementCounter, ';'); + block(STATS, '.count+=', incrementCounter, ';') } else { - block(STATS, '.count++;'); + block(STATS, '.count++;') } if (timer) { if (useScope) { - QUERY_COUNTER = scope.def(); - block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();'); + QUERY_COUNTER = scope.def() + block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();') } else { - block(TIMER, '.beginQuery(', STATS, ');'); + block(TIMER, '.beginQuery(', STATS, ');') } } } function emitProfileEnd (block) { - block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';'); + block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';') if (timer) { if (useScope) { block(TIMER, '.pushScopeStats(', QUERY_COUNTER, ',', TIMER, '.getNumPendingQueries(),', - STATS, ');'); + STATS, ');') } else { - block(TIMER, '.endQuery();'); + block(TIMER, '.endQuery();') } } } function scopeProfile (value) { - var prev = scope.def(CURRENT_STATE, '.profile'); - scope(CURRENT_STATE, '.profile=', value, ';'); - scope.exit(CURRENT_STATE, '.profile=', prev, ';'); + var prev = scope.def(CURRENT_STATE, '.profile') + scope(CURRENT_STATE, '.profile=', value, ';') + scope.exit(CURRENT_STATE, '.profile=', prev, ';') } - var USE_PROFILE; + var USE_PROFILE if (profileArg) { if (isStatic(profileArg)) { if (profileArg.enable) { - emitProfileStart(scope); - emitProfileEnd(scope.exit); - scopeProfile('true'); + emitProfileStart(scope) + emitProfileEnd(scope.exit) + scopeProfile('true') } else { - scopeProfile('false'); + scopeProfile('false') } return } - USE_PROFILE = profileArg.append(env, scope); - scopeProfile(USE_PROFILE); + USE_PROFILE = profileArg.append(env, scope) + scopeProfile(USE_PROFILE) } else { - USE_PROFILE = scope.def(CURRENT_STATE, '.profile'); + USE_PROFILE = scope.def(CURRENT_STATE, '.profile') } - var start = env.block(); - emitProfileStart(start); - scope('if(', USE_PROFILE, '){', start, '}'); - var end = env.block(); - emitProfileEnd(end); - scope.exit('if(', USE_PROFILE, '){', end, '}'); + var start = env.block() + emitProfileStart(start) + scope('if(', USE_PROFILE, '){', start, '}') + var end = env.block() + emitProfileEnd(end) + scope.exit('if(', USE_PROFILE, '){', end, '}') } function emitAttributes (env, scope, args, attributes, filter) { - var shared = env.shared; + var shared = env.shared function typeLength (x) { switch (x) { @@ -7774,38 +8453,38 @@ function reglCore ( } function emitBindAttribute (ATTRIBUTE, size, record) { - var GL = shared.gl; + var GL = shared.gl - var LOCATION = scope.def(ATTRIBUTE, '.location'); - var BINDING = scope.def(shared.attributes, '[', LOCATION, ']'); + var LOCATION = scope.def(ATTRIBUTE, '.location') + var BINDING = scope.def(shared.attributes, '[', LOCATION, ']') - var STATE = record.state; - var BUFFER = record.buffer; + var STATE = record.state + var BUFFER = record.buffer var CONST_COMPONENTS = [ record.x, record.y, record.z, record.w - ]; + ] var COMMON_KEYS = [ 'buffer', 'normalized', 'offset', 'stride' - ]; + ] function emitBuffer () { scope( 'if(!', BINDING, '.buffer){', - GL, '.enableVertexAttribArray(', LOCATION, ');}'); + GL, '.enableVertexAttribArray(', LOCATION, ');}') - var TYPE = record.type; - var SIZE; + var TYPE = record.type + var SIZE if (!record.size) { - SIZE = size; + SIZE = size } else { - SIZE = scope.def(record.size, '||', size); + SIZE = scope.def(record.size, '||', size) } scope('if(', @@ -7815,7 +8494,7 @@ function reglCore ( return BINDING + '.' + key + '!==' + record[key] }).join('||'), '){', - GL, '.bindBuffer(', GL_ARRAY_BUFFER$1, ',', BUFFER, '.buffer);', + GL, '.bindBuffer(', GL_ARRAY_BUFFER$2, ',', BUFFER, '.buffer);', GL, '.vertexAttribPointer(', [ LOCATION, SIZE, @@ -7829,14 +8508,14 @@ function reglCore ( COMMON_KEYS.map(function (key) { return BINDING + '.' + key + '=' + record[key] + ';' }).join(''), - '}'); + '}') if (extInstancing) { - var DIVISOR = record.divisor; + var DIVISOR = record.divisor scope( 'if(', BINDING, '.divisor!==', DIVISOR, '){', env.instancing, '.vertexAttribDivisorANGLE(', [LOCATION, DIVISOR], ');', - BINDING, '.divisor=', DIVISOR, ';}'); + BINDING, '.divisor=', DIVISOR, ';}') } } @@ -7852,74 +8531,87 @@ function reglCore ( CUTE_COMPONENTS.map(function (c, i) { return BINDING + '.' + c + '=' + CONST_COMPONENTS[i] + ';' }).join(''), - '}'); + '}') } if (STATE === ATTRIB_STATE_POINTER) { - emitBuffer(); + emitBuffer() } else if (STATE === ATTRIB_STATE_CONSTANT) { - emitConstant(); + emitConstant() } else { - scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){'); - emitBuffer(); - scope('}else{'); - emitConstant(); - scope('}'); + scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){') + emitBuffer() + scope('}else{') + emitConstant() + scope('}') } } attributes.forEach(function (attribute) { - var name = attribute.name; - var arg = args.attributes[name]; - var record; + var name = attribute.name + var arg = args.attributes[name] + var record if (arg) { if (!filter(arg)) { return } - record = arg.append(env, scope); + record = arg.append(env, scope) } else { if (!filter(SCOPE_DECL)) { return } - var scopeAttrib = env.scopeAttrib(name); + var scopeAttrib = env.scopeAttrib(name) check$1.optional(function () { env.assert(scope, scopeAttrib + '.state', - 'missing attribute ' + name); - }); - record = {}; + 'missing attribute ' + name) + }) + record = {} Object.keys(new AttributeRecord()).forEach(function (key) { - record[key] = scope.def(scopeAttrib, '.', key); - }); + record[key] = scope.def(scopeAttrib, '.', key) + }) } emitBindAttribute( - env.link(attribute), typeLength(attribute.info.type), record); - }); + env.link(attribute), typeLength(attribute.info.type), record) + }) } - function emitUniforms (env, scope, args, uniforms, filter) { - var shared = env.shared; - var GL = shared.gl; + function emitUniforms (env, scope, args, uniforms, filter, isBatchInnerLoop) { + var shared = env.shared + var GL = shared.gl - var infix; + var definedArrUniforms = {} + var infix for (var i = 0; i < uniforms.length; ++i) { - var uniform = uniforms[i]; - var name = uniform.name; - var type = uniform.info.type; - var arg = args.uniforms[name]; - var UNIFORM = env.link(uniform); - var LOCATION = UNIFORM + '.location'; + var uniform = uniforms[i] + var name = uniform.name + var type = uniform.info.type + var size = uniform.info.size + var arg = args.uniforms[name] + if (size > 1) { + // either foo[n] or foos, avoid define both + if (!arg) { + continue + } + var arrUniformName = name.replace('[0]', '') + if (definedArrUniforms[arrUniformName]) { + continue + } + definedArrUniforms[arrUniformName] = 1 + } + var UNIFORM = env.link(uniform) + var LOCATION = UNIFORM + '.location' - var VALUE; + var VALUE if (arg) { if (!filter(arg)) { continue } if (isStatic(arg)) { - var value = arg.value; + var value = arg.value check$1.command( value !== null && typeof value !== 'undefined', - 'missing uniform "' + name + '"', env.commandStr); + 'missing uniform "' + name + '"', env.commandStr) if (type === GL_SAMPLER_2D || type === GL_SAMPLER_CUBE) { check$1.command( typeof value === 'function' && @@ -7929,352 +8621,439 @@ function reglCore ( (type === GL_SAMPLER_CUBE && (value._reglType === 'textureCube' || value._reglType === 'framebufferCube'))), - 'invalid texture for uniform ' + name, env.commandStr); - var TEX_VALUE = env.link(value._texture || value.color[0]._texture); - scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());'); - scope.exit(TEX_VALUE, '.unbind();'); + 'invalid texture for uniform ' + name, env.commandStr) + var TEX_VALUE = env.link(value._texture || value.color[0]._texture) + scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());') + scope.exit(TEX_VALUE, '.unbind();') } else if ( type === GL_FLOAT_MAT2 || type === GL_FLOAT_MAT3 || type === GL_FLOAT_MAT4) { check$1.optional(function () { check$1.command(isArrayLike(value), - 'invalid matrix for uniform ' + name, env.commandStr); + 'invalid matrix for uniform ' + name, env.commandStr) check$1.command( (type === GL_FLOAT_MAT2 && value.length === 4) || (type === GL_FLOAT_MAT3 && value.length === 9) || (type === GL_FLOAT_MAT4 && value.length === 16), - 'invalid length for matrix uniform ' + name, env.commandStr); - }); + 'invalid length for matrix uniform ' + name, env.commandStr) + }) var MAT_VALUE = env.global.def('new Float32Array([' + - Array.prototype.slice.call(value) + '])'); - var dim = 2; + Array.prototype.slice.call(value) + '])') + var dim = 2 if (type === GL_FLOAT_MAT3) { - dim = 3; + dim = 3 } else if (type === GL_FLOAT_MAT4) { - dim = 4; + dim = 4 } scope( GL, '.uniformMatrix', dim, 'fv(', - LOCATION, ',false,', MAT_VALUE, ');'); + LOCATION, ',false,', MAT_VALUE, ');') } else { switch (type) { case GL_FLOAT$8: - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr); - infix = '1f'; + if (size === 1) { + check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) + } else { + check$1.command( + isArrayLike(value) && (value.length === size), + 'uniform ' + name, env.commandStr) + } + infix = '1f' break case GL_FLOAT_VEC2: check$1.command( - isArrayLike(value) && value.length === 2, - 'uniform ' + name, env.commandStr); - infix = '2f'; + isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + 'uniform ' + name, env.commandStr) + infix = '2f' break case GL_FLOAT_VEC3: check$1.command( - isArrayLike(value) && value.length === 3, - 'uniform ' + name, env.commandStr); - infix = '3f'; + isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + 'uniform ' + name, env.commandStr) + infix = '3f' break case GL_FLOAT_VEC4: check$1.command( - isArrayLike(value) && value.length === 4, - 'uniform ' + name, env.commandStr); - infix = '4f'; + isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + 'uniform ' + name, env.commandStr) + infix = '4f' break case GL_BOOL: - check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr); - infix = '1i'; + if (size === 1) { + check$1.commandType(value, 'boolean', 'uniform ' + name, env.commandStr) + } else { + check$1.command( + isArrayLike(value) && (value.length === size), + 'uniform ' + name, env.commandStr) + } + infix = '1i' break case GL_INT$3: - check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr); - infix = '1i'; + if (size === 1) { + check$1.commandType(value, 'number', 'uniform ' + name, env.commandStr) + } else { + check$1.command( + isArrayLike(value) && (value.length === size), + 'uniform ' + name, env.commandStr) + } + infix = '1i' break case GL_BOOL_VEC2: check$1.command( - isArrayLike(value) && value.length === 2, - 'uniform ' + name, env.commandStr); - infix = '2i'; + isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + 'uniform ' + name, env.commandStr) + infix = '2i' break case GL_INT_VEC2: check$1.command( - isArrayLike(value) && value.length === 2, - 'uniform ' + name, env.commandStr); - infix = '2i'; + isArrayLike(value) && (value.length && value.length % 2 === 0 && value.length <= size * 2), + 'uniform ' + name, env.commandStr) + infix = '2i' break case GL_BOOL_VEC3: check$1.command( - isArrayLike(value) && value.length === 3, - 'uniform ' + name, env.commandStr); - infix = '3i'; + isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + 'uniform ' + name, env.commandStr) + infix = '3i' break case GL_INT_VEC3: check$1.command( - isArrayLike(value) && value.length === 3, - 'uniform ' + name, env.commandStr); - infix = '3i'; + isArrayLike(value) && (value.length && value.length % 3 === 0 && value.length <= size * 3), + 'uniform ' + name, env.commandStr) + infix = '3i' break case GL_BOOL_VEC4: check$1.command( - isArrayLike(value) && value.length === 4, - 'uniform ' + name, env.commandStr); - infix = '4i'; + isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + 'uniform ' + name, env.commandStr) + infix = '4i' break case GL_INT_VEC4: check$1.command( - isArrayLike(value) && value.length === 4, - 'uniform ' + name, env.commandStr); - infix = '4i'; + isArrayLike(value) && (value.length && value.length % 4 === 0 && value.length <= size * 4), + 'uniform ' + name, env.commandStr) + infix = '4i' break } + if (size > 1) { + infix += 'v' + value = env.global.def('[' + + Array.prototype.slice.call(value) + ']') + } else { + value = isArrayLike(value) ? Array.prototype.slice.call(value) : value + } scope(GL, '.uniform', infix, '(', LOCATION, ',', - isArrayLike(value) ? Array.prototype.slice.call(value) : value, - ');'); + value, + ');') } continue } else { - VALUE = arg.append(env, scope); + VALUE = arg.append(env, scope) } } else { if (!filter(SCOPE_DECL)) { continue } - VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']'); + VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']') } if (type === GL_SAMPLER_2D) { + check$1(!Array.isArray(VALUE), 'must specify a scalar prop for textures') scope( 'if(', VALUE, '&&', VALUE, '._reglType==="framebuffer"){', VALUE, '=', VALUE, '.color[0];', - '}'); + '}') } else if (type === GL_SAMPLER_CUBE) { + check$1(!Array.isArray(VALUE), 'must specify a scalar prop for cube maps') scope( 'if(', VALUE, '&&', VALUE, '._reglType==="framebufferCube"){', VALUE, '=', VALUE, '.color[0];', - '}'); + '}') } // perform type validation check$1.optional(function () { - function check (pred, message) { + function emitCheck (pred, message) { env.assert(scope, pred, - 'bad data or missing for uniform "' + name + '". ' + message); + 'bad data or missing for uniform "' + name + '". ' + message) } - function checkType (type) { - check( - 'typeof ' + VALUE + '==="' + type + '"', - 'invalid type, expected ' + type); + function checkType (type, size) { + if (size === 1) { + check$1(!Array.isArray(VALUE), 'must not specify an array type for uniform') + } + emitCheck( + 'Array.isArray(' + VALUE + ') && typeof ' + VALUE + '[0]===" ' + type + '"' + + ' || typeof ' + VALUE + '==="' + type + '"', + 'invalid type, expected ' + type) } - function checkVector (n, type) { - check( - shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length===' + n, - 'invalid vector, should have length ' + n, env.commandStr); + function checkVector (n, type, size) { + if (Array.isArray(VALUE)) { + check$1(VALUE.length && VALUE.length % n === 0 && VALUE.length <= n * size, 'must have length of ' + (size === 1 ? '' : 'n * ') + n) + } else { + emitCheck( + shared.isArrayLike + '(' + VALUE + ')&&' + VALUE + '.length && ' + VALUE + '.length % ' + n + ' === 0' + + ' && ' + VALUE + '.length<=' + n * size, + 'invalid vector, should have length of ' + (size === 1 ? '' : 'n * ') + n, env.commandStr) + } } function checkTexture (target) { - check( + check$1(!Array.isArray(VALUE), 'must not specify a value type') + emitCheck( 'typeof ' + VALUE + '==="function"&&' + VALUE + '._reglType==="texture' + (target === GL_TEXTURE_2D$3 ? '2d' : 'Cube') + '"', - 'invalid texture type', env.commandStr); + 'invalid texture type', env.commandStr) } switch (type) { case GL_INT$3: - checkType('number'); + checkType('number', size) break case GL_INT_VEC2: - checkVector(2, 'number'); + checkVector(2, 'number', size) break case GL_INT_VEC3: - checkVector(3, 'number'); + checkVector(3, 'number', size) break case GL_INT_VEC4: - checkVector(4, 'number'); + checkVector(4, 'number', size) break case GL_FLOAT$8: - checkType('number'); + checkType('number', size) break case GL_FLOAT_VEC2: - checkVector(2, 'number'); + checkVector(2, 'number', size) break case GL_FLOAT_VEC3: - checkVector(3, 'number'); + checkVector(3, 'number', size) break case GL_FLOAT_VEC4: - checkVector(4, 'number'); + checkVector(4, 'number', size) break case GL_BOOL: - checkType('boolean'); + checkType('boolean', size) break case GL_BOOL_VEC2: - checkVector(2, 'boolean'); + checkVector(2, 'boolean', size) break case GL_BOOL_VEC3: - checkVector(3, 'boolean'); + checkVector(3, 'boolean', size) break case GL_BOOL_VEC4: - checkVector(4, 'boolean'); + checkVector(4, 'boolean', size) break case GL_FLOAT_MAT2: - checkVector(4, 'number'); + checkVector(4, 'number', size) break case GL_FLOAT_MAT3: - checkVector(9, 'number'); + checkVector(9, 'number', size) break case GL_FLOAT_MAT4: - checkVector(16, 'number'); + checkVector(16, 'number', size) break case GL_SAMPLER_2D: - checkTexture(GL_TEXTURE_2D$3); + checkTexture(GL_TEXTURE_2D$3) break case GL_SAMPLER_CUBE: - checkTexture(GL_TEXTURE_CUBE_MAP$2); + checkTexture(GL_TEXTURE_CUBE_MAP$2) break } - }); + }) - var unroll = 1; + var unroll = 1 switch (type) { case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: - var TEX = scope.def(VALUE, '._texture'); - scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());'); - scope.exit(TEX, '.unbind();'); + var TEX = scope.def(VALUE, '._texture') + scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());') + scope.exit(TEX, '.unbind();') continue case GL_INT$3: case GL_BOOL: - infix = '1i'; + infix = '1i' break case GL_INT_VEC2: case GL_BOOL_VEC2: - infix = '2i'; - unroll = 2; + infix = '2i' + unroll = 2 break case GL_INT_VEC3: case GL_BOOL_VEC3: - infix = '3i'; - unroll = 3; + infix = '3i' + unroll = 3 break case GL_INT_VEC4: case GL_BOOL_VEC4: - infix = '4i'; - unroll = 4; + infix = '4i' + unroll = 4 break case GL_FLOAT$8: - infix = '1f'; + infix = '1f' break case GL_FLOAT_VEC2: - infix = '2f'; - unroll = 2; + infix = '2f' + unroll = 2 break case GL_FLOAT_VEC3: - infix = '3f'; - unroll = 3; + infix = '3f' + unroll = 3 break case GL_FLOAT_VEC4: - infix = '4f'; - unroll = 4; + infix = '4f' + unroll = 4 break case GL_FLOAT_MAT2: - infix = 'Matrix2fv'; + infix = 'Matrix2fv' break case GL_FLOAT_MAT3: - infix = 'Matrix3fv'; + infix = 'Matrix3fv' break case GL_FLOAT_MAT4: - infix = 'Matrix4fv'; + infix = 'Matrix4fv' break } - scope(GL, '.uniform', infix, '(', LOCATION, ','); - if (infix.charAt(0) === 'M') { - var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2); - var STORAGE = env.global.def('new Float32Array(', matSize, ')'); - scope( - 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(', - loop(matSize, function (i) { - return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']' - }), ',', STORAGE, ')'); - } else if (unroll > 1) { - scope(loop(unroll, function (i) { - return VALUE + '[' + i + ']' - })); - } else { - scope(VALUE); + if (infix.indexOf('Matrix') === -1 && size > 1) { + infix += 'v' + unroll = 1 + } + + if (infix.charAt(0) === 'M') { + scope(GL, '.uniform', infix, '(', LOCATION, ',') + var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2) + var STORAGE = env.global.def('new Float32Array(', matSize, ')') + if (Array.isArray(VALUE)) { + scope( + 'false,(', + loop(matSize, function (i) { + return STORAGE + '[' + i + ']=' + VALUE[i] + }), ',', STORAGE, ')') + } else { + scope( + 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(', + loop(matSize, function (i) { + return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']' + }), ',', STORAGE, ')') + } + scope(');') + } else if (unroll > 1) { + var prev = [] + var cur = [] + for (var j = 0; j < unroll; ++j) { + if (Array.isArray(VALUE)) { + cur.push(VALUE[j]) + } else { + cur.push(scope.def(VALUE + '[' + j + ']')) + } + if (isBatchInnerLoop) { + prev.push(scope.def()) + } + } + if (isBatchInnerLoop) { + scope('if(!', env.batchId, '||', prev.map(function (p, i) { + return p + '!==' + cur[i] + }).join('||'), '){', prev.map(function (p, i) { + return p + '=' + cur[i] + ';' + }).join('')) + } + scope(GL, '.uniform', infix, '(', LOCATION, ',', cur.join(','), ');') + if (isBatchInnerLoop) { + scope('}') + } + } else { + check$1(!Array.isArray(VALUE), 'uniform value must not be an array') + if (isBatchInnerLoop) { + var prevS = scope.def() + scope('if(!', env.batchId, '||', prevS, '!==', VALUE, '){', + prevS, '=', VALUE, ';') + } + scope(GL, '.uniform', infix, '(', LOCATION, ',', VALUE, ');') + if (isBatchInnerLoop) { + scope('}') + } } - scope(');'); } } function emitDraw (env, outer, inner, args) { - var shared = env.shared; - var GL = shared.gl; - var DRAW_STATE = shared.draw; + var shared = env.shared + var GL = shared.gl + var DRAW_STATE = shared.draw - var drawOptions = args.draw; + var drawOptions = args.draw function emitElements () { - var defn = drawOptions.elements; - var ELEMENTS; - var scope = outer; + var defn = drawOptions.elements + var ELEMENTS + var scope = outer if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner; + scope = inner + } + ELEMENTS = defn.append(env, scope) + if (drawOptions.elementsActive) { + scope( + 'if(' + ELEMENTS + ')' + + GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);') } - ELEMENTS = defn.append(env, scope); } else { - ELEMENTS = scope.def(DRAW_STATE, '.', S_ELEMENTS); - } - if (ELEMENTS) { + ELEMENTS = scope.def() scope( - 'if(' + ELEMENTS + ')' + - GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$1 + ',' + ELEMENTS + '.buffer.buffer);'); + ELEMENTS, '=', DRAW_STATE, '.', S_ELEMENTS, ';', + 'if(', ELEMENTS, '){', + GL, '.bindBuffer(', GL_ELEMENT_ARRAY_BUFFER$2, ',', ELEMENTS, '.buffer.buffer);}', + 'else if(', shared.vao, '.currentVAO){', + ELEMENTS, '=', env.shared.elements + '.getElements(' + shared.vao, '.currentVAO.elements);', + (!extVertexArrays ? 'if(' + ELEMENTS + ')' + GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$2 + ',' + ELEMENTS + '.buffer.buffer);' : ''), + '}') } return ELEMENTS } function emitCount () { - var defn = drawOptions.count; - var COUNT; - var scope = outer; + var defn = drawOptions.count + var COUNT + var scope = outer if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { - scope = inner; + scope = inner } - COUNT = defn.append(env, scope); + COUNT = defn.append(env, scope) check$1.optional(function () { if (defn.MISSING) { - env.assert(outer, 'false', 'missing vertex count'); + env.assert(outer, 'false', 'missing vertex count') } if (defn.DYNAMIC) { - env.assert(scope, COUNT + '>=0', 'missing vertex count'); + env.assert(scope, COUNT + '>=0', 'missing vertex count') } - }); + }) } else { - COUNT = scope.def(DRAW_STATE, '.', S_COUNT); + COUNT = scope.def(DRAW_STATE, '.', S_COUNT) check$1.optional(function () { - env.assert(scope, COUNT + '>=0', 'missing vertex count'); - }); + env.assert(scope, COUNT + '>=0', 'missing vertex count') + }) } return COUNT } - var ELEMENTS = emitElements(); + var ELEMENTS = emitElements() function emitValue (name) { - var defn = drawOptions[name]; + var defn = drawOptions[name] if (defn) { if ((defn.contextDep && args.contextDynamic) || defn.propDep) { return defn.append(env, inner) @@ -8286,28 +9065,28 @@ function reglCore ( } } - var PRIMITIVE = emitValue(S_PRIMITIVE); - var OFFSET = emitValue(S_OFFSET); + var PRIMITIVE = emitValue(S_PRIMITIVE) + var OFFSET = emitValue(S_OFFSET) - var COUNT = emitCount(); + var COUNT = emitCount() if (typeof COUNT === 'number') { if (COUNT === 0) { return } } else { - inner('if(', COUNT, '){'); - inner.exit('}'); + inner('if(', COUNT, '){') + inner.exit('}') } - var INSTANCES, EXT_INSTANCING; + var INSTANCES, EXT_INSTANCING if (extInstancing) { - INSTANCES = emitValue(S_INSTANCES); - EXT_INSTANCING = env.instancing; + INSTANCES = emitValue(S_INSTANCES) + EXT_INSTANCING = env.instancing } - var ELEMENT_TYPE = ELEMENTS + '.type'; + var ELEMENT_TYPE = ELEMENTS + '.type' - var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements); + var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements) && !drawOptions.vaoActive function emitInstancing () { function drawElements () { @@ -8317,26 +9096,26 @@ function reglCore ( ELEMENT_TYPE, OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$8 + ')>>1)', INSTANCES - ], ');'); + ], ');') } function drawArrays () { inner(EXT_INSTANCING, '.drawArraysInstancedANGLE(', - [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');'); + [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');') } - if (ELEMENTS) { + if (ELEMENTS && ELEMENTS !== 'null') { if (!elementsStatic) { - inner('if(', ELEMENTS, '){'); - drawElements(); - inner('}else{'); - drawArrays(); - inner('}'); + inner('if(', ELEMENTS, '){') + drawElements() + inner('}else{') + drawArrays() + inner('}') } else { - drawElements(); + drawElements() } } else { - drawArrays(); + drawArrays() } } @@ -8347,55 +9126,55 @@ function reglCore ( COUNT, ELEMENT_TYPE, OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$8 + ')>>1)' - ] + ');'); + ] + ');') } function drawArrays () { - inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');'); + inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');') } - if (ELEMENTS) { + if (ELEMENTS && ELEMENTS !== 'null') { if (!elementsStatic) { - inner('if(', ELEMENTS, '){'); - drawElements(); - inner('}else{'); - drawArrays(); - inner('}'); + inner('if(', ELEMENTS, '){') + drawElements() + inner('}else{') + drawArrays() + inner('}') } else { - drawElements(); + drawElements() } } else { - drawArrays(); + drawArrays() } } if (extInstancing && (typeof INSTANCES !== 'number' || INSTANCES >= 0)) { if (typeof INSTANCES === 'string') { - inner('if(', INSTANCES, '>0){'); - emitInstancing(); - inner('}else if(', INSTANCES, '<0){'); - emitRegular(); - inner('}'); + inner('if(', INSTANCES, '>0){') + emitInstancing() + inner('}else if(', INSTANCES, '<0){') + emitRegular() + inner('}') } else { - emitInstancing(); + emitInstancing() } } else { - emitRegular(); + emitRegular() } } function createBody (emitBody, parentEnv, args, program, count) { - var env = createREGLEnvironment(); - var scope = env.proc('body', count); + var env = createREGLEnvironment() + var scope = env.proc('body', count) check$1.optional(function () { - env.commandStr = parentEnv.commandStr; - env.command = env.link(parentEnv.commandStr); - }); + env.commandStr = parentEnv.commandStr + env.command = env.link(parentEnv.commandStr) + }) if (extInstancing) { env.instancing = scope.def( - env.shared.extensions, '.angle_instanced_arrays'); + env.shared.extensions, '.angle_instanced_arrays') } - emitBody(env, scope, args, program); + emitBody(env, scope, args, program) return env.compile().body } @@ -8405,38 +9184,48 @@ function reglCore ( // =================================================== // =================================================== function emitDrawBody (env, draw, args, program) { - injectExtensions(env, draw); - emitAttributes(env, draw, args, program.attributes, function () { - return true - }); + injectExtensions(env, draw) + if (args.useVAO) { + if (args.drawVAO) { + draw(env.shared.vao, '.setVAO(', args.drawVAO.append(env, draw), ');') + } else { + draw(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') + } + } else { + draw(env.shared.vao, '.setVAO(null);') + emitAttributes(env, draw, args, program.attributes, function () { + return true + }) + } emitUniforms(env, draw, args, program.uniforms, function () { return true - }); - emitDraw(env, draw, draw, args); + }, false) + emitDraw(env, draw, draw, args) } function emitDrawProc (env, args) { - var draw = env.proc('draw', 1); + var draw = env.proc('draw', 1) - injectExtensions(env, draw); + injectExtensions(env, draw) - emitContext(env, draw, args.context); - emitPollFramebuffer(env, draw, args.framebuffer); + emitContext(env, draw, args.context) + emitPollFramebuffer(env, draw, args.framebuffer) - emitPollState(env, draw, args); - emitSetOptions(env, draw, args.state); + emitPollState(env, draw, args) + emitSetOptions(env, draw, args.state) - emitProfile(env, draw, args, false, true); + emitProfile(env, draw, args, false, true) - var program = args.shader.progVar.append(env, draw); - draw(env.shared.gl, '.useProgram(', program, '.program);'); + var program = args.shader.progVar.append(env, draw) + draw(env.shared.gl, '.useProgram(', program, '.program);') if (args.shader.program) { - emitDrawBody(env, draw, args, args.shader.program); + emitDrawBody(env, draw, args, args.shader.program) } else { - var drawCache = env.global.def('{}'); - var PROG_ID = draw.def(program, '.id'); - var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']'); + draw(env.shared.vao, '.setVAO(null);') + var drawCache = env.global.def('{}') + var PROG_ID = draw.def(program, '.id') + var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']') draw( env.cond(CACHED_PROC) .then(CACHED_PROC, '.call(this,a0);') @@ -8445,11 +9234,14 @@ function reglCore ( env.link(function (program) { return createBody(emitDrawBody, env, args, program, 1) }), '(', program, ');', - CACHED_PROC, '.call(this,a0);')); + CACHED_PROC, '.call(this,a0);')) } if (Object.keys(args.state).length > 0) { - draw(env.shared.current, '.dirty=true;'); + draw(env.shared.current, '.dirty=true;') + } + if (env.shared.vao) { + draw(env.shared.vao, '.setVAO(null);') } } @@ -8460,33 +9252,33 @@ function reglCore ( // =================================================== function emitBatchDynamicShaderBody (env, scope, args, program) { - env.batchId = 'a1'; + env.batchId = 'a1' - injectExtensions(env, scope); + injectExtensions(env, scope) function all () { return true } - emitAttributes(env, scope, args, program.attributes, all); - emitUniforms(env, scope, args, program.uniforms, all); - emitDraw(env, scope, scope, args); + emitAttributes(env, scope, args, program.attributes, all) + emitUniforms(env, scope, args, program.uniforms, all, false) + emitDraw(env, scope, scope, args) } function emitBatchBody (env, scope, args, program) { - injectExtensions(env, scope); + injectExtensions(env, scope) - var contextDynamic = args.contextDep; + var contextDynamic = args.contextDep - var BATCH_ID = scope.def(); - var PROP_LIST = 'a0'; - var NUM_PROPS = 'a1'; - var PROPS = scope.def(); - env.shared.props = PROPS; - env.batchId = BATCH_ID; + var BATCH_ID = scope.def() + var PROP_LIST = 'a0' + var NUM_PROPS = 'a1' + var PROPS = scope.def() + env.shared.props = PROPS + env.batchId = BATCH_ID - var outer = env.scope(); - var inner = env.scope(); + var outer = env.scope() + var inner = env.scope() scope( outer.entry, @@ -8494,7 +9286,7 @@ function reglCore ( PROPS, '=', PROP_LIST, '[', BATCH_ID, '];', inner, '}', - outer.exit); + outer.exit) function isInnerDefn (defn) { return ((defn.contextDep && contextDynamic) || defn.propDep) @@ -8505,22 +9297,22 @@ function reglCore ( } if (args.needsContext) { - emitContext(env, inner, args.context); + emitContext(env, inner, args.context) } if (args.needsFramebuffer) { - emitPollFramebuffer(env, inner, args.framebuffer); + emitPollFramebuffer(env, inner, args.framebuffer) } - emitSetOptions(env, inner, args.state, isInnerDefn); + emitSetOptions(env, inner, args.state, isInnerDefn) if (args.profile && isInnerDefn(args.profile)) { - emitProfile(env, inner, args, false, true); + emitProfile(env, inner, args, false, true) } if (!program) { - var progCache = env.global.def('{}'); - var PROGRAM = args.shader.progVar.append(env, inner); - var PROG_ID = inner.def(PROGRAM, '.id'); - var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']'); + var progCache = env.global.def('{}') + var PROGRAM = args.shader.progVar.append(env, inner) + var PROG_ID = inner.def(PROGRAM, '.id') + var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']') inner( env.shared.gl, '.useProgram(', PROGRAM, '.program);', 'if(!', CACHED_PROC, '){', @@ -8529,52 +9321,68 @@ function reglCore ( return createBody( emitBatchDynamicShaderBody, env, args, program, 2) }), '(', PROGRAM, ');}', - CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');'); + CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');') } else { - emitAttributes(env, outer, args, program.attributes, isOuterDefn); - emitAttributes(env, inner, args, program.attributes, isInnerDefn); - emitUniforms(env, outer, args, program.uniforms, isOuterDefn); - emitUniforms(env, inner, args, program.uniforms, isInnerDefn); - emitDraw(env, outer, inner, args); + if (args.useVAO) { + if (args.drawVAO) { + if (isInnerDefn(args.drawVAO)) { + // vao is a prop + inner(env.shared.vao, '.setVAO(', args.drawVAO.append(env, inner), ');') + } else { + // vao is invariant + outer(env.shared.vao, '.setVAO(', args.drawVAO.append(env, outer), ');') + } + } else { + // scoped vao binding + outer(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') + } + } else { + outer(env.shared.vao, '.setVAO(null);') + emitAttributes(env, outer, args, program.attributes, isOuterDefn) + emitAttributes(env, inner, args, program.attributes, isInnerDefn) + } + emitUniforms(env, outer, args, program.uniforms, isOuterDefn, false) + emitUniforms(env, inner, args, program.uniforms, isInnerDefn, true) + emitDraw(env, outer, inner, args) } } function emitBatchProc (env, args) { - var batch = env.proc('batch', 2); - env.batchId = '0'; + var batch = env.proc('batch', 2) + env.batchId = '0' - injectExtensions(env, batch); + injectExtensions(env, batch) // Check if any context variables depend on props - var contextDynamic = false; - var needsContext = true; + var contextDynamic = false + var needsContext = true Object.keys(args.context).forEach(function (name) { - contextDynamic = contextDynamic || args.context[name].propDep; - }); + contextDynamic = contextDynamic || args.context[name].propDep + }) if (!contextDynamic) { - emitContext(env, batch, args.context); - needsContext = false; + emitContext(env, batch, args.context) + needsContext = false } // framebuffer state affects framebufferWidth/height context vars - var framebuffer = args.framebuffer; - var needsFramebuffer = false; + var framebuffer = args.framebuffer + var needsFramebuffer = false if (framebuffer) { if (framebuffer.propDep) { - contextDynamic = needsFramebuffer = true; + contextDynamic = needsFramebuffer = true } else if (framebuffer.contextDep && contextDynamic) { - needsFramebuffer = true; + needsFramebuffer = true } if (!needsFramebuffer) { - emitPollFramebuffer(env, batch, framebuffer); + emitPollFramebuffer(env, batch, framebuffer) } } else { - emitPollFramebuffer(env, batch, null); + emitPollFramebuffer(env, batch, null) } // viewport is weird because it can affect context vars if (args.state.viewport && args.state.viewport.propDep) { - contextDynamic = true; + contextDynamic = true } function isInnerDefn (defn) { @@ -8582,41 +9390,42 @@ function reglCore ( } // set webgl options - emitPollState(env, batch, args); + emitPollState(env, batch, args) emitSetOptions(env, batch, args.state, function (defn) { return !isInnerDefn(defn) - }); + }) if (!args.profile || !isInnerDefn(args.profile)) { - emitProfile(env, batch, args, false, 'a1'); + emitProfile(env, batch, args, false, 'a1') } // Save these values to args so that the batch body routine can use them - args.contextDep = contextDynamic; - args.needsContext = needsContext; - args.needsFramebuffer = needsFramebuffer; + args.contextDep = contextDynamic + args.needsContext = needsContext + args.needsFramebuffer = needsFramebuffer // determine if shader is dynamic - var progDefn = args.shader.progVar; + var progDefn = args.shader.progVar if ((progDefn.contextDep && contextDynamic) || progDefn.propDep) { emitBatchBody( env, batch, args, - null); + null) } else { - var PROGRAM = progDefn.append(env, batch); - batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);'); + var PROGRAM = progDefn.append(env, batch) + batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);') if (args.shader.program) { emitBatchBody( env, batch, args, - args.shader.program); + args.shader.program) } else { - var batchCache = env.global.def('{}'); - var PROG_ID = batch.def(PROGRAM, '.id'); - var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']'); + batch(env.shared.vao, '.setVAO(null);') + var batchCache = env.global.def('{}') + var PROG_ID = batch.def(PROGRAM, '.id') + var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']') batch( env.cond(CACHED_PROC) .then(CACHED_PROC, '.call(this,a0,a1);') @@ -8625,12 +9434,16 @@ function reglCore ( env.link(function (program) { return createBody(emitBatchBody, env, args, program, 2) }), '(', PROGRAM, ');', - CACHED_PROC, '.call(this,a0,a1);')); + CACHED_PROC, '.call(this,a0,a1);')) } } if (Object.keys(args.state).length > 0) { - batch(env.shared.current, '.dirty=true;'); + batch(env.shared.current, '.dirty=true;') + } + + if (env.shared.vao) { + batch(env.shared.vao, '.setVAO(null);') } } @@ -8640,78 +9453,86 @@ function reglCore ( // =================================================== // =================================================== function emitScopeProc (env, args) { - var scope = env.proc('scope', 3); - env.batchId = 'a2'; + var scope = env.proc('scope', 3) + env.batchId = 'a2' - var shared = env.shared; - var CURRENT_STATE = shared.current; + var shared = env.shared + var CURRENT_STATE = shared.current - emitContext(env, scope, args.context); + emitContext(env, scope, args.context) if (args.framebuffer) { - args.framebuffer.append(env, scope); + args.framebuffer.append(env, scope) } sortState(Object.keys(args.state)).forEach(function (name) { - var defn = args.state[name]; - var value = defn.append(env, scope); + var defn = args.state[name] + var value = defn.append(env, scope) if (isArrayLike(value)) { value.forEach(function (v, i) { - scope.set(env.next[name], '[' + i + ']', v); - }); + scope.set(env.next[name], '[' + i + ']', v) + }) } else { - scope.set(shared.next, '.' + name, value); + scope.set(shared.next, '.' + name, value) } - }); + }) emitProfile(env, scope, args, true, true) ;[S_ELEMENTS, S_OFFSET, S_COUNT, S_INSTANCES, S_PRIMITIVE].forEach( function (opt) { - var variable = args.draw[opt]; + var variable = args.draw[opt] if (!variable) { return } - scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)); - }); + scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope)) + }) Object.keys(args.uniforms).forEach(function (opt) { + var value = args.uniforms[opt].append(env, scope) + if (Array.isArray(value)) { + value = '[' + value.join() + ']' + } scope.set( shared.uniforms, '[' + stringStore.id(opt) + ']', - args.uniforms[opt].append(env, scope)); - }); + value) + }) Object.keys(args.attributes).forEach(function (name) { - var record = args.attributes[name].append(env, scope); - var scopeAttrib = env.scopeAttrib(name); + var record = args.attributes[name].append(env, scope) + var scopeAttrib = env.scopeAttrib(name) Object.keys(new AttributeRecord()).forEach(function (prop) { - scope.set(scopeAttrib, '.' + prop, record[prop]); - }); - }); + scope.set(scopeAttrib, '.' + prop, record[prop]) + }) + }) + + if (args.scopeVAO) { + scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope)) + } function saveShader (name) { - var shader = args.shader[name]; + var shader = args.shader[name] if (shader) { - scope.set(shared.shader, '.' + name, shader.append(env, scope)); + scope.set(shared.shader, '.' + name, shader.append(env, scope)) } } - saveShader(S_VERT); - saveShader(S_FRAG); + saveShader(S_VERT) + saveShader(S_FRAG) if (Object.keys(args.state).length > 0) { - scope(CURRENT_STATE, '.dirty=true;'); - scope.exit(CURRENT_STATE, '.dirty=true;'); + scope(CURRENT_STATE, '.dirty=true;') + scope.exit(CURRENT_STATE, '.dirty=true;') } - scope('a1(', env.shared.context, ',a0,', env.batchId, ');'); + scope('a1(', env.shared.context, ',a0,', env.batchId, ');') } function isDynamicObject (object) { if (typeof object !== 'object' || isArrayLike(object)) { return } - var props = Object.keys(object); + var props = Object.keys(object) for (var i = 0; i < props.length; ++i) { if (dynamic.isDynamic(object[props[i]])) { return true @@ -8721,58 +9542,58 @@ function reglCore ( } function splatObject (env, options, name) { - var object = options.static[name]; + var object = options.static[name] if (!object || !isDynamicObject(object)) { return } - var globals = env.global; - var keys = Object.keys(object); - var thisDep = false; - var contextDep = false; - var propDep = false; - var objectRef = env.global.def('{}'); + var globals = env.global + var keys = Object.keys(object) + var thisDep = false + var contextDep = false + var propDep = false + var objectRef = env.global.def('{}') keys.forEach(function (key) { - var value = object[key]; + var value = object[key] if (dynamic.isDynamic(value)) { if (typeof value === 'function') { - value = object[key] = dynamic.unbox(value); + value = object[key] = dynamic.unbox(value) } - var deps = createDynamicDecl(value, null); - thisDep = thisDep || deps.thisDep; - propDep = propDep || deps.propDep; - contextDep = contextDep || deps.contextDep; + var deps = createDynamicDecl(value, null) + thisDep = thisDep || deps.thisDep + propDep = propDep || deps.propDep + contextDep = contextDep || deps.contextDep } else { - globals(objectRef, '.', key, '='); + globals(objectRef, '.', key, '=') switch (typeof value) { case 'number': - globals(value); + globals(value) break case 'string': - globals('"', value, '"'); + globals('"', value, '"') break case 'object': if (Array.isArray(value)) { - globals('[', value.join(), ']'); + globals('[', value.join(), ']') } break default: - globals(env.link(value)); + globals(env.link(value)) break } - globals(';'); + globals(';') } - }); + }) function appendBlock (env, block) { keys.forEach(function (key) { - var value = object[key]; + var value = object[key] if (!dynamic.isDynamic(value)) { return } - var ref = env.invoke(block, value); - block(objectRef, '.', key, '=', ref, ';'); - }); + var ref = env.invoke(block, value) + block(objectRef, '.', key, '=', ref, ';') + }) } options.dynamic[name] = new dynamic.DynamicVariable(DYN_THUNK, { @@ -8781,8 +9602,8 @@ function reglCore ( propDep: propDep, ref: objectRef, append: appendBlock - }); - delete options.static[name]; + }) + delete options.static[name] } // =========================================================================== @@ -8791,26 +9612,30 @@ function reglCore ( // =========================================================================== // =========================================================================== function compileCommand (options, attributes, uniforms, context, stats) { - var env = createREGLEnvironment(); + var env = createREGLEnvironment() // link stats, so that we can easily access it in the program. - env.stats = env.link(stats); + env.stats = env.link(stats) // splat options and attributes to allow for dynamic nested properties Object.keys(attributes.static).forEach(function (key) { - splatObject(env, attributes, key); - }); + splatObject(env, attributes, key) + }) NESTED_OPTIONS.forEach(function (name) { - splatObject(env, options, name); - }); + splatObject(env, options, name) + }) - var args = parseArguments(options, attributes, uniforms, context, env); + var args = parseArguments(options, attributes, uniforms, context, env) - emitDrawProc(env, args); - emitScopeProc(env, args); - emitBatchProc(env, args); + emitDrawProc(env, args) + emitScopeProc(env, args) + emitBatchProc(env, args) - return env.compile() + return extend(env.compile(), { + destroy: function () { + args.shader.program.destroy() + } + }) } // =========================================================================== @@ -8822,112 +9647,120 @@ function reglCore ( next: nextState, current: currentState, procs: (function () { - var env = createREGLEnvironment(); - var poll = env.proc('poll'); - var refresh = env.proc('refresh'); - var common = env.block(); - poll(common); - refresh(common); + var env = createREGLEnvironment() + var poll = env.proc('poll') + var refresh = env.proc('refresh') + var common = env.block() + poll(common) + refresh(common) - var shared = env.shared; - var GL = shared.gl; - var NEXT_STATE = shared.next; - var CURRENT_STATE = shared.current; + var shared = env.shared + var GL = shared.gl + var NEXT_STATE = shared.next + var CURRENT_STATE = shared.current - common(CURRENT_STATE, '.dirty=false;'); + common(CURRENT_STATE, '.dirty=false;') - emitPollFramebuffer(env, poll); - emitPollFramebuffer(env, refresh, null, true); + emitPollFramebuffer(env, poll) + emitPollFramebuffer(env, refresh, null, true) // Refresh updates all attribute state changes - var INSTANCING; + var INSTANCING if (extInstancing) { - INSTANCING = env.link(extInstancing); + INSTANCING = env.link(extInstancing) + } + + // update vertex array bindings + if (extensions.oes_vertex_array_object) { + refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);') } for (var i = 0; i < limits.maxAttributes; ++i) { - var BINDING = refresh.def(shared.attributes, '[', i, ']'); - var ifte = env.cond(BINDING, '.buffer'); + var BINDING = refresh.def(shared.attributes, '[', i, ']') + var ifte = env.cond(BINDING, '.buffer') ifte.then( GL, '.enableVertexAttribArray(', i, ');', GL, '.bindBuffer(', - GL_ARRAY_BUFFER$1, ',', - BINDING, '.buffer.buffer);', + GL_ARRAY_BUFFER$2, ',', + BINDING, '.buffer.buffer);', GL, '.vertexAttribPointer(', - i, ',', - BINDING, '.size,', - BINDING, '.type,', - BINDING, '.normalized,', - BINDING, '.stride,', - BINDING, '.offset);' + i, ',', + BINDING, '.size,', + BINDING, '.type,', + BINDING, '.normalized,', + BINDING, '.stride,', + BINDING, '.offset);' ).else( GL, '.disableVertexAttribArray(', i, ');', GL, '.vertexAttrib4f(', - i, ',', - BINDING, '.x,', - BINDING, '.y,', - BINDING, '.z,', - BINDING, '.w);', - BINDING, '.buffer=null;'); - refresh(ifte); + i, ',', + BINDING, '.x,', + BINDING, '.y,', + BINDING, '.z,', + BINDING, '.w);', + BINDING, '.buffer=null;') + refresh(ifte) if (extInstancing) { refresh( INSTANCING, '.vertexAttribDivisorANGLE(', i, ',', - BINDING, '.divisor);'); + BINDING, '.divisor);') } } + refresh( + env.shared.vao, '.currentVAO=null;', + env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);') Object.keys(GL_FLAGS).forEach(function (flag) { - var cap = GL_FLAGS[flag]; - var NEXT = common.def(NEXT_STATE, '.', flag); - var block = env.block(); + var cap = GL_FLAGS[flag] + var NEXT = common.def(NEXT_STATE, '.', flag) + var block = env.block() block('if(', NEXT, '){', GL, '.enable(', cap, ')}else{', GL, '.disable(', cap, ')}', - CURRENT_STATE, '.', flag, '=', NEXT, ';'); - refresh(block); + CURRENT_STATE, '.', flag, '=', NEXT, ';') + refresh(block) poll( 'if(', NEXT, '!==', CURRENT_STATE, '.', flag, '){', block, - '}'); - }); + '}') + }) Object.keys(GL_VARIABLES).forEach(function (name) { - var func = GL_VARIABLES[name]; - var init = currentState[name]; - var NEXT, CURRENT; - var block = env.block(); - block(GL, '.', func, '('); + var func = GL_VARIABLES[name] + var init = currentState[name] + var NEXT, CURRENT + var block = env.block() + block(GL, '.', func, '(') if (isArrayLike(init)) { - var n = init.length; - NEXT = env.global.def(NEXT_STATE, '.', name); - CURRENT = env.global.def(CURRENT_STATE, '.', name); + var n = init.length + NEXT = env.global.def(NEXT_STATE, '.', name) + CURRENT = env.global.def(CURRENT_STATE, '.', name) block( loop(n, function (i) { return NEXT + '[' + i + ']' }), ');', loop(n, function (i) { return CURRENT + '[' + i + ']=' + NEXT + '[' + i + '];' - }).join('')); + }).join('')) poll( 'if(', loop(n, function (i) { return NEXT + '[' + i + ']!==' + CURRENT + '[' + i + ']' }).join('||'), '){', block, - '}'); + '}') } else { - NEXT = common.def(NEXT_STATE, '.', name); - CURRENT = common.def(CURRENT_STATE, '.', name); + NEXT = common.def(NEXT_STATE, '.', name) + CURRENT = common.def(CURRENT_STATE, '.', name) block( NEXT, ');', - CURRENT_STATE, '.', name, '=', NEXT, ';'); + CURRENT_STATE, '.', name, '=', NEXT, ';') poll( 'if(', NEXT, '!==', CURRENT, '){', block, - '}'); + '}') } - refresh(block); - }); + refresh(block) + }) return env.compile() })(), @@ -8937,6 +9770,7 @@ function reglCore ( function stats () { return { + vaoCount: 0, bufferCount: 0, elementsCount: 0, framebufferCount: 0, @@ -8948,9 +9782,9 @@ function stats () { } } -var GL_QUERY_RESULT_EXT = 0x8866; -var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867; -var GL_TIME_ELAPSED_EXT = 0x88BF; +var GL_QUERY_RESULT_EXT = 0x8866 +var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867 +var GL_TIME_ELAPSED_EXT = 0x88BF var createTimer = function (gl, extensions) { if (!extensions.ext_disjoint_timer_query) { @@ -8958,108 +9792,108 @@ var createTimer = function (gl, extensions) { } // QUERY POOL BEGIN - var queryPool = []; + var queryPool = [] function allocQuery () { return queryPool.pop() || extensions.ext_disjoint_timer_query.createQueryEXT() } function freeQuery (query) { - queryPool.push(query); + queryPool.push(query) } // QUERY POOL END - var pendingQueries = []; + var pendingQueries = [] function beginQuery (stats) { - var query = allocQuery(); - extensions.ext_disjoint_timer_query.beginQueryEXT(GL_TIME_ELAPSED_EXT, query); - pendingQueries.push(query); - pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats); + var query = allocQuery() + extensions.ext_disjoint_timer_query.beginQueryEXT(GL_TIME_ELAPSED_EXT, query) + pendingQueries.push(query) + pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats) } function endQuery () { - extensions.ext_disjoint_timer_query.endQueryEXT(GL_TIME_ELAPSED_EXT); + extensions.ext_disjoint_timer_query.endQueryEXT(GL_TIME_ELAPSED_EXT) } // // Pending stats pool. // function PendingStats () { - this.startQueryIndex = -1; - this.endQueryIndex = -1; - this.sum = 0; - this.stats = null; + this.startQueryIndex = -1 + this.endQueryIndex = -1 + this.sum = 0 + this.stats = null } - var pendingStatsPool = []; + var pendingStatsPool = [] function allocPendingStats () { return pendingStatsPool.pop() || new PendingStats() } function freePendingStats (pendingStats) { - pendingStatsPool.push(pendingStats); + pendingStatsPool.push(pendingStats) } // Pending stats pool end - var pendingStats = []; + var pendingStats = [] function pushScopeStats (start, end, stats) { - var ps = allocPendingStats(); - ps.startQueryIndex = start; - ps.endQueryIndex = end; - ps.sum = 0; - ps.stats = stats; - pendingStats.push(ps); + var ps = allocPendingStats() + ps.startQueryIndex = start + ps.endQueryIndex = end + ps.sum = 0 + ps.stats = stats + pendingStats.push(ps) } // we should call this at the beginning of the frame, // in order to update gpuTime - var timeSum = []; - var queryPtr = []; + var timeSum = [] + var queryPtr = [] function update () { - var ptr, i; + var ptr, i - var n = pendingQueries.length; + var n = pendingQueries.length if (n === 0) { return } // Reserve space - queryPtr.length = Math.max(queryPtr.length, n + 1); - timeSum.length = Math.max(timeSum.length, n + 1); - timeSum[0] = 0; - queryPtr[0] = 0; + queryPtr.length = Math.max(queryPtr.length, n + 1) + timeSum.length = Math.max(timeSum.length, n + 1) + timeSum[0] = 0 + queryPtr[0] = 0 // Update all pending timer queries - var queryTime = 0; - ptr = 0; + var queryTime = 0 + ptr = 0 for (i = 0; i < pendingQueries.length; ++i) { - var query = pendingQueries[i]; + var query = pendingQueries[i] if (extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT)) { - queryTime += extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT); - freeQuery(query); + queryTime += extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT) + freeQuery(query) } else { - pendingQueries[ptr++] = query; + pendingQueries[ptr++] = query } - timeSum[i + 1] = queryTime; - queryPtr[i + 1] = ptr; + timeSum[i + 1] = queryTime + queryPtr[i + 1] = ptr } - pendingQueries.length = ptr; + pendingQueries.length = ptr // Update all pending stat queries - ptr = 0; + ptr = 0 for (i = 0; i < pendingStats.length; ++i) { - var stats = pendingStats[i]; - var start = stats.startQueryIndex; - var end = stats.endQueryIndex; - stats.sum += timeSum[end] - timeSum[start]; - var startPtr = queryPtr[start]; - var endPtr = queryPtr[end]; + var stats = pendingStats[i] + var start = stats.startQueryIndex + var end = stats.endQueryIndex + stats.sum += timeSum[end] - timeSum[start] + var startPtr = queryPtr[start] + var endPtr = queryPtr[end] if (endPtr === startPtr) { - stats.stats.gpuTime += stats.sum / 1e6; - freePendingStats(stats); + stats.stats.gpuTime += stats.sum / 1e6 + freePendingStats(stats) } else { - stats.startQueryIndex = startPtr; - stats.endQueryIndex = endPtr; - pendingStats[ptr++] = stats; + stats.startQueryIndex = startPtr + stats.endQueryIndex = endPtr + pendingStats[ptr++] = stats } } - pendingStats.length = ptr; + pendingStats.length = ptr } return { @@ -9071,32 +9905,32 @@ var createTimer = function (gl, extensions) { return pendingQueries.length }, clear: function () { - queryPool.push.apply(queryPool, pendingQueries); + queryPool.push.apply(queryPool, pendingQueries) for (var i = 0; i < queryPool.length; i++) { - extensions.ext_disjoint_timer_query.deleteQueryEXT(queryPool[i]); + extensions.ext_disjoint_timer_query.deleteQueryEXT(queryPool[i]) } - pendingQueries.length = 0; - queryPool.length = 0; + pendingQueries.length = 0 + queryPool.length = 0 }, restore: function () { - pendingQueries.length = 0; - queryPool.length = 0; + pendingQueries.length = 0 + queryPool.length = 0 } } -}; +} -var GL_COLOR_BUFFER_BIT = 16384; -var GL_DEPTH_BUFFER_BIT = 256; -var GL_STENCIL_BUFFER_BIT = 1024; +var GL_COLOR_BUFFER_BIT = 16384 +var GL_DEPTH_BUFFER_BIT = 256 +var GL_STENCIL_BUFFER_BIT = 1024 -var GL_ARRAY_BUFFER = 34962; +var GL_ARRAY_BUFFER = 34962 -var CONTEXT_LOST_EVENT = 'webglcontextlost'; -var CONTEXT_RESTORED_EVENT = 'webglcontextrestored'; +var CONTEXT_LOST_EVENT = 'webglcontextlost' +var CONTEXT_RESTORED_EVENT = 'webglcontextrestored' -var DYN_PROP = 1; -var DYN_CONTEXT = 2; -var DYN_STATE = 3; +var DYN_PROP = 1 +var DYN_CONTEXT = 2 +var DYN_STATE = 3 function find (haystack, needle) { for (var i = 0; i < haystack.length; ++i) { @@ -9108,28 +9942,28 @@ function find (haystack, needle) { } function wrapREGL (args) { - var config = parseArgs(args); + var config = parseArgs(args) if (!config) { return null } - var gl = config.gl; - var glAttributes = gl.getContextAttributes(); - var contextLost = gl.isContextLost(); + var gl = config.gl + var glAttributes = gl.getContextAttributes() + var contextLost = gl.isContextLost() - var extensionState = createExtensionCache(gl, config); + var extensionState = createExtensionCache(gl, config) if (!extensionState) { return null } - var stringStore = createStringStore(); - var stats$$1 = stats(); - var extensions = extensionState.extensions; - var timer = createTimer(gl, extensions); + var stringStore = createStringStore() + var stats$$1 = stats() + var extensions = extensionState.extensions + var timer = createTimer(gl, extensions) - var START_TIME = clock(); - var WIDTH = gl.drawingBufferWidth; - var HEIGHT = gl.drawingBufferHeight; + var START_TIME = clock() + var WIDTH = gl.drawingBufferWidth + var HEIGHT = gl.drawingBufferHeight var contextState = { tick: 0, @@ -9141,45 +9975,51 @@ function wrapREGL (args) { drawingBufferWidth: WIDTH, drawingBufferHeight: HEIGHT, pixelRatio: config.pixelRatio - }; - var uniformState = {}; + } + var uniformState = {} var drawState = { elements: null, primitive: 4, // GL_TRIANGLES count: -1, offset: 0, instances: -1 - }; + } - var limits = wrapLimits(gl, extensions); - var attributeState = wrapAttributeState( - gl, - extensions, - limits, - stringStore); + var limits = wrapLimits(gl, extensions) var bufferState = wrapBufferState( gl, stats$$1, config, - attributeState); - var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1); - var shaderState = wrapShaderState(gl, stringStore, stats$$1, config); + destroyBuffer) + var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1) + var attributeState = wrapAttributeState( + gl, + extensions, + limits, + stats$$1, + bufferState, + elementState, + drawState) + function destroyBuffer (buffer) { + return attributeState.destroyBuffer(buffer) + } + var shaderState = wrapShaderState(gl, stringStore, stats$$1, config) var textureState = createTextureSet( gl, extensions, limits, - function () { core.procs.poll(); }, + function () { core.procs.poll() }, contextState, stats$$1, - config); - var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config); + config) + var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config) var framebufferState = wrapFBOState( gl, extensions, limits, textureState, renderbufferState, - stats$$1); + stats$$1) var core = reglCore( gl, stringStore, @@ -9195,189 +10035,203 @@ function wrapREGL (args) { drawState, contextState, timer, - config); + config) var readPixels = wrapReadPixels( gl, framebufferState, core.procs.poll, contextState, - glAttributes, extensions, limits); + glAttributes, extensions, limits) - var nextState = core.next; - var canvas = gl.canvas; + var nextState = core.next + var canvas = gl.canvas - var rafCallbacks = []; - var lossCallbacks = []; - var restoreCallbacks = []; - var destroyCallbacks = [config.onDestroy]; + var rafCallbacks = [] + var lossCallbacks = [] + var restoreCallbacks = [] + var destroyCallbacks = [config.onDestroy] - var activeRAF = null; + var activeRAF = null function handleRAF () { if (rafCallbacks.length === 0) { if (timer) { - timer.update(); + timer.update() } - activeRAF = null; + activeRAF = null return } // schedule next animation frame - activeRAF = raf.next(handleRAF); + activeRAF = raf.next(handleRAF) // poll for changes - poll(); + poll() // fire a callback for all pending rafs for (var i = rafCallbacks.length - 1; i >= 0; --i) { - var cb = rafCallbacks[i]; + var cb = rafCallbacks[i] if (cb) { - cb(contextState, null, 0); + cb(contextState, null, 0) } } // flush all pending webgl calls - gl.flush(); + gl.flush() // poll GPU timers *after* gl.flush so we don't delay command dispatch if (timer) { - timer.update(); + timer.update() } } function startRAF () { if (!activeRAF && rafCallbacks.length > 0) { - activeRAF = raf.next(handleRAF); + activeRAF = raf.next(handleRAF) } } function stopRAF () { if (activeRAF) { - raf.cancel(handleRAF); - activeRAF = null; + raf.cancel(handleRAF) + activeRAF = null } } function handleContextLoss (event) { - event.preventDefault(); + event.preventDefault() // set context lost flag - contextLost = true; + contextLost = true // pause request animation frame - stopRAF(); + stopRAF() // lose context lossCallbacks.forEach(function (cb) { - cb(); - }); + cb() + }) } function handleContextRestored (event) { // clear error code - gl.getError(); + gl.getError() // clear context lost flag - contextLost = false; + contextLost = false // refresh state - extensionState.restore(); - shaderState.restore(); - bufferState.restore(); - textureState.restore(); - renderbufferState.restore(); - framebufferState.restore(); + extensionState.restore() + shaderState.restore() + bufferState.restore() + textureState.restore() + renderbufferState.restore() + framebufferState.restore() + attributeState.restore() if (timer) { - timer.restore(); + timer.restore() } // refresh state - core.procs.refresh(); + core.procs.refresh() // restart RAF - startRAF(); + startRAF() // restore context restoreCallbacks.forEach(function (cb) { - cb(); - }); + cb() + }) } if (canvas) { - canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false); - canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false); + canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false) + canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false) } function destroy () { - rafCallbacks.length = 0; - stopRAF(); + rafCallbacks.length = 0 + stopRAF() if (canvas) { - canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss); - canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored); + canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss) + canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored) } - shaderState.clear(); - framebufferState.clear(); - renderbufferState.clear(); - textureState.clear(); - elementState.clear(); - bufferState.clear(); + shaderState.clear() + framebufferState.clear() + renderbufferState.clear() + attributeState.clear() + textureState.clear() + elementState.clear() + bufferState.clear() if (timer) { - timer.clear(); + timer.clear() } destroyCallbacks.forEach(function (cb) { - cb(); - }); + cb() + }) } function compileProcedure (options) { - check$1(!!options, 'invalid args to regl({...})'); - check$1.type(options, 'object', 'invalid args to regl({...})'); + check$1(!!options, 'invalid args to regl({...})') + check$1.type(options, 'object', 'invalid args to regl({...})') function flattenNestedOptions (options) { - var result = extend({}, options); - delete result.uniforms; - delete result.attributes; - delete result.context; + var result = extend({}, options) + delete result.uniforms + delete result.attributes + delete result.context + delete result.vao if ('stencil' in result && result.stencil.op) { - result.stencil.opBack = result.stencil.opFront = result.stencil.op; - delete result.stencil.op; + result.stencil.opBack = result.stencil.opFront = result.stencil.op + delete result.stencil.op } function merge (name) { if (name in result) { - var child = result[name]; - delete result[name]; + var child = result[name] + delete result[name] Object.keys(child).forEach(function (prop) { - result[name + '.' + prop] = child[prop]; - }); + result[name + '.' + prop] = child[prop] + }) } } - merge('blend'); - merge('depth'); - merge('cull'); - merge('stencil'); - merge('polygonOffset'); - merge('scissor'); - merge('sample'); + merge('blend') + merge('depth') + merge('cull') + merge('stencil') + merge('polygonOffset') + merge('scissor') + merge('sample') + + if ('vao' in options) { + result.vao = options.vao + } return result } - function separateDynamic (object) { - var staticItems = {}; - var dynamicItems = {}; + function separateDynamic (object, useArrays) { + var staticItems = {} + var dynamicItems = {} Object.keys(object).forEach(function (option) { - var value = object[option]; + var value = object[option] if (dynamic.isDynamic(value)) { - dynamicItems[option] = dynamic.unbox(value, option); - } else { - staticItems[option] = value; + dynamicItems[option] = dynamic.unbox(value, option) + return + } else if (useArrays && Array.isArray(value)) { + for (var i = 0; i < value.length; ++i) { + if (dynamic.isDynamic(value[i])) { + dynamicItems[option] = dynamic.unbox(value, option) + return + } + } } - }); + staticItems[option] = value + }) return { dynamic: dynamicItems, static: staticItems @@ -9385,51 +10239,49 @@ function wrapREGL (args) { } // Treat context variables separate from other dynamic variables - var context = separateDynamic(options.context || {}); - var uniforms = separateDynamic(options.uniforms || {}); - var attributes = separateDynamic(options.attributes || {}); - var opts = separateDynamic(flattenNestedOptions(options)); + var context = separateDynamic(options.context || {}, true) + var uniforms = separateDynamic(options.uniforms || {}, true) + var attributes = separateDynamic(options.attributes || {}, false) + var opts = separateDynamic(flattenNestedOptions(options), false) var stats$$1 = { gpuTime: 0.0, cpuTime: 0.0, count: 0 - }; + } - var compiled = core.compile(opts, attributes, uniforms, context, stats$$1); + var compiled = core.compile(opts, attributes, uniforms, context, stats$$1) - var draw = compiled.draw; - var batch = compiled.batch; - var scope = compiled.scope; + var draw = compiled.draw + var batch = compiled.batch + var scope = compiled.scope // FIXME: we should modify code generation for batch commands so this // isn't necessary - var EMPTY_ARRAY = []; + var EMPTY_ARRAY = [] function reserve (count) { while (EMPTY_ARRAY.length < count) { - EMPTY_ARRAY.push(null); + EMPTY_ARRAY.push(null) } return EMPTY_ARRAY } function REGLCommand (args, body) { - var i; + var i if (contextLost) { - check$1.raise('context lost'); + check$1.raise('context lost') } if (typeof args === 'function') { return scope.call(this, null, args, 0) } else if (typeof body === 'function') { if (typeof args === 'number') { for (i = 0; i < args; ++i) { - scope.call(this, null, body, i); + scope.call(this, null, body, i) } - return } else if (Array.isArray(args)) { for (i = 0; i < args.length; ++i) { - scope.call(this, args[i], body, i); + scope.call(this, args[i], body, i) } - return } else { return scope.call(this, args, body, 0) } @@ -9447,78 +10299,81 @@ function wrapREGL (args) { } return extend(REGLCommand, { - stats: stats$$1 + stats: stats$$1, + destroy: function () { + compiled.destroy() + } }) } var setFBO = framebufferState.setFBO = compileProcedure({ framebuffer: dynamic.define.call(null, DYN_PROP, 'framebuffer') - }); + }) function clearImpl (_, options) { - var clearFlags = 0; - core.procs.poll(); + var clearFlags = 0 + core.procs.poll() - var c = options.color; + var c = options.color if (c) { - gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0); - clearFlags |= GL_COLOR_BUFFER_BIT; + gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0) + clearFlags |= GL_COLOR_BUFFER_BIT } if ('depth' in options) { - gl.clearDepth(+options.depth); - clearFlags |= GL_DEPTH_BUFFER_BIT; + gl.clearDepth(+options.depth) + clearFlags |= GL_DEPTH_BUFFER_BIT } if ('stencil' in options) { - gl.clearStencil(options.stencil | 0); - clearFlags |= GL_STENCIL_BUFFER_BIT; + gl.clearStencil(options.stencil | 0) + clearFlags |= GL_STENCIL_BUFFER_BIT } - check$1(!!clearFlags, 'called regl.clear with no buffer specified'); - gl.clear(clearFlags); + check$1(!!clearFlags, 'called regl.clear with no buffer specified') + gl.clear(clearFlags) } function clear (options) { check$1( typeof options === 'object' && options, - 'regl.clear() takes an object as input'); + 'regl.clear() takes an object as input') if ('framebuffer' in options) { if (options.framebuffer && options.framebuffer_reglType === 'framebufferCube') { for (var i = 0; i < 6; ++i) { setFBO(extend({ framebuffer: options.framebuffer.faces[i] - }, options), clearImpl); + }, options), clearImpl) } } else { - setFBO(options, clearImpl); + setFBO(options, clearImpl) } } else { - clearImpl(null, options); + clearImpl(null, options) } } function frame (cb) { - check$1.type(cb, 'function', 'regl.frame() callback must be a function'); - rafCallbacks.push(cb); + check$1.type(cb, 'function', 'regl.frame() callback must be a function') + rafCallbacks.push(cb) function cancel () { // FIXME: should we check something other than equals cb here? // what if a user calls frame twice with the same callback... // - var i = find(rafCallbacks, cb); - check$1(i >= 0, 'cannot cancel a frame twice'); + var i = find(rafCallbacks, cb) + check$1(i >= 0, 'cannot cancel a frame twice') function pendingCancel () { - var index = find(rafCallbacks, pendingCancel); - rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1]; - rafCallbacks.length -= 1; + var index = find(rafCallbacks, pendingCancel) + rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1] + rafCallbacks.length -= 1 if (rafCallbacks.length <= 0) { - stopRAF(); + stopRAF() } } - rafCallbacks[i] = pendingCancel; + rafCallbacks[i] = pendingCancel } - startRAF(); + startRAF() return { cancel: cancel @@ -9527,33 +10382,34 @@ function wrapREGL (args) { // poll viewport function pollViewport () { - var viewport = nextState.viewport; - var scissorBox = nextState.scissor_box; - viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0; + var viewport = nextState.viewport + var scissorBox = nextState.scissor_box + viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0 contextState.viewportWidth = contextState.framebufferWidth = contextState.drawingBufferWidth = viewport[2] = - scissorBox[2] = gl.drawingBufferWidth; + scissorBox[2] = gl.drawingBufferWidth contextState.viewportHeight = contextState.framebufferHeight = contextState.drawingBufferHeight = viewport[3] = - scissorBox[3] = gl.drawingBufferHeight; + scissorBox[3] = gl.drawingBufferHeight } function poll () { - contextState.tick += 1; - contextState.time = now(); - pollViewport(); - core.procs.poll(); + contextState.tick += 1 + contextState.time = now() + pollViewport() + core.procs.poll() } function refresh () { - pollViewport(); - core.procs.refresh(); + textureState.refresh() + pollViewport() + core.procs.refresh() if (timer) { - timer.update(); + timer.update() } } @@ -9561,35 +10417,35 @@ function wrapREGL (args) { return (clock() - START_TIME) / 1000.0 } - refresh(); + refresh() function addListener (event, callback) { - check$1.type(callback, 'function', 'listener callback must be a function'); + check$1.type(callback, 'function', 'listener callback must be a function') - var callbacks; + var callbacks switch (event) { case 'frame': return frame(callback) case 'lost': - callbacks = lossCallbacks; + callbacks = lossCallbacks break case 'restore': - callbacks = restoreCallbacks; + callbacks = restoreCallbacks break case 'destroy': - callbacks = destroyCallbacks; + callbacks = destroyCallbacks break default: - check$1.raise('invalid event, must be one of frame,lost,restore,destroy'); + check$1.raise('invalid event, must be one of frame,lost,restore,destroy') } - callbacks.push(callback); + callbacks.push(callback) return { cancel: function () { for (var i = 0; i < callbacks.length; ++i) { if (callbacks[i] === callback) { - callbacks[i] = callbacks[callbacks.length - 1]; - callbacks.pop(); + callbacks[i] = callbacks[callbacks.length - 1] + callbacks.pop() return } } @@ -9621,6 +10477,7 @@ function wrapREGL (args) { renderbuffer: renderbufferState.create, framebuffer: framebufferState.create, framebufferCube: framebufferState.createCube, + vao: attributeState.createVAO, // Expose context attributes attributes: glAttributes, @@ -9646,9 +10503,9 @@ function wrapREGL (args) { _refresh: refresh, poll: function () { - poll(); + poll() if (timer) { - timer.update(); + timer.update() } }, @@ -9657,9 +10514,9 @@ function wrapREGL (args) { // regl Statistics Information stats: stats$$1 - }); + }) - config.onDone(null, regl); + config.onDone(null, regl) return regl } @@ -9667,3 +10524,4 @@ function wrapREGL (args) { return wrapREGL; }))); +//# sourceMappingURL=regl.js.map diff --git a/lib/regl.min.js b/lib/regl.min.js index eeaa6ec..8b68260 100644 --- a/lib/regl.min.js +++ b/lib/regl.min.js @@ -1,151 +1,171 @@ -(function(aa,ia){"object"===typeof exports&&"undefined"!==typeof module?module.exports=ia():"function"===typeof define&&define.amd?define(ia):aa.createREGL=ia()})(this,function(){function aa(a,b){this.id=Ab++;this.type=a;this.data=b}function ia(a){if(0===a.length)return[];var b=a.charAt(0),c=a.charAt(a.length-1);if(1>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function cb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[bb(a)>>2];return 0>2].push(a)}var c=J(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!== -c?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function ma(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||M(a.data))}function db(a,b,c,e,g,d){for(var p=0;pd&&(d=e.buffer.byteLength,5123===f?d>>=1:5125===f&&(d>>=2));e.vertCount=d;d=h;0>h&&(d=4,h=e.buffer.dimension,1===h&&(d=0),2===h&&(d=1),3===h&&(d=4));e.primType=d}function p(a){e.elementsCount--;delete f[a.id];a.buffer.destroy();a.buffer=null}var f={},r=0,q={uint8:5121, -uint16:5123};b.oes_element_index_uint&&(q.uint32=5125);g.prototype.bind=function(){this.buffer.bind()};var t=[];return{create:function(a,b){function k(a){if(a)if("number"===typeof a)h(a),l.primType=4,l.vertCount=a|0,l.type=5121;else{var b=null,c=35044,e=-1,g=-1,f=0,m=0;if(Array.isArray(a)||M(a)||ma(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=jb[a.usage]),"primitive"in a&&(e=Sa[a.primitive]),"count"in a&&(g=a.count|0),"type"in a&&(m=q[a.type]),"length"in a)f=a.length|0;else if(f=g,5123=== -m||5122===m)f*=2;else if(5125===m||5124===m)f*=4;d(l,b,c,e,g,f,m)}else h(),l.primType=4,l.vertCount=0,l.type=5121;return k}var h=c.create(null,34963,!0),l=new g(h._buffer);e.elementsCount++;k(a);k._reglType="elements";k._elements=l;k.subdata=function(a,b){h.subdata(a,b);return k};k.destroy=function(){p(l)};return k},createStream:function(a){var b=t.pop();b||(b=new g(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){t.push(a)},getElements:function(a){return"function"=== -typeof a&&a._elements instanceof g?a._elements:null},clear:function(){S(f).forEach(p)}}}function kb(a){for(var b=x.allocType(5123,a.length),c=0;c>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?g:-14>d?g+(e+1024>>-14-d):15>=e,c.height>>=e,C(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function ib(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&A(this)}});p.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(X).forEach(function(b){a+=X[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;z.call(c);var d=D();"number"===typeof a?"number"===typeof b? -v(d,a|0,b|0):v(d,a|0,a|0):a?(O(c,a),N(d,a)):v(d,1,1);c.genMipmaps&&(d.mipmask=(d.width<<1)-1);f.mipmask=d.mipmask;r(f,d);f.internalformat=d.internalformat;e.width=d.width;e.height=d.height;T(f);B(d,3553);R(c,3553);Aa();ib(d);p.profile&&(f.stats.size=Ja(f.internalformat,f.type,d.width,d.height,c.genMipmaps,!1));e.format=J[f.internalformat];e.type=da[f.type];e.mag=oa[c.magFilter];e.min=za[c.minFilter];e.wrapS=ka[c.wrapS];e.wrapT=ka[c.wrapT];return e}var f=new F(3553);X[f.id]=f;d.textureCount++;e(b, -c);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var n=h();r(n,f);n.width=0;n.height=0;C(n,a);n.width=n.width||(f.width>>d)-b;n.height=n.height||(f.height>>d)-c;T(f);k(n,3553,b,c,d);Aa();l(n);return e};e.resize=function(b,c){var d=b|0,h=c|0||d;if(d===f.width&&h===f.height)return e;e.width=f.width=d;e.height=f.height=h;T(f);for(var n,w=f.channels,y=f.type,I=0;f.mipmask>>I;++I){var fa=d>>I,ga=h>>I;if(!fa||!ga)break;n=x.zero.allocType(y,fa*ga*w);a.texImage2D(3553,I,f.format,fa,ga,0,f.format,f.type,n); -n&&x.zero.freeType(n)}Aa();p.profile&&(f.stats.size=Ja(f.internalformat,f.type,d,h,!1,!1));return e};e._reglType="texture2d";e._texture=f;p.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()};return e},createCube:function(b,c,e,f,g,ua){function A(a,b,c,d,e,f){var H,Y=m.texInfo;z.call(Y);for(H=0;6>H;++H)n[H]=D();if("number"===typeof a||!a)for(a=a|0||1,H=0;6>H;++H)v(n[H],a,a);else if("object"===typeof a)if(b)N(n[0],a),N(n[1],b),N(n[2],c),N(n[3],d),N(n[4],e),N(n[5],f);else if(O(Y,a),q(m,a),"faces"in -a)for(a=a.faces,H=0;6>H;++H)r(n[H],m),N(n[H],a[H]);else for(H=0;6>H;++H)N(n[H],a);r(m,n[0]);m.mipmask=Y.genMipmaps?(n[0].width<<1)-1:n[0].mipmask;m.internalformat=n[0].internalformat;A.width=n[0].width;A.height=n[0].height;T(m);for(H=0;6>H;++H)B(n[H],34069+H);R(Y,34067);Aa();p.profile&&(m.stats.size=Ja(m.internalformat,m.type,A.width,A.height,Y.genMipmaps,!0));A.format=J[m.internalformat];A.type=da[m.type];A.mag=oa[Y.magFilter];A.min=za[Y.minFilter];A.wrapS=ka[Y.wrapS];A.wrapT=ka[Y.wrapT];for(H=0;6> -H;++H)ib(n[H]);return A}var m=new F(34067);X[m.id]=m;d.cubeCount++;var n=Array(6);A(b,c,e,f,g,ua);A.subimage=function(a,b,c,n,d){c|=0;n|=0;d|=0;var e=h();r(e,m);e.width=0;e.height=0;C(e,b);e.width=e.width||(m.width>>d)-c;e.height=e.height||(m.height>>d)-n;T(m);k(e,34069+a,c,n,d);Aa();l(e);return A};A.resize=function(b){b|=0;if(b!==m.width){A.width=m.width=b;A.height=m.height=b;T(m);for(var c=0;6>c;++c)for(var n=0;m.mipmask>>n;++n)a.texImage2D(34069+c,n,m.format,b>>n,b>>n,0,m.format,m.type,null);Aa(); -p.profile&&(m.stats.size=Ja(m.internalformat,m.type,A.width,A.height,!1,!0));return A}};A._reglType="textureCube";A._texture=m;p.profile&&(A.stats=m.stats);A.destroy=function(){m.decRef()};return A},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat,b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);R(b.texInfo,b.target)})}}}function Ob(a,b,c,e,g,d){function p(a,b,c){this.target=a;this.texture=b;this.renderbuffer=c;var d=a=0;b?(a=b.width,d=b.height):c&&(a=c.width,d=c.height); -this.width=a;this.height=d}function f(a){a&&(a.texture&&a.texture._texture.decRef(),a.renderbuffer&&a.renderbuffer._renderbuffer.decRef())}function r(a,b,c){a&&(a.texture?a.texture._texture.refCount+=1:a.renderbuffer._renderbuffer.refCount+=1)}function q(b,c){c&&(c.texture?a.framebufferTexture2D(36160,b,c.target,c.texture._texture.texture,0):a.framebufferRenderbuffer(36160,b,36161,c.renderbuffer._renderbuffer.renderbuffer))}function t(a){var b=3553,c=null,d=null,e=a;"object"===typeof a&&(e=a.data, -"target"in a&&(b=a.target|0));a=e._reglType;"texture2d"===a?c=e:"textureCube"===a?c=e:"renderbuffer"===a&&(d=e,b=36161);return new p(b,c,d)}function m(a,b,c,d,f){if(c)return a=e.create2D({width:a,height:b,format:d,type:f}),a._texture.refCount=0,new p(3553,a,null);a=g.create({width:a,height:b,format:d});a._renderbuffer.refCount=0;return new p(36161,null,a)}function C(a){return a&&(a.texture||a.renderbuffer)}function k(a,b,c){a&&(a.texture?a.texture.resize(b,c):a.renderbuffer&&a.renderbuffer.resize(b, -c),a.width=b,a.height=c)}function h(){this.id=O++;R[this.id]=this;this.framebuffer=a.createFramebuffer();this.height=this.width=0;this.colorAttachments=[];this.depthStencilAttachment=this.stencilAttachment=this.depthAttachment=null}function l(a){a.colorAttachments.forEach(f);f(a.depthAttachment);f(a.stencilAttachment);f(a.depthStencilAttachment)}function u(b){a.deleteFramebuffer(b.framebuffer);b.framebuffer=null;d.framebufferCount--;delete R[b.id]}function v(b){var d;a.bindFramebuffer(36160,b.framebuffer); -var e=b.colorAttachments;for(d=0;dd;++d){for(m=0;ma;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})}, -clear:function(){S(R).forEach(u)},restore:function(){B.cur=null;B.next=null;B.dirty=!0;S(R).forEach(function(b){b.framebuffer=a.createFramebuffer();v(b)})}})}function ub(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Pb(a,b,c,e){a=c.maxAttributes;b=Array(a);for(c=0;ca&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;C.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);S(q).forEach(b);q={};S(t).forEach(b);t={};C.forEach(function(b){a.deleteProgram(b.program)}); -C.length=0;m={};c.shaderCount=0},program:function(a,b,d){var e=m[b];e||(e=m[b]={});var g=e[a];g||(g=new f(b,a),c.shaderCount++,r(g,d),e[a]=g,C.push(g));return g},restore:function(){q={};t={};for(var a=0;a"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{","if(",g,"(",e,".buffer)){",y,"=",n,".createStream(",34962,",",e,".buffer);","}else{",y,"=",n,".getBuffer(",e,".buffer);","}",k,'="type" in ',e,"?",f.glTypes,"[",e,".type]:",y,".dtype;", -w.normalized,"=!!",e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",w.isStream,"){",n,".destroyStream(",y,");","}");return w})});return f}function M(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=D(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=P(b,function(a,c){return a.invoke(c,b)})});return d}function A(a,b,c,d,e){var f=z(a,e),g=x(a, -f,e),h=O(a,e),k=R(a,e),m=E(a,e),ba=g.viewport;ba&&(k.viewport=ba);ba=l("scissor.box");(g=g[ba])&&(k[ba]=g);g=0>1)",v],");")}function b(){c(u,".drawArraysInstancedANGLE(",[q,r,t,v],");")}p?da?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(k+".drawElements("+[q,t,C,r+"<<(("+C+"-5121)>>1)"]+");")}function b(){c(k+".drawArrays("+[q,r,t]+");")}p?da?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,k=h.gl,m=h.draw,l=d.draw,p=function(){var e=l.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(m, -".","elements");e&&f("if("+e+")"+k+".bindBuffer(34963,"+e+".buffer.buffer);");return e}(),q=e("primitive"),r=e("offset"),t=function(){var e=l.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(m,".","count");return e}();if("number"===typeof t){if(0===t)return}else c("if(",t,"){"),c.exit("}");var v,u;ea&&(v=e("instances"),u=a.instancing);var C=p+".type",da=l.elements&&va(l.elements);ea&&("number"!==typeof v||0<=v)?"string"===typeof v?(c("if(",v,">0){"),f(), -c("}else if(",v,"<0){"),g(),c("}")):f():g()}function ca(a,b,c,d,e){b=N();e=b.proc("body",e);ea&&(b.instancing=e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function L(a,b,c,d){wa(a,b);U(a,b,c,d.attributes,function(){return!0});W(a,b,c,d.uniforms,function(){return!0});S(a,b,b,c)}function da(a,b){var c=a.proc("draw",1);wa(a,c);ua(a,c,b.context);K(a,c,b.framebuffer);V(a,c,b);Q(a,c,b.state);G(a,c,b,!1,!0);var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(", -d,".program);");if(b.shader.program)L(a,c,b,b.shader.program);else{var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return ca(L,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0=--this.refCount&&p(this)};g.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(t).forEach(function(b){a+=t[b].stats.size});return a});return{create:function(b,c){function k(b,c){var d=0,e=0,m=32854;"object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(m=f[b.format])):"number"=== -typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==h.width||e!==h.height||m!==h.format)return k.width=h.width=d,k.height=h.height=e,h.format=m,a.bindRenderbuffer(36161,h.renderbuffer),a.renderbufferStorage(36161,m,d,e),g.profile&&(h.stats.size=Q[h.format]*h.width*h.height),k.format=r[h.format],k}var h=new d(a.createRenderbuffer());t[h.id]=h;e.renderbufferCount++;k(b,c);k.resize=function(b,c){var d=b|0,e=c|0||d;if(d===h.width&&e===h.height)return k;k.width=h.width=d;k.height=h.height=e; -a.bindRenderbuffer(36161,h.renderbuffer);a.renderbufferStorage(36161,h.format,d,e);g.profile&&(h.stats.size=Q[h.format]*h.width*h.height);return k};k._reglType="renderbuffer";k._renderbuffer=h;g.profile&&(k.stats=h.stats);k.destroy=function(){h.decRef()};return k},clear:function(){S(t).forEach(p)},restore:function(){S(t).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161, -null)}}},Wa=[];Wa[6408]=4;Wa[6407]=3;var Na=[];Na[5121]=1;Na[5126]=4;Na[36193]=2;var Da=["x","y","z","w"],Ub="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ga={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769,"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771, -"one minus constant alpha":32772,"src alpha saturate":776},Xa={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Pa={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683,"increment wrap":34055,"decrement wrap":34056,invert:5386},wb={cw:2304,ccw:2305},xb=new Z(!1,!1,!1,function(){}),Xb=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats= -null}function e(a,b,d){var e=p.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;f.push(e)}if(!b.ext_disjoint_timer_query)return null;var g=[],d=[],p=[],f=[],r=[],q=[];return{beginQuery:function(a){var c=g.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007,c);d.push(c);e(d.length-1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){q.length= -Math.max(q.length,a+1);r.length=Math.max(r.length,a+1);r[0]=0;var e=q[0]=0;for(c=a=0;c=G.length&&e()}var c=yb(G,a);G[c]=b}}}function q(){var a=S.viewport,b=S.scissor_box;a[0]=a[1]=b[0]=b[1]=0;O.viewportWidth=O.framebufferWidth=O.drawingBufferWidth=a[2]=b[2]=k.drawingBufferWidth;O.viewportHeight=O.framebufferHeight=O.drawingBufferHeight=a[3]=b[3]=k.drawingBufferHeight}function t(){O.tick+=1;O.time=z(); -q();V.procs.poll()}function m(){q();V.procs.refresh();B&&B.update()}function z(){return(zb()-D)/1E3}a=Eb(a);if(!a)return null;var k=a.gl,h=k.getContextAttributes();k.isContextLost();var l=Fb(k,a);if(!l)return null;var u=Bb(),v={bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},x=l.extensions,B=Xb(k,x),D=zb(),J=k.drawingBufferWidth,P=k.drawingBufferHeight,O={tick:0,time:0,viewportWidth:J,viewportHeight:P,framebufferWidth:J, -framebufferHeight:P,drawingBufferWidth:J,drawingBufferHeight:P,pixelRatio:a.pixelRatio},R=Vb(k,x),J=Pb(k,x,R,u),F=Gb(k,v,a,J),T=Hb(k,x,F,v),Q=Qb(k,u,v,a),A=Kb(k,x,R,function(){V.procs.poll()},O,v,a),M=Wb(k,x,R,v,a),K=Ob(k,x,R,A,M,v),V=Tb(k,u,x,R,F,T,A,K,{},J,Q,{elements:null,primitive:4,count:-1,offset:0,instances:-1},O,B,a),u=Rb(k,K,V.procs.poll,O,h,x,R),S=V.next,L=k.canvas,G=[],U=[],W=[],Z=[a.onDestroy],ca=null;L&&(L.addEventListener("webglcontextlost",g,!1),L.addEventListener("webglcontextrestored", -d,!1));var aa=K.setFBO=p({framebuffer:la.define.call(null,1,"framebuffer")});m();h=E(p,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)aa(E({framebuffer:a.framebuffer.faces[b]},a),f);else aa(a,f);else f(null,a)},prop:la.define.bind(null,1),context:la.define.bind(null,2),"this":la.define.bind(null,3),draw:p({}),buffer:function(a){return F.create(a,34962,!1,!1)},elements:function(a){return T.create(a,!1)},texture:A.create2D,cube:A.createCube, -renderbuffer:M.create,framebuffer:K.create,framebufferCube:K.createCube,attributes:h,frame:r,on:function(a,b){var c;switch(a){case "frame":return r(b);case "lost":c=U;break;case "restore":c=W;break;case "destroy":c=Z}c.push(b);return{cancel:function(){for(var a=0;a>>=b;c=(255>>=c;b|=c;c=(15>>=c;b|=c;c=(3>>c>>1}function hb(){function a(a){a:{for(var b=16;268435456>=b;b*=16)if(a<=b){a=b;break a}a=0}b=c[gb(a)>>2];return 0>2].push(a)}var c=R(8,function(){return[]});return{alloc:a,free:b,allocType:function(b,c){var d=null;switch(b){case 5120:d=new Int8Array(a(c),0,c);break;case 5121:d=new Uint8Array(a(c),0,c);break;case 5122:d=new Int16Array(a(2*c),0,c);break;case 5123:d=new Uint16Array(a(2*c),0,c);break;case 5124:d=new Int32Array(a(4*c),0,c);break;case 5125:d=new Uint32Array(a(4*c),0,c);break;case 5126:d=new Float32Array(a(4*c),0,c);break;default:return null}return d.length!== +c?d.subarray(0,c):d},freeType:function(a){b(a.buffer)}}}function la(a){return!!a&&"object"===typeof a&&Array.isArray(a.shape)&&Array.isArray(a.stride)&&"number"===typeof a.offset&&a.shape.length===a.stride.length&&(Array.isArray(a.data)||O(a.data))}function ib(a,b,c,e,f,d){for(var q=0;qe&&(e=d.buffer.byteLength,5123===k?e>>=1:5125===k&&(e>>=2));d.vertCount=e;e=g;0>g&&(e=4,g=d.buffer.dimension,1===g&&(e=0),2===g&&(e=1),3===g&&(e=4));d.primType=e}function q(a){e.elementsCount--;delete n[a.id];a.buffer.destroy();a.buffer=null}var n={},v=0,k={uint8:5121,uint16:5123};b.oes_element_index_uint&&(k.uint32=5125);f.prototype.bind=function(){this.buffer.bind()};var u=[];return{create:function(a, +b){function l(a){if(a)if("number"===typeof a)g(a),h.primType=4,h.vertCount=a|0,h.type=5121;else{var b=null,c=35044,e=-1,f=-1,m=0,n=0;if(Array.isArray(a)||O(a)||la(a))b=a;else if("data"in a&&(b=a.data),"usage"in a&&(c=nb[a.usage]),"primitive"in a&&(e=Ka[a.primitive]),"count"in a&&(f=a.count|0),"type"in a&&(n=k[a.type]),"length"in a)m=a.length|0;else if(m=f,5123===n||5122===n)m*=2;else if(5125===n||5124===n)m*=4;d(h,b,c,e,f,m,n)}else g(),h.primType=4,h.vertCount=0,h.type=5121;return l}var g=c.create(null, +34963,!0),h=new f(g._buffer);e.elementsCount++;l(a);l._reglType="elements";l._elements=h;l.subdata=function(a,b){g.subdata(a,b);return l};l.destroy=function(){q(h)};return l},createStream:function(a){var b=u.pop();b||(b=new f(c.create(null,34963,!0,!1)._buffer));d(b,a,35040,-1,-1,0,0);return b},destroyStream:function(a){u.push(a)},getElements:function(a){return"function"===typeof a&&a._elements instanceof f?a._elements:null},clear:function(){I(n).forEach(q)}}}function ob(a){for(var b=G.allocType(5123, +a.length),c=0;c>>31<<15,d=(e<<1>>>24)-127,e=e>>13&1023;b[c]=-24>d?f:-14>d?f+(e+1024>>-14-d):15>=e,c.height>>=e,x(c,d[e]),a.mipmask|=1<b;++b)a.images[b]=null;return a}function ya(a){for(var b=a.images,c=0;cb){for(var c=0;c=--this.refCount&&F(this)}});q.profile&&(d.getTotalTextureSize=function(){var a=0;Object.keys(ea).forEach(function(b){a+=ea[b].stats.size});return a});return{create2D:function(b,c){function e(a,b){var c=f.texInfo;w.call(c);var d=ma();"number"===typeof a?"number"===typeof b?p(d,a|0,b|0):p(d,a|0,a|0):a?(H(c,a),P(d,a)):p(d,1,1);c.genMipmaps&&(d.mipmask=(d.width<<1)-1);f.mipmask=d.mipmask;v(f, +d);f.internalformat=d.internalformat;e.width=d.width;e.height=d.height;T(f);t(d,3553);M(c,3553);wa();ya(d);q.profile&&(f.stats.size=La(f.internalformat,f.type,d.width,d.height,c.genMipmaps,!1));e.format=ca[f.internalformat];e.type=K[f.type];e.mag=Fa[c.magFilter];e.min=pa[c.minFilter];e.wrapS=qa[c.wrapS];e.wrapT=qa[c.wrapT];return e}var f=new y(3553);ea[f.id]=f;d.textureCount++;e(b,c);e.subimage=function(a,b,c,d){b|=0;c|=0;d|=0;var y=g();v(y,f);y.width=0;y.height=0;x(y,a);y.width=y.width||(f.width>> +d)-b;y.height=y.height||(f.height>>d)-c;T(f);l(y,3553,b,c,d);wa();h(y);return e};e.resize=function(b,c){var d=b|0,g=c|0||d;if(d===f.width&&g===f.height)return e;e.width=f.width=d;e.height=f.height=g;T(f);for(var y=0;f.mipmask>>y;++y){var h=d>>y,z=g>>y;if(!h||!z)break;a.texImage2D(3553,y,f.format,h,z,0,f.format,f.type,null)}wa();q.profile&&(f.stats.size=La(f.internalformat,f.type,d,g,!1,!1));return e};e._reglType="texture2d";e._texture=f;q.profile&&(e.stats=f.stats);e.destroy=function(){f.decRef()}; +return e},createCube:function(b,c,e,f,n,r){function m(a,b,c,d,e,f){var g,da=A.texInfo;w.call(da);for(g=0;6>g;++g)F[g]=ma();if("number"===typeof a||!a)for(a=a|0||1,g=0;6>g;++g)p(F[g],a,a);else if("object"===typeof a)if(b)P(F[0],a),P(F[1],b),P(F[2],c),P(F[3],d),P(F[4],e),P(F[5],f);else if(H(da,a),k(A,a),"faces"in a)for(a=a.faces,g=0;6>g;++g)v(F[g],A),P(F[g],a[g]);else for(g=0;6>g;++g)P(F[g],a);v(A,F[0]);A.mipmask=da.genMipmaps?(F[0].width<<1)-1:F[0].mipmask;A.internalformat=F[0].internalformat;m.width= +F[0].width;m.height=F[0].height;T(A);for(g=0;6>g;++g)t(F[g],34069+g);M(da,34067);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,da.genMipmaps,!0));m.format=ca[A.internalformat];m.type=K[A.type];m.mag=Fa[da.magFilter];m.min=pa[da.minFilter];m.wrapS=qa[da.wrapS];m.wrapT=qa[da.wrapT];for(g=0;6>g;++g)ya(F[g]);return m}var A=new y(34067);ea[A.id]=A;d.cubeCount++;var F=Array(6);m(b,c,e,f,n,r);m.subimage=function(a,b,c,d,e){c|=0;d|=0;e|=0;var f=g();v(f,A);f.width=0;f.height=0; +x(f,b);f.width=f.width||(A.width>>e)-c;f.height=f.height||(A.height>>e)-d;T(A);l(f,34069+a,c,d,e);wa();h(f);return m};m.resize=function(b){b|=0;if(b!==A.width){m.width=A.width=b;m.height=A.height=b;T(A);for(var c=0;6>c;++c)for(var d=0;A.mipmask>>d;++d)a.texImage2D(34069+c,d,A.format,b>>d,b>>d,0,A.format,A.type,null);wa();q.profile&&(A.stats.size=La(A.internalformat,A.type,m.width,m.height,!1,!0));return m}};m._reglType="textureCube";m._texture=A;q.profile&&(m.stats=A.stats);m.destroy=function(){A.decRef()}; +return m},clear:function(){for(var b=0;bc;++c)if(0!==(b.mipmask&1<>c,b.height>>c,0,b.internalformat, +b.type,null);else for(var d=0;6>d;++d)a.texImage2D(34069+d,c,b.internalformat,b.width>>c,b.height>>c,0,b.internalformat,b.type,null);M(b.texInfo,b.target)})},refresh:function(){for(var b=0;bd;++d){for(p= +0;pa;++a)c[a].resize(d);b.width=b.height=d;return b},_reglType:"framebufferCube",destroy:function(){c.forEach(function(a){a.destroy()})}})},clear:function(){I(M).forEach(r)}, +restore:function(){t.cur=null;t.next=null;t.dirty=!0;I(M).forEach(function(b){b.framebuffer=a.createFramebuffer();p(b)})}})}function $a(){this.w=this.z=this.y=this.x=this.state=0;this.buffer=null;this.size=0;this.normalized=!1;this.type=5126;this.divisor=this.stride=this.offset=0}function Sb(a,b,c,e,f,d,q){function n(a){if(a!==r.currentVAO){var c=b.oes_vertex_array_object;a?c.bindVertexArrayOES(a.vao):c.bindVertexArrayOES(null);r.currentVAO=a}}function v(c){if(c!==r.currentVAO){if(c)c.bindAttrs(); +else{for(var d=b.angle_instanced_arrays,e=0;e=m.byteLength?l.subdata(m): +(l.destroy(),c.buffers[h]=null));c.buffers[h]||(l=c.buffers[h]=f.create(p,34962,!1,!0));k.buffer=f.getBuffer(l);k.size=k.buffer.dimension|0;k.normalized=!1;k.type=k.buffer.dtype;k.offset=0;k.stride=0;k.divisor=0;k.state=1;a[h]=1}else f.getBuffer(p)?(k.buffer=f.getBuffer(p),k.size=k.buffer.dimension|0,k.normalized=!1,k.type=k.buffer.dtype,k.offset=0,k.stride=0,k.divisor=0,k.state=1):f.getBuffer(p.buffer)?(k.buffer=f.getBuffer(p.buffer),k.size=(+p.size||k.buffer.dimension)|0,k.normalized=!!p.normalized|| +!1,k.type="type"in p?Ja[p.type]:k.buffer.dtype,k.offset=(p.offset||0)|0,k.stride=(p.stride||0)|0,k.divisor=(p.divisor||0)|0,k.state=1):"x"in p&&(k.x=+p.x||0,k.y=+p.y||0,k.z=+p.z||0,k.w=+p.w||0,k.state=2)}for(l=0;la&&(a=b.stats.uniformsCount)});return a},c.getMaxAttributesCount=function(){var a=0;x.forEach(function(b){b.stats.attributesCount>a&&(a=b.stats.attributesCount)});return a});return{clear:function(){var b=a.deleteShader.bind(a);I(k).forEach(b);k={};I(u).forEach(b); +u={};x.forEach(function(b){a.deleteProgram(b.program)});x.length=0;m={};c.shaderCount=0},program:function(b,d,e,f){var l=m[d];l||(l=m[d]={});var q=l[b];if(q&&(q.refCount++,!f))return q;var w=new n(d,b);c.shaderCount++;v(w,e,f);q||(l[b]=w);x.push(w);return L(w,{destroy:function(){w.refCount--;if(0>=w.refCount){a.deleteProgram(w.program);var b=x.indexOf(w);x.splice(b,1);c.shaderCount--}0>=l[w.vertId].refCount&&(a.deleteShader(u[w.vertId]),delete u[w.vertId],delete m[w.fragId][w.vertId]);Object.keys(m[w.fragId]).length|| +(a.deleteShader(k[w.fragId]),delete k[w.fragId],delete m[w.fragId])}})},restore:function(){k={};u={};for(var a=0;a"+b+"?"+e+".constant["+b+"]:0;"}).join(""),"}}else{","if(",g,"(",e,".buffer)){",k,"=",f,".createStream(",34962,",",e,".buffer);","}else{",k,"=",f,".getBuffer(",e,".buffer);","}",m,'="type" in ',e,"?",z.glTypes,"[",e,".type]:",k,".dtype;",B.normalized,"=!!", +e,".normalized;");d("size");d("offset");d("stride");d("divisor");c("}}");c.exit("if(",B.isStream,"){",f,".destroyStream(",k,");","}");return B})});return g}function F(a){var b=a["static"],c=a.dynamic,d={};Object.keys(b).forEach(function(a){var c=b[a];d[a]=w(function(a,b){return"number"===typeof c||"boolean"===typeof c?""+c:a.link(c)})});Object.keys(c).forEach(function(a){var b=c[a];d[a]=K(b,function(a,c){return a.invoke(c,b)})});return d}function A(a,b,d,e,f){function g(a){var b=p[a];b&&(ja[a]=b)} +var m=O(a,b),l=G(a,f),p=C(a,l,f),X=M(a,f),ja=y(a,f),q=H(a,f,m);g("viewport");g(h("scissor.box"));var n=0>1)",u],");")}function b(){c(t,".drawArraysInstancedANGLE(",[n,q,r,u],");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}function g(){function a(){c(l+".drawElements("+[n,r,x,q+"<<(("+x+"-5121)>>1)"]+");")}function b(){c(l+".drawArrays("+[n,q,r]+");")}p&&"null"!==p?v?a():(c("if(",p,"){"),a(),c("}else{"),b(),c("}")):b()}var h=a.shared,l=h.gl,k=h.draw,m=d.draw, +p=function(){var e=m.elements,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f);m.elementsActive&&f("if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);")}else e=f.def(),f(e,"=",k,".","elements",";","if(",e,"){",l,".bindBuffer(",34963,",",e,".buffer.buffer);}","else if(",h.vao,".currentVAO){",e,"=",a.shared.elements+".getElements("+h.vao,".currentVAO.elements);",na?"":"if("+e+")"+l+".bindBuffer(34963,"+e+".buffer.buffer);","}");return e}(),n=e("primitive"),q=e("offset"), +r=function(){var e=m.count,f=b;if(e){if(e.contextDep&&d.contextDynamic||e.propDep)f=c;e=e.append(a,f)}else e=f.def(k,".","count");return e}();if("number"===typeof r){if(0===r)return}else c("if(",r,"){"),c.exit("}");var u,t;W&&(u=e("instances"),t=a.instancing);var x=p+".type",v=m.elements&&xa(m.elements)&&!m.vaoActive;W&&("number"!==typeof u||0<=u)?"string"===typeof u?(c("if(",u,">0){"),f(),c("}else if(",u,"<0){"),g(),c("}")):f():g()}function ca(a,b,c,d,e){b=P();e=b.proc("body",e);W&&(b.instancing= +e.def(b.shared.extensions,".angle_instanced_arrays"));a(b,e,c,d);return b.compile().body}function Z(a,b,c,d){N(a,b);c.useVAO?c.drawVAO?b(a.shared.vao,".setVAO(",c.drawVAO.append(a,b),");"):b(a.shared.vao,".setVAO(",a.shared.vao,".targetVAO);"):(b(a.shared.vao,".setVAO(null);"),ga(a,b,c,d.attributes,function(){return!0}));Q(a,b,c,d.uniforms,function(){return!0},!1);U(a,b,b,c)}function Fa(a,b){var c=a.proc("draw",1);N(a,c);ia(a,c,b.context);S(a,c,b.framebuffer);Aa(a,c,b);I(a,c,b.state);E(a,c,b,!1,!0); +var d=b.shader.progVar.append(a,c);c(a.shared.gl,".useProgram(",d,".program);");if(b.shader.program)Z(a,c,b,b.shader.program);else{c(a.shared.vao,".setVAO(null);");var e=a.global.def("{}"),f=c.def(d,".id"),g=c.def(e,"[",f,"]");c(a.cond(g).then(g,".call(this,a0);")["else"](g,"=",e,"[",f,"]=",a.link(function(c){return ca(Z,a,b,c,1)}),"(",d,");",g,".call(this,a0);"))}0=--this.refCount&&q(this)};f.profile&&(e.getTotalRenderbufferSize=function(){var a=0;Object.keys(u).forEach(function(b){a+=u[b].stats.size});return a});return{create:function(b, +c){function l(b,c){var d=0,e=0,k=32854;"object"===typeof b&&b?("shape"in b?(e=b.shape,d=e[0]|0,e=e[1]|0):("radius"in b&&(d=e=b.radius|0),"width"in b&&(d=b.width|0),"height"in b&&(e=b.height|0)),"format"in b&&(k=n[b.format])):"number"===typeof b?(d=b|0,e="number"===typeof c?c|0:d):b||(d=e=1);if(d!==g.width||e!==g.height||k!==g.format)return l.width=g.width=d,l.height=g.height=e,g.format=k,a.bindRenderbuffer(36161,g.renderbuffer),a.renderbufferStorage(36161,k,d,e),f.profile&&(g.stats.size=Q[g.format]* +g.width*g.height),l.format=v[g.format],l}var g=new d(a.createRenderbuffer());u[g.id]=g;e.renderbufferCount++;l(b,c);l.resize=function(b,c){var d=b|0,e=c|0||d;if(d===g.width&&e===g.height)return l;l.width=g.width=d;l.height=g.height=e;a.bindRenderbuffer(36161,g.renderbuffer);a.renderbufferStorage(36161,g.format,d,e);f.profile&&(g.stats.size=Q[g.format]*g.width*g.height);return l};l._reglType="renderbuffer";l._renderbuffer=g;f.profile&&(l.stats=g.stats);l.destroy=function(){g.decRef()};return l},clear:function(){I(u).forEach(q)}, +restore:function(){I(u).forEach(function(b){b.renderbuffer=a.createRenderbuffer();a.bindRenderbuffer(36161,b.renderbuffer);a.renderbufferStorage(36161,b.format,b.width,b.height)});a.bindRenderbuffer(36161,null)}}},Za=[];Za[6408]=4;Za[6407]=3;var Ra=[];Ra[5121]=1;Ra[5126]=4;Ra[36193]=2;var Da=["x","y","z","w"],Xb="blend.func blend.equation stencil.func stencil.opFront stencil.opBack sample.coverage viewport scissor.box polygonOffset.offset".split(" "),Ga={0:0,1:1,zero:0,one:1,"src color":768,"one minus src color":769, +"src alpha":770,"one minus src alpha":771,"dst color":774,"one minus dst color":775,"dst alpha":772,"one minus dst alpha":773,"constant color":32769,"one minus constant color":32770,"constant alpha":32771,"one minus constant alpha":32772,"src alpha saturate":776},ab={never:512,less:513,"<":513,equal:514,"=":514,"==":514,"===":514,lequal:515,"<=":515,greater:516,">":516,notequal:517,"!=":517,"!==":517,gequal:518,">=":518,always:519},Ta={0:0,zero:0,keep:7680,replace:7681,increment:7682,decrement:7683, +"increment wrap":34055,"decrement wrap":34056,invert:5386},zb={cw:2304,ccw:2305},Ab=new J(!1,!1,!1,function(){}),$b=function(a,b){function c(){this.endQueryIndex=this.startQueryIndex=-1;this.sum=0;this.stats=null}function e(a,b,d){var e=q.pop()||new c;e.startQueryIndex=a;e.endQueryIndex=b;e.sum=0;e.stats=d;n.push(e)}if(!b.ext_disjoint_timer_query)return null;var f=[],d=[],q=[],n=[],v=[],k=[];return{beginQuery:function(a){var c=f.pop()||b.ext_disjoint_timer_query.createQueryEXT();b.ext_disjoint_timer_query.beginQueryEXT(35007, +c);d.push(c);e(d.length-1,d.length,a)},endQuery:function(){b.ext_disjoint_timer_query.endQueryEXT(35007)},pushScopeStats:e,update:function(){var a,c;a=d.length;if(0!==a){k.length=Math.max(k.length,a+1);v.length=Math.max(v.length,a+1);v[0]=0;var e=k[0]=0;for(c=a=0;c=E.length&&e()}var c=Bb(E,a);E[c]=b}}}function k(){var a=Q.viewport,b=Q.scissor_box;a[0]=a[1]=b[0]=b[1]=0;H.viewportWidth=H.framebufferWidth=H.drawingBufferWidth=a[2]=b[2]=l.drawingBufferWidth;H.viewportHeight=H.framebufferHeight=H.drawingBufferHeight=a[3]=b[3]=l.drawingBufferHeight}function u(){H.tick+=1;H.time=x();k();I.procs.poll()}function m(){A.refresh();k();I.procs.refresh();t&&t.update()}function x(){return(Cb()- +G)/1E3}a=Hb(a);if(!a)return null;var l=a.gl,g=l.getContextAttributes();l.isContextLost();var h=Ib(l,a);if(!h)return null;var r=Eb(),p={vaoCount:0,bufferCount:0,elementsCount:0,framebufferCount:0,shaderCount:0,textureCount:0,cubeCount:0,renderbufferCount:0,maxTextureUnits:0},w=h.extensions,t=$b(l,w),G=Cb(),C=l.drawingBufferWidth,J=l.drawingBufferHeight,H={tick:0,time:0,viewportWidth:C,viewportHeight:J,framebufferWidth:C,framebufferHeight:J,drawingBufferWidth:C,drawingBufferHeight:J,pixelRatio:a.pixelRatio}, +C={elements:null,primitive:4,count:-1,offset:0,instances:-1},M=Yb(l,w),y=Jb(l,p,a,function(a){return K.destroyBuffer(a)}),T=Kb(l,w,y,p),K=Sb(l,w,M,p,y,T,C),F=Tb(l,r,p,a),A=Nb(l,w,M,function(){I.procs.poll()},H,p,a),O=Zb(l,w,M,p,a),S=Rb(l,w,M,A,O,p),I=Wb(l,r,w,M,y,T,A,S,{},K,F,C,H,t,a),r=Ub(l,S,I.procs.poll,H,g,w,M),Q=I.next,N=l.canvas,E=[],R=[],U=[],Z=[a.onDestroy],ca=null;N&&(N.addEventListener("webglcontextlost",f,!1),N.addEventListener("webglcontextrestored",d,!1));var aa=S.setFBO=q({framebuffer:Y.define.call(null, +1,"framebuffer")});m();g=L(q,{clear:function(a){if("framebuffer"in a)if(a.framebuffer&&"framebufferCube"===a.framebuffer_reglType)for(var b=0;6>b;++b)aa(L({framebuffer:a.framebuffer.faces[b]},a),n);else aa(a,n);else n(null,a)},prop:Y.define.bind(null,1),context:Y.define.bind(null,2),"this":Y.define.bind(null,3),draw:q({}),buffer:function(a){return y.create(a,34962,!1,!1)},elements:function(a){return T.create(a,!1)},texture:A.create2D,cube:A.createCube,renderbuffer:O.create,framebuffer:S.create,framebufferCube:S.createCube, +vao:K.createVAO,attributes:g,frame:v,on:function(a,b){var c;switch(a){case "frame":return v(b);case "lost":c=R;break;case "restore":c=U;break;case "destroy":c=Z}c.push(b);return{cancel:function(){for(var a=0;a