UNPKG

@allmaps/render

Version:

Render functions for WebGL and image buffers

864 lines (863 loc) 27.2 kB
import { throttle } from "lodash-es"; import { wrap } from "comlink"; import { mergeOptions, squaredDistance, hexToFractionalRgb, hexToFractionalOpaqueRgba } from "@allmaps/stdlib"; import { supportedDistortionMeasures } from "@allmaps/transform"; import { BaseRenderer } from "./BaseRenderer.js"; import { createWebGL2WarpedMapFactory } from "../maps/WebGL2WarpedMap.js"; import { CacheableWorkerImageDataTile } from "../tilecache/CacheableWorkerImageDataTile.js"; import { WarpedMapEvent, WarpedMapEventType } from "../shared/events.js"; import { multiplyHomogeneousTransform, homogeneousTransformToMatrix4, invertHomogeneousTransform } from "../shared/homogeneous-transform.js"; import { createShader, createProgram } from "../shared/webgl2.js"; import { Viewport } from "../viewport/Viewport.js"; import vertex_shader_default from "../shaders/map/vertex-shader.glsl.js"; import fragment_shader_default from "../shaders/map/fragment-shader.glsl.js"; import vertex_shader_default$1 from "../shaders/lines/vertex-shader.glsl.js"; import fragment_shader_default$1 from "../shaders/lines/fragment-shader.glsl.js"; import vertex_shader_default$2 from "../shaders/points/vertex-shader.glsl.js"; import fragment_shader_default$2 from "../shaders/points/fragment-shader.glsl.js"; import WorkerWrapper from "../workers/fetch-and-get-image-data.js"; import WorkerWrapper$1 from "../workers/apply-sprites-image-data.js"; const THROTTLE_PREPARE_RENDER_WAIT_MS = 200; const THROTTLE_PREPARE_RENDER_OPTIONS = { leading: true, trailing: true }; const THROTTLE_CHANGED_WAIT_MS = 50; const THROTTLE_CHANGED_OPTIONS = { leading: true, trailing: true }; const SIGNIFICANT_VIEWPORT_EPSILON = 100 * Number.EPSILON; const SIGNIFICANT_VIEWPORT_DISTANCE = 5; const ANIMATION_DURATION = 750; const DEFAULT_SPECIFIC_WEBGL2_RENDER_OPTIONS = {}; class WebGL2Renderer extends BaseRenderer { #worker; #spritesWorker; gl; mapProgram; linesProgram; pointsProgram; uniformCache; previousSignificantViewport; lastAnimationFrameRequestId; animating = false; animationStart; animationProgress = 0; disableRender = false; throttledPrepareRenderInternal; throttledChanged; /** * Creates an instance of WebGL2Renderer. * * @constructor * @param gl - WebGL 2 rendering context * @param options - options */ constructor(gl, options) { const mapVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default ); const mapFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default ); const linesVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default$1 ); const linesFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default$1 ); const pointsVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default$2 ); const pointsFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default$2 ); const mapProgram = createProgram(gl, mapVertexShader, mapFragmentShader); const linesProgram = createProgram( gl, linesVertexShader, linesFragmentShader ); const pointsProgram = createProgram( gl, pointsVertexShader, pointsFragmentShader ); const worker = new WorkerWrapper(); const spritesWorker = new WorkerWrapper$1(); const wrappedWorker = wrap(worker); const wrappedSpritesWorker = wrap(spritesWorker); super( createWebGL2WarpedMapFactory(gl, mapProgram, linesProgram, pointsProgram), CacheableWorkerImageDataTile.createFactory( wrappedWorker, wrappedSpritesWorker ), options ); this.#worker = worker; this.#spritesWorker = spritesWorker; this.gl = gl; this.options = mergeOptions( DEFAULT_SPECIFIC_WEBGL2_RENDER_OPTIONS, this.options ); this.mapProgram = mapProgram; this.linesProgram = linesProgram; this.pointsProgram = pointsProgram; this.uniformCache = /* @__PURE__ */ new Map(); gl.deleteShader(mapVertexShader); gl.deleteShader(mapFragmentShader); gl.deleteShader(mapVertexShader); gl.deleteShader(mapFragmentShader); gl.deleteShader(mapVertexShader); gl.deleteShader(mapFragmentShader); gl.disable(gl.DEPTH_TEST); this.addEventListeners(); this.throttledPrepareRenderInternal = throttle( this.prepareRenderInternal.bind(this), THROTTLE_PREPARE_RENDER_WAIT_MS, THROTTLE_PREPARE_RENDER_OPTIONS ); this.throttledChanged = throttle( this.changed.bind(this), THROTTLE_CHANGED_WAIT_MS, THROTTLE_CHANGED_OPTIONS ); } initializeWebGL(gl) { const mapVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default ); const mapFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default ); const linesVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default$1 ); const linesFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default$1 ); const pointsVertexShader = createShader( gl, gl.VERTEX_SHADER, vertex_shader_default$2 ); const pointsFragmentShader = createShader( gl, gl.FRAGMENT_SHADER, fragment_shader_default$2 ); const mapProgram = createProgram(gl, mapVertexShader, mapFragmentShader); const linesProgram = createProgram( gl, linesVertexShader, linesFragmentShader ); const pointsProgram = createProgram( gl, pointsVertexShader, pointsFragmentShader ); this.gl = gl; this.mapProgram = mapProgram; this.linesProgram = linesProgram; this.pointsProgram = pointsProgram; this.uniformCache = /* @__PURE__ */ new Map(); gl.disable(gl.DEPTH_TEST); for (const webgl2WarpedMap of this.warpedMapList.getWarpedMaps()) { webgl2WarpedMap.initializeWebGL(mapProgram, linesProgram, pointsProgram); } } /** * Render the map for a given viewport. * * If no viewport is specified the current viewport is rerendered. * If no current viewport is known, a viewport is deduced based on the WarpedMapList and canvas width and hight. * * @param viewport - the current viewport */ render(viewport) { if (this.disableRender) { return; } this.viewport = viewport || this.viewport || Viewport.fromSizeAndMaps( [this.gl.canvas.width, this.gl.canvas.width], this.warpedMapList ); this.loadMissingImagesInViewport(); if (this.someImagesInViewport()) { this.throttledPrepareRenderInternal(); } this.renderInternal(); } clear() { this.warpedMapList.clear(); this.mapsInViewport = /* @__PURE__ */ new Set(); this.mapsWithFetchableTilesForViewport = /* @__PURE__ */ new Set(); this.gl.clear(this.gl.DEPTH_BUFFER_BIT | this.gl.COLOR_BUFFER_BIT); this.tileCache.clear(); } cancelThrottledFunctions() { this.throttledPrepareRenderInternal.cancel(); this.throttledChanged.cancel(); } destroy() { this.cancelThrottledFunctions(); for (const webgl2WarpedMap of this.warpedMapList.getWarpedMaps()) { this.removeEventListenersFromWebGL2WarpedMap(webgl2WarpedMap); } this.removeEventListeners(); super.destroy(); this.gl.deleteProgram(this.mapProgram); this.gl.deleteProgram(this.linesProgram); this.gl.deleteProgram(this.pointsProgram); this.#worker.terminate(); this.#spritesWorker.terminate(); } getUniformLocation(gl, program, name) { let programCache = this.uniformCache.get(program); if (!programCache) { programCache = /* @__PURE__ */ new Map(); this.uniformCache.set(program, programCache); } if (!programCache.has(name)) { const location = gl.getUniformLocation(program, name); programCache.set(name, location); } return programCache.get(name); } updateMapsForViewport(allFechableTilesForViewport) { const { mapsWithFetchableTilesForViewportEntering, mapsWithFetchableTilesForViewportLeaving, mapsInViewportEntering, mapsInViewportLeaving } = super.updateMapsForViewport(allFechableTilesForViewport); this.updateVertexBuffers(mapsWithFetchableTilesForViewportEntering); return { mapsWithFetchableTilesForViewportEntering, mapsWithFetchableTilesForViewportLeaving, mapsInViewportEntering, mapsInViewportLeaving }; } resetPrevious(mapIds) { const webgl2WarpedMaps = this.warpedMapList.getWarpedMaps({ mapIds }); for (const webgl2WarpedMap of webgl2WarpedMaps) { webgl2WarpedMap.resetPrevious(); } } updateVertexBuffers(mapIds) { if (!this.viewport) { return; } const webgl2WarpedMaps = this.warpedMapList.getWarpedMaps({ mapIds }); for (const webgl2WarpedMap of webgl2WarpedMaps) { webgl2WarpedMap.updateVertexBuffers( this.viewport.projectedGeoToClipHomogeneousTransform ); } } prepareRenderInternal() { this.assureProjection(); this.requestFetchableTiles(); } shouldRequestFetchableTiles() { if (!this.viewport) { return false; } if (this.animating) { return false; } if (!this.previousSignificantViewport) { this.previousSignificantViewport = this.viewport; return true; } else { const rectangleSquaredDistances = []; for (let i = 0; i < 4; i++) { rectangleSquaredDistances.push( squaredDistance( this.previousSignificantViewport.projectedGeoRectangle[i], this.viewport.projectedGeoRectangle[i] ) / Math.pow(this.viewport.projectedGeoPerViewportScale, 2) ); } const maxSquaredDistance = Math.max(...rectangleSquaredDistances); if (maxSquaredDistance < SIGNIFICANT_VIEWPORT_EPSILON) { return true; } if (maxSquaredDistance > Math.pow(SIGNIFICANT_VIEWPORT_DISTANCE, 2)) { this.previousSignificantViewport = this.viewport; return true; } else { return false; } } } shouldAnticipateInteraction() { return true; } renderInternal() { if (!this.viewport) { return; } const gl = this.gl; gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); this.renderMapsInternal(); this.renderLinesInternal(); this.renderPointsInternal(); } renderMapsInternal() { if (!this.viewport) { return; } this.setMapProgramUniforms(); for (const mapId of this.mapsWithFetchableTilesForViewport) { const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (!webgl2WarpedMap || !webgl2WarpedMap.shouldRenderMap()) { continue; } this.setMapProgramMapUniforms(webgl2WarpedMap); const count = webgl2WarpedMap.resourceTrianglePoints.length; const primitiveType = this.gl.TRIANGLES; const offset = 0; this.gl.bindVertexArray(webgl2WarpedMap.mapVao); this.gl.drawArrays(primitiveType, offset, count); } } renderLinesInternal() { this.setLinesProgramUniforms(); for (const mapId of this.mapsWithFetchableTilesForViewport) { const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (!webgl2WarpedMap || !webgl2WarpedMap.shouldRenderLines()) { continue; } this.setLinesProgramMapUniforms(webgl2WarpedMap); const count = webgl2WarpedMap.lineGroups.reduce( (accumulator, lineGroup) => accumulator + lineGroup.projectedGeoLines.length, 0 ) * 6; const primitiveType = this.gl.TRIANGLES; const offset = 0; this.gl.bindVertexArray(webgl2WarpedMap.linesVao); this.gl.drawArrays(primitiveType, offset, count); } } renderPointsInternal() { this.setPointsProgramUniforms(); for (const mapId of this.mapsWithFetchableTilesForViewport) { const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (!webgl2WarpedMap || !webgl2WarpedMap.shouldRenderPoints()) { continue; } this.setPointsProgramMapUniforms(webgl2WarpedMap); const count = webgl2WarpedMap.pointGroups.reduce( (accumulator, pointGroup) => accumulator + pointGroup.projectedGeoPoints.length, 0 ); const primitiveType = this.gl.POINTS; const offset = 0; this.gl.bindVertexArray(webgl2WarpedMap.pointsVao); this.gl.drawArrays(primitiveType, offset, count); } } setMapProgramUniforms() { const program = this.mapProgram; const gl = this.gl; gl.useProgram(program); const animationProgressLocation = this.getUniformLocation( gl, program, "u_animationProgress" ); gl.uniform1f(animationProgressLocation, this.animationProgress); } setMapProgramMapUniforms(webgl2WarpedMap) { if (!this.viewport) { return; } const gl = this.gl; const program = this.mapProgram; gl.useProgram(program); const renderHomogeneousTransform = multiplyHomogeneousTransform( this.viewport.projectedGeoToClipHomogeneousTransform, webgl2WarpedMap.invertedRenderHomogeneousTransform ); const renderHomogeneousTransformLocation = this.getUniformLocation( gl, program, "u_renderHomogeneousTransform" ); gl.uniformMatrix4fv( renderHomogeneousTransformLocation, false, homogeneousTransformToMatrix4(renderHomogeneousTransform) ); const opacityLocation = this.getUniformLocation(gl, program, "u_opacity"); gl.uniform1f(opacityLocation, webgl2WarpedMap.options.opacity); const saturationLocation = this.getUniformLocation( gl, program, "u_saturation" ); gl.uniform1f(saturationLocation, webgl2WarpedMap.options.saturation); const removeColorLocation = this.getUniformLocation( gl, program, "u_removeColor" ); gl.uniform1f( removeColorLocation, webgl2WarpedMap.options.removeColor ? 1 : 0 ); const removeColorColorLocation = this.getUniformLocation( gl, program, "u_removeColorColor" ); gl.uniform3fv( removeColorColorLocation, hexToFractionalRgb(webgl2WarpedMap.options.removeColorColor) ); const removeColorThresholdLocation = this.getUniformLocation( gl, program, "u_removeColorThreshold" ); gl.uniform1f( removeColorThresholdLocation, webgl2WarpedMap.options.removeColorThreshold ); const removeColorHardnessLocation = this.getUniformLocation( gl, program, "u_removeColorHardness" ); gl.uniform1f( removeColorHardnessLocation, webgl2WarpedMap.options.removeColorHardness ); const colorizeLocation = this.getUniformLocation(gl, program, "u_colorize"); gl.uniform1f(colorizeLocation, webgl2WarpedMap.options.colorize ? 1 : 0); const colorizeColorLocation = this.getUniformLocation( gl, program, "u_colorizeColor" ); gl.uniform3fv( colorizeColorLocation, hexToFractionalRgb(webgl2WarpedMap.options.colorizeColor) ); const gridLocation = this.getUniformLocation(gl, program, "u_renderGrid"); gl.uniform1f(gridLocation, webgl2WarpedMap.options.renderGrid ? 1 : 0); const colorGrid = this.getUniformLocation(gl, program, "u_renderGridColor"); gl.uniform4fv( colorGrid, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.renderGridColor) ); const distortionLocation = this.getUniformLocation( gl, program, "u_distortion" ); gl.uniform1f(distortionLocation, webgl2WarpedMap.distortionMeasure ? 1 : 0); const distortionMeasureLocation = this.getUniformLocation( gl, program, "u_distortionMeasure" ); gl.uniform1i( distortionMeasureLocation, webgl2WarpedMap.distortionMeasure ? supportedDistortionMeasures.indexOf(webgl2WarpedMap.distortionMeasure) : 0 ); const distortionColor00Location = this.getUniformLocation( gl, program, "u_distortionColor00" ); gl.uniform4fv( distortionColor00Location, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.distortionColor00) ); const distortionColor01Location = this.getUniformLocation( gl, program, "u_distortionColor01" ); gl.uniform4fv( distortionColor01Location, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.distortionColor01) ); const distortionColor1Location = this.getUniformLocation( gl, program, "u_distortionColor1" ); gl.uniform4fv( distortionColor1Location, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.distortionColor1) ); const distortionColor2Location = this.getUniformLocation( gl, program, "u_distortionColor2" ); gl.uniform4fv( distortionColor2Location, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.distortionColor2) ); const distortionColorLocation3 = this.getUniformLocation( gl, program, "u_distortionColor3" ); gl.uniform4fv( distortionColorLocation3, hexToFractionalOpaqueRgba(webgl2WarpedMap.options.distortionColor3) ); const debugTrianglesLocation = this.getUniformLocation( gl, program, "u_debugTriangles" ); gl.uniform1f( debugTrianglesLocation, webgl2WarpedMap.options.debugTriangles ? 1 : 0 ); const debugTilesLocation = this.getUniformLocation( gl, program, "u_debugTiles" ); gl.uniform1f(debugTilesLocation, webgl2WarpedMap.options.debugTiles ? 1 : 0); const scaleFactorForViewportLocation = this.getUniformLocation( gl, program, "u_scaleFactorForViewport" ); const scaleFactorForViewport = webgl2WarpedMap.tileZoomLevelForViewport ? webgl2WarpedMap.tileZoomLevelForViewport.scaleFactor : 1; gl.uniform1i(scaleFactorForViewportLocation, scaleFactorForViewport); const cachedTilesTextureArrayLocation = this.getUniformLocation( gl, program, "u_cachedTilesTextureArray" ); gl.uniform1i(cachedTilesTextureArrayLocation, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D_ARRAY, webgl2WarpedMap.cachedTilesTextureArray); const cachedTilesResourceOriginPointsAndSizesLocation = this.getUniformLocation( gl, program, "u_cachedTilesResourceOriginPointsAndSizesTexture" ); gl.uniform1i(cachedTilesResourceOriginPointsAndSizesLocation, 1); gl.activeTexture(gl.TEXTURE1); gl.bindTexture( gl.TEXTURE_2D, webgl2WarpedMap.cachedTilesResourceOriginPointsAndSizesTexture ); const cachedTileScaleFactorsTextureLocation = this.getUniformLocation( gl, program, "u_cachedTilesScaleFactorsTexture" ); gl.uniform1i(cachedTileScaleFactorsTextureLocation, 2); gl.activeTexture(gl.TEXTURE2); gl.bindTexture( gl.TEXTURE_2D, webgl2WarpedMap.cachedTilesScaleFactorsTexture ); } setLinesProgramUniforms() { if (!this.viewport) { return; } const gl = this.gl; const program = this.linesProgram; gl.useProgram(program); const viewportToClipHomogeneousTransformLocation = this.getUniformLocation( gl, program, "u_viewportToClipHomogeneousTransform" ); gl.uniformMatrix4fv( viewportToClipHomogeneousTransformLocation, false, homogeneousTransformToMatrix4( this.viewport.viewportToClipHomogeneousTransform ) ); const clipToViewportHomogeneousTransformLocation = this.getUniformLocation( gl, program, "u_clipToViewportHomogeneousTransform" ); gl.uniformMatrix4fv( clipToViewportHomogeneousTransformLocation, false, homogeneousTransformToMatrix4( invertHomogeneousTransform( this.viewport.viewportToClipHomogeneousTransform ) ) ); const animationProgressLocation = this.getUniformLocation( gl, program, "u_animationProgress" ); gl.uniform1f(animationProgressLocation, this.animationProgress); } setLinesProgramMapUniforms(webgl2WarpedMap) { if (!this.viewport) { return; } const gl = this.gl; const program = this.linesProgram; gl.useProgram(program); const renderHomogeneousTransform = multiplyHomogeneousTransform( this.viewport.projectedGeoToClipHomogeneousTransform, webgl2WarpedMap.invertedRenderHomogeneousTransform ); const renderHomogeneousTransformLocation = this.getUniformLocation( gl, program, "u_renderHomogeneousTransform" ); gl.uniformMatrix4fv( renderHomogeneousTransformLocation, false, homogeneousTransformToMatrix4(renderHomogeneousTransform) ); } setPointsProgramUniforms() { if (!this.viewport) { return; } const gl = this.gl; const program = this.pointsProgram; gl.useProgram(program); const animationProgressLocation = this.getUniformLocation( gl, program, "u_animationProgress" ); gl.uniform1f(animationProgressLocation, this.animationProgress); const devicePixelRatioLocation = this.getUniformLocation( gl, program, "u_devicePixelRatio" ); gl.uniform1f(devicePixelRatioLocation, this.viewport.devicePixelRatio); } setPointsProgramMapUniforms(webgl2WarpedMap) { if (!this.viewport) { return; } const gl = this.gl; const program = this.pointsProgram; gl.useProgram(program); const renderHomogeneousTransform = multiplyHomogeneousTransform( this.viewport.projectedGeoToClipHomogeneousTransform, webgl2WarpedMap.invertedRenderHomogeneousTransform ); const renderHomogeneousTransformLocation = this.getUniformLocation( gl, program, "u_renderHomogeneousTransform" ); gl.uniformMatrix4fv( renderHomogeneousTransformLocation, false, homogeneousTransformToMatrix4(renderHomogeneousTransform) ); } startAnimation(mapIds) { this.changed(); this.updateVertexBuffers(mapIds); if (this.lastAnimationFrameRequestId !== void 0) { cancelAnimationFrame(this.lastAnimationFrameRequestId); } this.animating = true; this.animationProgress = 0; this.animationStart = void 0; this.lastAnimationFrameRequestId = requestAnimationFrame( ((now) => this.animationFrame(now, mapIds)).bind(this) ); } animationFrame(now, mapIds) { if (!this.animationStart) { this.animationStart = now; } if (now - this.animationStart < ANIMATION_DURATION) { this.animationProgress = (now - this.animationStart) / ANIMATION_DURATION; this.changed(); this.renderInternal(); this.lastAnimationFrameRequestId = requestAnimationFrame( ((now2) => this.animationFrame(now2, mapIds)).bind(this) ); } else { this.finishAnimation(mapIds); } } finishAnimation(mapIds) { this.resetPrevious(mapIds); this.updateVertexBuffers(mapIds); this.animating = false; this.animationProgress = 0; this.animationStart = void 0; this.previousSignificantViewport = this.viewport; this.prepareRenderInternal(); this.changed(); } changed() { this.dispatchEvent(new WarpedMapEvent(WarpedMapEventType.CHANGED)); } imageLoaded(event) { if (event instanceof WarpedMapEvent) { this.dispatchEvent( new WarpedMapEvent(WarpedMapEventType.IMAGELOADED, event.data) ); } } clearMap(mapId) { const webGL2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (webGL2WarpedMap) { webGL2WarpedMap.clearTextures(); } } mapTileLoaded(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds || !event.data?.tileUrl) { throw new Error("Event data missing"); } const { mapIds, tileUrl } = event.data; const mapId = mapIds[0]; const tile = this.tileCache.getCacheableTile(tileUrl); if (!tile) { return; } if (!tile.isCachedTile()) { return; } const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (!webgl2WarpedMap) { return; } webgl2WarpedMap.addCachedTileAndUpdateTextures(tile); } } mapTileDeleted(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds || !event.data.tileUrl) { throw new Error("Event data missing"); } const { mapIds, tileUrl } = event.data; const mapId = mapIds[0]; const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (!webgl2WarpedMap) { return; } webgl2WarpedMap.removeCachedTileAndUpdateTextures(tileUrl); } } warpedMapAdded(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds) { throw new Error("Event data missing"); } const { mapIds } = event.data; const mapId = mapIds[0]; const webgl2WarpedMap = this.warpedMapList.getWarpedMap(mapId); if (webgl2WarpedMap) { this.addEventListenersToWebGL2WarpedMap(webgl2WarpedMap); } } } prepareChange(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds) { throw new Error("Event data missing"); } const { mapIds } = event.data; for (const webgl2WarpedMap of this.warpedMapList.getWarpedMaps({ mapIds })) { if (this.animating) { webgl2WarpedMap.mixPreviousAndNew(1 - this.animationProgress); } } } } animatedChange(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds) { throw new Error("Event data missing"); } const { mapIds } = event.data; this.startAnimation(mapIds); } } immediateChange(event) { if (event instanceof WarpedMapEvent) { if (!event.data?.mapIds) { throw new Error("Event data missing"); } const { mapIds } = event.data; this.finishAnimation(mapIds); } } addEventListenersToWebGL2WarpedMap(webgl2WarpedMap) { webgl2WarpedMap.addEventListener( WarpedMapEventType.TEXTURESUPDATED, this.throttledChanged.bind(this) ); } removeEventListenersFromWebGL2WarpedMap(webgl2WarpedMap) { webgl2WarpedMap.removeEventListener( WarpedMapEventType.TEXTURESUPDATED, this.throttledChanged.bind(this) ); } contextLost() { this.disableRender = true; this.cancelThrottledFunctions(); for (const webgl2WarpedMap of this.warpedMapList.getWarpedMaps()) { webgl2WarpedMap.cancelThrottledFunctions(); } this.tileCache.clear(); } contextRestored() { this.initializeWebGL(this.gl); this.disableRender = false; } } export { DEFAULT_SPECIFIC_WEBGL2_RENDER_OPTIONS, WebGL2Renderer }; //# sourceMappingURL=WebGL2Renderer.js.map