Merge pull request #2615 from pearcetm/webgl-glnearest

Add support for imageSmoothingEnabled to WebGLDrawer
This commit is contained in:
Ian Gilman 2024-11-15 09:27:18 -08:00 committed by GitHub
commit cd9e4e8c4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 12 deletions

View File

@ -214,7 +214,7 @@
* For complete list of modes, please @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation/ globalCompositeOperation}
*
* @property {Boolean} [imageSmoothingEnabled=true]
* Image smoothing for canvas rendering (only if the canvas drawer is used). Note: Ignored
* Image smoothing for rendering (only if the canvas or webgl drawer is used). Note: Ignored
* by some (especially older) browsers which do not support this canvas property.
* This property can be changed in {@link Viewer.DrawerBase.setImageSmoothingEnabled}.
*

View File

@ -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,15 @@
// 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
if( this._imageSmoothingEnabled !== enabled ){
this._imageSmoothingEnabled = enabled;
this._unloadTextures();
this.viewer.world.draw();
}
}
/**
@ -600,6 +603,11 @@
}
// private
_textureFilter(){
return this._imageSmoothingEnabled ? this._gl.LINEAR : this._gl.NEAREST;
}
// private
_setupRenderer(){
let gl = this._gl;
@ -616,7 +624,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 +823,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 +963,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 +988,14 @@
};
}
// private
_unloadTextures(){
let canvases = Array.from(this._TextureMap.keys());
canvases.forEach(canvas => {
this._cleanupImageData(canvas); // deletes texture, removes from _TextureMap
});
}
// private
_uploadImageData(tileContext){

View File

@ -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){
<label>Debug: <input type="checkbox" data-image="" data-field="debug"></label>
<label>Composite: <select data-image="" data-field="composite"></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>`.replaceAll('data-image=""', `data-image="${key}"`).replace('__title__', label));