From b0d11391b235a825668bb753a28f4f11e37b680a Mon Sep 17 00:00:00 2001 From: GaborFarkas Date: Mon, 27 Jun 2016 11:41:35 +0200 Subject: [PATCH] Fix rounding problems Fragment shader does not know about the projection matrix, thus it has to take the pixel ratio into account. --- src/ol/render/webgl/imagereplay/index.js | 11 ++++++++--- src/ol/render/webgl/webgllinestringdefault.glsl | 17 ++++++----------- .../webgl/webgllinestringdefaultshader.js | 14 ++++++++++---- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/ol/render/webgl/imagereplay/index.js b/src/ol/render/webgl/imagereplay/index.js index b56ab23544..daacc18459 100644 --- a/src/ol/render/webgl/imagereplay/index.js +++ b/src/ol/render/webgl/imagereplay/index.js @@ -194,7 +194,7 @@ ol.render.webgl.Replay.prototype.replay = function(context, 'indicesBuffer must not be null'); context.bindBuffer(goog.webgl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer_); - var locations = this.setUpProgram_(gl, context, size); + var locations = this.setUpProgram_(gl, context, size, pixelRatio); // set the "uniform" values var projectionMatrix = ol.transform.reset(this.projectionMatrix_); @@ -657,9 +657,10 @@ ol.render.webgl.ImageReplay.prototype.createTextures_ = function(textures, image * @param {WebGLRenderingContext} gl gl. * @param {ol.webgl.Context} context Context. * @param {ol.Size} size Size. + * @param {number} pixelRatio Pixel ratio. * @return {ol.render.webgl.imagereplay.shader.Default.Locations} Locations. */ -ol.render.webgl.ImageReplay.prototype.setUpProgram_ = function(gl, context, size) { +ol.render.webgl.ImageReplay.prototype.setUpProgram_ = function(gl, context, size, pixelRatio) { // get the program var fragmentShader = ol.render.webgl.imagereplay.defaultshader.fragment; var vertexShader = ol.render.webgl.imagereplay.defaultshader.vertex; @@ -1335,9 +1336,10 @@ ol.render.webgl.LineStringReplay.prototype.getDeleteResourcesFunction = function * @param {WebGLRenderingContext} gl gl. * @param {ol.webgl.Context} context Context. * @param {ol.Size} size Size. + * @param {number} pixelRatio Pixel ratio. * @return {ol.render.webgl.linestringreplay.shader.Default.Locations} Locations. */ -ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context, size) { +ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context, size, pixelRatio) { // get the program var fragmentShader, vertexShader; fragmentShader = @@ -1384,6 +1386,7 @@ ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context, gl.uniform1f(locations.u_miterLimit, this.state_.miterLimit); } gl.uniform2fv(locations.u_size, size); + gl.uniform1f(locations.u_pixelRatio, pixelRatio); return locations; }; @@ -1398,7 +1401,9 @@ ol.render.webgl.LineStringReplay.prototype.setUpProgram_ = function(gl, context, */ ol.render.webgl.LineStringReplay.prototype.drawReplay_ = function(gl, context, skippedFeaturesHash, hitDetection) { //Save GL parameters. + /** @type {number} */ var tmpDepthFunc = gl.getParameter(gl.DEPTH_FUNC); + /** @type {boolean} */ var tmpDepthMask = gl.getParameter(gl.DEPTH_WRITEMASK); gl.enable(gl.DEPTH_TEST); diff --git a/src/ol/render/webgl/webgllinestringdefault.glsl b/src/ol/render/webgl/webgllinestringdefault.glsl index fbf287894b..c034a9662e 100644 --- a/src/ol/render/webgl/webgllinestringdefault.glsl +++ b/src/ol/render/webgl/webgllinestringdefault.glsl @@ -4,7 +4,7 @@ //! COMMON varying float v_round; -varying vec4 v_roundVertex; +varying vec2 v_roundVertex; varying float v_halfWidth; @@ -26,20 +26,15 @@ void main(void) { v_round = 0.0; float direction = a_direction / abs(a_direction); vec4 projPos = u_projectionMatrix * vec4(a_position, 0., 1.); + v_roundVertex = projPos.xy; if (mod(a_direction, 3.0) == 0.0 || mod(a_direction, 17.0) == 0.0) { vec2 dirVect = a_nextPos - a_position; vec2 normal = normalize(vec2(-dirVect.y, dirVect.x)); offset = v_halfWidth * normal * direction; - if (mod(a_direction, 2.0) == 0.0) { - v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.); - } } else if (mod(a_direction, 5.0) == 0.0 || mod(a_direction, 13.0) == 0.0) { vec2 dirVect = a_lastPos - a_position; vec2 normal = normalize(vec2(dirVect.y, -dirVect.x)); offset = v_halfWidth * normal * direction; - if (mod(a_direction, 2.0) == 0.0) { - v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.); - } } else if (mod(a_direction, 19.0) == 0.0 || mod(a_direction, 23.0) == 0.0) { vec2 dirVect = a_nextPos - a_position; vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x)); @@ -50,7 +45,6 @@ void main(void) { offset = normal * direction * miterLength; if (mod(a_direction, 2.0) == 0.0) { v_round = 1.0; - v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.); } else if (miterLength > u_miterLimit) { offset = tmpNormal * direction * v_halfWidth; } @@ -106,7 +100,6 @@ void main(void) { offset = normal * length; if (mod(a_direction, 2.0) == 0.0) { v_round = 1.0; - v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.); } } if (!degenerate) { @@ -121,11 +114,13 @@ void main(void) { uniform float u_opacity; uniform vec4 u_color; uniform vec2 u_size; +uniform float u_pixelRatio; void main(void) { if (v_round > 0.0) { - vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x, (v_roundVertex.y + 1.0) / 2.0 * u_size.y); - if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth) { + vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x * u_pixelRatio, + (v_roundVertex.y + 1.0) / 2.0 * u_size.y * u_pixelRatio); + if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth * u_pixelRatio) { discard; } } diff --git a/src/ol/render/webgl/webgllinestringdefaultshader.js b/src/ol/render/webgl/webgllinestringdefaultshader.js index e69ebcb62b..d28e2f4967 100644 --- a/src/ol/render/webgl/webgllinestringdefaultshader.js +++ b/src/ol/render/webgl/webgllinestringdefaultshader.js @@ -23,14 +23,14 @@ goog.addSingletonGetter(ol.render.webgl.linestringreplay.shader.DefaultFragment) * @const * @type {string} */ -ol.render.webgl.linestringreplay.shader.DefaultFragment.DEBUG_SOURCE = 'precision mediump float;\nvarying float v_round;\nvarying vec4 v_roundVertex;\nvarying float v_halfWidth;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_color;\nuniform vec2 u_size;\n\nvoid main(void) {\n if (v_round > 0.0) {\n vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x, (v_roundVertex.y + 1.0) / 2.0 * u_size.y);\n if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth) {\n discard;\n }\n }\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'; +ol.render.webgl.linestringreplay.shader.DefaultFragment.DEBUG_SOURCE = 'precision mediump float;\nvarying float v_round;\nvarying vec2 v_roundVertex;\nvarying float v_halfWidth;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_color;\nuniform vec2 u_size;\nuniform float u_pixelRatio;\n\nvoid main(void) {\n if (v_round > 0.0) {\n vec2 windowCoords = vec2((v_roundVertex.x + 1.0) / 2.0 * u_size.x * u_pixelRatio,\n (v_roundVertex.y + 1.0) / 2.0 * u_size.y * u_pixelRatio);\n if (length(windowCoords - gl_FragCoord.xy) > v_halfWidth * u_pixelRatio) {\n discard;\n }\n }\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;varying float a;varying vec4 b;varying float c;uniform float l;uniform vec4 m;uniform vec2 n;void main(void){if(a>0.0){vec2 windowCoords=vec2((b.x+1.0)/2.0*n.x,(b.y+1.0)/2.0*n.y);if(length(windowCoords-gl_FragCoord.xy)>c){discard;}} gl_FragColor=m;float alpha=m.a*l;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}'; +ol.render.webgl.linestringreplay.shader.DefaultFragment.OPTIMIZED_SOURCE = 'precision mediump float;varying float a;varying vec2 b;varying float c;uniform float l;uniform vec4 m;uniform vec2 n;uniform float o;void main(void){if(a>0.0){vec2 windowCoords=vec2((b.x+1.0)/2.0*n.x*o,(b.y+1.0)/2.0*n.y*o);if(length(windowCoords-gl_FragCoord.xy)>c*o){discard;}} gl_FragColor=m;float alpha=m.a*l;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}'; /** @@ -58,14 +58,14 @@ goog.addSingletonGetter(ol.render.webgl.linestringreplay.shader.DefaultVertex); * @const * @type {string} */ -ol.render.webgl.linestringreplay.shader.DefaultVertex.DEBUG_SOURCE = 'varying float v_round;\nvarying vec4 v_roundVertex;\nvarying float v_halfWidth;\n\n\nattribute vec2 a_lastPos;\nattribute vec2 a_position;\nattribute vec2 a_nextPos;\nattribute float a_direction;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform float u_lineWidth;\nuniform float u_miterLimit;\n\nvoid main(void) {\n bool degenerate = false;\n v_halfWidth = u_lineWidth / 2.0;\n vec2 offset;\n v_round = 0.0;\n float direction = a_direction / abs(a_direction);\n vec4 projPos = u_projectionMatrix * vec4(a_position, 0., 1.);\n if (mod(a_direction, 3.0) == 0.0 || mod(a_direction, 17.0) == 0.0) {\n vec2 dirVect = a_nextPos - a_position;\n vec2 normal = normalize(vec2(-dirVect.y, dirVect.x));\n offset = v_halfWidth * normal * direction;\n if (mod(a_direction, 2.0) == 0.0) {\n v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.);\n }\n } else if (mod(a_direction, 5.0) == 0.0 || mod(a_direction, 13.0) == 0.0) {\n vec2 dirVect = a_lastPos - a_position;\n vec2 normal = normalize(vec2(dirVect.y, -dirVect.x));\n offset = v_halfWidth * normal * direction;\n if (mod(a_direction, 2.0) == 0.0) {\n v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.);\n }\n } else if (mod(a_direction, 19.0) == 0.0 || mod(a_direction, 23.0) == 0.0) {\n vec2 dirVect = a_nextPos - a_position;\n vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\n vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\n vec2 normal = vec2(-tangent.y, tangent.x);\n float miterLength = abs(v_halfWidth / dot(normal, tmpNormal));\n if (mod(a_direction, 23.0) == 0.0) {\n offset = normal * direction * miterLength;\n if (mod(a_direction, 2.0) == 0.0) {\n v_round = 1.0;\n v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.);\n } else if (miterLength > u_miterLimit) {\n offset = tmpNormal * direction * v_halfWidth;\n }\n } else {\n dirVect = a_lastPos - a_position;\n vec2 longOffset, shortOffset, longVertex;\n vec4 shortProjVertex;\n if (length(a_nextPos - a_position) > length(a_lastPos - a_position)) {\n longOffset = tmpNormal * direction * v_halfWidth;\n shortOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * v_halfWidth;\n longVertex = a_nextPos;\n shortProjVertex = u_projectionMatrix * vec4(a_lastPos, 0., 1.);\n } else {\n shortOffset = tmpNormal * direction * v_halfWidth;\n longOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * v_halfWidth;\n longVertex = a_lastPos;\n shortProjVertex = u_projectionMatrix * vec4(a_nextPos, 0., 1.);\n }\n //Intersection algorithm based on theory by Paul Bourke (http://paulbourke.net/geometry/pointlineplane/).\n vec4 p1 = u_projectionMatrix * vec4(longVertex, 0., 1.) + u_offsetScaleMatrix * vec4(longOffset, 0., 0.);\n vec4 p2 = projPos + u_offsetScaleMatrix * vec4(longOffset, 0., 0.);\n vec4 p3 = shortProjVertex + u_offsetScaleMatrix * vec4(-shortOffset, 0., 0.);\n vec4 p4 = shortProjVertex + u_offsetScaleMatrix * vec4(shortOffset, 0., 0.);\n float denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);\n float epsilon = 0.000000000001;\n float firstU = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom;\n float secondU = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom;\n if (firstU > epsilon && firstU < 1.0 - epsilon && secondU > epsilon && secondU < 1.0 - epsilon) {\n gl_Position = shortProjVertex;\n gl_Position.x = p1.x + firstU * (p2.x - p1.x);\n gl_Position.y = p1.y + firstU * (p2.y - p1.y);\n degenerate = true;\n } else {\n offset = normal * direction * miterLength;\n }\n }\n } else if (mod(a_direction, 7.0) == 0.0 || mod(a_direction, 11.0) == 0.0) {\n vec2 normal;\n if (mod(a_direction, 7.0) == 0.0) {\n vec2 dirVect = a_position - a_nextPos;\n vec2 firstNormal = normalize(dirVect);\n vec2 secondNormal = vec2(firstNormal.y * direction, -firstNormal.x * direction);\n vec2 hypotenuse = normalize(firstNormal - secondNormal);\n normal = vec2(hypotenuse.y * direction, -hypotenuse.x * direction);\n } else {\n vec2 dirVect = a_position - a_lastPos;\n vec2 firstNormal = normalize(dirVect);\n vec2 secondNormal = vec2(-firstNormal.y * direction, firstNormal.x * direction);\n vec2 hypotenuse = normalize(firstNormal - secondNormal);\n normal = vec2(-hypotenuse.y * direction, hypotenuse.x * direction);\n }\n float length = sqrt(v_halfWidth * v_halfWidth * 2.0);\n offset = normal * length;\n if (mod(a_direction, 2.0) == 0.0) {\n v_round = 1.0;\n v_roundVertex = projPos + u_offsetScaleMatrix * vec4(0., 0., 0., 0.);\n }\n }\n if (!degenerate) {\n vec4 offsets = u_offsetScaleMatrix * vec4(offset, 0., 0.);\n gl_Position = projPos + offsets;\n }\n}\n\n\n'; +ol.render.webgl.linestringreplay.shader.DefaultVertex.DEBUG_SOURCE = 'varying float v_round;\nvarying vec2 v_roundVertex;\nvarying float v_halfWidth;\n\n\nattribute vec2 a_lastPos;\nattribute vec2 a_position;\nattribute vec2 a_nextPos;\nattribute float a_direction;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform float u_lineWidth;\nuniform float u_miterLimit;\n\nvoid main(void) {\n bool degenerate = false;\n v_halfWidth = u_lineWidth / 2.0;\n vec2 offset;\n v_round = 0.0;\n float direction = a_direction / abs(a_direction);\n vec4 projPos = u_projectionMatrix * vec4(a_position, 0., 1.);\n v_roundVertex = projPos.xy;\n if (mod(a_direction, 3.0) == 0.0 || mod(a_direction, 17.0) == 0.0) {\n vec2 dirVect = a_nextPos - a_position;\n vec2 normal = normalize(vec2(-dirVect.y, dirVect.x));\n offset = v_halfWidth * normal * direction;\n } else if (mod(a_direction, 5.0) == 0.0 || mod(a_direction, 13.0) == 0.0) {\n vec2 dirVect = a_lastPos - a_position;\n vec2 normal = normalize(vec2(dirVect.y, -dirVect.x));\n offset = v_halfWidth * normal * direction;\n } else if (mod(a_direction, 19.0) == 0.0 || mod(a_direction, 23.0) == 0.0) {\n vec2 dirVect = a_nextPos - a_position;\n vec2 tmpNormal = normalize(vec2(-dirVect.y, dirVect.x));\n vec2 tangent = normalize(normalize(a_nextPos - a_position) + normalize(a_position - a_lastPos));\n vec2 normal = vec2(-tangent.y, tangent.x);\n float miterLength = abs(v_halfWidth / dot(normal, tmpNormal));\n if (mod(a_direction, 23.0) == 0.0) {\n offset = normal * direction * miterLength;\n if (mod(a_direction, 2.0) == 0.0) {\n v_round = 1.0;\n } else if (miterLength > u_miterLimit) {\n offset = tmpNormal * direction * v_halfWidth;\n }\n } else {\n dirVect = a_lastPos - a_position;\n vec2 longOffset, shortOffset, longVertex;\n vec4 shortProjVertex;\n if (length(a_nextPos - a_position) > length(a_lastPos - a_position)) {\n longOffset = tmpNormal * direction * v_halfWidth;\n shortOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * v_halfWidth;\n longVertex = a_nextPos;\n shortProjVertex = u_projectionMatrix * vec4(a_lastPos, 0., 1.);\n } else {\n shortOffset = tmpNormal * direction * v_halfWidth;\n longOffset = normalize(vec2(dirVect.y, -dirVect.x)) * direction * v_halfWidth;\n longVertex = a_lastPos;\n shortProjVertex = u_projectionMatrix * vec4(a_nextPos, 0., 1.);\n }\n //Intersection algorithm based on theory by Paul Bourke (http://paulbourke.net/geometry/pointlineplane/).\n vec4 p1 = u_projectionMatrix * vec4(longVertex, 0., 1.) + u_offsetScaleMatrix * vec4(longOffset, 0., 0.);\n vec4 p2 = projPos + u_offsetScaleMatrix * vec4(longOffset, 0., 0.);\n vec4 p3 = shortProjVertex + u_offsetScaleMatrix * vec4(-shortOffset, 0., 0.);\n vec4 p4 = shortProjVertex + u_offsetScaleMatrix * vec4(shortOffset, 0., 0.);\n float denom = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y);\n float epsilon = 0.000000000001;\n float firstU = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denom;\n float secondU = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denom;\n if (firstU > epsilon && firstU < 1.0 - epsilon && secondU > epsilon && secondU < 1.0 - epsilon) {\n gl_Position = shortProjVertex;\n gl_Position.x = p1.x + firstU * (p2.x - p1.x);\n gl_Position.y = p1.y + firstU * (p2.y - p1.y);\n degenerate = true;\n } else {\n offset = normal * direction * miterLength;\n }\n }\n } else if (mod(a_direction, 7.0) == 0.0 || mod(a_direction, 11.0) == 0.0) {\n vec2 normal;\n if (mod(a_direction, 7.0) == 0.0) {\n vec2 dirVect = a_position - a_nextPos;\n vec2 firstNormal = normalize(dirVect);\n vec2 secondNormal = vec2(firstNormal.y * direction, -firstNormal.x * direction);\n vec2 hypotenuse = normalize(firstNormal - secondNormal);\n normal = vec2(hypotenuse.y * direction, -hypotenuse.x * direction);\n } else {\n vec2 dirVect = a_position - a_lastPos;\n vec2 firstNormal = normalize(dirVect);\n vec2 secondNormal = vec2(-firstNormal.y * direction, firstNormal.x * direction);\n vec2 hypotenuse = normalize(firstNormal - secondNormal);\n normal = vec2(-hypotenuse.y * direction, hypotenuse.x * direction);\n }\n float length = sqrt(v_halfWidth * v_halfWidth * 2.0);\n offset = normal * length;\n if (mod(a_direction, 2.0) == 0.0) {\n v_round = 1.0;\n }\n }\n if (!degenerate) {\n vec4 offsets = u_offsetScaleMatrix * vec4(offset, 0., 0.);\n gl_Position = projPos + offsets;\n }\n}\n\n\n'; /** * @const * @type {string} */ -ol.render.webgl.linestringreplay.shader.DefaultVertex.OPTIMIZED_SOURCE = 'varying float a;varying vec4 b;varying float c;attribute vec2 d;attribute vec2 e;attribute vec2 f;attribute float g;uniform mat4 h;uniform mat4 i;uniform float j;uniform float k;void main(void){bool degenerate=false;c=j/2.0;vec2 offset;a=0.0;float direction=g/abs(g);vec4 projPos=h*vec4(e,0.,1.);if(mod(g,3.0)==0.0||mod(g,17.0)==0.0){vec2 dirVect=f-e;vec2 normal=normalize(vec2(-dirVect.y,dirVect.x));offset=c*normal*direction;if(mod(g,2.0)==0.0){b=projPos+i*vec4(0.,0.,0.,0.);}} else if(mod(g,5.0)==0.0||mod(g,13.0)==0.0){vec2 dirVect=d-e;vec2 normal=normalize(vec2(dirVect.y,-dirVect.x));offset=c*normal*direction;if(mod(g,2.0)==0.0){b=projPos+i*vec4(0.,0.,0.,0.);}} else if(mod(g,19.0)==0.0||mod(g,23.0)==0.0){vec2 dirVect=f-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);float miterLength=abs(c/dot(normal,tmpNormal));if(mod(g,23.0)==0.0){offset=normal*direction*miterLength;if(mod(g,2.0)==0.0){a=1.0;b=projPos+i*vec4(0.,0.,0.,0.);}else if(miterLength>k){offset=tmpNormal*direction*c;}} else{dirVect=d-e;vec2 longOffset,shortOffset,longVertex;vec4 shortProjVertex;if(length(f-e)>length(d-e)){longOffset=tmpNormal*direction*c;shortOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*c;longVertex=f;shortProjVertex=h*vec4(d,0.,1.);}else{shortOffset=tmpNormal*direction*c;longOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*c;longVertex=d;shortProjVertex=h*vec4(f,0.,1.);}vec4 p1=h*vec4(longVertex,0.,1.)+i*vec4(longOffset,0.,0.);vec4 p2=projPos+i*vec4(longOffset,0.,0.);vec4 p3=shortProjVertex+i*vec4(-shortOffset,0.,0.);vec4 p4=shortProjVertex+i*vec4(shortOffset,0.,0.);float denom=(p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);float epsilon=0.000000000001;float firstU=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;float secondU=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;if(firstU>epsilon&&firstU<1.0-epsilon&&secondU>epsilon&&secondU<1.0-epsilon){gl_Position=shortProjVertex;gl_Position.x=p1.x+firstU*(p2.x-p1.x);gl_Position.y=p1.y+firstU*(p2.y-p1.y);degenerate=true;}else{offset=normal*direction*miterLength;}}}else if(mod(g,7.0)==0.0||mod(g,11.0)==0.0){vec2 normal;if(mod(g,7.0)==0.0){vec2 dirVect=e-f;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(firstNormal.y*direction,-firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);normal=vec2(hypotenuse.y*direction,-hypotenuse.x*direction);}else{vec2 dirVect=e-d;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(-firstNormal.y*direction,firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);normal=vec2(-hypotenuse.y*direction,hypotenuse.x*direction);}float length=sqrt(c*c*2.0);offset=normal*length;if(mod(g,2.0)==0.0){a=1.0;b=projPos+i*vec4(0.,0.,0.,0.);}} if(!degenerate){vec4 offsets=i*vec4(offset,0.,0.);gl_Position=projPos+offsets;}}'; +ol.render.webgl.linestringreplay.shader.DefaultVertex.OPTIMIZED_SOURCE = 'varying float a;varying vec2 b;varying float c;attribute vec2 d;attribute vec2 e;attribute vec2 f;attribute float g;uniform mat4 h;uniform mat4 i;uniform float j;uniform float k;void main(void){bool degenerate=false;c=j/2.0;vec2 offset;a=0.0;float direction=g/abs(g);vec4 projPos=h*vec4(e,0.,1.);b=projPos.xy;if(mod(g,3.0)==0.0||mod(g,17.0)==0.0){vec2 dirVect=f-e;vec2 normal=normalize(vec2(-dirVect.y,dirVect.x));offset=c*normal*direction;}else if(mod(g,5.0)==0.0||mod(g,13.0)==0.0){vec2 dirVect=d-e;vec2 normal=normalize(vec2(dirVect.y,-dirVect.x));offset=c*normal*direction;}else if(mod(g,19.0)==0.0||mod(g,23.0)==0.0){vec2 dirVect=f-e;vec2 tmpNormal=normalize(vec2(-dirVect.y,dirVect.x));vec2 tangent=normalize(normalize(f-e)+normalize(e-d));vec2 normal=vec2(-tangent.y,tangent.x);float miterLength=abs(c/dot(normal,tmpNormal));if(mod(g,23.0)==0.0){offset=normal*direction*miterLength;if(mod(g,2.0)==0.0){a=1.0;}else if(miterLength>k){offset=tmpNormal*direction*c;}} else{dirVect=d-e;vec2 longOffset,shortOffset,longVertex;vec4 shortProjVertex;if(length(f-e)>length(d-e)){longOffset=tmpNormal*direction*c;shortOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*c;longVertex=f;shortProjVertex=h*vec4(d,0.,1.);}else{shortOffset=tmpNormal*direction*c;longOffset=normalize(vec2(dirVect.y,-dirVect.x))*direction*c;longVertex=d;shortProjVertex=h*vec4(f,0.,1.);}vec4 p1=h*vec4(longVertex,0.,1.)+i*vec4(longOffset,0.,0.);vec4 p2=projPos+i*vec4(longOffset,0.,0.);vec4 p3=shortProjVertex+i*vec4(-shortOffset,0.,0.);vec4 p4=shortProjVertex+i*vec4(shortOffset,0.,0.);float denom=(p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y);float epsilon=0.000000000001;float firstU=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/denom;float secondU=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/denom;if(firstU>epsilon&&firstU<1.0-epsilon&&secondU>epsilon&&secondU<1.0-epsilon){gl_Position=shortProjVertex;gl_Position.x=p1.x+firstU*(p2.x-p1.x);gl_Position.y=p1.y+firstU*(p2.y-p1.y);degenerate=true;}else{offset=normal*direction*miterLength;}}}else if(mod(g,7.0)==0.0||mod(g,11.0)==0.0){vec2 normal;if(mod(g,7.0)==0.0){vec2 dirVect=e-f;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(firstNormal.y*direction,-firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);normal=vec2(hypotenuse.y*direction,-hypotenuse.x*direction);}else{vec2 dirVect=e-d;vec2 firstNormal=normalize(dirVect);vec2 secondNormal=vec2(-firstNormal.y*direction,firstNormal.x*direction);vec2 hypotenuse=normalize(firstNormal-secondNormal);normal=vec2(-hypotenuse.y*direction,hypotenuse.x*direction);}float length=sqrt(c*c*2.0);offset=normal*length;if(mod(g,2.0)==0.0){a=1.0;}} if(!degenerate){vec4 offsets=i*vec4(offset,0.,0.);gl_Position=projPos+offsets;}}'; /** @@ -115,6 +115,12 @@ ol.render.webgl.linestringreplay.shader.Default.Locations = function(gl, program this.u_opacity = gl.getUniformLocation( program, goog.DEBUG ? 'u_opacity' : 'l'); + /** + * @type {WebGLUniformLocation} + */ + this.u_pixelRatio = gl.getUniformLocation( + program, goog.DEBUG ? 'u_pixelRatio' : 'o'); + /** * @type {WebGLUniformLocation} */