UNPKG

@polygonjs/plugin-mapbox

Version:

Mapbox plugin for the 3D engine https://polygonjs.com

1,510 lines 116 kB
(function(factory) { typeof define === "function" && define.amd ? define(factory) : factory(); })(function() { "use strict"; function isBuiltIn(name) { return name.startsWith("gl_") || name.startsWith("webgl_"); } function isWebGL2(gl) { return !!gl.texImage3D; } function isTypedArray(v) { return v && v.buffer && v.buffer instanceof ArrayBuffer; } function isArrayThatCanHaveBadValues(v) { return Array.isArray(v) || v instanceof Float32Array || v instanceof Float64Array; } function quotedStringOrEmpty(s) { return s ? `"${s}"` : ""; } const enumStringToValue = {}; function enumArrayToString(gl, enums) { const enumStrings = []; if (enums.length) { for (let i = 0; i < enums.length; ++i) { enums.push(glEnumToString(enums[i])); } return "[" + enumStrings.join(", ") + "]"; } return enumStrings.toString(); } function makeBitFieldToStringFunc(enums) { return function(gl, value) { let orResult = 0; const orEnums = []; for (let i = 0; i < enums.length; ++i) { const enumValue = enumStringToValue[enums[i]]; if ((value & enumValue) !== 0) { orResult |= enumValue; orEnums.push(glEnumToString(enumValue)); } } if (orResult === value) { return orEnums.join(" | "); } else { return glEnumToString(value); } }; } const enumToStringsMap = /* @__PURE__ */ new Map(); function addEnumsFromAPI(api) { for (const key in api) { const value = api[key]; if (typeof value === "number") { if (!enumToStringsMap.has(value)) { enumToStringsMap.set(value, /* @__PURE__ */ new Set()); } enumToStringsMap.get(value).add(key); } } } function glEnumToString(value) { const matches = enumToStringsMap.get(value); return matches ? [...matches.keys()].map((v) => `${v}`).join(" | ") : `/*UNKNOWN WebGL ENUM*/ ${typeof value === "number" ? `0x${value.toString(16)}` : value}`; } const FLOAT = 5126; const FLOAT_VEC2 = 35664; const FLOAT_VEC3 = 35665; const FLOAT_VEC4 = 35666; const INT = 5124; const INT_VEC2 = 35667; const INT_VEC3 = 35668; const INT_VEC4 = 35669; const BOOL = 35670; const BOOL_VEC2 = 35671; const BOOL_VEC3 = 35672; const BOOL_VEC4 = 35673; const FLOAT_MAT2 = 35674; const FLOAT_MAT3 = 35675; const FLOAT_MAT4 = 35676; const SAMPLER_2D = 35678; const SAMPLER_CUBE = 35680; const SAMPLER_3D = 35679; const SAMPLER_2D_SHADOW = 35682; const FLOAT_MAT2x3 = 35685; const FLOAT_MAT2x4 = 35686; const FLOAT_MAT3x2 = 35687; const FLOAT_MAT3x4 = 35688; const FLOAT_MAT4x2 = 35689; const FLOAT_MAT4x3 = 35690; const SAMPLER_2D_ARRAY = 36289; const SAMPLER_2D_ARRAY_SHADOW = 36292; const SAMPLER_CUBE_SHADOW = 36293; const UNSIGNED_INT = 5125; const UNSIGNED_INT_VEC2 = 36294; const UNSIGNED_INT_VEC3 = 36295; const UNSIGNED_INT_VEC4 = 36296; const INT_SAMPLER_2D = 36298; const INT_SAMPLER_3D = 36299; const INT_SAMPLER_CUBE = 36300; const INT_SAMPLER_2D_ARRAY = 36303; const UNSIGNED_INT_SAMPLER_2D = 36306; const UNSIGNED_INT_SAMPLER_3D = 36307; const UNSIGNED_INT_SAMPLER_CUBE = 36308; const UNSIGNED_INT_SAMPLER_2D_ARRAY = 36311; const uniformTypeMap = /* @__PURE__ */ new Map([ [FLOAT, { size: 1, name: "float" }], [FLOAT_VEC2, { size: 2, name: "vec2" }], [FLOAT_VEC3, { size: 3, name: "vec3" }], [FLOAT_VEC4, { size: 4, name: "vec4" }], [INT, { size: 1, name: "int" }], [INT_VEC2, { size: 2, name: "ivec2" }], [INT_VEC3, { size: 3, name: "ivec3" }], [INT_VEC4, { size: 4, name: "ivec4" }], [UNSIGNED_INT, { size: 1, name: "uint" }], [UNSIGNED_INT_VEC2, { size: 2, name: "uvec2" }], [UNSIGNED_INT_VEC3, { size: 3, name: "uvec3" }], [UNSIGNED_INT_VEC4, { size: 4, name: "uvec4" }], [BOOL, { size: 1, name: "bool" }], [BOOL_VEC2, { size: 2, name: "bvec2" }], [BOOL_VEC3, { size: 3, name: "bvec3" }], [BOOL_VEC4, { size: 4, name: "bvec4" }], [FLOAT_MAT2, { size: 4, name: "mat2" }], [FLOAT_MAT3, { size: 9, name: "mat3" }], [FLOAT_MAT4, { size: 16, name: "mat4" }], [FLOAT_MAT2x3, { size: 6, name: "mat2x3" }], [FLOAT_MAT2x4, { size: 8, name: "mat2x4" }], [FLOAT_MAT3x2, { size: 6, name: "mat3x2" }], [FLOAT_MAT3x4, { size: 12, name: "mat3x4" }], [FLOAT_MAT4x2, { size: 8, name: "mat4x2" }], [FLOAT_MAT4x3, { size: 12, name: "mat4x3" }], [SAMPLER_2D, { size: 1, name: "sampler2D" }], [SAMPLER_CUBE, { size: 1, name: "samplerCube" }], [SAMPLER_3D, { size: 1, name: "sampler3D" }], [SAMPLER_2D_SHADOW, { size: 1, name: "sampler2DShadow" }], [SAMPLER_2D_ARRAY, { size: 1, name: "sampler2DArray" }], [SAMPLER_2D_ARRAY_SHADOW, { size: 1, name: "sampler2DArrayShadow" }], [SAMPLER_CUBE_SHADOW, { size: 1, name: "samplerCubeShadow" }], [INT_SAMPLER_2D, { size: 1, name: "isampler2D" }], [INT_SAMPLER_3D, { size: 1, name: "isampler3D" }], [INT_SAMPLER_CUBE, { size: 1, name: "isamplerCube" }], [INT_SAMPLER_2D_ARRAY, { size: 1, name: "isampler2DArray" }], [UNSIGNED_INT_SAMPLER_2D, { size: 1, name: "usampler2D" }], [UNSIGNED_INT_SAMPLER_3D, { size: 1, name: "usampler3D" }], [UNSIGNED_INT_SAMPLER_CUBE, { size: 1, name: "usamplerCube" }], [UNSIGNED_INT_SAMPLER_2D_ARRAY, { size: 1, name: "usampler2DArray" }] ]); function getUniformTypeInfo(type) { return uniformTypeMap.get(type); } const TEXTURE_BINDING_2D = 32873; const TEXTURE_BINDING_CUBE_MAP = 34068; const TEXTURE_BINDING_3D = 32874; const TEXTURE_BINDING_2D_ARRAY = 35869; const ARRAY_BUFFER = 34962; const ELEMENT_ARRAY_BUFFER = 34963; const ARRAY_BUFFER_BINDING = 34964; const ELEMENT_ARRAY_BUFFER_BINDING = 34965; const TEXTURE_2D = 3553; const TEXTURE_3D = 32879; const TEXTURE_2D_ARRAY = 35866; const TEXTURE_CUBE_MAP = 34067; const FRAMEBUFFER = 36160; const RENDERBUFFER = 36161; const FRAMEBUFFER_BINDING = 36006; const RENDERBUFFER_BINDING = 36007; const TRANSFORM_FEEDBACK_BUFFER = 35982; const TRANSFORM_FEEDBACK_BUFFER_BINDING = 35983; const DRAW_FRAMEBUFFER = 36009; const READ_FRAMEBUFFER = 36008; const READ_FRAMEBUFFER_BINDING = 36010; const UNIFORM_BUFFER = 35345; const UNIFORM_BUFFER_BINDING = 35368; const TRANSFORM_FEEDBACK = 36386; const TRANSFORM_FEEDBACK_BINDING = 36389; const bindPointMap = /* @__PURE__ */ new Map([ [ARRAY_BUFFER, ARRAY_BUFFER_BINDING], [ELEMENT_ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER_BINDING], [TEXTURE_2D, TEXTURE_BINDING_2D], [TEXTURE_CUBE_MAP, TEXTURE_BINDING_CUBE_MAP], [TEXTURE_3D, TEXTURE_BINDING_3D], [TEXTURE_2D_ARRAY, TEXTURE_BINDING_2D_ARRAY], [RENDERBUFFER, RENDERBUFFER_BINDING], [FRAMEBUFFER, FRAMEBUFFER_BINDING], [DRAW_FRAMEBUFFER, FRAMEBUFFER_BINDING], [READ_FRAMEBUFFER, READ_FRAMEBUFFER_BINDING], [UNIFORM_BUFFER, UNIFORM_BUFFER_BINDING], [TRANSFORM_FEEDBACK_BUFFER, TRANSFORM_FEEDBACK_BUFFER_BINDING], [TRANSFORM_FEEDBACK, TRANSFORM_FEEDBACK_BINDING] ]); function getBindingQueryEnumForBindPoint(bindPoint) { return bindPointMap.get(bindPoint); } const BYTE = 5120; const SHORT = 5122; const UNSIGNED_BYTE = 5121; const UNSIGNED_SHORT = 5123; const glTypeToSizeMap = /* @__PURE__ */ new Map([ [BOOL, 1], [BYTE, 1], [UNSIGNED_BYTE, 1], [SHORT, 2], [UNSIGNED_SHORT, 2], [INT, 4], [UNSIGNED_INT, 4], [FLOAT, 4] ]); function getBytesPerValueForGLType(type) { return glTypeToSizeMap.get(type) || 0; } const glTypeToTypedArrayMap = /* @__PURE__ */ new Map([ [UNSIGNED_BYTE, Uint8Array], [UNSIGNED_SHORT, Uint16Array], [UNSIGNED_INT, Uint32Array] ]); function glTypeToTypedArray(type) { return glTypeToTypedArrayMap.get(type); } const drawFuncsToArgs = { drawArrays(primType, startOffset, vertCount) { return { startOffset, vertCount, instances: 1 }; }, drawElements(primType, vertCount, indexType, startOffset) { return { startOffset, vertCount, instances: 1, indexType }; }, drawArraysInstanced(primType, startOffset, vertCount, instances) { return { startOffset, vertCount, instances }; }, drawElementsInstanced(primType, vertCount, indexType, startOffset, instances) { return { startOffset, vertCount, instances, indexType }; }, drawArraysInstancedANGLE(primType, startOffset, vertCount, instances) { return { startOffset, vertCount, instances }; }, drawElementsInstancedANGLE(primType, vertCount, indexType, startOffset, instances) { return { startOffset, vertCount, instances, indexType }; }, drawRangeElements(primType, start, end, vertCount, indexType, startOffset) { return { startOffset, vertCount, instances: 1, indexType }; } }; function getDrawFunctionArgs(funcName, args) { return drawFuncsToArgs[funcName](...args); } function isDrawFunction(funcName) { return !!drawFuncsToArgs[funcName]; } const attrTypeMap = /* @__PURE__ */ new Map([ [FLOAT, { size: 4 }], [FLOAT_VEC2, { size: 8 }], [FLOAT_VEC3, { size: 12 }], [FLOAT_VEC4, { size: 16 }], [INT, { size: 4 }], [INT_VEC2, { size: 8 }], [INT_VEC3, { size: 12 }], [INT_VEC4, { size: 16 }], [UNSIGNED_INT, { size: 4 }], [UNSIGNED_INT_VEC2, { size: 8 }], [UNSIGNED_INT_VEC3, { size: 12 }], [UNSIGNED_INT_VEC4, { size: 16 }], [BOOL, { size: 4 }], [BOOL_VEC2, { size: 8 }], [BOOL_VEC3, { size: 12 }], [BOOL_VEC4, { size: 16 }], [FLOAT_MAT2, { size: 4, count: 2 }], [FLOAT_MAT3, { size: 9, count: 3 }], [FLOAT_MAT4, { size: 16, count: 4 }] ]); function getAttributeTypeInfo(type) { return attrTypeMap.get(type); } const VERTEX_ATTRIB_ARRAY_DIVISOR = 35070; function computeLastUseIndexForDrawArrays(startOffset, vertCount) { return startOffset + vertCount - 1; } function getLastUsedIndexForDrawElements(gl, funcName, startOffset, vertCount, instances, indexType, getWebGLObjectString, getIndicesForBuffer, errors) { const elementBuffer = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING); if (!elementBuffer) { errors.push("No ELEMENT_ARRAY_BUFFER bound"); return void 0; } const bytesPerIndex = getBytesPerValueForGLType(indexType); const bufferSize = gl.getBufferParameter(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE); const sizeNeeded = startOffset + vertCount * bytesPerIndex; if (sizeNeeded > bufferSize) { errors.push(`offset: ${startOffset} and count: ${vertCount} with index type: ${glEnumToString(indexType)} passed to ${funcName} are out of range for current ELEMENT_ARRAY_BUFFER. Those parameters require ${sizeNeeded} bytes but the current ELEMENT_ARRAY_BUFFER ${getWebGLObjectString(elementBuffer)} only has ${bufferSize} bytes`); return void 0; } const buffer = getIndicesForBuffer(elementBuffer); const Type = glTypeToTypedArray(indexType); const view = new Type(buffer, startOffset); let maxIndex = view[0]; for (let i = 1; i < vertCount; ++i) { maxIndex = Math.max(maxIndex, view[i]); } return maxIndex; } function checkAttributesForBufferOverflow(gl, funcName, args, getWebGLObjectString, getIndicesForBuffer) { const { vertCount, startOffset, indexType, instances } = getDrawFunctionArgs(funcName, args); if (vertCount <= 0 || instances <= 0) { return []; } const program = gl.getParameter(gl.CURRENT_PROGRAM); const errors = []; const nonInstancedLastIndex = indexType ? getLastUsedIndexForDrawElements(gl, funcName, startOffset, vertCount, instances, indexType, getWebGLObjectString, getIndicesForBuffer, errors) : computeLastUseIndexForDrawArrays(startOffset, vertCount); if (errors.length) { return errors; } const hasDivisor = isWebGL2(gl) || gl.getExtension("ANGLE_instanced_arrays"); const numAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); const oldArrayBuffer = gl.getParameter(gl.ARRAY_BUFFER_BINDING); for (let ii = 0; ii < numAttributes; ++ii) { const { name, type } = gl.getActiveAttrib(program, ii); if (isBuiltIn(name)) { continue; } const index = gl.getAttribLocation(program, name); const { count } = { count: 1, ...getAttributeTypeInfo(type) }; for (let jj = 0; jj < count; ++jj) { const ndx = index + jj; const enabled = gl.getVertexAttrib(ndx, gl.VERTEX_ATTRIB_ARRAY_ENABLED); if (!enabled) { continue; } const buffer = gl.getVertexAttrib(ndx, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); if (!buffer) { errors.push(`no buffer bound to attribute (${name}) location: ${index}`); continue; } const numComponents = gl.getVertexAttrib(ndx, gl.VERTEX_ATTRIB_ARRAY_SIZE); const type2 = gl.getVertexAttrib(ndx, gl.VERTEX_ATTRIB_ARRAY_TYPE); const bytesPerElement = getBytesPerValueForGLType(type2) * numComponents; const offset = gl.getVertexAttribOffset(ndx, gl.VERTEX_ATTRIB_ARRAY_POINTER); const specifiedStride = gl.getVertexAttrib(ndx, gl.VERTEX_ATTRIB_ARRAY_STRIDE); const stride = specifiedStride ? specifiedStride : bytesPerElement; const divisor = hasDivisor ? gl.getVertexAttrib(ndx, VERTEX_ATTRIB_ARRAY_DIVISOR) : 0; gl.bindBuffer(gl.ARRAY_BUFFER, buffer); const bufferSize = gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE); const effectiveLastIndex = divisor > 0 ? ((instances + divisor - 1) / divisor | 0) - 1 : nonInstancedLastIndex; const sizeNeeded = offset + effectiveLastIndex * stride + bytesPerElement; if (sizeNeeded > bufferSize) { errors.push(`${getWebGLObjectString(buffer)} assigned to attribute ${ndx} used as attribute '${name}' in current program is too small for draw parameters. index of highest vertex accessed: ${effectiveLastIndex} attribute size: ${numComponents}, type: ${glEnumToString(type2)}, stride: ${specifiedStride}, offset: ${offset}, divisor: ${divisor} needs ${sizeNeeded} bytes for draw but buffer is only ${bufferSize} bytes`); } } } gl.bindBuffer(gl.ARRAY_BUFFER, oldArrayBuffer); return errors; } const SAMPLER_2D$1 = 35678; const SAMPLER_CUBE$1 = 35680; const SAMPLER_3D$1 = 35679; const SAMPLER_2D_SHADOW$1 = 35682; const SAMPLER_2D_ARRAY$1 = 36289; const SAMPLER_2D_ARRAY_SHADOW$1 = 36292; const SAMPLER_CUBE_SHADOW$1 = 36293; const INT_SAMPLER_2D$1 = 36298; const INT_SAMPLER_3D$1 = 36299; const INT_SAMPLER_CUBE$1 = 36300; const INT_SAMPLER_2D_ARRAY$1 = 36303; const UNSIGNED_INT_SAMPLER_2D$1 = 36306; const UNSIGNED_INT_SAMPLER_3D$1 = 36307; const UNSIGNED_INT_SAMPLER_CUBE$1 = 36308; const UNSIGNED_INT_SAMPLER_2D_ARRAY$1 = 36311; const samplerTypes = /* @__PURE__ */ new Map([ [SAMPLER_2D$1, { uniformType: "sampler2D", numberType: "float/normalized", bindPoint: "2D" }], [SAMPLER_CUBE$1, { uniformType: "samplerCube", numberType: "float/normalized", bindPoint: "CUBE" }], [SAMPLER_3D$1, { uniformType: "sampler3D", numberType: "float/normalized", bindPoint: "3D" }], [SAMPLER_2D_SHADOW$1, { uniformType: "sampler2D", numberType: "float/normalized", bindPoint: "2D" }], [SAMPLER_2D_ARRAY$1, { uniformType: "sampler2DArray", numberType: "float/normalized", bindPoint: "2D_ARRAY" }], [ SAMPLER_2D_ARRAY_SHADOW$1, { uniformType: "sampler2DArray", numberType: "float/normalized", bindPoint: "2D_ARRAY" } ], [SAMPLER_CUBE_SHADOW$1, { uniformType: "samplerCube", numberType: "float/normalized", bindPoint: "CUBE" }], [INT_SAMPLER_2D$1, { uniformType: "isampler2D", numberType: "int", bindPoint: "2D" }], [INT_SAMPLER_3D$1, { uniformType: "isampler3D", numberType: "int", bindPoint: "3D" }], [INT_SAMPLER_CUBE$1, { uniformType: "isamplerCube", numberType: "int", bindPoint: "CUBE" }], [INT_SAMPLER_2D_ARRAY$1, { uniformType: "isampler2DArray", numberType: "int", bindPoint: "2D_ARRAY" }], [UNSIGNED_INT_SAMPLER_2D$1, { uniformType: "usampler2D", numberType: "unsigned int", bindPoint: "2D" }], [UNSIGNED_INT_SAMPLER_3D$1, { uniformType: "usampler3D", numberType: "unsigned int", bindPoint: "3D" }], [UNSIGNED_INT_SAMPLER_CUBE$1, { uniformType: "usamplerCube", numberType: "unsigned int", bindPoint: "CUBE" }], [ UNSIGNED_INT_SAMPLER_2D_ARRAY$1, { uniformType: "usampler2DArray", numberType: "unsigned int", bindPoint: "2D_ARRAY" } ] ]); function getBindPointForSampler(type) { return samplerTypes.get(type).bindPoint; } function uniformTypeIsSampler(type) { return samplerTypes.has(type); } function getNumberTypeForUniformSamplerType(type) { return samplerTypes.get(type).numberType; } function getUniformTypeForUniformSamplerType(type) { return samplerTypes.get(type).uniformType; } const TEXTURE_2D$1 = 3553; const TEXTURE_3D$1 = 32879; const TEXTURE_2D_ARRAY$1 = 35866; const TEXTURE_CUBE_MAP$1 = 34067; const TEXTURE_CUBE_MAP_POSITIVE_X = 34069; const TEXTURE_CUBE_MAP_NEGATIVE_X = 34070; const TEXTURE_CUBE_MAP_POSITIVE_Y = 34071; const TEXTURE_CUBE_MAP_NEGATIVE_Y = 34072; const TEXTURE_CUBE_MAP_POSITIVE_Z = 34073; const TEXTURE_CUBE_MAP_NEGATIVE_Z = 34074; const targetToBindPointMap = /* @__PURE__ */ new Map([ [TEXTURE_2D$1, "2D"], [TEXTURE_3D$1, "3D"], [TEXTURE_CUBE_MAP$1, "CUBE"], [TEXTURE_CUBE_MAP_POSITIVE_X, "CUBE"], [TEXTURE_CUBE_MAP_NEGATIVE_X, "CUBE"], [TEXTURE_CUBE_MAP_POSITIVE_Y, "CUBE"], [TEXTURE_CUBE_MAP_NEGATIVE_Y, "CUBE"], [TEXTURE_CUBE_MAP_POSITIVE_Z, "CUBE"], [TEXTURE_CUBE_MAP_NEGATIVE_Z, "CUBE"], [TEXTURE_2D_ARRAY$1, "2D_ARRAY"] ]); function getBindPointForTarget(target) { return targetToBindPointMap.get(target); } const TEXTURE_BINDING_2D$1 = 32873; const TEXTURE_BINDING_CUBE_MAP$1 = 34068; const TEXTURE_BINDING_3D$1 = 32874; const TEXTURE_BINDING_2D_ARRAY$1 = 35869; const samplerTypeToBinding = /* @__PURE__ */ new Map([ [SAMPLER_2D$1, TEXTURE_BINDING_2D$1], [SAMPLER_2D_SHADOW$1, TEXTURE_BINDING_2D$1], [SAMPLER_3D$1, TEXTURE_BINDING_3D$1], [SAMPLER_2D_ARRAY$1, TEXTURE_BINDING_2D_ARRAY$1], [SAMPLER_2D_ARRAY_SHADOW$1, TEXTURE_BINDING_2D_ARRAY$1], [SAMPLER_CUBE$1, TEXTURE_BINDING_CUBE_MAP$1], [SAMPLER_CUBE_SHADOW$1, TEXTURE_BINDING_CUBE_MAP$1] ]); function getTextureForUnit(gl, unit, type) { gl.activeTexture(gl.TEXTURE0 + unit); const binding = samplerTypeToBinding.get(type); return gl.getParameter(binding); } const MAX_COLOR_ATTACHMENTS = 36063; function getMaxColorAttachments(gl) { if (!isWebGL2(gl)) { const ext = gl.getExtension("WEBGL_draw_buffers"); if (!ext) { return 1; } } return gl.getParameter(MAX_COLOR_ATTACHMENTS); } function addTextureAttachment(gl, attachment, textureAttachments) { const type = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); if (type === gl.NONE) { return; } const obj = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); if (obj instanceof WebGLTexture) { if (!textureAttachments.has(obj)) { textureAttachments.set(obj, []); } textureAttachments.get(obj).push(attachment); } } function checkFramebufferFeedback(gl, getWebGLObjectString) { const framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); if (!framebuffer) { return []; } const maxColorAttachments = getMaxColorAttachments(gl); const textureAttachments = /* @__PURE__ */ new Map(); for (let i = 0; i < maxColorAttachments; ++i) { addTextureAttachment(gl, gl.COLOR_ATTACHMENT0 + i, textureAttachments); } addTextureAttachment(gl, gl.DEPTH_ATTACHMENT, textureAttachments); addTextureAttachment(gl, gl.STENCIL_ATTACHMENT, textureAttachments); if (!isWebGL2(gl)) { addTextureAttachment(gl, gl.DEPTH_STENCIL_ATTACHMENT, textureAttachments); } const oldActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE); const program = gl.getParameter(gl.CURRENT_PROGRAM); const numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); const errors = []; for (let ii = 0; ii < numUniforms; ++ii) { const { name, type, size } = gl.getActiveUniform(program, ii); if (isBuiltIn(name) || !uniformTypeIsSampler(type)) { continue; } if (size > 1) { const baseName = name.substr(-3) === "[0]" ? name.substr(0, name.length - 3) : name; for (let t = 0; t < size; ++t) { errors.push(...checkTextureUsage(gl, framebuffer, textureAttachments, program, `${baseName}[${t}]`, type, getWebGLObjectString)); } } else { errors.push(...checkTextureUsage(gl, framebuffer, textureAttachments, program, name, type, getWebGLObjectString)); } } gl.activeTexture(oldActiveTexture); return errors; } function checkTextureUsage(gl, framebuffer, textureAttachments, program, uniformName, uniformType, getWebGLObjectString) { const location = gl.getUniformLocation(program, uniformName); const textureUnit = gl.getUniform(program, location); const texture = getTextureForUnit(gl, textureUnit, uniformType); const attachments = textureAttachments.get(texture); return attachments ? [ `${getWebGLObjectString(texture)} on uniform: ${uniformName} bound to texture unit ${textureUnit} is also attached to ${getWebGLObjectString(framebuffer)} on attachment: ${attachments.map((a) => glEnumToString(a)).join(", ")}` ] : []; } function getBrowser() { const userAgent = navigator.userAgent; let m = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []; if (/trident/i.test(m[1])) { m = /\brv[ :]+(\d+)/g.exec(userAgent) || []; return { name: "IE", version: m[1] }; } if (m[1] === "Chrome") { const temp = userAgent.match(/\b(OPR|Edge)\/(\d+)/); if (temp) { return { name: temp[1].replace("OPR", "Opera"), version: temp[2] }; } } m = m[2] ? [m[1], m[2]] : [navigator.appName, navigator.appVersion, "-?"]; const version = userAgent.match(/version\/(\d+)/i); if (version) { m.splice(1, 1, version[1]); } return { name: m[0], version: m[1] }; } const parseStack = function() { const browser = getBrowser(); let lineNdx; let matcher; if (/chrome|opera/i.test(browser.name)) { lineNdx = 3; matcher = function(line) { const m = /at ([^(]+)*\(*(.*?):(\d+):(\d+)/.exec(line); if (m) { let userFnName = m[1]; let url = m[2]; const lineNo = parseInt(m[3]); const colNo = parseInt(m[4]); if (url === "") { url = userFnName; userFnName = ""; } return { url, lineNo, colNo, funcName: userFnName }; } return void 0; }; } else if (/firefox|safari/i.test(browser.name)) { lineNdx = 2; matcher = function(line) { const m = /@(.*?):(\d+):(\d+)/.exec(line); if (m) { const url = m[1]; const lineNo = parseInt(m[2]); const colNo = parseInt(m[3]); return { url, lineNo, colNo }; } return void 0; }; } return function stackParser(stack) { if (matcher) { try { const lines = stack.split("\n"); return matcher(lines[lineNdx]); } catch (e) { } } return void 0; }; }(); function createTextureUnits(gl) { const textureUnits = []; const numUnits = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); for (let i = 0; i < numUnits; ++i) { textureUnits.push(/* @__PURE__ */ new Map()); } return textureUnits; } const TEXTURE0 = 33984; const TEXTURE_2D$2 = 3553; const TEXTURE_3D$2 = 32879; const TEXTURE_CUBE_MAP$2 = 34067; const TEXTURE_CUBE_MAP_POSITIVE_X$1 = 34069; const TEXTURE_CUBE_MAP_NEGATIVE_X$1 = 34070; const TEXTURE_CUBE_MAP_POSITIVE_Y$1 = 34071; const TEXTURE_CUBE_MAP_NEGATIVE_Y$1 = 34072; const TEXTURE_CUBE_MAP_POSITIVE_Z$1 = 34073; const TEXTURE_CUBE_MAP_NEGATIVE_Z$1 = 34074; const TEXTURE_MIN_FILTER = 10241; const TEXTURE_MAG_FILTER = 10240; const TEXTURE_BASE_LEVEL = 33084; const TEXTURE_MAX_LEVEL = 33085; const TEXTURE_WRAP_S = 10242; const TEXTURE_WRAP_T = 10243; const REPEAT = 10497; const TEXTURE_2D_ARRAY$2 = 35866; const CLAMP_TO_EDGE = 33071; const NEAREST = 9728; const LINEAR = 9729; const NEAREST_MIPMAP_LINEAR = 9986; const texImage2DArgParersMap = /* @__PURE__ */ new Map([ [ 9, function([target, level, internalFormat, width, height, , format, type]) { return { target, level, internalFormat, width, height, format, type }; } ], [ 6, function([target, level, internalFormat, format, type, texImageSource]) { return { target, level, internalFormat, width: texImageSource.width, height: texImageSource.height, format, type }; } ], [ 10, function([target, level, internalFormat, width, height, , format, type]) { return { target, level, internalFormat, width, height, format, type }; } ] ]); const ALPHA = 6406; const RGB = 6407; const RGBA = 6408; const LUMINANCE = 6409; const LUMINANCE_ALPHA = 6410; const DEPTH_COMPONENT = 6402; const DEPTH_STENCIL = 34041; const unsizedInternalFormats = /* @__PURE__ */ new Set([ALPHA, LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA]); function getInternalFormatStringForInternalFormatType(internalFormat, type) { return unsizedInternalFormats.has(internalFormat) ? `${glEnumToString(internalFormat)}/${glEnumToString(type)}` : glEnumToString(internalFormat); } const targetToFaceIndex = /* @__PURE__ */ new Map([ [TEXTURE_2D$2, 0], [TEXTURE_3D$2, 0], [TEXTURE_2D_ARRAY$2, 0], [TEXTURE_CUBE_MAP$2, 0], [TEXTURE_CUBE_MAP_POSITIVE_X$1, 0], [TEXTURE_CUBE_MAP_NEGATIVE_X$1, 1], [TEXTURE_CUBE_MAP_POSITIVE_Y$1, 2], [TEXTURE_CUBE_MAP_NEGATIVE_Y$1, 3], [TEXTURE_CUBE_MAP_POSITIVE_Z$1, 4], [TEXTURE_CUBE_MAP_NEGATIVE_Z$1, 5] ]); function getFaceTarget(face, type) { if (type === TEXTURE_CUBE_MAP$2) { return `(${glEnumToString(TEXTURE_CUBE_MAP_POSITIVE_X$1 + face)})`; } else { return ""; } } const R8 = 33321; const R8_SNORM = 36756; const R16F = 33325; const R32F = 33326; const R8UI = 33330; const R8I = 33329; const RG16UI = 33338; const RG16I = 33337; const RG32UI = 33340; const RG32I = 33339; const RG8 = 33323; const RG8_SNORM = 36757; const RG16F = 33327; const RG32F = 33328; const RG8UI = 33336; const RG8I = 33335; const R16UI = 33332; const R16I = 33331; const R32UI = 33334; const R32I = 33333; const RGB8 = 32849; const SRGB8 = 35905; const RGB565 = 36194; const RGB8_SNORM = 36758; const R11F_G11F_B10F = 35898; const RGB9_E5 = 35901; const RGB16F = 34843; const RGB32F = 34837; const RGB8UI = 36221; const RGB8I = 36239; const RGB16UI = 36215; const RGB16I = 36233; const RGB32UI = 36209; const RGB32I = 36227; const RGBA8 = 32856; const SRGB8_ALPHA8 = 35907; const RGBA8_SNORM = 36759; const RGB5_A1 = 32855; const RGBA4 = 32854; const RGB10_A2 = 32857; const RGBA16F = 34842; const RGBA32F = 34836; const RGBA8UI = 36220; const RGBA8I = 36238; const RGB10_A2UI = 36975; const RGBA16UI = 36214; const RGBA16I = 36232; const RGBA32I = 36226; const RGBA32UI = 36208; const DEPTH_COMPONENT16 = 33189; const DEPTH_COMPONENT24 = 33190; const DEPTH_COMPONENT32F = 36012; const DEPTH32F_STENCIL8 = 36013; const DEPTH24_STENCIL8 = 35056; const BYTE$1 = 5120; const UNSIGNED_BYTE$1 = 5121; const SHORT$1 = 5122; const UNSIGNED_SHORT$1 = 5123; const INT$1 = 5124; const UNSIGNED_INT$1 = 5125; const FLOAT$1 = 5126; const UNSIGNED_SHORT_4_4_4_4 = 32819; const UNSIGNED_SHORT_5_5_5_1 = 32820; const UNSIGNED_SHORT_5_6_5 = 33635; const HALF_FLOAT = 5131; const HALF_FLOAT_OES = 36193; const UNSIGNED_INT_2_10_10_10_REV = 33640; const UNSIGNED_INT_10F_11F_11F_REV = 35899; const UNSIGNED_INT_5_9_9_9_REV = 35902; const FLOAT_32_UNSIGNED_INT_24_8_REV = 36269; const UNSIGNED_INT_24_8 = 34042; const RG = 33319; const RG_INTEGER = 33320; const RED = 6403; const RED_INTEGER = 36244; const RGB_INTEGER = 36248; const RGBA_INTEGER = 36249; function createTextureInternalFormatInfoMap() { const textureInternalFormatInfoMap = /* @__PURE__ */ new Map([ [ ALPHA, { textureFormat: ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1] } ], [ LUMINANCE, { textureFormat: LUMINANCE, colorRenderable: true, textureFilterable: true, bytesPerElement: [1, 2, 2, 4], type: [UNSIGNED_BYTE$1] } ], [ LUMINANCE_ALPHA, { textureFormat: LUMINANCE_ALPHA, colorRenderable: true, textureFilterable: true, bytesPerElement: [2, 4, 4, 8], type: [UNSIGNED_BYTE$1] } ], [ RGB, { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 6, 6, 12, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_6_5] } ], [ RGBA, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 8, 8, 16, 2, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1] } ], [ R8, { textureFormat: RED, colorRenderable: true, textureFilterable: true, bytesPerElement: [1], type: [UNSIGNED_BYTE$1] } ], [ R8_SNORM, { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [1], type: [BYTE$1] } ], [ R16F, { textureFormat: RED, colorRenderable: false, textureFilterable: true, bytesPerElement: [4, 2], type: [FLOAT$1, HALF_FLOAT] } ], [ R32F, { textureFormat: RED, colorRenderable: false, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1] } ], [ R8UI, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [UNSIGNED_BYTE$1] } ], [ R8I, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [1], type: [BYTE$1] } ], [ R16UI, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_SHORT$1] } ], [ R16I, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [SHORT$1] } ], [ R32UI, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1] } ], [ R32I, { textureFormat: RED_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [INT$1] } ], [ RG8, { textureFormat: RG, colorRenderable: true, textureFilterable: true, bytesPerElement: [2], type: [UNSIGNED_BYTE$1] } ], [ RG8_SNORM, { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [2], type: [BYTE$1] } ], [ RG16F, { textureFormat: RG, colorRenderable: false, textureFilterable: true, bytesPerElement: [8, 4], type: [FLOAT$1, HALF_FLOAT] } ], [ RG32F, { textureFormat: RG, colorRenderable: false, textureFilterable: false, bytesPerElement: [8], type: [FLOAT$1] } ], [ RG8UI, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [UNSIGNED_BYTE$1] } ], [ RG8I, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [2], type: [BYTE$1] } ], [ RG16UI, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_SHORT$1] } ], [ RG16I, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [SHORT$1] } ], [ RG32UI, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_INT$1] } ], [ RG32I, { textureFormat: RG_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [INT$1] } ], [ RGB8, { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1] } ], [ SRGB8, { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [UNSIGNED_BYTE$1] } ], [ RGB565, { textureFormat: RGB, colorRenderable: true, textureFilterable: true, bytesPerElement: [3, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_6_5] } ], [ RGB8_SNORM, { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [3], type: [BYTE$1] } ], [ R11F_G11F_B10F, { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_10F_11F_11F_REV] } ], [ RGB9_E5, { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6, 4], type: [FLOAT$1, HALF_FLOAT, UNSIGNED_INT_5_9_9_9_REV] } ], [ RGB16F, { textureFormat: RGB, colorRenderable: false, textureFilterable: true, bytesPerElement: [12, 6], type: [FLOAT$1, HALF_FLOAT] } ], [ RGB32F, { textureFormat: RGB, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [FLOAT$1] } ], [ RGB8UI, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [UNSIGNED_BYTE$1] } ], [ RGB8I, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [3], type: [BYTE$1] } ], [ RGB16UI, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [UNSIGNED_SHORT$1] } ], [ RGB16I, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [6], type: [SHORT$1] } ], [ RGB32UI, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [UNSIGNED_INT$1] } ], [ RGB32I, { textureFormat: RGB_INTEGER, colorRenderable: false, textureFilterable: false, bytesPerElement: [12], type: [INT$1] } ], [ RGBA8, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1] } ], [ SRGB8_ALPHA8, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_BYTE$1] } ], [ RGBA8_SNORM, { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [4], type: [BYTE$1] } ], [ RGB5_A1, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2, 4], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_INT_2_10_10_10_REV] } ], [ RGBA4, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4, 2], type: [UNSIGNED_BYTE$1, UNSIGNED_SHORT_4_4_4_4] } ], [ RGB10_A2, { textureFormat: RGBA, colorRenderable: true, textureFilterable: true, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV] } ], [ RGBA16F, { textureFormat: RGBA, colorRenderable: false, textureFilterable: true, bytesPerElement: [16, 8], type: [FLOAT$1, HALF_FLOAT] } ], [ RGBA32F, { textureFormat: RGBA, colorRenderable: false, textureFilterable: false, bytesPerElement: [16], type: [FLOAT$1] } ], [ RGBA8UI, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_BYTE$1] } ], [ RGBA8I, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [BYTE$1] } ], [ RGB10_A2UI, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_2_10_10_10_REV] } ], [ RGBA16UI, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [UNSIGNED_SHORT$1] } ], [ RGBA16I, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [8], type: [SHORT$1] } ], [ RGBA32I, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [INT$1] } ], [ RGBA32UI, { textureFormat: RGBA_INTEGER, colorRenderable: true, textureFilterable: false, bytesPerElement: [16], type: [UNSIGNED_INT$1] } ], [ DEPTH_COMPONENT16, { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [2, 4], type: [UNSIGNED_SHORT$1, UNSIGNED_INT$1] } ], [ DEPTH_COMPONENT24, { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT$1] } ], [ DEPTH_COMPONENT32F, { textureFormat: DEPTH_COMPONENT, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT$1] } ], [ DEPTH24_STENCIL8, { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [UNSIGNED_INT_24_8] } ], [ DEPTH32F_STENCIL8, { textureFormat: DEPTH_STENCIL, colorRenderable: true, textureFilterable: false, bytesPerElement: [4], type: [FLOAT_32_UNSIGNED_INT_24_8_REV] } ] ]); textureInternalFormatInfoMap.forEach((info) => { info.bytesPerElementMap = {}; info.bytesPerElement.forEach(function(bytesPerElement, ndx) { const type = info.type[ndx]; info.bytesPerElementMap[type] = bytesPerElement; }); }); const internalFormatStringToFormatInfoMap = /* @__PURE__ */ new Map(); textureInternalFormatInfoMap.forEach((info, internalFormat) => { if (unsizedInternalFormats.has(internalFormat)) { info.type.forEach((type) => { internalFormatStringToFormatInfoMap.set(getInternalFormatStringForInternalFormatType(internalFormat, type), info); }); } else { internalFormatStringToFormatInfoMap.set(getInternalFormatStringForInternalFormatType(internalFormat), info); } }); return { textureInternalFormatInfoMap, internalFormatStringToFormatInfoMap }; } function isPowerOf2(value) { return (value & value - 1) === 0; } function computeNumMipsNeeded(width, height = 0, depth = 0) { return (Math.log2(Math.max(width, height, depth)) | 0) + 1; } function insertIf(condition, ...elements) { return condition ? elements : []; } function getNPotIssues(width, height) { return [ ...insertIf(!isPowerOf2(width), `width(${width}) is not a power of 2`), ...insertIf(!isPowerOf2(height), `height(${height}) is not a power of 2`) ].join(" and "); } function getClampToEdgeIssues(wrapS, wrapT) { return [ ...insertIf(wrapS !== CLAMP_TO_EDGE, `TEXTURE_WRAP_S (${glEnumToString(wrapS)}) is not CLAMP_TO_EDGE`), ...insertIf(wrapT !== CLAMP_TO_EDGE, `TEXTURE_WRAP_T (${glEnumToString(wrapT)}) is not CLAMP_TO_EDGE`) ].join(" and "); } function getNumberTypeForInternalFormat(internalFormat) { const str = glEnumToString(internalFormat); if (str.endsWith("UI")) { return "unsigned int"; } if (str.endsWith("I")) { return "int"; } return "float/normalized"; } function getDimensionsString(type, width, height, depth) { return type === TEXTURE_2D$2 || type === TEXTURE_CUBE_MAP$2 ? `${width}x${height}` : `${width}x${height}x${depth}`; } class TextureManager { constructor(gl) { const isWebGL2$1 = isWebGL2(gl); const needPOT = !isWebGL2$1; const extensions = /* @__PURE__ */ new Set(); const textureToTextureInfoMap = /* @__PURE__ */ new Map(); const samplerToParametersMap = /* @__PURE__ */ new Map(); const textureUnits = createTextureUnits(gl); const maxMips = computeNumMipsNeeded(gl.getParameter(gl.MAX_TEXTURE_SIZE)); const { internalFormatStringToFormatInfoMap } = createTextureInternalFormatInfoMap(); let activeTextureUnitIndex = 0; let activeTextureUnit = textureUnits[0]; this.numTextureUnits = textureUnits.length; function recomputeRenderability(textureInfo) { textureInfo.notRenderable = computeRenderability(textureInfo, textureInfo.parameters); } function recomputeAllTextureUnrenderability() { textureToTextureInfoMap.forEach(recomputeRenderability); } function computeRenderability(textureInfo, parameters) { const { type, mips } = textureInfo; const baseLevel = parameters.get(TEXTURE_BASE_LEVEL) || 0; const maxLevel = parameters.get(TEXTURE_MAX_LEVEL) || maxMips; if (maxLevel < baseLevel) { return `TEXTURE_MAX_LEVEL(${maxLevel}) is less than TEXTURE_BASE_LEVEL(${baseLevel})`; } const baseLevelFaces = mips[baseLevel]; if (!baseLevelFaces) { return "no base level mip ${baseLevel}"; } const baseMipFace = baseLevelFaces[0]; if (!baseMipFace) { return "TEXTURE_CUBE_MAP_POSITIVE_X face does not exist"; } const { width: baseWidth, height: baseHeight, depth: baseDepth, internalFormatString: baseInternalFormatString } = baseMipFace; const numFaces = type === TEXTURE_CUBE_MAP$2 ? 6 : 1; const minFilter = parameters.get(TEXTURE_MIN_FILTER); const internalFormatInfo = internalFormatStringToFormatInfoMap.get(baseInternalFormatString); if (internalFormatInfo) { const textureFilterable = internalFormatInfo.textureFilterable; if (!textureFilterable) { if (minFilter !== NEAREST) { return `texture of type (${baseInternalFormatString}) is not filterable but TEXTURE_MIN_FILTER is set to ${glEnumToString(minFilter)}`; } else { const magFilter = parameters.get(TEXTURE_MAG_FILTER); if (magFilter !== NEAREST) { return `texture of type (${baseInternalFormatString}) is not filterable but TEXTURE_MAG_FILTER is set to ${glEnumToString(magFilter)}`; } } } } const numMipsNeeded = minFilter === LINEAR || minFilter === NEAREST ? 1 : computeNumMipsNeeded(baseWidth, baseHeight, baseDepth); { let mipWidth = baseWidth; let mipHeight = baseHeight; let mipDepth = baseDepth; const lastMip = Math.min(maxLevel, baseLevel + numMipsNeeded - 1); for (let mipLevel = baseLevel; mipLevel <= lastMip; ++mipLevel) { const faceMips = mips[mipLevel]; if (!faceMips) { return `filtering is set to use mips (TEXTURE_MIN_FILTER = ${glEnumToString(minFilter)}) but mip level ${mipLevel} does not exist`; } for (let face = 0; face < numFaces; ++face) { const mip = faceMips[face]; if (!mip) { return `filtering is set to use mips (TEXTURE_MIN_FILTER = ${glEnumToString(minFilter)}) but mip level ${mipLevel}${getFaceTarget(face, type)} does not exist`; } if (mip.width !== mipWidth || mip.height !== mipHeight || mip.depth !== mipDepth) { return `mip level ${mipLevel}${getFaceTarget(face, type)} needs to be ${getDimensionsString(type, mipWidth, mipHeight, mipDepth)} but it is ${getDimensionsString(type, mip.width, mip.height, mip.depth)}`; } if (mip.internalFormatString !== baseInternalFormatString) { return `mip level ${mipLevel}${getFaceTarget(face, type)}'s internal format ${mip.internalFormatString} does not match mip level 0's internal format ${baseInternalFormatString}`; } } mipWidth = Math.max(1, mipWidth / 2 | 0); mipHeight = Math.max(1, mipHeight / 2 | 0); if (type !== TEXTURE_2D_ARRAY$2) { mipDepth = Math.max(1, mipDepth / 2 | 0); } } } if (needPOT) { if (!isPowerOf2(baseWidth) || !isPowerOf2(baseHeight)) { if (numMipsNeeded > 1) { return `texture's ${getNPotIssues(baseWidth, baseHeight)} but TEXTURE_MIN_FILTER (${glEnumToString(minFilter)}) is set to need mips`; } const wrapS = parameters.get(TEXTURE_WRAP_S); const wrapT = parameters.get(TEXTURE_WRAP_T); if (wrapS !== CLAMP_TO_EDGE || wrapT !== CLAMP_TO_EDGE) { return `texture's ${getNPotIssues(baseWidth, baseHeight)} but ${getClampToEdgeIssues(wrapS, wrapT)}.`; } } } if (type === TEXTURE_CUBE_MAP$2) { if (baseWidth !== baseHeight) { return `texture is CUBE_MAP but dimensions ${