UNPKG

@deck.gl/arcgis

Version:

Use deck.gl as a custom ArcGIS API for JavaScript layer

144 lines (143 loc) 4.7 kB
// deck.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors /* eslint-disable no-invalid-this */ import { GL } from '@luma.gl/constants'; import { Deck } from '@deck.gl/core'; import { Model, Geometry } from '@luma.gl/engine'; import { WebGLDevice } from '@luma.gl/webgl'; async function createDeckInstance(gl) { return new Promise(resolve => { const deckInstance = new Deck({ // Input is handled by the ArcGIS API for JavaScript. controller: false, // We use the same WebGL context as the ArcGIS API for JavaScript. gl, // We need depth testing in general; we don't know what layers might be added to the deck. parameters: { depthCompare: 'less-equal' }, // To disable canvas resizing, since the FBO is owned by the ArcGIS API for JavaScript. width: null, height: null, onDeviceInitialized: (device) => { resolve({ deckInstance, device }); } }); }); } export async function initializeResources(gl) { const { deckInstance, device } = await createDeckInstance(gl); const texture = device.createTexture({ format: 'rgba8unorm', width: 1, height: 1, sampler: { minFilter: 'linear', magFilter: 'linear', addressModeU: 'clamp-to-edge', addressModeV: 'clamp-to-edge' } }); const model = new Model(device, { vs: `\ #version 300 es in vec2 pos; out vec2 v_texcoord; void main(void) { gl_Position = vec4(pos, 0.0, 1.0); v_texcoord = (pos + 1.0) / 2.0; } `, fs: `\ #version 300 es precision mediump float; uniform sampler2D deckglTexture; in vec2 v_texcoord; out vec4 fragColor; void main(void) { vec4 imageColor = texture(deckglTexture, v_texcoord); imageColor.rgb *= imageColor.a; fragColor = imageColor; } `, bindings: { deckglTexture: texture }, parameters: { depthWriteEnabled: true, depthCompare: 'less-equal', blendColorSrcFactor: 'one', blendColorDstFactor: 'one-minus-src-alpha', blendAlphaSrcFactor: 'one', blendAlphaDstFactor: 'one-minus-src-alpha', blendColorOperation: 'add', blendAlphaOperation: 'add' }, geometry: new Geometry({ topology: 'triangle-strip', attributes: { pos: { size: 2, value: new Int8Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1]) } } }), vertexCount: 6, disableWarnings: true }); const fbo = device.createFramebuffer({ id: 'deckfbo', width: 1, height: 1, colorAttachments: [texture], depthStencilAttachment: 'depth16unorm' }); deckInstance.setProps({ // This deck renders into an auxiliary framebuffer. _framebuffer: fbo, _customRender: redrawReason => { if (redrawReason === 'arcgis') { deckInstance._drawLayers(redrawReason); } else { this.redraw(); } } }); return { deck: deckInstance, texture, fbo, model }; } export function render(resources, viewport) { const { model, deck, fbo } = resources; const device = model.device; if (device instanceof WebGLDevice) { // @ts-ignore device.getParametersWebGL should return `any` not `void`? const screenFbo = device.getParametersWebGL(36006); const { width, height, ...viewState } = viewport; /* global window */ const dpr = window.devicePixelRatio; const pixelWidth = Math.round(width * dpr); const pixelHeight = Math.round(height * dpr); fbo.resize({ width: pixelWidth, height: pixelHeight }); deck.setProps({ viewState }); // redraw deck immediately into deckFbo deck.redraw('arcgis'); // We overlay the texture on top of the map using the full-screen quad. const textureToScreenPass = device.beginRenderPass({ framebuffer: screenFbo, parameters: { viewport: [0, 0, pixelWidth, pixelHeight] }, clearColor: false, clearDepth: false }); try { model.draw(textureToScreenPass); } finally { textureToScreenPass.end(); } } } export function finalizeResources(resources) { resources.deck.finalize(); resources.model.destroy(); resources.fbo.destroy(); resources.texture.destroy(); } //# sourceMappingURL=commons.js.map