diff --git a/src/webgldrawer.js b/src/webgldrawer.js
index 0489eecb..bd712f28 100644
--- a/src/webgldrawer.js
+++ b/src/webgldrawer.js
@@ -92,6 +92,8 @@
this._renderingCanvas = null;
this._backupCanvasDrawer = null;
+ this._imageSmoothingEnabled = true; // will be updated by setImageSmoothingEnabled
+
// Add listeners for events that require modifying the scene or camera
this._boundToTileReady = ev => this._tileReadyHandler(ev);
this._boundToImageUnloaded = ev => this._imageUnloadedHandler(ev);
@@ -135,10 +137,7 @@
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- let canvases = Array.from(this._TextureMap.keys());
- canvases.forEach(canvas => {
- this._cleanupImageData(canvas); // deletes texture, removes from _TextureMap
- });
+ this._unloadTextures();
// Delete all our created resources
gl.deleteBuffer(this._secondPass.bufferOutputPosition);
@@ -486,11 +485,18 @@
// Public API required by all Drawer implementations
/**
- * Required by DrawerBase, but has no effect on WebGLDrawer.
- * @param {Boolean} enabled
+ * Sets whether image smoothing is enabled or disabled
+ * @param {Boolean} enabled If true, uses gl.LINEAR as the TEXTURE_MIN_FILTER and TEXTURE_MAX_FILTER, otherwise gl.NEAREST.
*/
setImageSmoothingEnabled(enabled){
- // noop - this property does not impact WebGLDrawer
+ const changed = this._imageSmoothingEnabled !== enabled;
+ this._imageSmoothingEnabled = enabled;
+ if( changed ){
+ // We need to unload all existing textures so they can be recreated with the new filter
+ this._unloadTextures();
+ }
+ // trigger a re-draw
+ this.viewer.world.draw();
}
/**
@@ -600,6 +606,11 @@
}
+ // private
+ _textureFilter(){
+ return this._imageSmoothingEnabled ? this._gl.LINEAR : this._gl.NEAREST;
+ }
+
// private
_setupRenderer(){
let gl = this._gl;
@@ -616,7 +627,7 @@
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this._renderToTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this._renderingCanvas.width, this._renderingCanvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this._textureFilter());
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
@@ -815,7 +826,7 @@
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this._renderToTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this._textureFilter());
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
@@ -955,8 +966,8 @@
// Set the parameters so we can render any size image.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this._textureFilter());
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this._textureFilter());
// Upload the image into the texture.
this._uploadImageData(tileContext);
@@ -980,6 +991,14 @@
};
}
+ // private
+ _unloadTextures(){
+ let canvases = Array.from(this._TextureMap.keys());
+ canvases.forEach(canvas => {
+ this._cleanupImageData(canvas); // deletes texture, removes from _TextureMap
+ });
+ }
+
// private
_uploadImageData(tileContext){
diff --git a/test/demo/drawercomparison.js b/test/demo/drawercomparison.js
index bb96219b..16acc74e 100644
--- a/test/demo/drawercomparison.js
+++ b/test/demo/drawercomparison.js
@@ -193,6 +193,11 @@ function updateTiledImage(tiledImage, data, value, item){
tiledImage.setOpacity(Number(value));
} else if (field == 'flipped'){
tiledImage.setFlip($(item).prop('checked'));
+ } else if (field == 'smoothing'){
+ const checked = $(item).prop('checked');
+ viewer1.drawer.setImageSmoothingEnabled(checked);
+ viewer2.drawer.setImageSmoothingEnabled(checked);
+ $('[data-field=smoothing]').prop('checked', checked);
} else if (field == 'cropped'){
if( $(item).prop('checked') ){
let scale = tiledImage.source.width;
@@ -355,6 +360,7 @@ function makeImagePickerElement(key, label){
+
`.replaceAll('data-image=""', `data-image="${key}"`).replace('__title__', label));