From 28e51740c62c1e9ddfe85575c3b2469e1b0574f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 3 Nov 2014 17:44:18 +0100 Subject: [PATCH] Address precision/jitter problems Address precision/jitter problems by using coordinates relative to the Replay max extent rather that the world. --- src/ol/render/webgl/webglreplay.js | 67 +++++++++++++++---- .../webgl/webglvectorlayerrenderer.js | 16 ++--- 2 files changed, 57 insertions(+), 26 deletions(-) diff --git a/src/ol/render/webgl/webglreplay.js b/src/ol/render/webgl/webglreplay.js index c5f8d144f0..f3e5f2973a 100644 --- a/src/ol/render/webgl/webglreplay.js +++ b/src/ol/render/webgl/webglreplay.js @@ -3,9 +3,11 @@ goog.provide('ol.render.webgl.ReplayGroup'); goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.object'); +goog.require('goog.vec.Mat4'); goog.require('ol.extent'); goog.require('ol.render.IReplayGroup'); goog.require('ol.render.webgl.imagereplay.shader'); +goog.require('ol.vec.Mat4'); @@ -13,10 +15,11 @@ goog.require('ol.render.webgl.imagereplay.shader'); * @constructor * @implements {ol.render.IVectorContext} * @param {number} tolerance Tolerance. + * @param {ol.Extent} maxExtent Max extent. * @protected * @struct */ -ol.render.webgl.ImageReplay = function(tolerance) { +ol.render.webgl.ImageReplay = function(tolerance, maxExtent) { /** * @type {number|undefined} @@ -30,6 +33,12 @@ ol.render.webgl.ImageReplay = function(tolerance) { */ this.anchorY_ = undefined; + /** + * @private + * @type {ol.Extent} + */ + this.origin_ = ol.extent.getBottomLeft(maxExtent); + /** * @type {ol.Extent} * @private @@ -109,6 +118,12 @@ ol.render.webgl.ImageReplay = function(tolerance) { */ this.originY_ = undefined; + /** + * @type {!goog.vec.Mat4.Number} + * @private + */ + this.projectionMatrix_ = goog.vec.Mat4.createNumberIdentity(); + /** * @type {Array.} * @private @@ -205,8 +220,8 @@ ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = var numVertices = this.vertices_.length; var i, x, y, n; for (i = offset; i < end; i += stride) { - x = flatCoordinates[i]; - y = flatCoordinates[i + 1]; + x = flatCoordinates[i] - this.origin_[0]; + y = flatCoordinates[i + 1] - this.origin_[1]; n = numVertices / 7; @@ -401,15 +416,19 @@ ol.render.webgl.ImageReplay.prototype.getExtent = function() { /** * @param {ol.webgl.Context} context Context. + * @param {ol.Coordinate} center Center. + * @param {number} resolution Resolution. + * @param {number} rotation Rotation. + * @param {ol.Size} size Size. + * @param {ol.Extent} extent Extent. * @param {number} pixelRatio Pixel ratio. - * @param {Array.} size Size. - * @param {goog.vec.Mat4.Number} transform Transform. * @param {Object} skippedFeaturesHash Ids of features to skip. * @return {T|undefined} Callback result. * @template T */ ol.render.webgl.ImageReplay.prototype.replay = function(context, - pixelRatio, size, transform, skippedFeaturesHash) { + center, resolution, rotation, size, extent, pixelRatio, + skippedFeaturesHash) { var gl = context.getGL(); var program = context.getProgram( @@ -422,6 +441,14 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context, gl, program); } + var projectionMatrix = this.projectionMatrix_; + ol.vec.Mat4.makeTransform2D(projectionMatrix, + 0.0, 0.0, + 2 / (resolution * size[0]), + 2 / (resolution * size[1]), + -rotation, + -(center[0] - this.origin_[0]), -(center[1] - this.origin_[1])); + var locations = this.locations_; gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.verticesBuffer_); @@ -442,7 +469,7 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context, gl.vertexAttribPointer(locations.a_opacity, 1, goog.webgl.FLOAT, false, 28, 24); - gl.uniformMatrix4fv(locations.u_projectionMatrix, false, transform); + gl.uniformMatrix4fv(locations.u_projectionMatrix, false, projectionMatrix); gl.uniformMatrix2fv(locations.u_sizeMatrix, false, new Float32Array([1 / size[0], 0.0, 0.0, 1 / size[1]])); @@ -519,9 +546,16 @@ ol.render.webgl.ImageReplay.prototype.setTextStyle = goog.abstractMethod; * @constructor * @implements {ol.render.IReplayGroup} * @param {number} tolerance Tolerance. + * @param {ol.Extent} maxExtent Max extent. * @struct */ -ol.render.webgl.ReplayGroup = function(tolerance) { +ol.render.webgl.ReplayGroup = function(tolerance, maxExtent) { + + /** + * @type {ol.Extent} + * @private + */ + this.maxExtent_ = maxExtent; /** * @type {number} @@ -572,7 +606,7 @@ ol.render.webgl.ReplayGroup.prototype.getReplay = if (!goog.isDef(replay)) { var constructor = ol.render.webgl.BATCH_CONSTRUCTORS_[replayType]; goog.asserts.assert(goog.isDef(constructor)); - replay = new constructor(this.tolerance_); + replay = new constructor(this.tolerance_, this.maxExtent_); this.replays_[replayType] = replay; } return replay; @@ -589,23 +623,27 @@ ol.render.webgl.ReplayGroup.prototype.isEmpty = function() { /** * @param {ol.webgl.Context} context Context. + * @param {ol.Coordinate} center Center. + * @param {number} resolution Resolution. + * @param {number} rotation Rotation. + * @param {ol.Size} size Size. * @param {ol.Extent} extent Extent. * @param {number} pixelRatio Pixel ratio. - * @param {Array.} size Size. - * @param {goog.vec.Mat4.Number} transform Transform. * @param {Object} skippedFeaturesHash Ids of features to skip. * @return {T|undefined} Callback result. * @template T */ ol.render.webgl.ReplayGroup.prototype.replay = function(context, - extent, pixelRatio, size, transform, skippedFeaturesHash) { + center, resolution, rotation, size, extent, pixelRatio, + skippedFeaturesHash) { var i, ii, replay, result; for (i = 0, ii = ol.render.REPLAY_ORDER.length; i < ii; ++i) { replay = this.replays_[ol.render.REPLAY_ORDER[i]]; if (goog.isDef(replay) && ol.extent.intersects(extent, replay.getExtent())) { result = replay.replay(context, - pixelRatio, size, transform, skippedFeaturesHash); + center, resolution, rotation, size, extent, pixelRatio, + skippedFeaturesHash); if (result) { return result; } @@ -619,7 +657,8 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context, * @const * @private * @type {Object.} + * function(new: ol.render.webgl.ImageReplay, number, + * ol.Extent)>} */ ol.render.webgl.BATCH_CONSTRUCTORS_ = { 'Image': ol.render.webgl.ImageReplay diff --git a/src/ol/renderer/webgl/webglvectorlayerrenderer.js b/src/ol/renderer/webgl/webglvectorlayerrenderer.js index 78355ec7ac..c9a869dd35 100644 --- a/src/ol/renderer/webgl/webglvectorlayerrenderer.js +++ b/src/ol/renderer/webgl/webglvectorlayerrenderer.js @@ -9,7 +9,6 @@ goog.require('ol.layer.Vector'); goog.require('ol.render.webgl.ReplayGroup'); goog.require('ol.renderer.vector'); goog.require('ol.renderer.webgl.Layer'); -goog.require('ol.vec.Mat4'); @@ -68,20 +67,12 @@ goog.inherits(ol.renderer.webgl.VectorLayer, ol.renderer.webgl.Layer); */ ol.renderer.webgl.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) { - var viewState = frameState.viewState; - ol.vec.Mat4.makeTransform2D(this.projectionMatrix, - 0.0, 0.0, - 2 / (viewState.resolution * frameState.size[0]), - 2 / (viewState.resolution * frameState.size[1]), - -viewState.rotation, - -viewState.center[0], -viewState.center[1]); - var replayGroup = this.replayGroup_; if (!goog.isNull(replayGroup) && !replayGroup.isEmpty()) { replayGroup.replay(context, - frameState.extent, frameState.pixelRatio, frameState.size, - this.projectionMatrix, + viewState.center, viewState.resolution, viewState.rotation, + frameState.size, frameState.extent, frameState.pixelRatio, frameState.skippedFeatureUids); } @@ -160,7 +151,8 @@ ol.renderer.webgl.VectorLayer.prototype.prepareFrame = this.dirty_ = false; var replayGroup = new ol.render.webgl.ReplayGroup( - ol.renderer.vector.getTolerance(resolution, pixelRatio)); + ol.renderer.vector.getTolerance(resolution, pixelRatio), + extent); vectorSource.loadFeatures(extent, resolution, projection); var renderFeature = /**