From ec2ab8265c8ceb9562e6290e25ec54491071e207 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sun, 22 Jul 2012 02:24:17 +0200 Subject: [PATCH] Add brightness and contrast controls, thanks @evanw --- src/ol/base/layer.js | 36 +++++++++++++++++++++++++++ src/ol/layerrenderer/layerrenderer.js | 20 +++++++++++++++ src/ol/webgl/layerrenderer.js | 16 ++++++++++++ src/ol/webgl/map.js | 16 ++++++++++++ 4 files changed, 88 insertions(+) diff --git a/src/ol/base/layer.js b/src/ol/base/layer.js index df5999eb2c..163534d612 100644 --- a/src/ol/base/layer.js +++ b/src/ol/base/layer.js @@ -9,6 +9,8 @@ goog.require('ol.Store'); * @enum {string} */ ol.LayerProperty = { + BRIGHTNESS: 'brightness', + CONTRAST: 'contrast', HUE: 'hue', OPACITY: 'opacity', SATURATION: 'saturation', @@ -33,6 +35,8 @@ ol.Layer = function(store, opt_values) { */ this.store_ = store; + this.setBrightness(0); + this.setContrast(0); this.setHue(0); this.setOpacity(1); this.setSaturation(0); @@ -46,6 +50,22 @@ ol.Layer = function(store, opt_values) { goog.inherits(ol.Layer, ol.Object); +/** + * @return {number} Brightness. + */ +ol.Layer.prototype.getBrightness = function() { + return /** @type {number} */ this.get(ol.LayerProperty.BRIGHTNESS); +}; + + +/** + * @return {number} Contrast. + */ +ol.Layer.prototype.getContrast = function() { + return /** @type {number} */ this.get(ol.LayerProperty.CONTRAST); +}; + + /** * @return {number} Hue. */ @@ -88,6 +108,22 @@ ol.Layer.prototype.getVisible = function() { }; +/** + * @param {number} brightness Brightness. + */ +ol.Layer.prototype.setBrightness = function(brightness) { + this.set(ol.LayerProperty.BRIGHTNESS, brightness); +}; + + +/** + * @param {number} contrast Contrast. + */ +ol.Layer.prototype.setContrast = function(contrast) { + this.set(ol.LayerProperty.CONTRAST, contrast); +}; + + /** * @param {number} hue Hue. */ diff --git a/src/ol/layerrenderer/layerrenderer.js b/src/ol/layerrenderer/layerrenderer.js index 74b6d85929..d1320d7a5c 100644 --- a/src/ol/layerrenderer/layerrenderer.js +++ b/src/ol/layerrenderer/layerrenderer.js @@ -29,6 +29,14 @@ ol.LayerRenderer = function(map, layer) { */ this.layer_ = layer; + goog.events.listen(this.layer_, + ol.Object.getChangedEventType(ol.LayerProperty.BRIGHTNESS), + this.handleLayerBrightnessChange, false, this); + + goog.events.listen(this.layer_, + ol.Object.getChangedEventType(ol.LayerProperty.CONTRAST), + this.handleLayerContrastChange, false, this); + goog.events.listen(this.layer_, ol.Object.getChangedEventType(ol.LayerProperty.HUE), this.handleLayerHueChange, false, this); @@ -65,6 +73,18 @@ ol.LayerRenderer.prototype.getMap = function() { }; +/** + * @protected + */ +ol.LayerRenderer.prototype.handleLayerBrightnessChange = goog.nullFunction; + + +/** + * @protected + */ +ol.LayerRenderer.prototype.handleLayerContrastChange = goog.nullFunction; + + /** * @protected */ diff --git a/src/ol/webgl/layerrenderer.js b/src/ol/webgl/layerrenderer.js index 91eb3e45b0..94e2518742 100644 --- a/src/ol/webgl/layerrenderer.js +++ b/src/ol/webgl/layerrenderer.js @@ -56,6 +56,22 @@ ol.webgl.LayerRenderer.prototype.getMap = function() { ol.webgl.LayerRenderer.prototype.getMatrix = goog.abstractMethod; +/** + * @inheritDoc + */ +ol.webgl.LayerRenderer.prototype.handleLayerBrightnessChange = function() { + this.dispatchChangeEvent(); +}; + + +/** + * @inheritDoc + */ +ol.webgl.LayerRenderer.prototype.handleLayerContrastChange = function() { + this.dispatchChangeEvent(); +}; + + /** * @inheritDoc */ diff --git a/src/ol/webgl/map.js b/src/ol/webgl/map.js index 77ac1dee4c..bdff207a7d 100644 --- a/src/ol/webgl/map.js +++ b/src/ol/webgl/map.js @@ -34,6 +34,7 @@ ol.DEBUG_WEBGL = false; /** * @constructor * @extends {ol.webgl.shader.Fragment} + * @see https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/brightnesscontrast.js * @see https://github.com/evanw/glfx.js/blob/master/src/filters/adjust/huesaturation.js */ ol.webgl.map.shader.Fragment = function() { @@ -41,6 +42,8 @@ ol.webgl.map.shader.Fragment = function() { 'precision mediump float;', '', 'uniform mat4 uMatrix;', + 'uniform float uBrightness;', + 'uniform float uContrast;', 'uniform float uHue;', 'uniform float uOpacity;', 'uniform float uSaturation;', @@ -71,6 +74,13 @@ ol.webgl.map.shader.Fragment = function() { ' color.rgb += (average - color.rgb) * (-uSaturation);', ' }', '', + ' color.rgb += uBrightness;', + ' if (uContrast > 0.0) {', + ' color.rgb = (color.rgb - 0.5) / (1.0 - uContrast) + 0.5;', + ' } else {', + ' color.rgb = (color.rgb - 0.5) * (1.0 + uContrast) + 0.5;', + ' }', + '', ' color.a = color.a * uOpacity;', '', ' gl_FragColor = color;', @@ -156,6 +166,8 @@ ol.webgl.Map = function(target, opt_values) { * @private * @type {{aPosition: number, * aTexCoord: number, + * uBrightness: WebGLUniformLocation, + * uContrast: WebGLUniformLocation, * uHue: WebGLUniformLocation, * uMatrix: WebGLUniformLocation, * uOpacity: WebGLUniformLocation, @@ -484,6 +496,8 @@ ol.webgl.Map.prototype.renderInternal = function() { this.locations_ = { aPosition: gl.getAttribLocation(program, 'aPosition'), aTexCoord: gl.getAttribLocation(program, 'aTexCoord'), + uBrightness: gl.getUniformLocation(program, 'uBrightness'), + uContrast: gl.getUniformLocation(program, 'uContrast'), uHue: gl.getUniformLocation(program, 'uHue'), uMatrix: gl.getUniformLocation(program, 'uMatrix'), uOpacity: gl.getUniformLocation(program, 'uOpacity'), @@ -517,6 +531,8 @@ ol.webgl.Map.prototype.renderInternal = function() { this.forEachVisibleLayer(function(layer, layerRenderer) { gl.uniformMatrix4fv( this.locations_.uMatrix, false, layerRenderer.getMatrix()); + gl.uniform1f(this.locations_.uBrightness, layer.getBrightness()); + gl.uniform1f(this.locations_.uContrast, layer.getContrast()); gl.uniform1f(this.locations_.uHue, layer.getHue()); gl.uniform1f(this.locations_.uOpacity, layer.getOpacity()); gl.uniform1f(this.locations_.uSaturation, layer.getSaturation());