From 581ea8c77507f0841b93e80f53b607a0b94a7749 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 2 Apr 2015 19:11:46 +0200 Subject: [PATCH] Add color to WEBGL polygons --- src/ol/render/webgl/imagereplay/index.js | 63 +++++++++++++------ src/ol/render/webgl/webglpolygondefault.glsl | 5 +- .../render/webgl/webglpolygondefaultshader.js | 18 ++++-- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/ol/render/webgl/imagereplay/index.js b/src/ol/render/webgl/imagereplay/index.js index 1953fba331..659e552183 100644 --- a/src/ol/render/webgl/imagereplay/index.js +++ b/src/ol/render/webgl/imagereplay/index.js @@ -3,6 +3,7 @@ goog.provide('ol.render.webgl.PolygonReplay'); goog.provide('ol.render.webgl.ReplayGroup'); goog.require('ol'); +goog.require('ol.color'); goog.require('ol.ext.earcut'); goog.require('ol.extent'); goog.require('ol.obj'); @@ -921,9 +922,10 @@ ol.render.webgl.PolygonReplay = function(tolerance, maxExtent) { /** * @private - * @type {ol.color.Matrix} + * @type {ol.Color} */ - this.colorMatrix_ = new ol.color.Matrix(); + this.fillColor_ = null; + /** * The origin of the coordinate system for the point coordinates sent to @@ -993,21 +995,27 @@ goog.inherits(ol.render.webgl.PolygonReplay, ol.render.VectorContext); */ ol.render.webgl.PolygonReplay.prototype.drawCoordinates_ = function(coordinates) { + // Triangulate the polgon var triangulation = ol.ext.earcut(coordinates, true); - var offset = this.vertices_.length / 2; - if (offset === 0) { - this.indices_ = triangulation.indices; - this.vertices_ = triangulation.vertices; - } else { - var i, ii; - var indices = triangulation.indices; - for (i = 0, ii = indices.length; i < ii; ++i) { - this.indices_.push(indices[i] + offset); - } - var vertices = triangulation.vertices; - for (i = 0, ii = vertices.length; i < ii; ++i) { - this.vertices_.push(vertices[i]); - } + var i, ii; + var indices = triangulation.indices; + + // Shift the indices to take into account previously handled polygons + var offset = this.vertices_.length / 6; + for (i = 0, ii = indices.length; i < ii; ++i) { + this.indices_.push(indices[i] + offset); + } + + // Add the color property to each vertex + // TODO performance: make it more efficient + var vertices = triangulation.vertices; + for (i = 0, ii = vertices.length / 2; i < ii; ++i) { + this.vertices_.push(vertices[2 * i]); + this.vertices_.push(vertices[2 * i + 1]); + this.vertices_.push(this.fillColor_[0]); + this.vertices_.push(this.fillColor_[1]); + this.vertices_.push(this.fillColor_[2]); + this.vertices_.push(this.fillColor_[3]); } }; @@ -1031,6 +1039,9 @@ ol.render.webgl.PolygonReplay.prototype.drawMultiLineStringGeometry = */ ol.render.webgl.PolygonReplay.prototype.drawMultiPolygonGeometry = function(geometry, feature) { + if (goog.isNull(this.fillColor_)) { + return; + } var coordinatess = geometry.getCoordinates(); this.startIndices_.push(this.indices_.length); this.startIndicesFeature_.push(feature); @@ -1046,6 +1057,9 @@ ol.render.webgl.PolygonReplay.prototype.drawMultiPolygonGeometry = */ ol.render.webgl.PolygonReplay.prototype.drawPolygonGeometry = function(polygonGeometry, feature) { + if (goog.isNull(this.fillColor_)) { + return; + } var coordinates = polygonGeometry.getCoordinates(); this.startIndices_.push(this.indices_.length); this.startIndicesFeature_.push(feature); @@ -1143,8 +1157,8 @@ ol.render.webgl.PolygonReplay.prototype.replay = function(context, // get the locations var locations; if (goog.isNull(this.defaultLocations_)) { - locations = - new ol.render.webgl.polygonreplay.shader.Default.Locations(gl, program); + locations = new ol.render.webgl.polygonreplay.shader.Default + .Locations(gl, program); this.defaultLocations_ = locations; } else { locations = this.defaultLocations_; @@ -1155,8 +1169,11 @@ ol.render.webgl.PolygonReplay.prototype.replay = function(context, // enable the vertex attrib arrays gl.enableVertexAttribArray(locations.a_position); gl.vertexAttribPointer(locations.a_position, 2, goog.webgl.FLOAT, - false, 8, 0); + false, 24, 0); + gl.enableVertexAttribArray(locations.a_color); + gl.vertexAttribPointer(locations.a_color, 4, goog.webgl.FLOAT, + false, 24, 8); // set the "uniform" values // TODO: use RTE to avoid jitter @@ -1180,6 +1197,7 @@ ol.render.webgl.PolygonReplay.prototype.replay = function(context, // disable the vertex attrib arrays gl.disableVertexAttribArray(locations.a_position); + gl.disableVertexAttribArray(locations.a_color); return result; }; @@ -1213,6 +1231,13 @@ ol.render.webgl.PolygonReplay.prototype.drawReplay_ = ol.render.webgl.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) { // TODO implement + if (!goog.isNull(fillStyle)) { + var fillStyleColor = fillStyle.getColor(); + this.fillColor_ = !goog.isNull(fillStyleColor) ? + ol.color.asArray(fillStyleColor) : [0.0, 0.0, 0.0, 1.0]; + } else { + this.fillColor_ = null; + } }; diff --git a/src/ol/render/webgl/webglpolygondefault.glsl b/src/ol/render/webgl/webglpolygondefault.glsl index 1a29c4cf5d..59712c4228 100644 --- a/src/ol/render/webgl/webglpolygondefault.glsl +++ b/src/ol/render/webgl/webglpolygondefault.glsl @@ -3,14 +3,17 @@ //! COMMON +varying vec4 v_color; //! VERTEX attribute vec2 a_position; +attribute vec4 a_color; uniform mat4 u_projectionMatrix; void main(void) { + v_color = a_color; gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.); } @@ -18,5 +21,5 @@ void main(void) { //! FRAGMENT void main(void) { - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + gl_FragColor = v_color; } diff --git a/src/ol/render/webgl/webglpolygondefaultshader.js b/src/ol/render/webgl/webglpolygondefaultshader.js index 80b5c760b3..30db27c23e 100644 --- a/src/ol/render/webgl/webglpolygondefaultshader.js +++ b/src/ol/render/webgl/webglpolygondefaultshader.js @@ -21,14 +21,14 @@ goog.addSingletonGetter(ol.render.webgl.polygonreplay.shader.DefaultFragment); * @const * @type {string} */ -ol.render.webgl.polygonreplay.shader.DefaultFragment.DEBUG_SOURCE = 'precision mediump float;\n\n\n\nvoid main(void) {\n gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n}\n'; +ol.render.webgl.polygonreplay.shader.DefaultFragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec4 v_color;\n\n\n\nvoid main(void) {\n gl_FragColor = v_color;\n}\n'; /** * @const * @type {string} */ -ol.render.webgl.polygonreplay.shader.DefaultFragment.OPTIMIZED_SOURCE = 'precision mediump float;void main(void){gl_FragColor=vec4(1.0,1.0,1.0,1.0);}'; +ol.render.webgl.polygonreplay.shader.DefaultFragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec4 a;void main(void){gl_FragColor=a;}'; /** @@ -57,14 +57,14 @@ goog.addSingletonGetter(ol.render.webgl.polygonreplay.shader.DefaultVertex); * @const * @type {string} */ -ol.render.webgl.polygonreplay.shader.DefaultVertex.DEBUG_SOURCE = '\n\nattribute vec2 a_position;\n\nuniform mat4 u_projectionMatrix;\n\nvoid main(void) {\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\n}\n\n\n'; +ol.render.webgl.polygonreplay.shader.DefaultVertex.DEBUG_SOURCE = 'varying vec4 v_color;\n\n\nattribute vec2 a_position;\nattribute vec4 a_color;\n\nuniform mat4 u_projectionMatrix;\n\nvoid main(void) {\n v_color = a_color;\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\n}\n\n\n'; /** * @const * @type {string} */ -ol.render.webgl.polygonreplay.shader.DefaultVertex.OPTIMIZED_SOURCE = 'attribute vec2 a;uniform mat4 b;void main(void){gl_Position=b*vec4(a,0.,1.);}'; +ol.render.webgl.polygonreplay.shader.DefaultVertex.OPTIMIZED_SOURCE = 'varying vec4 a;attribute vec2 b;attribute vec4 c;uniform mat4 d;void main(void){a=c;gl_Position=d*vec4(b,0.,1.);}'; /** @@ -89,11 +89,17 @@ ol.render.webgl.polygonreplay.shader.Default.Locations = function(gl, program) { * @type {WebGLUniformLocation} */ this.u_projectionMatrix = gl.getUniformLocation( - program, goog.DEBUG ? 'u_projectionMatrix' : 'b'); + program, goog.DEBUG ? 'u_projectionMatrix' : 'd'); + + /** + * @type {number} + */ + this.a_color = gl.getAttribLocation( + program, goog.DEBUG ? 'a_color' : 'c'); /** * @type {number} */ this.a_position = gl.getAttribLocation( - program, goog.DEBUG ? 'a_position' : 'a'); + program, goog.DEBUG ? 'a_position' : 'b'); };