WebGLDrawer demonstration
-Image options (drag and drop to re-order images)
- - -Example code
-- let viewer = OpenSeadragon({ - ... - drawer: 'webgl', - drawerOptions: { - webgl: { - programs: [], - } - } - ... - }); --
diff --git a/src/drawerbase.js b/src/drawerbase.js index ac7b3bd1..7232e614 100644 --- a/src/drawerbase.js +++ b/src/drawerbase.js @@ -237,6 +237,7 @@ $.DrawerBase = class DrawerBase{ * * NOTE: This event is only fired in certain drawing contexts: either the 'canvas' drawer is * being used, or the 'webgl' drawer with 'drawerOptions.webgl.continuousTileRefresh'. + * TODO: if we get rid of this in the webgl drawer, this can be moved to canvas drawer and the comment about continuousTileRefresh can be removed * * @event tile-drawing * @memberof OpenSeadragon.Viewer diff --git a/src/openseadragon.js b/src/openseadragon.js index b63aaf6f..49e3a364 100644 --- a/src/openseadragon.js +++ b/src/openseadragon.js @@ -1346,22 +1346,20 @@ function OpenSeadragon( options ){ compositeOperation: null, // to be passed into each TiledImage // DRAWER SETTINGS - drawer: ['webgl', 'canvas', 'html'], // prefer using webgl, context2d, fallback to html + drawer: ['webgl', 'canvas', 'html'], // prefer using webgl, then canvas (i.e. context2d), then fallback to html /** * drawerOptions dictionary. * @type {Object} drawerOptions - * @property {Object} webgl - options if the WebGLDrawer is used. - * Set 'continuousTileFresh: true' if tile data is modified programmatically - * by filtering plugins or similar. - * @property {Object} context2d - options if the CanvasDrawer is used - * @property {Object} html - options if the HTMLDrawer is used - * @property {Object} custom - options if a custom drawer is used + * @property {Object} webgl - options if the WebGLDrawer is used. No options are currently supported. + * @property {Object} canvas - options if the CanvasDrawer is used. No options are currently supported. + * @property {Object} html - options if the HTMLDrawer is used. No options are currently supported. + * @property {Object} custom - options if a custom drawer is used. No options are currently supported. */ drawerOptions: { webgl: { - continuousTileRefresh: false, + }, - context2d: { + canvas: { }, html: { diff --git a/src/tiledimage.js b/src/tiledimage.js index 9aaf561e..a1ff089a 100644 --- a/src/tiledimage.js +++ b/src/tiledimage.js @@ -236,6 +236,13 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag return this._needsDraw; }, + /** + * Mark the tiled image as needing to be (re)drawn + */ + redraw: function() { + this._needsDraw = true; + }, + /** * @returns {Boolean} Whether all tiles necessary for this TiledImage to draw at the current view have been loaded. */ diff --git a/src/viewer.js b/src/viewer.js index b11233a6..b6280f37 100644 --- a/src/viewer.js +++ b/src/viewer.js @@ -438,7 +438,7 @@ $.Viewer = function( options ) { if (Object.prototype.hasOwnProperty.call(this.drawerOptions, 'useCanvas') ){ $.console.error('useCanvas is deprecated, use the "drawer" option to indicate preferred drawer(s)'); - // for backwards compatibility, use HTMLDrawer if useCanvas is defined an is falsey + // for backwards compatibility, use HTMLDrawer if useCanvas is defined and is falsey if (!this.drawerOptions.useCanvas){ this.drawer = $.HTMLDrawer; } @@ -450,8 +450,8 @@ $.Viewer = function( options ) { drawerCandidates = [$.DEFAULT_SETTINGS.drawer].flat(); // ensure it is a list $.console.warn('No valid drawers were selected. Using the default value.'); } - // extend the drawerOptions object with additional properties to pass to the Drawer implementation - // TODO: how to deal with the possibility that none of the requested drawers are supported? + + this.drawer = null; for (let i = 0; i < drawerCandidates.length; i++) { @@ -532,6 +532,7 @@ $.Viewer = function( options ) { displayRegionColor: this.navigatorDisplayRegionColor, crossOriginPolicy: this.crossOriginPolicy, animationTime: this.animationTime, + drawer: this.drawer.getType(), }); } diff --git a/src/webgldrawer.js b/src/webgldrawer.js index 0d34e299..d9eb672c 100644 --- a/src/webgldrawer.js +++ b/src/webgldrawer.js @@ -112,9 +112,6 @@ // Delete all our created resources gl.deleteBuffer(this._secondPass.bufferOutputPosition); gl.deleteFramebuffer(this._glFrameBuffer); - // TODO: if/when render buffers or frame buffers are used, release them: - // gl.deleteRenderbuffer(someRenderbuffer); - // gl.deleteFramebuffer(someFramebuffer); // make canvases 1 x 1 px and delete references this._renderingCanvas.width = this._renderingCanvas.height = 1; @@ -208,20 +205,21 @@ //iterate over tiled images and draw each one using a two-pass rendering pipeline if needed tiledImages.forEach( (tiledImage, tiledImageIndex) => { - let useContext2dPipeline = ( tiledImage.compositeOperation || - this.viewer.compositeOperation || - tiledImage._clip || - tiledImage._croppingPolygons || - tiledImage.debugMode - ); - - let useTwoPassRendering = useContext2dPipeline || (tiledImage.opacity < 1); // TODO: check hasTransparency in addition to opacity - let tilesToDraw = tiledImage.getTilesToDraw(); if(tilesToDraw.length === 0){ return; } + let firstTile = tilesToDraw[0]; + + let useContext2dPipeline = ( tiledImage.compositeOperation || + this.viewer.compositeOperation || + tiledImage._clip || + tiledImage._croppingPolygons || + tiledImage.debugMode + ); + + let useTwoPassRendering = useContext2dPipeline || (tiledImage.opacity < 1) || firstTile.hasTransparency; // using the context2d pipeline requires a clean rendering (back) buffer to start if(useContext2dPipeline){ @@ -321,8 +319,6 @@ } } - // gl.flush(); // is this necessary? - if(useTwoPassRendering){ // Second rendering pass: Render the tiled image from the framebuffer into the back buffer gl.useProgram(this._secondPass.shaderProgram); @@ -346,21 +342,19 @@ // Draw the quad (two triangles) gl.drawArrays(gl.TRIANGLES, 0, 6); - // TODO: is this the mechanism we want to use here? + // TODO: Can we get rid of this entirely in this version of the webgl drawer? // iterate over any filters - filters can use this._renderToTexture to get rendered data if desired - let filters = this.filters || []; - for(let fi = 0; fi < filters.length; fi++){ - let filter = this.filters[fi]; - if(filter.apply){ - filter.apply(gl); // filter.apply should write data on top of the backbuffer (bound above) - } - } + // let filters = this.filters || []; + // for(let fi = 0; fi < filters.length; fi++){ + // let filter = this.filters[fi]; + // if(filter.apply){ + // filter.apply(gl); // filter.apply should write data on top of the backbuffer (bound above) + // } + // } } renderingBufferHasImageData = true; - // gl.flush(); //make sure drawing to the output buffer of the rendering canvas is complete. Is this necessary? - if(useContext2dPipeline){ // draw from the rendering canvas onto the output canvas, clipping/cropping if needed. this._applyContext2dPipeline(tiledImage, tilesToDraw, tiledImageIndex); @@ -371,7 +365,7 @@ } // Fire tiled-image-drawn event. - // TODO: the image data may not be on the output canvas yet!! + // TODO: do we need to ensure the image has been drawn to the output canvas already? is it possible the image data may not be on the output canvas? if( this.viewer ){ /** * Raised when a tiled image is drawn to the canvas. Only valid @@ -505,17 +499,18 @@ let overallMatrix = viewMatrix.multiply(matrix); - opacityArray[index] = tile.opacity;// * tiledImage.opacity; + opacityArray[index] = tile.opacity; textureDataArray[index] = texture; matrixArray[index] = overallMatrix.values; - if(this.continuousTileRefresh){ - // Upload the image into the texture - // TODO: test if this works appropriately - let tileContext = tile.getCanvasContext(); - this._raiseTileDrawingEvent(tiledImage, this._outputContext, tile, tileContext); - this._uploadImageData(tileContext, tile, tiledImage); - } + // TODO: can we get rid of this in this version of the webgl drawer? + // if(this.continuousTileRefresh){ + // // Upload the image into the texture + // // TODO: test if this works appropriately + // let tileContext = tile.getCanvasContext(); + // this._raiseTileDrawingEvent(tiledImage, this._outputContext, tile, tileContext); + // this._uploadImageData(tileContext, tile, tiledImage); + // } } @@ -889,8 +884,6 @@ this._gl.deleteTexture(textureInfo.texture); } - // release the position buffer from the GPU - // TODO: do this! } // private // necessary for clip testing to pass (test uses spyOnce(drawer._setClip)) diff --git a/test/demo/drawercomparison.html b/test/demo/drawercomparison.html index d40c8ef8..e8ca6e48 100644 --- a/test/demo/drawercomparison.html +++ b/test/demo/drawercomparison.html @@ -6,7 +6,6 @@ - - -
-- let viewer = OpenSeadragon({ - ... - drawer: 'webgl', - drawerOptions: { - webgl: { - programs: [], - } - } - ... - }); --