From 94b153708545e484ec4b3bb2d14e6b4cd65a9191 Mon Sep 17 00:00:00 2001 From: 1chandu Date: Fri, 25 Aug 2017 17:07:18 -0700 Subject: [PATCH] 4.1 release patch (#889) * Fixes #855 --- CHANGELOG.md | 17 ++++ docs/advanced/subclassed-layers.md | 22 +++-- docs/advanced/tips-and-tricks.md | 5 ++ docs/api-reference/base-layer.md | 8 ++ docs/layers/hexagon-cell-layer.md | 2 +- docs/whats-new.md | 4 + .../arc-brushing-layer/arc-brushing-layer.js | 5 +- examples/brushing/deckgl-overlay.js | 3 +- .../scatterplot-brushing-layer.js | 5 +- .../layer-browser/src/examples/core-layers.js | 3 +- .../src/examples/sample-layers.js | 2 +- examples/sample-layers/s2-layer/s2-layer.js | 11 +-- package.json | 2 +- .../core/geojson-layer/geojson-layer.js | 87 +++++++------------ src/layers/core/grid-layer/grid-aggregator.js | 18 ++-- .../screen-grid-layer/screen-grid-layer.js | 9 +- src/lib/draw-and-pick.js | 14 +-- 17 files changed, 125 insertions(+), 92 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13e5a7ea9c3..2d1988d5d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,23 @@ Ref: http://keepachangelog.com/en/0.3.0/ ## Official Releases +#### [4.1.1] - 2017-8-25 + +- Example fixes. (#884) +- getShaders() : update docs and examples. (#876) +- Make sure blend modes override layer parameters during picking (#879) +- Add depthTest:false to ScreenGridLayer (#875) +- Layer.parameters: Update docs and forward in GeojsonLayer (#874) +- Fix S2Layer fill color (#870) +- Fix Maximum call stack size exceeded error in grid aggregator (#868) +- Fix S2Layer base class and props. (#869) +- Doc paragraph reformatting. Bump code links to 4.1-release (#854) +- A pass on refreshing picking and event handling docs (#850) +- Update dependencies to use luma 4.0.1 version (#849) +- interaction bug fixes (#817) + +### deck.gl v4.1 + ### deck.gl v4.0 #### [4.0.0] - 2017-4-6 Major deck.gl Release diff --git a/docs/advanced/subclassed-layers.md b/docs/advanced/subclassed-layers.md index 85f46826a5b..0eb29eda68f 100644 --- a/docs/advanced/subclassed-layers.md +++ b/docs/advanced/subclassed-layers.md @@ -59,17 +59,22 @@ export default MultiColorPathLayer extends PathLayer { You can replace the shaders used in a layer by overriding the `getShaders()` method. Every core layer calls this method during initialization. It -returns the shaders used by the layer in an object: +returns the shaders and modules used by the layer in an object: - `vs`: string, GLSL source of the vertex shader - `fs`: string, GLSL source of the fragment shader +- `modules`: Array, list of shader modules to be used Read about [writing your own shaders](/docs/advanced/writing-shaders.md). -When you are implementing your own custom layers, it is encouraged that you -also define a `getShaders()` function to retreive your shaders. +When you are implementing your own custom layers, and want to change the shaders +it is encouraged that you also define a `getShaders()` function and selectively +overwrite required shader(s) with custom shaders. This makes it much easier for others to subclass your layer and make small changes to the shaders. +Note: When overwriting `getShaders()` you should pass down any unmodified shader(s) +and `modules` as is. See code example below. + ## Defining Additional Uniforms The best way to pass additional uniforms to your custom shader is to override @@ -79,7 +84,7 @@ the `draw()` method: /// my-scatterplot-layer.js // Example to draw rounded rectangles instead of circles in ScatterplotLayer import {ScatterplotLayer} from 'deck.gl'; -import fragmentShader from 'my-scatterplot-layer-fragment'; +import customFragmentShader from 'my-scatterplot-layer-fragment'; export default RoundedRectangleLayer extends ScatterplotLayer { @@ -94,10 +99,11 @@ export default RoundedRectangleLayer extends ScatterplotLayer { } getShaders() { - return { - vs: super.getShaders().vs, - fs: fragmentShader - } + // use object.assign to make sure we don't overwrite existing fields like `vs`, `modules`... + const shaders = Object.assign({}, super.getShaders(), { + fs: customFragmentShader + }); + return shaders; } } RoundedRectangleLayer.defaultProps = { diff --git a/docs/advanced/tips-and-tricks.md b/docs/advanced/tips-and-tricks.md index 41689dce70e..3176de71e6a 100644 --- a/docs/advanced/tips-and-tricks.md +++ b/docs/advanced/tips-and-tricks.md @@ -1,5 +1,10 @@ # Tips and Tricks +## Notes on Rendering Control + +The base `Layer` class (which is inherited by all layers) supports a new property `parameters` that allows applications to specify the state of WebGL parameters such as blending mode, depth testing etc. This provides a tremendous amount of extra flexibility to applications. The new `parameters` prop leverages the luma.gl v4 [setParameters](http://uber.github.io/luma.gl/#/documentation/api-reference/get-parameter) API, which allows all WebGL parameters to be specified as keys in a single parameter object. + + ## Notes on Blending Modes To get a handle on blending modes, it helps to consider that deck.gl diff --git a/docs/api-reference/base-layer.md b/docs/api-reference/base-layer.md index a15f76ce76a..3c166ac7cae 100644 --- a/docs/api-reference/base-layer.md +++ b/docs/api-reference/base-layer.md @@ -252,6 +252,13 @@ prop. ### Render Properties +##### `parameters` (Function, optional) + +The `parameters` allows applications to specify values for WebGL parameters such as blending mode, depth testing etc. Any `parameters` will be applied temporarily while rendering this layer only. + +Please refer to the luma.gl v4 [setParameters](http://uber.github.io/luma.gl/#/documentation/api-reference/get-parameter) API for documentation on supported parameters and values. + + ##### `getPolygonOffset` (Function, optional) - Default: `({layerIndex}) => [0, -layerIndex * 100]` @@ -275,6 +282,7 @@ If the accessor is assigned a falsy value, polygon offset will be set to `[0, 0] might return because of the precision error of 32-bit projection matrices. Try set the `fp64` prop to `true` in this case.* + ## Members *Remarks: Layer members are designed to support the creation of new layers or diff --git a/docs/layers/hexagon-cell-layer.md b/docs/layers/hexagon-cell-layer.md index 2af629dabe2..8aaa046192c 100644 --- a/docs/layers/hexagon-cell-layer.md +++ b/docs/layers/hexagon-cell-layer.md @@ -67,7 +67,7 @@ they will be used to calculate primitive hexagon instead of `hexagonVertices` - Default: `1` Hexagon radius multiplier, between 0 - 1. The radius of hexagon is calculated by -`coverage * getRadius(d)` +`coverage * radius` ##### `elevationScale` (Number, optional) diff --git a/docs/whats-new.md b/docs/whats-new.md index df86c92710b..5347992b12b 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -14,6 +14,10 @@ Two new functions - `DeckGL.queryObject` and `DeckGL.queryVisibleObjects` allow For developers that write their own custome layers, the `shadertools` shader assembly system is now in place to replace the existing `assembleShaders` function in deck.gl. The new shader assembler system supports organizing shader codes into modules and is integrated with luma.gl's [`Model`]() so users no longer need to call `assembleShaders` before creating the `Model` for the layer. +## Per-Layer control of WebGL Parameters + +The base `Layer` class (which is inherited by all layers) supports a new property `parameters` that allows applications to specify the state of WebGL parameters such as blending mode, depth testing etc. This provides significant control over the detailed rendering of layers to applications. Note that the new `parameters` prop directly leverages the luma.gl v4 [setParameters](http://uber.github.io/luma.gl/#/documentation/api-reference/get-parameter) API, which allows all WebGL parameters to be specified as keys in a single parameter object. + ## CompositeLayer Composite layers, which were introduced in v4.0, have received some polish and performance improvements. `CompositeLayer.renderLayers` function now returns a nested array that could contain `null` values, and deck.gl will automatically flatten, filter and render all layers in the array. This is a small convenience that makes using the `renderLayers` methods in complex composite layers a little more readable. deck.gl now also avoids rerendering sublayers of `CompositeLayer` whose props haven't changed. diff --git a/examples/brushing/arc-brushing-layer/arc-brushing-layer.js b/examples/brushing/arc-brushing-layer/arc-brushing-layer.js index 9fe403bfcc6..dc4313e3103 100644 --- a/examples/brushing/arc-brushing-layer/arc-brushing-layer.js +++ b/examples/brushing/arc-brushing-layer/arc-brushing-layer.js @@ -40,7 +40,10 @@ export default class ArcBrushingLayer extends ArcLayer { getShaders() { // use customized shaders - return {vs: arcVertex, fs: arcFragment, modules: []}; + return Object.assign({}, super.getShaders(), { + vs: arcVertex, + fs: arcFragment + }); } draw({uniforms}) { diff --git a/examples/brushing/deckgl-overlay.js b/examples/brushing/deckgl-overlay.js index 16015552406..8567b897d26 100644 --- a/examples/brushing/deckgl-overlay.js +++ b/examples/brushing/deckgl-overlay.js @@ -160,7 +160,8 @@ export default class DeckGLOverlay extends Component { pickable: false, // only show source points when brushing radiusScale: startBrushing ? 3000 : 0, - getColor: d => (d.gain > 0 ? targetColor : sourceColor) + getColor: d => (d.gain > 0 ? targetColor : sourceColor), + getTargetPosition: d => [d[0], d[1], 0] }), new ScatterplotBrushingLayer({ id: 'targets-ring', diff --git a/examples/brushing/scatterplot-brushing-layer/scatterplot-brushing-layer.js b/examples/brushing/scatterplot-brushing-layer/scatterplot-brushing-layer.js index 96a906bc892..0d5fbefaf58 100644 --- a/examples/brushing/scatterplot-brushing-layer/scatterplot-brushing-layer.js +++ b/examples/brushing/scatterplot-brushing-layer/scatterplot-brushing-layer.js @@ -38,7 +38,10 @@ export default class ScatterplotBrushingLayer extends ScatterplotLayer { getShaders() { // get customized shaders - return {vs: scatterplotVertex, fs: scatterplotFragment, modules: []}; + return Object.assign({}, super.getShaders(), { + vs: scatterplotVertex, + fs: scatterplotFragment + }); } // add instanceSourcePositions as attribute diff --git a/examples/layer-browser/src/examples/core-layers.js b/examples/layer-browser/src/examples/core-layers.js index 42d9439420d..6684ffbc177 100644 --- a/examples/layer-browser/src/examples/core-layers.js +++ b/examples/layer-browser/src/examples/core-layers.js @@ -87,7 +87,8 @@ const GeoJsonLayerExample = { getElevation: f => 500, lineWidthScale: 10, lineWidthMinPixels: 1, - pickable: true + pickable: true, + fp64: true } }; diff --git a/examples/layer-browser/src/examples/sample-layers.js b/examples/layer-browser/src/examples/sample-layers.js index 92d65b3a76e..14072395c13 100644 --- a/examples/layer-browser/src/examples/sample-layers.js +++ b/examples/layer-browser/src/examples/sample-layers.js @@ -10,7 +10,7 @@ const S2LayerExample = { opacity: 0.6, getS2Token: f => f.token, getPath: f => f.path, - getFillColor: f => [f.value * 256, (1 - f.value) * 256, (1 - f.value) * 128], + getFillColor: f => [f.value * 255, (1 - f.value) * 255, (1 - f.value) * 128], getStrokeWidth: f => 10, pickable: true } diff --git a/examples/sample-layers/s2-layer/s2-layer.js b/examples/sample-layers/s2-layer/s2-layer.js index e2a8434e07f..5513cdd99e5 100644 --- a/examples/sample-layers/s2-layer/s2-layer.js +++ b/examples/sample-layers/s2-layer/s2-layer.js @@ -38,7 +38,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import {Layer, PolygonLayer} from 'deck.gl'; +import {CompositeLayer, PolygonLayer} from 'deck.gl'; import {getS2Polygon} from './s2-utils'; @@ -47,9 +47,9 @@ const defaultFillColor = [0xBD, 0xE2, 0x7A, 0xFF]; const defaultProps = { drawCells: true, - fillCells: true, + filled: true, - extrusion: false, + extruded: false, wireframe: false, // Cell geometry @@ -64,13 +64,13 @@ const defaultProps = { getFillColor: f => f.fillColor || defaultFillColor }; -export default class S2Layer extends Layer { +export default class S2Layer extends CompositeLayer { initializeState() { } renderLayers() { const {id, getS2Token, getFillColor, getHeight} = this.props; - const {extruded, wireframe} = this.props; + const {extruded, wireframe, filled} = this.props; // Filled Polygon Layer // TODO - use a composite polygon layer that renders outlines etc @@ -81,6 +81,7 @@ export default class S2Layer extends Layer { getColor: getFillColor, extruded, wireframe, + filled, updateTriggers: Object.assign({}, this.props.updateTriggers, { getColor: this.props.updateTriggers.getFillColor }) diff --git a/package.json b/package.json index 517d711ac69..b1d8c880b92 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "deck.gl", "description": "A suite of 3D-enabled data visualization overlays, suitable for react-map-gl", "license": "MIT", - "version": "4.1.0", + "version": "4.1.1", "keywords": [ "webgl", "visualization", diff --git a/src/layers/core/geojson-layer/geojson-layer.js b/src/layers/core/geojson-layer/geojson-layer.js index 18792555ac3..202b28d4042 100644 --- a/src/layers/core/geojson-layer/geojson-layer.js +++ b/src/layers/core/geojson-layer/geojson-layer.js @@ -110,34 +110,35 @@ export default class GeoJsonLayer extends CompositeLayer { const {getLineColor, getFillColor, getRadius, getLineWidth, getElevation, updateTriggers} = this.props; - // base layer props - const {opacity, pickable, visible, getPolygonOffset} = this.props; - - // viewport props - const {positionOrigin, projectionMode, modelMatrix} = this.props; - const drawPoints = pointFeatures && pointFeatures.length > 0; const drawLines = lineFeatures && lineFeatures.length > 0; const hasPolygonLines = polygonOutlineFeatures && polygonOutlineFeatures.length > 0; const hasPolygon = polygonFeatures && polygonFeatures.length > 0; + // base layer props + const {opacity, pickable, visible, parameters, getPolygonOffset} = this.props; + // viewport props + const {positionOrigin, projectionMode, modelMatrix} = this.props; + + const forwardProps = { + // Forward layer props + opacity, pickable, visible, parameters, getPolygonOffset, + // Forward viewport props + projectionMode, positionOrigin, modelMatrix, + // Forward common props + fp64 + }; + // Filled Polygon Layer const polygonFillLayer = filled && hasPolygon && - new SolidPolygonLayer({ + new SolidPolygonLayer(Object.assign({}, forwardProps, { id: `${id}-polygon-fill`, data: polygonFeatures, + extruded, wireframe: false, lightSettings, - fp64, - opacity, - pickable, - visible, - getPolygonOffset, - projectionMode, - positionOrigin, - modelMatrix, getPolygon: getCoordinates, getElevation, getColor: getFillColor, @@ -145,24 +146,17 @@ export default class GeoJsonLayer extends CompositeLayer { getElevation: updateTriggers.getElevation, getColor: updateTriggers.getFillColor } - }); + })); const polygonWireframeLayer = wireframe && extruded && hasPolygon && - new SolidPolygonLayer({ + new SolidPolygonLayer(Object.assign({}, forwardProps, { id: `${id}-polygon-wireframe`, data: polygonFeatures, + extruded, wireframe: true, - fp64, - opacity, - pickable, - visible, - getPolygonOffset, - projectionMode, - positionOrigin, - modelMatrix, getPolygon: getCoordinates, getElevation, getColor: getLineColor, @@ -170,12 +164,12 @@ export default class GeoJsonLayer extends CompositeLayer { getElevation: updateTriggers.getElevation, getColor: updateTriggers.getLineColor } - }); + })); const polygonLineLayer = !extruded && stroked && hasPolygonLines && - new PathLayer({ + new PathLayer(Object.assign({}, forwardProps, { id: `${id}-polygon-outline`, data: polygonOutlineFeatures, widthScale: lineWidthScale, @@ -183,14 +177,7 @@ export default class GeoJsonLayer extends CompositeLayer { widthMaxPixels: lineWidthMaxPixels, rounded: lineJointRounded, miterLimit: lineMiterLimit, - fp64, - opacity, - pickable, - visible, - getPolygonOffset, - projectionMode, - positionOrigin, - modelMatrix, + getPath: getCoordinates, getColor: getLineColor, getWidth: getLineWidth, @@ -198,24 +185,18 @@ export default class GeoJsonLayer extends CompositeLayer { getColor: updateTriggers.getLineColor, getWidth: updateTriggers.getLineWidth } - }); + })); - const pathLayer = drawLines && new PathLayer({ + const pathLayer = drawLines && new PathLayer(Object.assign({}, forwardProps, { id: `${id}-line-paths`, data: lineFeatures, + widthScale: lineWidthScale, widthMinPixels: lineWidthMinPixels, widthMaxPixels: lineWidthMaxPixels, rounded: lineJointRounded, miterLimit: lineMiterLimit, - fp64, - opacity, - pickable, - visible, - getPolygonOffset, - projectionMode, - positionOrigin, - modelMatrix, + getPath: getCoordinates, getColor: getLineColor, getWidth: getLineWidth, @@ -223,22 +204,16 @@ export default class GeoJsonLayer extends CompositeLayer { getColor: updateTriggers.getLineColor, getWidth: updateTriggers.getLineWidth } - }); + })); - const pointLayer = drawPoints && new ScatterplotLayer({ + const pointLayer = drawPoints && new ScatterplotLayer(Object.assign({}, forwardProps, { id: `${id}-points`, data: pointFeatures, + radiusScale: pointRadiusScale, radiusMinPixels: pointRadiusMinPixels, radiusMaxPixels: pointRadiusMaxPixels, - fp64, - opacity, - pickable, - visible, - getPolygonOffset, - projectionMode, - positionOrigin, - modelMatrix, + getPosition: getCoordinates, getColor: getFillColor, getRadius, @@ -246,7 +221,7 @@ export default class GeoJsonLayer extends CompositeLayer { getColor: updateTriggers.getFillColor, getRadius: updateTriggers.getRadius } - }); + })); return [ // If not extruded: flat fill layer is drawn below outlines diff --git a/src/layers/core/grid-layer/grid-aggregator.js b/src/layers/core/grid-layer/grid-aggregator.js index c7216d7abd1..4bd4bd3ff12 100644 --- a/src/layers/core/grid-layer/grid-aggregator.js +++ b/src/layers/core/grid-layer/grid-aggregator.js @@ -44,15 +44,21 @@ export function pointToDensityGridData(points, cellSize, getPosition) { * @param {function} getPosition - position accessor * @returns {object} - grid hash and cell dimension */ -function _pointsToGridHashing(points, cellSize, getPosition) { +function _pointsToGridHashing(points = [], cellSize, getPosition) { // find the geometric center of sample points - const allLat = points - .map(p => getPosition(p)[1]) - .filter(Number.isFinite); + let latMin = Infinity; + let latMax = -Infinity; + let pLat; + + for (let p = 0; p < points.length; p++) { + pLat = getPosition(points[p])[1]; + if (Number.isFinite(pLat)) { + latMin = pLat < latMin ? pLat : latMin; + latMax = pLat > latMax ? pLat : latMax; + } + } - const latMin = Math.min.apply(null, allLat); - const latMax = Math.max.apply(null, allLat); const centerLat = (latMin + latMax) / 2; const gridOffset = _calculateGridLatLonOffset(cellSize, centerLat); diff --git a/src/layers/core/screen-grid-layer/screen-grid-layer.js b/src/layers/core/screen-grid-layer/screen-grid-layer.js index ff77aa67325..72724dab344 100644 --- a/src/layers/core/screen-grid-layer/screen-grid-layer.js +++ b/src/layers/core/screen-grid-layer/screen-grid-layer.js @@ -75,14 +75,15 @@ export default class ScreenGridLayer extends Layer { } draw({uniforms}) { - const {minColor, maxColor} = this.props; + const {minColor, maxColor, parameters = {}} = this.props; const {model, cellScale, maxCount} = this.state; uniforms = Object.assign({}, uniforms, {minColor, maxColor, cellScale, maxCount}); model.draw({ uniforms, - parameters: { - depthMask: true - } + parameters: Object.assign({ + depthTest: false, + depthMask: false + }, parameters) }); } diff --git a/src/lib/draw-and-pick.js b/src/lib/draw-and-pick.js index ba35a0b54a8..2d995288641 100644 --- a/src/lib/draw-and-pick.js +++ b/src/lib/draw-and-pick.js @@ -330,11 +330,7 @@ function getPickedColors(gl, { return withParameters(gl, { framebuffer: pickingFBO, scissorTest: true, - scissor: [x, y, width, height], - blend: true, - blendFunc: [gl.ONE, gl.ZERO, gl.CONSTANT_ALPHA, gl.ZERO], - blendEquation: gl.FUNC_ADD - // TODO - Set clear color + scissor: [x, y, width, height] }, () => { // Clear the frame buffer @@ -355,7 +351,13 @@ function getPickedColors(gl, { layer.context.uniforms, {layerIndex} ), - parameters: layer.props.parameters || {} + // Blend parameters must not be overriden + parameters: Object.assign({}, layer.props.parameters || {}, { + blend: true, + blendFunc: [gl.ONE, gl.ZERO, gl.CONSTANT_ALPHA, gl.ZERO], + blendEquation: gl.FUNC_ADD, + clearColor: [0, 0, 0, 0] + }) }); } });