From c2fc800fc151fdaaa435b6933e93fbd65172b9f5 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 18 Nov 2021 09:48:26 -0700 Subject: [PATCH] Allow WebGL tile layer style to be updated --- src/ol/layer/WebGLTile.js | 22 ++++++++++++++++++++++ src/ol/renderer/webgl/Layer.js | 11 +++++++++++ src/ol/renderer/webgl/TileLayer.js | 18 ++++++++++++++++++ src/ol/webgl/Helper.js | 24 +++++++++++++++++------- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/ol/layer/WebGLTile.js b/src/ol/layer/WebGLTile.js index c4847b6792..dc34479ce9 100644 --- a/src/ol/layer/WebGLTile.js +++ b/src/ol/layer/WebGLTile.js @@ -311,6 +311,28 @@ class WebGLTileLayer extends BaseTileLayer { }); } + /** + * Update the layer style. The `updateStyleVariables` function is a more efficient + * way to update layer rendering. In cases where the whole style needs to be updated, + * this method may be called instead. + * @param {Style} style The new style. + */ + setStyle(style) { + this.style_ = style; + const source = this.getSource(); + const parsedStyle = parseStyle( + this.style_, + 'bandCount' in source ? source.bandCount : 4 + ); + const renderer = this.getRenderer(); + renderer.reset({ + vertexShader: parsedStyle.vertexShader, + fragmentShader: parsedStyle.fragmentShader, + uniforms: parsedStyle.uniforms, + }); + this.changed(); + } + /** * Update any variables used by the layer style and trigger a re-render. * @param {Object} variables Variables to update. diff --git a/src/ol/renderer/webgl/Layer.js b/src/ol/renderer/webgl/Layer.js index c1b35cc5c1..39610eb4b0 100644 --- a/src/ol/renderer/webgl/Layer.js +++ b/src/ol/renderer/webgl/Layer.js @@ -90,6 +90,17 @@ class WebGLLayerRenderer extends LayerRenderer { layer.addChangeListener(LayerProperty.MAP, this.removeHelper_.bind(this)); } + /** + * Reset options (only handles uniforms). + * @param {Options} options Options. + */ + reset(options) { + this.uniforms_ = options.uniforms; + if (this.helper) { + this.helper.setUniforms(this.uniforms_); + } + } + removeHelper_() { if (this.helper) { this.helper.dispose(); diff --git a/src/ol/renderer/webgl/TileLayer.js b/src/ol/renderer/webgl/TileLayer.js index 16b3c3309e..68c0917031 100644 --- a/src/ol/renderer/webgl/TileLayer.js +++ b/src/ol/renderer/webgl/TileLayer.js @@ -213,6 +213,24 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer { this.tileTextureCache_ = new LRUCache(cacheSize); } + /** + * @param {Options} options Options. + */ + reset(options) { + super.reset({ + uniforms: options.uniforms, + }); + this.vertexShader_ = options.vertexShader; + this.fragmentShader_ = options.fragmentShader; + + if (this.helper) { + this.program_ = this.helper.getProgram( + this.fragmentShader_, + this.vertexShader_ + ); + } + } + afterHelperCreated() { this.program_ = this.helper.getProgram( this.fragmentShader_, diff --git a/src/ol/webgl/Helper.js b/src/ol/webgl/Helper.js index ef70a3f4d2..ae8358c00d 100644 --- a/src/ol/webgl/Helper.js +++ b/src/ol/webgl/Helper.js @@ -340,7 +340,6 @@ class WebGLHelper extends Disposable { * @type {WebGLRenderingContext} */ this.gl_ = getContext(this.canvas_); - const gl = this.getGL(); /** * @private @@ -407,14 +406,11 @@ class WebGLHelper extends Disposable { */ this.uniforms_ = []; if (options.uniforms) { - for (const name in options.uniforms) { - this.uniforms_.push({ - name: name, - value: options.uniforms[name], - }); - } + this.setUniforms(options.uniforms); } + const gl = this.getGL(); + /** * An array of PostProcessingPass objects is kept in this variable, built from the steps provided in the * options. If no post process was given, a default one is used (so as not to have to make an exception to @@ -447,6 +443,20 @@ class WebGLHelper extends Disposable { this.startTime_ = Date.now(); } + /** + * @param {Object} uniforms Uniform definitions. + */ + setUniforms(uniforms) { + this.uniforms_ = []; + for (const name in uniforms) { + this.uniforms_.push({ + name: name, + value: uniforms[name], + }); + } + this.uniformLocations_ = {}; + } + /** * @param {string} canvasCacheKey The canvas cache key. * @return {boolean} The provided key matches the one this helper was constructed with.