diff --git a/src/ol/render/webgl/imagereplay/index.js b/src/ol/render/webgl/imagereplay/index.js index d8eb21f6eb..1d6f5e69af 100644 --- a/src/ol/render/webgl/imagereplay/index.js +++ b/src/ol/render/webgl/imagereplay/index.js @@ -15,6 +15,10 @@ goog.require('ol.render.replay'); goog.require('ol.render.webgl.imagereplay.defaultshader'); goog.require('ol.transform'); goog.require('ol.render.webgl'); +goog.require('ol.render.webgl.linestringreplay.shader.Default'); +goog.require('ol.render.webgl.linestringreplay.shader.Default.Locations'); +goog.require('ol.render.webgl.linestringreplay.shader.DefaultFragment'); +goog.require('ol.render.webgl.linestringreplay.shader.DefaultVertex'); goog.require('ol.render.webgl.polygonreplay.shader.Default'); goog.require('ol.render.webgl.polygonreplay.shader.Default.Locations'); goog.require('ol.render.webgl.polygonreplay.shader.DefaultFragment'); @@ -1009,30 +1013,33 @@ goog.inherits(ol.render.webgl.LineStringReplay, ol.render.webgl.Replay); /** * Draw one line. - * @param {Array.} coordinates Coordinates. + * @param {Array.} flatCoordinates Flat coordinates. + * @param {number} offset Offset. + * @param {number} end End. + * @param {number} stride Stride. * @private */ -ol.render.webgl.LineStringReplay.prototype.drawCoordinates_ = function(coordinates) { +ol.render.webgl.LineStringReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) { var i, ii; var numVertices = this.vertices_.length; + var numIndices = this.indices_.length; + var n = this.indices_.length > 0 ? this.indices_[numIndices - 1] + 1 : 0; // Shift the indices to take into account previously handled lines - for (i = 0, ii = coordinates.length - 1; i < ii; ++i) { - var point1 = coordinates[i]; - this.vertices_[numVertices++] = point1[0] - this.origin_[0]; - this.vertices_[numVertices++] = point1[1] - this.origin_[1]; - this.vertices_[numVertices++] = this.state_.strokeColor[0]; - this.vertices_[numVertices++] = this.state_.strokeColor[1]; - this.vertices_[numVertices++] = this.state_.strokeColor[2]; - this.vertices_[numVertices++] = this.state_.strokeColor[3]; + for (i = offset, ii = end - stride; i < ii; i += stride) { - var point2 = coordinates[i + 1]; - this.vertices_[numVertices++] = point2[0] - this.origin_[0]; - this.vertices_[numVertices++] = point2[1] - this.origin_[1]; - this.vertices_[numVertices++] = this.state_.strokeColor[0]; - this.vertices_[numVertices++] = this.state_.strokeColor[1]; - this.vertices_[numVertices++] = this.state_.strokeColor[2]; - this.vertices_[numVertices++] = this.state_.strokeColor[3]; + if (i == offset) { + this.vertices_[numVertices++] = flatCoordinates[i] - this.origin_[0]; + this.vertices_[numVertices++] = flatCoordinates[i + 1] - this.origin_[1]; + + i += stride; + } + + this.vertices_[numVertices++] = flatCoordinates[i] - this.origin_[0]; + this.vertices_[numVertices++] = flatCoordinates[i + 1] - this.origin_[1]; + + this.indices_[numIndices++] = n++; + this.indices_[numIndices++] = n; } }; @@ -1040,19 +1047,25 @@ ol.render.webgl.LineStringReplay.prototype.drawCoordinates_ = function(coordinat /** * @inheritDoc */ -ol.render.webgl.LineStringReplay.prototype.drawLineString = function(geometry, feature) { - this.drawCoordinates_(geometry.getCoordinates()); +ol.render.webgl.LineStringReplay.prototype.drawLineString = function(lineStringGeometry, feature) { + var flatCoordinates = lineStringGeometry.getFlatCoordinates(); + var stride = lineStringGeometry.getStride(); + this.drawCoordinates_( + flatCoordinates, 0, flatCoordinates.length, stride); }; /** * @inheritDoc */ -ol.render.webgl.LineStringReplay.prototype.drawMultiLineString = function(geometry, feature) { - var coordinatess = geometry.getCoordinates(); +ol.render.webgl.LineStringReplay.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) { + var lineStringGeometries = multiLineStringGeometry.getLineStrings(); var i, ii; - for (i = 0, ii = coordinatess.length; i < ii; ++i) { - this.drawCoordinates_(coordinatess[i]); + for (i = 0, ii = lineStringGeometries.length; i < ii; ++i) { + var flatCoordinates = lineStringGeometries[i].getFlatCoordinates(); + var stride = lineStringGeometries[i].getStride(); + this.drawCoordinates_( + flatCoordinates, 0, flatCoordinates.length, stride); } }; @@ -1095,21 +1108,21 @@ ol.render.webgl.LineStringReplay.prototype.getDeleteResourcesFunction = function * @private * @param {WebGLRenderingContext} gl gl. * @param {ol.webgl.Context} context Context. - * @return {ol.render.webgl.polygonreplay.shader.Default.Locations} Locations. + * @return {ol.render.webgl.linestringreplay.shader.Default.Locations} Locations. */ ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context) { // get the program var fragmentShader, vertexShader; fragmentShader = - ol.render.webgl.polygonreplay.shader.DefaultFragment.getInstance(); + ol.render.webgl.linestringreplay.shader.DefaultFragment.getInstance(); vertexShader = - ol.render.webgl.polygonreplay.shader.DefaultVertex.getInstance(); + ol.render.webgl.linestringreplay.shader.DefaultVertex.getInstance(); var program = context.getProgram(fragmentShader, vertexShader); // get the locations var locations; if (goog.isNull(this.defaultLocations_)) { - locations = new ol.render.webgl.polygonreplay.shader.Default + locations = new ol.render.webgl.linestringreplay.shader.Default .Locations(gl, program); this.defaultLocations_ = locations; } else { @@ -1121,11 +1134,10 @@ ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context) // enable the vertex attrib arrays gl.enableVertexAttribArray(locations.a_position); gl.vertexAttribPointer(locations.a_position, 2, goog.webgl.FLOAT, - false, 24, 0); + false, 8, 0); - gl.enableVertexAttribArray(locations.a_color); - gl.vertexAttribPointer(locations.a_color, 4, goog.webgl.FLOAT, - false, 24, 8); + // enable renderer specific uniforms + gl.uniform4fv(locations.u_color, this.state_.strokeColor); return locations; }; @@ -1141,12 +1153,12 @@ ol.render.webgl.LineStringReplay.prototype.drawReplay_ = function(gl, context, s if (!goog.object.isEmpty(skippedFeaturesHash)) { // TODO: draw by blocks to skip features } else { - var numItems = this.vertices_.length / 6; + var numItems = this.indices_.length; // FIXME: not compatible with batching, hardcoding some arbitrary value if (this.state_.lineWidth) { gl.lineWidth(this.state_.lineWidth); } - gl.drawArrays(goog.webgl.LINES, 0, numItems); + gl.drawElements(goog.webgl.LINES, numItems, goog.webgl.UNSIGNED_SHORT, 0); gl.lineWidth(1); } }; diff --git a/src/ol/render/webgl/webgl.js b/src/ol/render/webgl/webgl.js index 9f34dca2eb..262a7639d1 100644 --- a/src/ol/render/webgl/webgl.js +++ b/src/ol/render/webgl/webgl.js @@ -6,6 +6,33 @@ goog.provide('ol.render.webgl'); */ ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0]; +/** + * @const + * @type {string} + */ +ol.render.webgl.defaultLineCap = 'round'; + + +/** + * @const + * @type {Array.} + */ +ol.render.webgl.defaultLineDash = []; + + +/** + * @const + * @type {string} + */ +ol.render.webgl.defaultLineJoin = 'round'; + + +/** + * @const + * @type {number} + */ +ol.render.webgl.defaultMiterLimit = 10; + /** * @const * @type {ol.Color} diff --git a/src/ol/render/webgl/webgllinestringdefault.glsl b/src/ol/render/webgl/webgllinestringdefault.glsl new file mode 100644 index 0000000000..8b81af911e --- /dev/null +++ b/src/ol/render/webgl/webgllinestringdefault.glsl @@ -0,0 +1,34 @@ +//! NAMESPACE=ol.render.webgl.linestringreplay.shader.Default +//! CLASS=ol.render.webgl.linestringreplay.shader.Default + + +//! COMMON + + +//! VERTEX +attribute vec2 a_position; + +uniform mat4 u_projectionMatrix; +uniform mat4 u_offsetScaleMatrix; +uniform mat4 u_offsetRotateMatrix; + +void main(void) { + mat4 offsetMatrix = u_offsetScaleMatrix; + vec4 offsets = offsetMatrix * vec4(0., 0., 0., 0.); + gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.) + offsets; +} + + +//! FRAGMENT + +uniform float u_opacity; +uniform vec4 u_color; + +void main(void) { + gl_FragColor = u_color; + float alpha = u_color.a * u_opacity; + if (alpha == 0.0) { + discard; + } + gl_FragColor.a = alpha; +} diff --git a/src/ol/render/webgl/webgllinestringdefaultshader.js b/src/ol/render/webgl/webgllinestringdefaultshader.js new file mode 100644 index 0000000000..d886ff52fb --- /dev/null +++ b/src/ol/render/webgl/webgllinestringdefaultshader.js @@ -0,0 +1,123 @@ +// This file is automatically generated, do not edit +goog.provide('ol.render.webgl.linestringreplay.shader.Default'); +goog.provide('ol.render.webgl.linestringreplay.shader.Default.Locations'); +goog.provide('ol.render.webgl.linestringreplay.shader.DefaultFragment'); +goog.provide('ol.render.webgl.linestringreplay.shader.DefaultVertex'); + +goog.require('ol.webgl.shader'); + + +/** + * @constructor + * @extends {ol.webgl.shader.Fragment} + * @struct + */ +ol.render.webgl.linestringreplay.shader.DefaultFragment = function() { + goog.base(this, ol.render.webgl.linestringreplay.shader.DefaultFragment.SOURCE); +}; +goog.inherits(ol.render.webgl.linestringreplay.shader.DefaultFragment, ol.webgl.shader.Fragment); +goog.addSingletonGetter(ol.render.webgl.linestringreplay.shader.DefaultFragment); + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultFragment.DEBUG_SOURCE = 'precision mediump float;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_color;\n\nvoid main(void) {\n gl_FragColor = u_color;\n float alpha = u_color.a * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n'; + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultFragment.OPTIMIZED_SOURCE = 'precision mediump float;uniform float e;uniform vec4 f;void main(void){gl_FragColor=f;float alpha=f.a*e;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}'; + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultFragment.SOURCE = goog.DEBUG ? + ol.render.webgl.linestringreplay.shader.DefaultFragment.DEBUG_SOURCE : + ol.render.webgl.linestringreplay.shader.DefaultFragment.OPTIMIZED_SOURCE; + + +/** + * @constructor + * @extends {ol.webgl.shader.Vertex} + * @struct + */ +ol.render.webgl.linestringreplay.shader.DefaultVertex = function() { + goog.base(this, ol.render.webgl.linestringreplay.shader.DefaultVertex.SOURCE); +}; +goog.inherits(ol.render.webgl.linestringreplay.shader.DefaultVertex, ol.webgl.shader.Vertex); +goog.addSingletonGetter(ol.render.webgl.linestringreplay.shader.DefaultVertex); + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultVertex.DEBUG_SOURCE = '\n\nattribute vec2 a_position;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n vec4 offsets = offsetMatrix * vec4(0., 0., 0., 0.);\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.) + offsets;\n}\n\n\n'; + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultVertex.OPTIMIZED_SOURCE = 'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){mat4 offsetMatrix=c;vec4 offsets=offsetMatrix*vec4(0.,0.,0.,0.);gl_Position=b*vec4(a,0.,1.)+offsets;}'; + + +/** + * @const + * @type {string} + */ +ol.render.webgl.linestringreplay.shader.DefaultVertex.SOURCE = goog.DEBUG ? + ol.render.webgl.linestringreplay.shader.DefaultVertex.DEBUG_SOURCE : + ol.render.webgl.linestringreplay.shader.DefaultVertex.OPTIMIZED_SOURCE; + + +/** + * @constructor + * @param {WebGLRenderingContext} gl GL. + * @param {WebGLProgram} program Program. + * @struct + */ +ol.render.webgl.linestringreplay.shader.Default.Locations = function(gl, program) { + + /** + * @type {WebGLUniformLocation} + */ + this.u_color = gl.getUniformLocation( + program, goog.DEBUG ? 'u_color' : 'f'); + + /** + * @type {WebGLUniformLocation} + */ + this.u_offsetRotateMatrix = gl.getUniformLocation( + program, goog.DEBUG ? 'u_offsetRotateMatrix' : 'd'); + + /** + * @type {WebGLUniformLocation} + */ + this.u_offsetScaleMatrix = gl.getUniformLocation( + program, goog.DEBUG ? 'u_offsetScaleMatrix' : 'c'); + + /** + * @type {WebGLUniformLocation} + */ + this.u_opacity = gl.getUniformLocation( + program, goog.DEBUG ? 'u_opacity' : 'e'); + + /** + * @type {WebGLUniformLocation} + */ + this.u_projectionMatrix = gl.getUniformLocation( + program, goog.DEBUG ? 'u_projectionMatrix' : 'b'); + + /** + * @type {number} + */ + this.a_position = gl.getAttribLocation( + program, goog.DEBUG ? 'a_position' : 'a'); +};