Properly handle alt tiles of transparent images

This commit is contained in:
Andreas Hocevar
2021-08-11 21:13:20 +02:00
parent efae01e71f
commit 4526f2ef34
4 changed files with 15 additions and 4 deletions

View File

@@ -33,6 +33,8 @@ const map = new Map({
const data = context.getImageData(0, 0, size, size).data; const data = context.getImageData(0, 0, size, size).data;
return Promise.resolve(data); return Promise.resolve(data);
}, },
// disable opacity transition to avoid overlapping labels during tile loading
transition: 0,
}), }),
}), }),
], ],

View File

@@ -293,6 +293,7 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
const uid = getUid(this); const uid = getUid(this);
const time = frameState.time; const time = frameState.time;
let blend = false;
// look for cached tiles to use if a target tile is not ready // look for cached tiles to use if a target tile is not ready
const tileTextures = tileTexturesByZ[z]; const tileTextures = tileTexturesByZ[z];
@@ -308,6 +309,7 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
tile.endTransition(uid); tile.endTransition(uid);
continue; continue;
} }
blend = true;
const tileCoordKey = getTileCoordKey(tileCoord); const tileCoordKey = getTileCoordKey(tileCoord);
alphaLookup[tileCoordKey] = alpha; alphaLookup[tileCoordKey] = alpha;
} }
@@ -340,7 +342,7 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
} }
this.helper.useProgram(this.program_); this.helper.useProgram(this.program_);
this.helper.prepareDraw(frameState); this.helper.prepareDraw(frameState, !blend);
const zs = Object.keys(tileTexturesByZ) const zs = Object.keys(tileTexturesByZ)
.map(Number) .map(Number)

View File

@@ -6,6 +6,7 @@ import EventType from '../events/EventType.js';
import TileEventType from './TileEventType.js'; import TileEventType from './TileEventType.js';
import TileSource, {TileSourceEvent} from './Tile.js'; import TileSource, {TileSourceEvent} from './Tile.js';
import TileState from '../TileState.js'; import TileState from '../TileState.js';
import {assign} from '../obj.js';
import {createXYZ, extentFromProjection} from '../tilegrid.js'; import {createXYZ, extentFromProjection} from '../tilegrid.js';
import {getKeyZXY} from '../tilecoord.js'; import {getKeyZXY} from '../tilecoord.js';
import {getUid} from '../util.js'; import {getUid} from '../util.js';
@@ -110,7 +111,9 @@ class DataTileSource extends TileSource {
return sourceLoader(z, x, y); return sourceLoader(z, x, y);
} }
const tile = new DataTile({tileCoord: [z, x, y], loader: loader}); const tile = new DataTile(
assign({tileCoord: [z, x, y], loader: loader}, this.tileOptions)
);
tile.key = this.getKey(); tile.key = this.getKey();
tile.addEventListener(EventType.CHANGE, this.handleTileChange_); tile.addEventListener(EventType.CHANGE, this.handleTileChange_);

View File

@@ -434,9 +434,10 @@ class WebGLHelper extends Disposable {
* Post process passes will be initialized here, the first one being bound as a render target for * Post process passes will be initialized here, the first one being bound as a render target for
* subsequent draw calls. * subsequent draw calls.
* @param {import("../PluggableMap.js").FrameState} frameState current frame state * @param {import("../PluggableMap.js").FrameState} frameState current frame state
* @param {boolean} [opt_disableAlphaBlend] If true, no alpha blending will happen.
* @api * @api
*/ */
prepareDraw(frameState) { prepareDraw(frameState, opt_disableAlphaBlend) {
const gl = this.getGL(); const gl = this.getGL();
const canvas = this.getCanvas(); const canvas = this.getCanvas();
const size = frameState.size; const size = frameState.size;
@@ -459,7 +460,10 @@ class WebGLHelper extends Disposable {
gl.clearColor(0.0, 0.0, 0.0, 0.0); gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.BLEND); gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); gl.blendFunc(
gl.ONE,
opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA
);
gl.useProgram(this.currentProgram_); gl.useProgram(this.currentProgram_);
this.applyFrameState(frameState); this.applyFrameState(frameState);