Merge pull request #17 from elemoine/webgl-point-jitter

[webgl-point] Address precision/jitter problems
This commit is contained in:
Éric Lemoine
2014-11-03 18:10:19 +01:00
2 changed files with 57 additions and 26 deletions
+53 -14
View File
@@ -3,9 +3,11 @@ goog.provide('ol.render.webgl.ReplayGroup');
goog.require('goog.array'); goog.require('goog.array');
goog.require('goog.asserts'); goog.require('goog.asserts');
goog.require('goog.object'); goog.require('goog.object');
goog.require('goog.vec.Mat4');
goog.require('ol.extent'); goog.require('ol.extent');
goog.require('ol.render.IReplayGroup'); goog.require('ol.render.IReplayGroup');
goog.require('ol.render.webgl.imagereplay.shader'); goog.require('ol.render.webgl.imagereplay.shader');
goog.require('ol.vec.Mat4');
@@ -13,10 +15,11 @@ goog.require('ol.render.webgl.imagereplay.shader');
* @constructor * @constructor
* @implements {ol.render.IVectorContext} * @implements {ol.render.IVectorContext}
* @param {number} tolerance Tolerance. * @param {number} tolerance Tolerance.
* @param {ol.Extent} maxExtent Max extent.
* @protected * @protected
* @struct * @struct
*/ */
ol.render.webgl.ImageReplay = function(tolerance) { ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
/** /**
* @type {number|undefined} * @type {number|undefined}
@@ -30,6 +33,12 @@ ol.render.webgl.ImageReplay = function(tolerance) {
*/ */
this.anchorY_ = undefined; this.anchorY_ = undefined;
/**
* @private
* @type {ol.Extent}
*/
this.origin_ = ol.extent.getBottomLeft(maxExtent);
/** /**
* @type {ol.Extent} * @type {ol.Extent}
* @private * @private
@@ -109,6 +118,12 @@ ol.render.webgl.ImageReplay = function(tolerance) {
*/ */
this.originY_ = undefined; this.originY_ = undefined;
/**
* @type {!goog.vec.Mat4.Number}
* @private
*/
this.projectionMatrix_ = goog.vec.Mat4.createNumberIdentity();
/** /**
* @type {Array.<WebGLTexture>} * @type {Array.<WebGLTexture>}
* @private * @private
@@ -205,8 +220,8 @@ ol.render.webgl.ImageReplay.prototype.drawCoordinates_ =
var numVertices = this.vertices_.length; var numVertices = this.vertices_.length;
var i, x, y, n; var i, x, y, n;
for (i = offset; i < end; i += stride) { for (i = offset; i < end; i += stride) {
x = flatCoordinates[i]; x = flatCoordinates[i] - this.origin_[0];
y = flatCoordinates[i + 1]; y = flatCoordinates[i + 1] - this.origin_[1];
n = numVertices / 7; n = numVertices / 7;
@@ -401,15 +416,19 @@ ol.render.webgl.ImageReplay.prototype.getExtent = function() {
/** /**
* @param {ol.webgl.Context} context Context. * @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 {number} pixelRatio Pixel ratio.
* @param {Array.<number>} size Size.
* @param {goog.vec.Mat4.Number} transform Transform.
* @param {Object} skippedFeaturesHash Ids of features to skip. * @param {Object} skippedFeaturesHash Ids of features to skip.
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.webgl.ImageReplay.prototype.replay = function(context, ol.render.webgl.ImageReplay.prototype.replay = function(context,
pixelRatio, size, transform, skippedFeaturesHash) { center, resolution, rotation, size, extent, pixelRatio,
skippedFeaturesHash) {
var gl = context.getGL(); var gl = context.getGL();
var program = context.getProgram( var program = context.getProgram(
@@ -422,6 +441,14 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context,
gl, program); 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_; var locations = this.locations_;
gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.verticesBuffer_); 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, gl.vertexAttribPointer(locations.a_opacity, 1, goog.webgl.FLOAT,
false, 28, 24); false, 28, 24);
gl.uniformMatrix4fv(locations.u_projectionMatrix, false, transform); gl.uniformMatrix4fv(locations.u_projectionMatrix, false, projectionMatrix);
gl.uniformMatrix2fv(locations.u_sizeMatrix, false, gl.uniformMatrix2fv(locations.u_sizeMatrix, false,
new Float32Array([1 / size[0], 0.0, 0.0, 1 / size[1]])); 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 * @constructor
* @implements {ol.render.IReplayGroup} * @implements {ol.render.IReplayGroup}
* @param {number} tolerance Tolerance. * @param {number} tolerance Tolerance.
* @param {ol.Extent} maxExtent Max extent.
* @struct * @struct
*/ */
ol.render.webgl.ReplayGroup = function(tolerance) { ol.render.webgl.ReplayGroup = function(tolerance, maxExtent) {
/**
* @type {ol.Extent}
* @private
*/
this.maxExtent_ = maxExtent;
/** /**
* @type {number} * @type {number}
@@ -572,7 +606,7 @@ ol.render.webgl.ReplayGroup.prototype.getReplay =
if (!goog.isDef(replay)) { if (!goog.isDef(replay)) {
var constructor = ol.render.webgl.BATCH_CONSTRUCTORS_[replayType]; var constructor = ol.render.webgl.BATCH_CONSTRUCTORS_[replayType];
goog.asserts.assert(goog.isDef(constructor)); goog.asserts.assert(goog.isDef(constructor));
replay = new constructor(this.tolerance_); replay = new constructor(this.tolerance_, this.maxExtent_);
this.replays_[replayType] = replay; this.replays_[replayType] = replay;
} }
return replay; return replay;
@@ -589,23 +623,27 @@ ol.render.webgl.ReplayGroup.prototype.isEmpty = function() {
/** /**
* @param {ol.webgl.Context} context Context. * @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 {ol.Extent} extent Extent.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {Array.<number>} size Size.
* @param {goog.vec.Mat4.Number} transform Transform.
* @param {Object} skippedFeaturesHash Ids of features to skip. * @param {Object} skippedFeaturesHash Ids of features to skip.
* @return {T|undefined} Callback result. * @return {T|undefined} Callback result.
* @template T * @template T
*/ */
ol.render.webgl.ReplayGroup.prototype.replay = function(context, 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; var i, ii, replay, result;
for (i = 0, ii = ol.render.REPLAY_ORDER.length; i < ii; ++i) { for (i = 0, ii = ol.render.REPLAY_ORDER.length; i < ii; ++i) {
replay = this.replays_[ol.render.REPLAY_ORDER[i]]; replay = this.replays_[ol.render.REPLAY_ORDER[i]];
if (goog.isDef(replay) && if (goog.isDef(replay) &&
ol.extent.intersects(extent, replay.getExtent())) { ol.extent.intersects(extent, replay.getExtent())) {
result = replay.replay(context, result = replay.replay(context,
pixelRatio, size, transform, skippedFeaturesHash); center, resolution, rotation, size, extent, pixelRatio,
skippedFeaturesHash);
if (result) { if (result) {
return result; return result;
} }
@@ -619,7 +657,8 @@ ol.render.webgl.ReplayGroup.prototype.replay = function(context,
* @const * @const
* @private * @private
* @type {Object.<ol.render.ReplayType, * @type {Object.<ol.render.ReplayType,
* function(new: ol.render.webgl.ImageReplay, number)>} * function(new: ol.render.webgl.ImageReplay, number,
* ol.Extent)>}
*/ */
ol.render.webgl.BATCH_CONSTRUCTORS_ = { ol.render.webgl.BATCH_CONSTRUCTORS_ = {
'Image': ol.render.webgl.ImageReplay 'Image': ol.render.webgl.ImageReplay
@@ -9,7 +9,6 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.webgl.ReplayGroup'); goog.require('ol.render.webgl.ReplayGroup');
goog.require('ol.renderer.vector'); goog.require('ol.renderer.vector');
goog.require('ol.renderer.webgl.Layer'); 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 = ol.renderer.webgl.VectorLayer.prototype.composeFrame =
function(frameState, layerState, context) { function(frameState, layerState, context) {
var viewState = frameState.viewState; 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_; var replayGroup = this.replayGroup_;
if (!goog.isNull(replayGroup) && !replayGroup.isEmpty()) { if (!goog.isNull(replayGroup) && !replayGroup.isEmpty()) {
replayGroup.replay(context, replayGroup.replay(context,
frameState.extent, frameState.pixelRatio, frameState.size, viewState.center, viewState.resolution, viewState.rotation,
this.projectionMatrix, frameState.size, frameState.extent, frameState.pixelRatio,
frameState.skippedFeatureUids); frameState.skippedFeatureUids);
} }
@@ -160,7 +151,8 @@ ol.renderer.webgl.VectorLayer.prototype.prepareFrame =
this.dirty_ = false; this.dirty_ = false;
var replayGroup = new ol.render.webgl.ReplayGroup( 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); vectorSource.loadFeatures(extent, resolution, projection);
var renderFeature = var renderFeature =
/** /**