Add support for imageSmoothingEnabled to WebGLDrawer

This commit is contained in:
Tom 2024-11-13 16:43:46 -05:00
parent e1e0ec6b24
commit 16dbfc62be
2 changed files with 36 additions and 11 deletions

View File

@ -92,6 +92,8 @@
this._renderingCanvas = null; this._renderingCanvas = null;
this._backupCanvasDrawer = null; this._backupCanvasDrawer = null;
this._imageSmoothingEnabled = true; // will be updated by setImageSmoothingEnabled
// Add listeners for events that require modifying the scene or camera // Add listeners for events that require modifying the scene or camera
this._boundToTileReady = ev => this._tileReadyHandler(ev); this._boundToTileReady = ev => this._tileReadyHandler(ev);
this._boundToImageUnloaded = ev => this._imageUnloadedHandler(ev); this._boundToImageUnloaded = ev => this._imageUnloadedHandler(ev);
@ -135,10 +137,7 @@
gl.bindRenderbuffer(gl.RENDERBUFFER, null); gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null); gl.bindFramebuffer(gl.FRAMEBUFFER, null);
let canvases = Array.from(this._TextureMap.keys()); this._unloadTextures();
canvases.forEach(canvas => {
this._cleanupImageData(canvas); // deletes texture, removes from _TextureMap
});
// Delete all our created resources // Delete all our created resources
gl.deleteBuffer(this._secondPass.bufferOutputPosition); gl.deleteBuffer(this._secondPass.bufferOutputPosition);
@ -486,11 +485,18 @@
// Public API required by all Drawer implementations // Public API required by all Drawer implementations
/** /**
* Required by DrawerBase, but has no effect on WebGLDrawer. * Sets whether image smoothing is enabled or disabled
* @param {Boolean} enabled * @param {Boolean} enabled If true, uses gl.LINEAR as the TEXTURE_MIN_FILTER and TEXTURE_MAX_FILTER, otherwise gl.NEAREST.
*/ */
setImageSmoothingEnabled(enabled){ 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 // private
_setupRenderer(){ _setupRenderer(){
let gl = this._gl; let gl = this._gl;
@ -616,7 +627,7 @@
gl.activeTexture(gl.TEXTURE0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this._renderToTexture); 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.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_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_WRAP_T, gl.CLAMP_TO_EDGE);
@ -815,7 +826,7 @@
gl.activeTexture(gl.TEXTURE0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this._renderToTexture); 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.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_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_WRAP_T, gl.CLAMP_TO_EDGE);
@ -955,8 +966,8 @@
// Set the parameters so we can render any size image. // 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_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_WRAP_T, gl.CLAMP_TO_EDGE);
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_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this._textureFilter());
// Upload the image into the texture. // Upload the image into the texture.
this._uploadImageData(tileContext); 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 // private
_uploadImageData(tileContext){ _uploadImageData(tileContext){

View File

@ -193,6 +193,11 @@ function updateTiledImage(tiledImage, data, value, item){
tiledImage.setOpacity(Number(value)); tiledImage.setOpacity(Number(value));
} else if (field == 'flipped'){ } else if (field == 'flipped'){
tiledImage.setFlip($(item).prop('checked')); 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'){ } else if (field == 'cropped'){
if( $(item).prop('checked') ){ if( $(item).prop('checked') ){
let scale = tiledImage.source.width; let scale = tiledImage.source.width;
@ -355,6 +360,7 @@ function makeImagePickerElement(key, label){
<label>Debug: <input type="checkbox" data-image="" data-field="debug"></label> <label>Debug: <input type="checkbox" data-image="" data-field="debug"></label>
<label>Composite: <select data-image="" data-field="composite"></select></label> <label>Composite: <select data-image="" data-field="composite"></select></label>
<label>Wrap: <select data-image="" data-field="wrapping"></select></label> <label>Wrap: <select data-image="" data-field="wrapping"></select></label>
<label>Smoothing: <input type="checkbox" data-image="" data-field="smoothing" checked></label>
</div> </div>
</div>`.replaceAll('data-image=""', `data-image="${key}"`).replace('__title__', label)); </div>`.replaceAll('data-image=""', `data-image="${key}"`).replace('__title__', label));