Remove ol.ENABLE_WEBGL condition from webgl files
This commit is contained in:
@@ -3,103 +3,99 @@ goog.provide('ol.render.webgl');
|
|||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @const
|
||||||
/**
|
* @type {string}
|
||||||
* @const
|
*/
|
||||||
* @type {string}
|
ol.render.webgl.defaultFont = '10px sans-serif';
|
||||||
*/
|
|
||||||
ol.render.webgl.defaultFont = '10px sans-serif';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {ol.Color}
|
* @type {ol.Color}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
|
ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultLineCap = 'round';
|
ol.render.webgl.defaultLineCap = 'round';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {Array.<number>}
|
* @type {Array.<number>}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultLineDash = [];
|
ol.render.webgl.defaultLineDash = [];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultLineDashOffset = 0;
|
ol.render.webgl.defaultLineDashOffset = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultLineJoin = 'round';
|
ol.render.webgl.defaultLineJoin = 'round';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultMiterLimit = 10;
|
ol.render.webgl.defaultMiterLimit = 10;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {ol.Color}
|
* @type {ol.Color}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
|
ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultTextAlign = 0.5;
|
ol.render.webgl.defaultTextAlign = 0.5;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultTextBaseline = 0.5;
|
ol.render.webgl.defaultTextBaseline = 0.5;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.defaultLineWidth = 1;
|
ol.render.webgl.defaultLineWidth = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the orientation of a triangle based on the determinant method.
|
* Calculates the orientation of a triangle based on the determinant method.
|
||||||
* @param {number} x1 First X coordinate.
|
* @param {number} x1 First X coordinate.
|
||||||
* @param {number} y1 First Y coordinate.
|
* @param {number} y1 First Y coordinate.
|
||||||
* @param {number} x2 Second X coordinate.
|
* @param {number} x2 Second X coordinate.
|
||||||
* @param {number} y2 Second Y coordinate.
|
* @param {number} y2 Second Y coordinate.
|
||||||
* @param {number} x3 Third X coordinate.
|
* @param {number} x3 Third X coordinate.
|
||||||
* @param {number} y3 Third Y coordinate.
|
* @param {number} y3 Third Y coordinate.
|
||||||
* @return {boolean|undefined} Triangle is clockwise.
|
* @return {boolean|undefined} Triangle is clockwise.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
|
ol.render.webgl.triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
|
||||||
var area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
|
var area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
|
||||||
return (area <= ol.render.webgl.EPSILON && area >= -ol.render.webgl.EPSILON) ?
|
return (area <= ol.render.webgl.EPSILON && area >= -ol.render.webgl.EPSILON) ?
|
||||||
undefined : area > 0;
|
undefined : area > 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.EPSILON = Number.EPSILON || 2.220446049250313e-16;
|
ol.render.webgl.EPSILON = Number.EPSILON || 2.220446049250313e-16;
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,412 +13,408 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.Buffer');
|
goog.require('ol.webgl.Buffer');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
/**
|
* @extends {ol.render.webgl.Replay}
|
||||||
* @constructor
|
* @param {number} tolerance Tolerance.
|
||||||
* @extends {ol.render.webgl.Replay}
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
* @param {number} tolerance Tolerance.
|
* @struct
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
*/
|
||||||
* @struct
|
ol.render.webgl.CircleReplay = function(tolerance, maxExtent) {
|
||||||
*/
|
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
||||||
ol.render.webgl.CircleReplay = function(tolerance, maxExtent) {
|
|
||||||
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.render.webgl.circlereplay.defaultshader.Locations}
|
|
||||||
*/
|
|
||||||
this.defaultLocations_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<Array.<Array.<number>|number>>}
|
|
||||||
*/
|
|
||||||
this.styles_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.styleIndices_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.radius_ = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {{fillColor: (Array.<number>|null),
|
|
||||||
* strokeColor: (Array.<number>|null),
|
|
||||||
* lineDash: Array.<number>,
|
|
||||||
* lineDashOffset: (number|undefined),
|
|
||||||
* lineWidth: (number|undefined),
|
|
||||||
* changed: boolean}|null}
|
|
||||||
*/
|
|
||||||
this.state_ = {
|
|
||||||
fillColor: null,
|
|
||||||
strokeColor: null,
|
|
||||||
lineDash: null,
|
|
||||||
lineDashOffset: undefined,
|
|
||||||
lineWidth: undefined,
|
|
||||||
changed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.CircleReplay, ol.render.webgl.Replay);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @type {ol.render.webgl.circlereplay.defaultshader.Locations}
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {number} end End.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.drawCoordinates_ = function(
|
this.defaultLocations_ = null;
|
||||||
flatCoordinates, offset, end, stride) {
|
|
||||||
var numVertices = this.vertices.length;
|
|
||||||
var numIndices = this.indices.length;
|
|
||||||
var n = numVertices / 4;
|
|
||||||
var i, ii;
|
|
||||||
for (i = offset, ii = end; i < ii; i += stride) {
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i];
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
|
||||||
this.vertices[numVertices++] = 0;
|
|
||||||
this.vertices[numVertices++] = this.radius_;
|
|
||||||
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i];
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
|
||||||
this.vertices[numVertices++] = 1;
|
|
||||||
this.vertices[numVertices++] = this.radius_;
|
|
||||||
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i];
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
|
||||||
this.vertices[numVertices++] = 2;
|
|
||||||
this.vertices[numVertices++] = this.radius_;
|
|
||||||
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i];
|
|
||||||
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
|
||||||
this.vertices[numVertices++] = 3;
|
|
||||||
this.vertices[numVertices++] = this.radius_;
|
|
||||||
|
|
||||||
this.indices[numIndices++] = n;
|
|
||||||
this.indices[numIndices++] = n + 1;
|
|
||||||
this.indices[numIndices++] = n + 2;
|
|
||||||
|
|
||||||
this.indices[numIndices++] = n + 2;
|
|
||||||
this.indices[numIndices++] = n + 3;
|
|
||||||
this.indices[numIndices++] = n;
|
|
||||||
|
|
||||||
n += 4;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {Array.<Array.<Array.<number>|number>>}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.drawCircle = function(circleGeometry, feature) {
|
this.styles_ = [];
|
||||||
var radius = circleGeometry.getRadius();
|
|
||||||
var stride = circleGeometry.getStride();
|
/**
|
||||||
if (radius) {
|
* @private
|
||||||
this.startIndices.push(this.indices.length);
|
* @type {Array.<number>}
|
||||||
this.startIndicesFeature.push(feature);
|
*/
|
||||||
if (this.state_.changed) {
|
this.styleIndices_ = [];
|
||||||
this.styleIndices_.push(this.indices.length);
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.radius_ = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {{fillColor: (Array.<number>|null),
|
||||||
|
* strokeColor: (Array.<number>|null),
|
||||||
|
* lineDash: Array.<number>,
|
||||||
|
* lineDashOffset: (number|undefined),
|
||||||
|
* lineWidth: (number|undefined),
|
||||||
|
* changed: boolean}|null}
|
||||||
|
*/
|
||||||
|
this.state_ = {
|
||||||
|
fillColor: null,
|
||||||
|
strokeColor: null,
|
||||||
|
lineDash: null,
|
||||||
|
lineDashOffset: undefined,
|
||||||
|
lineWidth: undefined,
|
||||||
|
changed: false
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.CircleReplay, ol.render.webgl.Replay);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {number} end End.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.CircleReplay.prototype.drawCoordinates_ = function(
|
||||||
|
flatCoordinates, offset, end, stride) {
|
||||||
|
var numVertices = this.vertices.length;
|
||||||
|
var numIndices = this.indices.length;
|
||||||
|
var n = numVertices / 4;
|
||||||
|
var i, ii;
|
||||||
|
for (i = offset, ii = end; i < ii; i += stride) {
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i];
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
||||||
|
this.vertices[numVertices++] = 0;
|
||||||
|
this.vertices[numVertices++] = this.radius_;
|
||||||
|
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i];
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
||||||
|
this.vertices[numVertices++] = 1;
|
||||||
|
this.vertices[numVertices++] = this.radius_;
|
||||||
|
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i];
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
||||||
|
this.vertices[numVertices++] = 2;
|
||||||
|
this.vertices[numVertices++] = this.radius_;
|
||||||
|
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i];
|
||||||
|
this.vertices[numVertices++] = flatCoordinates[i + 1];
|
||||||
|
this.vertices[numVertices++] = 3;
|
||||||
|
this.vertices[numVertices++] = this.radius_;
|
||||||
|
|
||||||
|
this.indices[numIndices++] = n;
|
||||||
|
this.indices[numIndices++] = n + 1;
|
||||||
|
this.indices[numIndices++] = n + 2;
|
||||||
|
|
||||||
|
this.indices[numIndices++] = n + 2;
|
||||||
|
this.indices[numIndices++] = n + 3;
|
||||||
|
this.indices[numIndices++] = n;
|
||||||
|
|
||||||
|
n += 4;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.CircleReplay.prototype.drawCircle = function(circleGeometry, feature) {
|
||||||
|
var radius = circleGeometry.getRadius();
|
||||||
|
var stride = circleGeometry.getStride();
|
||||||
|
if (radius) {
|
||||||
|
this.startIndices.push(this.indices.length);
|
||||||
|
this.startIndicesFeature.push(feature);
|
||||||
|
if (this.state_.changed) {
|
||||||
|
this.styleIndices_.push(this.indices.length);
|
||||||
|
this.state_.changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.radius_ = radius;
|
||||||
|
var flatCoordinates = circleGeometry.getFlatCoordinates();
|
||||||
|
flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, 2,
|
||||||
|
stride, -this.origin[0], -this.origin[1]);
|
||||||
|
this.drawCoordinates_(flatCoordinates, 0, 2, stride);
|
||||||
|
} else {
|
||||||
|
if (this.state_.changed) {
|
||||||
|
this.styles_.pop();
|
||||||
|
if (this.styles_.length) {
|
||||||
|
var lastState = this.styles_[this.styles_.length - 1];
|
||||||
|
this.state_.fillColor = /** @type {Array.<number>} */ (lastState[0]);
|
||||||
|
this.state_.strokeColor = /** @type {Array.<number>} */ (lastState[1]);
|
||||||
|
this.state_.lineWidth = /** @type {number} */ (lastState[2]);
|
||||||
this.state_.changed = false;
|
this.state_.changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.radius_ = radius;
|
|
||||||
var flatCoordinates = circleGeometry.getFlatCoordinates();
|
|
||||||
flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, 2,
|
|
||||||
stride, -this.origin[0], -this.origin[1]);
|
|
||||||
this.drawCoordinates_(flatCoordinates, 0, 2, stride);
|
|
||||||
} else {
|
|
||||||
if (this.state_.changed) {
|
|
||||||
this.styles_.pop();
|
|
||||||
if (this.styles_.length) {
|
|
||||||
var lastState = this.styles_[this.styles_.length - 1];
|
|
||||||
this.state_.fillColor = /** @type {Array.<number>} */ (lastState[0]);
|
|
||||||
this.state_.strokeColor = /** @type {Array.<number>} */ (lastState[1]);
|
|
||||||
this.state_.lineWidth = /** @type {number} */ (lastState[2]);
|
|
||||||
this.state_.changed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
**/
|
||||||
|
ol.render.webgl.CircleReplay.prototype.finish = function(context) {
|
||||||
|
// create, bind, and populate the vertices buffer
|
||||||
|
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||||
|
|
||||||
|
// create, bind, and populate the indices buffer
|
||||||
|
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
||||||
|
|
||||||
|
this.startIndices.push(this.indices.length);
|
||||||
|
|
||||||
|
//Clean up, if there is nothing to draw
|
||||||
|
if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
|
||||||
|
this.styles_ = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.vertices = null;
|
||||||
|
this.indices = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.CircleReplay.prototype.getDeleteResourcesFunction = function(context) {
|
||||||
|
// We only delete our stuff here. The shaders and the program may
|
||||||
|
// be used by other CircleReplay instances (for other layers). And
|
||||||
|
// they will be deleted when disposing of the ol.webgl.Context
|
||||||
|
// object.
|
||||||
|
var verticesBuffer = this.verticesBuffer;
|
||||||
|
var indicesBuffer = this.indicesBuffer;
|
||||||
|
return function() {
|
||||||
|
context.deleteBuffer(verticesBuffer);
|
||||||
|
context.deleteBuffer(indicesBuffer);
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
**/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.finish = function(context) {
|
ol.render.webgl.CircleReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||||
// create, bind, and populate the vertices buffer
|
// get the program
|
||||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
var fragmentShader, vertexShader;
|
||||||
|
fragmentShader = ol.render.webgl.circlereplay.defaultshader.fragment;
|
||||||
|
vertexShader = ol.render.webgl.circlereplay.defaultshader.vertex;
|
||||||
|
var program = context.getProgram(fragmentShader, vertexShader);
|
||||||
|
|
||||||
// create, bind, and populate the indices buffer
|
// get the locations
|
||||||
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
var locations;
|
||||||
|
if (!this.defaultLocations_) {
|
||||||
|
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||||
|
locations = new ol.render.webgl.circlereplay.defaultshader.Locations(gl, program);
|
||||||
|
this.defaultLocations_ = locations;
|
||||||
|
} else {
|
||||||
|
locations = this.defaultLocations_;
|
||||||
|
}
|
||||||
|
|
||||||
this.startIndices.push(this.indices.length);
|
context.useProgram(program);
|
||||||
|
|
||||||
//Clean up, if there is nothing to draw
|
// enable the vertex attrib arrays
|
||||||
if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
|
gl.enableVertexAttribArray(locations.a_position);
|
||||||
this.styles_ = [];
|
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
||||||
}
|
false, 16, 0);
|
||||||
|
|
||||||
this.vertices = null;
|
gl.enableVertexAttribArray(locations.a_instruction);
|
||||||
this.indices = null;
|
gl.vertexAttribPointer(locations.a_instruction, 1, ol.webgl.FLOAT,
|
||||||
};
|
false, 16, 8);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(locations.a_radius);
|
||||||
|
gl.vertexAttribPointer(locations.a_radius, 1, ol.webgl.FLOAT,
|
||||||
|
false, 16, 12);
|
||||||
|
|
||||||
|
// Enable renderer specific uniforms.
|
||||||
|
gl.uniform2fv(locations.u_size, size);
|
||||||
|
gl.uniform1f(locations.u_pixelRatio, pixelRatio);
|
||||||
|
|
||||||
|
return locations;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.getDeleteResourcesFunction = function(context) {
|
ol.render.webgl.CircleReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||||
// We only delete our stuff here. The shaders and the program may
|
gl.disableVertexAttribArray(locations.a_position);
|
||||||
// be used by other CircleReplay instances (for other layers). And
|
gl.disableVertexAttribArray(locations.a_instruction);
|
||||||
// they will be deleted when disposing of the ol.webgl.Context
|
gl.disableVertexAttribArray(locations.a_radius);
|
||||||
// object.
|
};
|
||||||
var verticesBuffer = this.verticesBuffer;
|
|
||||||
var indicesBuffer = this.indicesBuffer;
|
|
||||||
return function() {
|
|
||||||
context.deleteBuffer(verticesBuffer);
|
|
||||||
context.deleteBuffer(indicesBuffer);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
ol.render.webgl.CircleReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||||
// get the program
|
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||||
var fragmentShader, vertexShader;
|
this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
|
||||||
fragmentShader = ol.render.webgl.circlereplay.defaultshader.fragment;
|
} else {
|
||||||
vertexShader = ol.render.webgl.circlereplay.defaultshader.vertex;
|
//Draw by style groups to minimize drawElements() calls.
|
||||||
var program = context.getProgram(fragmentShader, vertexShader);
|
var i, start, end, nextStyle;
|
||||||
|
end = this.startIndices[this.startIndices.length - 1];
|
||||||
// get the locations
|
|
||||||
var locations;
|
|
||||||
if (!this.defaultLocations_) {
|
|
||||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
|
||||||
locations = new ol.render.webgl.circlereplay.defaultshader.Locations(gl, program);
|
|
||||||
this.defaultLocations_ = locations;
|
|
||||||
} else {
|
|
||||||
locations = this.defaultLocations_;
|
|
||||||
}
|
|
||||||
|
|
||||||
context.useProgram(program);
|
|
||||||
|
|
||||||
// enable the vertex attrib arrays
|
|
||||||
gl.enableVertexAttribArray(locations.a_position);
|
|
||||||
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
|
||||||
false, 16, 0);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_instruction);
|
|
||||||
gl.vertexAttribPointer(locations.a_instruction, 1, ol.webgl.FLOAT,
|
|
||||||
false, 16, 8);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_radius);
|
|
||||||
gl.vertexAttribPointer(locations.a_radius, 1, ol.webgl.FLOAT,
|
|
||||||
false, 16, 12);
|
|
||||||
|
|
||||||
// Enable renderer specific uniforms.
|
|
||||||
gl.uniform2fv(locations.u_size, size);
|
|
||||||
gl.uniform1f(locations.u_pixelRatio, pixelRatio);
|
|
||||||
|
|
||||||
return locations;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.CircleReplay.prototype.shutDownProgram = function(gl, locations) {
|
|
||||||
gl.disableVertexAttribArray(locations.a_position);
|
|
||||||
gl.disableVertexAttribArray(locations.a_instruction);
|
|
||||||
gl.disableVertexAttribArray(locations.a_radius);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.CircleReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
|
||||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
|
||||||
this.drawReplaySkipping_(gl, context, skippedFeaturesHash);
|
|
||||||
} else {
|
|
||||||
//Draw by style groups to minimize drawElements() calls.
|
|
||||||
var i, start, end, nextStyle;
|
|
||||||
end = this.startIndices[this.startIndices.length - 1];
|
|
||||||
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
|
||||||
start = this.styleIndices_[i];
|
|
||||||
nextStyle = this.styles_[i];
|
|
||||||
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
|
||||||
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
|
||||||
/** @type {number} */ (nextStyle[2]));
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
end = start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.CircleReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
|
||||||
featureCallback, opt_hitExtent) {
|
|
||||||
var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
|
|
||||||
featureIndex = this.startIndices.length - 2;
|
|
||||||
end = this.startIndices[featureIndex + 1];
|
|
||||||
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
||||||
|
start = this.styleIndices_[i];
|
||||||
nextStyle = this.styles_[i];
|
nextStyle = this.styles_[i];
|
||||||
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
||||||
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
||||||
/** @type {number} */ (nextStyle[2]));
|
/** @type {number} */ (nextStyle[2]));
|
||||||
groupStart = this.styleIndices_[i];
|
this.drawElements(gl, context, start, end);
|
||||||
|
end = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
while (featureIndex >= 0 &&
|
|
||||||
this.startIndices[featureIndex] >= groupStart) {
|
|
||||||
start = this.startIndices[featureIndex];
|
|
||||||
feature = this.startIndicesFeature[featureIndex];
|
|
||||||
featureUid = ol.getUid(feature).toString();
|
|
||||||
|
|
||||||
if (skippedFeaturesHash[featureUid] === undefined &&
|
/**
|
||||||
feature.getGeometry() &&
|
* @inheritDoc
|
||||||
(opt_hitExtent === undefined || ol.extent.intersects(
|
*/
|
||||||
/** @type {Array<number>} */ (opt_hitExtent),
|
ol.render.webgl.CircleReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||||
feature.getGeometry().getExtent()))) {
|
featureCallback, opt_hitExtent) {
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex;
|
||||||
|
featureIndex = this.startIndices.length - 2;
|
||||||
|
end = this.startIndices[featureIndex + 1];
|
||||||
|
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
||||||
|
nextStyle = this.styles_[i];
|
||||||
|
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
||||||
|
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
||||||
|
/** @type {number} */ (nextStyle[2]));
|
||||||
|
groupStart = this.styleIndices_[i];
|
||||||
|
|
||||||
|
while (featureIndex >= 0 &&
|
||||||
|
this.startIndices[featureIndex] >= groupStart) {
|
||||||
|
start = this.startIndices[featureIndex];
|
||||||
|
feature = this.startIndicesFeature[featureIndex];
|
||||||
|
featureUid = ol.getUid(feature).toString();
|
||||||
|
|
||||||
|
if (skippedFeaturesHash[featureUid] === undefined &&
|
||||||
|
feature.getGeometry() &&
|
||||||
|
(opt_hitExtent === undefined || ol.extent.intersects(
|
||||||
|
/** @type {Array<number>} */ (opt_hitExtent),
|
||||||
|
feature.getGeometry().getExtent()))) {
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
this.drawElements(gl, context, start, end);
|
||||||
|
|
||||||
|
var result = featureCallback(feature);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
featureIndex--;
|
||||||
|
end = start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.CircleReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash) {
|
||||||
|
var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
|
||||||
|
featureIndex = this.startIndices.length - 2;
|
||||||
|
end = start = this.startIndices[featureIndex + 1];
|
||||||
|
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
||||||
|
nextStyle = this.styles_[i];
|
||||||
|
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
||||||
|
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
||||||
|
/** @type {number} */ (nextStyle[2]));
|
||||||
|
groupStart = this.styleIndices_[i];
|
||||||
|
|
||||||
|
while (featureIndex >= 0 &&
|
||||||
|
this.startIndices[featureIndex] >= groupStart) {
|
||||||
|
featureStart = this.startIndices[featureIndex];
|
||||||
|
feature = this.startIndicesFeature[featureIndex];
|
||||||
|
featureUid = ol.getUid(feature).toString();
|
||||||
|
|
||||||
|
if (skippedFeaturesHash[featureUid]) {
|
||||||
|
if (start !== end) {
|
||||||
this.drawElements(gl, context, start, end);
|
this.drawElements(gl, context, start, end);
|
||||||
|
|
||||||
var result = featureCallback(feature);
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
featureIndex--;
|
end = featureStart;
|
||||||
end = start;
|
|
||||||
}
|
}
|
||||||
|
featureIndex--;
|
||||||
|
start = featureStart;
|
||||||
}
|
}
|
||||||
return undefined;
|
if (start !== end) {
|
||||||
};
|
this.drawElements(gl, context, start, end);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {Object} skippedFeaturesHash Ids of features to skip.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.CircleReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash) {
|
|
||||||
var i, start, end, nextStyle, groupStart, feature, featureUid, featureIndex, featureStart;
|
|
||||||
featureIndex = this.startIndices.length - 2;
|
|
||||||
end = start = this.startIndices[featureIndex + 1];
|
|
||||||
for (i = this.styleIndices_.length - 1; i >= 0; --i) {
|
|
||||||
nextStyle = this.styles_[i];
|
|
||||||
this.setFillStyle_(gl, /** @type {Array.<number>} */ (nextStyle[0]));
|
|
||||||
this.setStrokeStyle_(gl, /** @type {Array.<number>} */ (nextStyle[1]),
|
|
||||||
/** @type {number} */ (nextStyle[2]));
|
|
||||||
groupStart = this.styleIndices_[i];
|
|
||||||
|
|
||||||
while (featureIndex >= 0 &&
|
|
||||||
this.startIndices[featureIndex] >= groupStart) {
|
|
||||||
featureStart = this.startIndices[featureIndex];
|
|
||||||
feature = this.startIndicesFeature[featureIndex];
|
|
||||||
featureUid = ol.getUid(feature).toString();
|
|
||||||
|
|
||||||
if (skippedFeaturesHash[featureUid]) {
|
|
||||||
if (start !== end) {
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
}
|
|
||||||
end = featureStart;
|
|
||||||
}
|
|
||||||
featureIndex--;
|
|
||||||
start = featureStart;
|
|
||||||
}
|
|
||||||
if (start !== end) {
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
}
|
|
||||||
start = end = groupStart;
|
|
||||||
}
|
}
|
||||||
};
|
start = end = groupStart;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
* @param {Array.<number>} color Color.
|
* @param {Array.<number>} color Color.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.setFillStyle_ = function(gl, color) {
|
ol.render.webgl.CircleReplay.prototype.setFillStyle_ = function(gl, color) {
|
||||||
gl.uniform4fv(this.defaultLocations_.u_fillColor, color);
|
gl.uniform4fv(this.defaultLocations_.u_fillColor, color);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
* @param {Array.<number>} color Color.
|
* @param {Array.<number>} color Color.
|
||||||
* @param {number} lineWidth Line width.
|
* @param {number} lineWidth Line width.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth) {
|
ol.render.webgl.CircleReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth) {
|
||||||
gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);
|
gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);
|
||||||
gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
|
gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.CircleReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
ol.render.webgl.CircleReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
||||||
var strokeStyleColor, strokeStyleWidth;
|
var strokeStyleColor, strokeStyleWidth;
|
||||||
if (strokeStyle) {
|
if (strokeStyle) {
|
||||||
var strokeStyleLineDash = strokeStyle.getLineDash();
|
var strokeStyleLineDash = strokeStyle.getLineDash();
|
||||||
this.state_.lineDash = strokeStyleLineDash ?
|
this.state_.lineDash = strokeStyleLineDash ?
|
||||||
strokeStyleLineDash : ol.render.webgl.defaultLineDash;
|
strokeStyleLineDash : ol.render.webgl.defaultLineDash;
|
||||||
var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
|
var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
|
||||||
this.state_.lineDashOffset = strokeStyleLineDashOffset ?
|
this.state_.lineDashOffset = strokeStyleLineDashOffset ?
|
||||||
strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
|
strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
|
||||||
strokeStyleColor = strokeStyle.getColor();
|
strokeStyleColor = strokeStyle.getColor();
|
||||||
if (!(strokeStyleColor instanceof CanvasGradient) &&
|
if (!(strokeStyleColor instanceof CanvasGradient) &&
|
||||||
!(strokeStyleColor instanceof CanvasPattern)) {
|
!(strokeStyleColor instanceof CanvasPattern)) {
|
||||||
strokeStyleColor = ol.color.asArray(strokeStyleColor).map(function(c, i) {
|
strokeStyleColor = ol.color.asArray(strokeStyleColor).map(function(c, i) {
|
||||||
return i != 3 ? c / 255 : c;
|
|
||||||
}) || ol.render.webgl.defaultStrokeStyle;
|
|
||||||
} else {
|
|
||||||
strokeStyleColor = ol.render.webgl.defaultStrokeStyle;
|
|
||||||
}
|
|
||||||
strokeStyleWidth = strokeStyle.getWidth();
|
|
||||||
strokeStyleWidth = strokeStyleWidth !== undefined ?
|
|
||||||
strokeStyleWidth : ol.render.webgl.defaultLineWidth;
|
|
||||||
} else {
|
|
||||||
strokeStyleColor = [0, 0, 0, 0];
|
|
||||||
strokeStyleWidth = 0;
|
|
||||||
}
|
|
||||||
var fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];
|
|
||||||
if (!(fillStyleColor instanceof CanvasGradient) &&
|
|
||||||
!(fillStyleColor instanceof CanvasPattern)) {
|
|
||||||
fillStyleColor = ol.color.asArray(fillStyleColor).map(function(c, i) {
|
|
||||||
return i != 3 ? c / 255 : c;
|
return i != 3 ? c / 255 : c;
|
||||||
}) || ol.render.webgl.defaultFillStyle;
|
}) || ol.render.webgl.defaultStrokeStyle;
|
||||||
} else {
|
} else {
|
||||||
fillStyleColor = ol.render.webgl.defaultFillStyle;
|
strokeStyleColor = ol.render.webgl.defaultStrokeStyle;
|
||||||
}
|
}
|
||||||
if (!this.state_.strokeColor || !ol.array.equals(this.state_.strokeColor, strokeStyleColor) ||
|
strokeStyleWidth = strokeStyle.getWidth();
|
||||||
!this.state_.fillColor || !ol.array.equals(this.state_.fillColor, fillStyleColor) ||
|
strokeStyleWidth = strokeStyleWidth !== undefined ?
|
||||||
this.state_.lineWidth !== strokeStyleWidth) {
|
strokeStyleWidth : ol.render.webgl.defaultLineWidth;
|
||||||
this.state_.changed = true;
|
} else {
|
||||||
this.state_.fillColor = fillStyleColor;
|
strokeStyleColor = [0, 0, 0, 0];
|
||||||
this.state_.strokeColor = strokeStyleColor;
|
strokeStyleWidth = 0;
|
||||||
this.state_.lineWidth = strokeStyleWidth;
|
}
|
||||||
this.styles_.push([fillStyleColor, strokeStyleColor, strokeStyleWidth]);
|
var fillStyleColor = fillStyle ? fillStyle.getColor() : [0, 0, 0, 0];
|
||||||
}
|
if (!(fillStyleColor instanceof CanvasGradient) &&
|
||||||
};
|
!(fillStyleColor instanceof CanvasPattern)) {
|
||||||
|
fillStyleColor = ol.color.asArray(fillStyleColor).map(function(c, i) {
|
||||||
}
|
return i != 3 ? c / 255 : c;
|
||||||
|
}) || ol.render.webgl.defaultFillStyle;
|
||||||
|
} else {
|
||||||
|
fillStyleColor = ol.render.webgl.defaultFillStyle;
|
||||||
|
}
|
||||||
|
if (!this.state_.strokeColor || !ol.array.equals(this.state_.strokeColor, strokeStyleColor) ||
|
||||||
|
!this.state_.fillColor || !ol.array.equals(this.state_.fillColor, fillStyleColor) ||
|
||||||
|
this.state_.lineWidth !== strokeStyleWidth) {
|
||||||
|
this.state_.changed = true;
|
||||||
|
this.state_.fillColor = fillStyleColor;
|
||||||
|
this.state_.strokeColor = strokeStyleColor;
|
||||||
|
this.state_.lineWidth = strokeStyleWidth;
|
||||||
|
this.styles_.push([fillStyleColor, strokeStyleColor, strokeStyleWidth]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,161 +6,157 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.circlereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_fillColor;\nuniform vec4 u_strokeColor;\nuniform vec2 u_size;\n\nvoid main(void) {\n vec2 windowCenter = vec2((v_center.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_center.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n vec2 windowOffset = vec2((v_offset.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_offset.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n float radius = length(windowCenter - windowOffset);\n float dist = length(windowCenter - gl_FragCoord.xy);\n if (dist > radius + v_halfWidth) {\n if (u_strokeColor.a == 0.0) {\n gl_FragColor = u_fillColor;\n } else {\n gl_FragColor = u_strokeColor;\n }\n gl_FragColor.a = gl_FragColor.a - (dist - (radius + v_halfWidth));\n } else if (u_fillColor.a == 0.0) {\n // Hooray, no fill, just stroke. We can use real antialiasing.\n gl_FragColor = u_strokeColor;\n if (dist < radius - v_halfWidth) {\n gl_FragColor.a = gl_FragColor.a - (radius - v_halfWidth - dist);\n }\n } else {\n gl_FragColor = u_fillColor;\n float strokeDist = radius - v_halfWidth;\n float antialias = 2.0 * v_pixelRatio;\n if (dist > strokeDist) {\n gl_FragColor = u_strokeColor;\n } else if (dist >= strokeDist - antialias) {\n float step = smoothstep(strokeDist - antialias, strokeDist, dist);\n gl_FragColor = mix(u_fillColor, u_strokeColor, step);\n }\n }\n gl_FragColor.a = gl_FragColor.a * u_opacity;\n if (gl_FragColor.a <= 0.0) {\n discard;\n }\n}\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying vec2 b;varying float c;varying float d;uniform float m;uniform vec4 n;uniform vec4 o;uniform vec2 p;void main(void){vec2 windowCenter=vec2((a.x+1.0)/2.0*p.x*d,(a.y+1.0)/2.0*p.y*d);vec2 windowOffset=vec2((b.x+1.0)/2.0*p.x*d,(b.y+1.0)/2.0*p.y*d);float radius=length(windowCenter-windowOffset);float dist=length(windowCenter-gl_FragCoord.xy);if(dist>radius+c){if(o.a==0.0){gl_FragColor=n;}else{gl_FragColor=o;}gl_FragColor.a=gl_FragColor.a-(dist-(radius+c));}else if(n.a==0.0){gl_FragColor=o;if(dist<radius-c){gl_FragColor.a=gl_FragColor.a-(radius-c-dist);}} else{gl_FragColor=n;float strokeDist=radius-c;float antialias=2.0*d;if(dist>strokeDist){gl_FragColor=o;}else if(dist>=strokeDist-antialias){float step=smoothstep(strokeDist-antialias,strokeDist,dist);gl_FragColor=mix(n,o,step);}} gl_FragColor.a=gl_FragColor.a*m;if(gl_FragColor.a<=0.0){discard;}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.fragment = new ol.render.webgl.circlereplay.defaultshader.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.circlereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\nattribute vec2 a_position;\nattribute float a_instruction;\nattribute float a_radius;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\nuniform float u_lineWidth;\nuniform float u_pixelRatio;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n v_center = vec4(u_projectionMatrix * vec4(a_position, 0.0, 1.0)).xy;\n v_pixelRatio = u_pixelRatio;\n float lineWidth = u_lineWidth * u_pixelRatio;\n v_halfWidth = lineWidth / 2.0;\n if (lineWidth == 0.0) {\n lineWidth = 2.0 * u_pixelRatio;\n }\n vec2 offset;\n // Radius with anitaliasing (roughly).\n float radius = a_radius + 3.0 * u_pixelRatio;\n // Until we get gl_VertexID in WebGL, we store an instruction.\n if (a_instruction == 0.0) {\n // Offsetting the edges of the triangle by lineWidth / 2 is necessary, however\n // we should also leave some space for the antialiasing, thus we offset by lineWidth.\n offset = vec2(-1.0, 1.0);\n } else if (a_instruction == 1.0) {\n offset = vec2(-1.0, -1.0);\n } else if (a_instruction == 2.0) {\n offset = vec2(1.0, -1.0);\n } else {\n offset = vec2(1.0, 1.0);\n }\n\n gl_Position = u_projectionMatrix * vec4(a_position + offset * radius, 0.0, 1.0) +\n offsetMatrix * vec4(offset * lineWidth, 0.0, 0.0);\n v_offset = vec4(u_projectionMatrix * vec4(a_position.x + a_radius, a_position.y,\n 0.0, 1.0)).xy;\n\n if (distance(v_center, v_offset) > 20000.0) {\n gl_Position = vec4(v_center, 0.0, 1.0);\n }\n}\n\n\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying vec2 b;varying float c;varying float d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;void main(void){mat4 offsetMatrix=i*j;a=vec4(h*vec4(e,0.0,1.0)).xy;d=l;float lineWidth=k*l;c=lineWidth/2.0;if(lineWidth==0.0){lineWidth=2.0*l;}vec2 offset;float radius=g+3.0*l;if(f==0.0){offset=vec2(-1.0,1.0);}else if(f==1.0){offset=vec2(-1.0,-1.0);}else if(f==2.0){offset=vec2(1.0,-1.0);}else{offset=vec2(1.0,1.0);}gl_Position=h*vec4(e+offset*radius,0.0,1.0)+offsetMatrix*vec4(offset*lineWidth,0.0,0.0);b=vec4(h*vec4(e.x+g,e.y,0.0,1.0)).xy;if(distance(a,b)>20000.0){gl_Position=vec4(a,0.0,1.0);}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.vertex = new ol.render.webgl.circlereplay.defaultshader.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.circlereplay.defaultshader.Locations = function(gl, program) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment = function() {
|
this.u_fillColor = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.circlereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\n\nuniform float u_opacity;\nuniform vec4 u_fillColor;\nuniform vec4 u_strokeColor;\nuniform vec2 u_size;\n\nvoid main(void) {\n vec2 windowCenter = vec2((v_center.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_center.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n vec2 windowOffset = vec2((v_offset.x + 1.0) / 2.0 * u_size.x * v_pixelRatio,\n (v_offset.y + 1.0) / 2.0 * u_size.y * v_pixelRatio);\n float radius = length(windowCenter - windowOffset);\n float dist = length(windowCenter - gl_FragCoord.xy);\n if (dist > radius + v_halfWidth) {\n if (u_strokeColor.a == 0.0) {\n gl_FragColor = u_fillColor;\n } else {\n gl_FragColor = u_strokeColor;\n }\n gl_FragColor.a = gl_FragColor.a - (dist - (radius + v_halfWidth));\n } else if (u_fillColor.a == 0.0) {\n // Hooray, no fill, just stroke. We can use real antialiasing.\n gl_FragColor = u_strokeColor;\n if (dist < radius - v_halfWidth) {\n gl_FragColor.a = gl_FragColor.a - (radius - v_halfWidth - dist);\n }\n } else {\n gl_FragColor = u_fillColor;\n float strokeDist = radius - v_halfWidth;\n float antialias = 2.0 * v_pixelRatio;\n if (dist > strokeDist) {\n gl_FragColor = u_strokeColor;\n } else if (dist >= strokeDist - antialias) {\n float step = smoothstep(strokeDist - antialias, strokeDist, dist);\n gl_FragColor = mix(u_fillColor, u_strokeColor, step);\n }\n }\n gl_FragColor.a = gl_FragColor.a * u_opacity;\n if (gl_FragColor.a <= 0.0) {\n discard;\n }\n}\n';
|
this.u_lineWidth = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying vec2 b;varying float c;varying float d;uniform float m;uniform vec4 n;uniform vec4 o;uniform vec2 p;void main(void){vec2 windowCenter=vec2((a.x+1.0)/2.0*p.x*d,(a.y+1.0)/2.0*p.y*d);vec2 windowOffset=vec2((b.x+1.0)/2.0*p.x*d,(b.y+1.0)/2.0*p.y*d);float radius=length(windowCenter-windowOffset);float dist=length(windowCenter-gl_FragCoord.xy);if(dist>radius+c){if(o.a==0.0){gl_FragColor=n;}else{gl_FragColor=o;}gl_FragColor.a=gl_FragColor.a-(dist-(radius+c));}else if(n.a==0.0){gl_FragColor=o;if(dist<radius-c){gl_FragColor.a=gl_FragColor.a-(radius-c-dist);}} else{gl_FragColor=n;float strokeDist=radius-c;float antialias=2.0*d;if(dist>strokeDist){gl_FragColor=o;}else if(dist>=strokeDist-antialias){float step=smoothstep(strokeDist-antialias,strokeDist,dist);gl_FragColor=mix(n,o,step);}} gl_FragColor.a=gl_FragColor.a*m;if(gl_FragColor.a<=0.0){discard;}}';
|
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||||
ol.render.webgl.circlereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.circlereplay.defaultshader.fragment = new ol.render.webgl.circlereplay.defaultshader.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex = function() {
|
this.u_opacity = gl.getUniformLocation(
|
||||||
ol.webgl.Vertex.call(this, ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.circlereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_center;\nvarying vec2 v_offset;\nvarying float v_halfWidth;\nvarying float v_pixelRatio;\n\n\nattribute vec2 a_position;\nattribute float a_instruction;\nattribute float a_radius;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\nuniform float u_lineWidth;\nuniform float u_pixelRatio;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n v_center = vec4(u_projectionMatrix * vec4(a_position, 0.0, 1.0)).xy;\n v_pixelRatio = u_pixelRatio;\n float lineWidth = u_lineWidth * u_pixelRatio;\n v_halfWidth = lineWidth / 2.0;\n if (lineWidth == 0.0) {\n lineWidth = 2.0 * u_pixelRatio;\n }\n vec2 offset;\n // Radius with anitaliasing (roughly).\n float radius = a_radius + 3.0 * u_pixelRatio;\n // Until we get gl_VertexID in WebGL, we store an instruction.\n if (a_instruction == 0.0) {\n // Offsetting the edges of the triangle by lineWidth / 2 is necessary, however\n // we should also leave some space for the antialiasing, thus we offset by lineWidth.\n offset = vec2(-1.0, 1.0);\n } else if (a_instruction == 1.0) {\n offset = vec2(-1.0, -1.0);\n } else if (a_instruction == 2.0) {\n offset = vec2(1.0, -1.0);\n } else {\n offset = vec2(1.0, 1.0);\n }\n\n gl_Position = u_projectionMatrix * vec4(a_position + offset * radius, 0.0, 1.0) +\n offsetMatrix * vec4(offset * lineWidth, 0.0, 0.0);\n v_offset = vec4(u_projectionMatrix * vec4(a_position.x + a_radius, a_position.y,\n 0.0, 1.0)).xy;\n\n if (distance(v_center, v_offset) > 20000.0) {\n gl_Position = vec4(v_center, 0.0, 1.0);\n }\n}\n\n\n';
|
this.u_pixelRatio = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying vec2 b;varying float c;varying float d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;uniform float k;uniform float l;void main(void){mat4 offsetMatrix=i*j;a=vec4(h*vec4(e,0.0,1.0)).xy;d=l;float lineWidth=k*l;c=lineWidth/2.0;if(lineWidth==0.0){lineWidth=2.0*l;}vec2 offset;float radius=g+3.0*l;if(f==0.0){offset=vec2(-1.0,1.0);}else if(f==1.0){offset=vec2(-1.0,-1.0);}else if(f==2.0){offset=vec2(1.0,-1.0);}else{offset=vec2(1.0,1.0);}gl_Position=h*vec4(e+offset*radius,0.0,1.0)+offsetMatrix*vec4(offset*lineWidth,0.0,0.0);b=vec4(h*vec4(e.x+g,e.y,0.0,1.0)).xy;if(distance(a,b)>20000.0){gl_Position=vec4(a,0.0,1.0);}}';
|
this.u_projectionMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
this.u_size = gl.getUniformLocation(
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'u_size' : 'p');
|
||||||
ol.render.webgl.circlereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.circlereplay.defaultshader.vertex = new ol.render.webgl.circlereplay.defaultshader.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.circlereplay.defaultshader.Locations = function(gl, program) {
|
this.u_strokeColor = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_strokeColor' : 'o');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {WebGLUniformLocation}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.u_fillColor = gl.getUniformLocation(
|
this.a_instruction = gl.getAttribLocation(
|
||||||
program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
program, ol.DEBUG_WEBGL ? 'a_instruction' : 'f');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {WebGLUniformLocation}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.u_lineWidth = gl.getUniformLocation(
|
this.a_position = gl.getAttribLocation(
|
||||||
program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {WebGLUniformLocation}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
this.a_radius = gl.getAttribLocation(
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
program, ol.DEBUG_WEBGL ? 'a_radius' : 'g');
|
||||||
|
};
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_opacity = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_pixelRatio = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_pixelRatio' : 'l');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_projectionMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_size = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_size' : 'p');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_strokeColor = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_strokeColor' : 'o');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_instruction = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_instruction' : 'f');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_position = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_radius = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_radius' : 'g');
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,169 +5,165 @@ goog.require('ol.render.webgl.TextureReplay');
|
|||||||
goog.require('ol.webgl.Buffer');
|
goog.require('ol.webgl.Buffer');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.render.webgl.TextureReplay}
|
||||||
|
* @param {number} tolerance Tolerance.
|
||||||
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
|
||||||
|
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||||
* @extends {ol.render.webgl.TextureReplay}
|
* @protected
|
||||||
* @param {number} tolerance Tolerance.
|
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
|
this.images_ = [];
|
||||||
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.images_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.hitDetectionImages_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<WebGLTexture>}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.textures_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<WebGLTexture>}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.hitDetectionTextures_ = [];
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||||
|
* @protected
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
|
this.hitDetectionImages_ = [];
|
||||||
this.startIndices.push(this.indices.length);
|
|
||||||
this.startIndicesFeature.push(feature);
|
|
||||||
var flatCoordinates = multiPointGeometry.getFlatCoordinates();
|
|
||||||
var stride = multiPointGeometry.getStride();
|
|
||||||
this.drawCoordinates(
|
|
||||||
flatCoordinates, 0, flatCoordinates.length, stride);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @type {Array.<WebGLTexture>}
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) {
|
this.textures_ = [];
|
||||||
this.startIndices.push(this.indices.length);
|
|
||||||
this.startIndicesFeature.push(feature);
|
|
||||||
var flatCoordinates = pointGeometry.getFlatCoordinates();
|
|
||||||
var stride = pointGeometry.getStride();
|
|
||||||
this.drawCoordinates(
|
|
||||||
flatCoordinates, 0, flatCoordinates.length, stride);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @type {Array.<WebGLTexture>}
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.finish = function(context) {
|
this.hitDetectionTextures_ = [];
|
||||||
var gl = context.getGL();
|
|
||||||
|
|
||||||
this.groupIndices.push(this.indices.length);
|
};
|
||||||
this.hitDetectionGroupIndices.push(this.indices.length);
|
ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay);
|
||||||
|
|
||||||
// create, bind, and populate the vertices buffer
|
|
||||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
|
||||||
|
|
||||||
var indices = this.indices;
|
|
||||||
|
|
||||||
// create, bind, and populate the indices buffer
|
|
||||||
this.indicesBuffer = new ol.webgl.Buffer(indices);
|
|
||||||
|
|
||||||
// create textures
|
|
||||||
/** @type {Object.<string, WebGLTexture>} */
|
|
||||||
var texturePerImage = {};
|
|
||||||
|
|
||||||
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
|
||||||
|
|
||||||
this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_,
|
|
||||||
texturePerImage, gl);
|
|
||||||
|
|
||||||
this.images_ = null;
|
|
||||||
this.hitDetectionImages_ = null;
|
|
||||||
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.setImageStyle = function(imageStyle) {
|
ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
|
||||||
var anchor = imageStyle.getAnchor();
|
this.startIndices.push(this.indices.length);
|
||||||
var image = imageStyle.getImage(1);
|
this.startIndicesFeature.push(feature);
|
||||||
var imageSize = imageStyle.getImageSize();
|
var flatCoordinates = multiPointGeometry.getFlatCoordinates();
|
||||||
var hitDetectionImage = imageStyle.getHitDetectionImage(1);
|
var stride = multiPointGeometry.getStride();
|
||||||
var opacity = imageStyle.getOpacity();
|
this.drawCoordinates(
|
||||||
var origin = imageStyle.getOrigin();
|
flatCoordinates, 0, flatCoordinates.length, stride);
|
||||||
var rotateWithView = imageStyle.getRotateWithView();
|
};
|
||||||
var rotation = imageStyle.getRotation();
|
|
||||||
var size = imageStyle.getSize();
|
|
||||||
var scale = imageStyle.getScale();
|
|
||||||
|
|
||||||
var currentImage;
|
|
||||||
if (this.images_.length === 0) {
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay.prototype.drawPoint = function(pointGeometry, feature) {
|
||||||
|
this.startIndices.push(this.indices.length);
|
||||||
|
this.startIndicesFeature.push(feature);
|
||||||
|
var flatCoordinates = pointGeometry.getFlatCoordinates();
|
||||||
|
var stride = pointGeometry.getStride();
|
||||||
|
this.drawCoordinates(
|
||||||
|
flatCoordinates, 0, flatCoordinates.length, stride);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay.prototype.finish = function(context) {
|
||||||
|
var gl = context.getGL();
|
||||||
|
|
||||||
|
this.groupIndices.push(this.indices.length);
|
||||||
|
this.hitDetectionGroupIndices.push(this.indices.length);
|
||||||
|
|
||||||
|
// create, bind, and populate the vertices buffer
|
||||||
|
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||||
|
|
||||||
|
var indices = this.indices;
|
||||||
|
|
||||||
|
// create, bind, and populate the indices buffer
|
||||||
|
this.indicesBuffer = new ol.webgl.Buffer(indices);
|
||||||
|
|
||||||
|
// create textures
|
||||||
|
/** @type {Object.<string, WebGLTexture>} */
|
||||||
|
var texturePerImage = {};
|
||||||
|
|
||||||
|
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
||||||
|
|
||||||
|
this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_,
|
||||||
|
texturePerImage, gl);
|
||||||
|
|
||||||
|
this.images_ = null;
|
||||||
|
this.hitDetectionImages_ = null;
|
||||||
|
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ImageReplay.prototype.setImageStyle = function(imageStyle) {
|
||||||
|
var anchor = imageStyle.getAnchor();
|
||||||
|
var image = imageStyle.getImage(1);
|
||||||
|
var imageSize = imageStyle.getImageSize();
|
||||||
|
var hitDetectionImage = imageStyle.getHitDetectionImage(1);
|
||||||
|
var opacity = imageStyle.getOpacity();
|
||||||
|
var origin = imageStyle.getOrigin();
|
||||||
|
var rotateWithView = imageStyle.getRotateWithView();
|
||||||
|
var rotation = imageStyle.getRotation();
|
||||||
|
var size = imageStyle.getSize();
|
||||||
|
var scale = imageStyle.getScale();
|
||||||
|
|
||||||
|
var currentImage;
|
||||||
|
if (this.images_.length === 0) {
|
||||||
|
this.images_.push(image);
|
||||||
|
} else {
|
||||||
|
currentImage = this.images_[this.images_.length - 1];
|
||||||
|
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
||||||
|
this.groupIndices.push(this.indices.length);
|
||||||
this.images_.push(image);
|
this.images_.push(image);
|
||||||
} else {
|
|
||||||
currentImage = this.images_[this.images_.length - 1];
|
|
||||||
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
|
||||||
this.groupIndices.push(this.indices.length);
|
|
||||||
this.images_.push(image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.hitDetectionImages_.length === 0) {
|
if (this.hitDetectionImages_.length === 0) {
|
||||||
|
this.hitDetectionImages_.push(hitDetectionImage);
|
||||||
|
} else {
|
||||||
|
currentImage =
|
||||||
|
this.hitDetectionImages_[this.hitDetectionImages_.length - 1];
|
||||||
|
if (ol.getUid(currentImage) != ol.getUid(hitDetectionImage)) {
|
||||||
|
this.hitDetectionGroupIndices.push(this.indices.length);
|
||||||
this.hitDetectionImages_.push(hitDetectionImage);
|
this.hitDetectionImages_.push(hitDetectionImage);
|
||||||
} else {
|
|
||||||
currentImage =
|
|
||||||
this.hitDetectionImages_[this.hitDetectionImages_.length - 1];
|
|
||||||
if (ol.getUid(currentImage) != ol.getUid(hitDetectionImage)) {
|
|
||||||
this.hitDetectionGroupIndices.push(this.indices.length);
|
|
||||||
this.hitDetectionImages_.push(hitDetectionImage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.anchorX = anchor[0];
|
this.anchorX = anchor[0];
|
||||||
this.anchorY = anchor[1];
|
this.anchorY = anchor[1];
|
||||||
this.height = size[1];
|
this.height = size[1];
|
||||||
this.imageHeight = imageSize[1];
|
this.imageHeight = imageSize[1];
|
||||||
this.imageWidth = imageSize[0];
|
this.imageWidth = imageSize[0];
|
||||||
this.opacity = opacity;
|
this.opacity = opacity;
|
||||||
this.originX = origin[0];
|
this.originX = origin[0];
|
||||||
this.originY = origin[1];
|
this.originY = origin[1];
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
this.rotateWithView = rotateWithView;
|
this.rotateWithView = rotateWithView;
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
this.width = size[0];
|
this.width = size[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
|
ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
|
||||||
return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
|
return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
|
ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
|
||||||
return this.hitDetectionTextures_;
|
return this.hitDetectionTextures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,410 +8,406 @@ goog.require('ol.render.VectorContext');
|
|||||||
goog.require('ol.render.webgl.ReplayGroup');
|
goog.require('ol.render.webgl.ReplayGroup');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.render.VectorContext}
|
||||||
|
* @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.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate = function(context, center, resolution, rotation, size, extent, pixelRatio) {
|
||||||
|
ol.render.VectorContext.call(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
|
||||||
* @extends {ol.render.VectorContext}
|
|
||||||
* @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.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Immediate = function(context, center, resolution, rotation, size, extent, pixelRatio) {
|
|
||||||
ol.render.VectorContext.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.context_ = context;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.center_ = center;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.extent_ = extent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.pixelRatio_ = pixelRatio;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.size_ = size;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.rotation_ = rotation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.resolution_ = resolution;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.style.Image}
|
|
||||||
*/
|
|
||||||
this.imageStyle_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.style.Fill}
|
|
||||||
*/
|
|
||||||
this.fillStyle_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.style.Stroke}
|
|
||||||
*/
|
|
||||||
this.strokeStyle_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.style.Text}
|
|
||||||
*/
|
|
||||||
this.textStyle_ = null;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.Immediate, ol.render.VectorContext);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {number} end End.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
|
this.context_ = context;
|
||||||
flatCoordinates, offset, end, stride) {
|
|
||||||
var context = this.context_;
|
|
||||||
var replay = /** @type {ol.render.webgl.TextReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.TEXT));
|
|
||||||
replay.setTextStyle(this.textStyle_);
|
|
||||||
replay.drawText(flatCoordinates, offset, end, stride, null, null);
|
|
||||||
replay.finish(context);
|
|
||||||
// default colors
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the rendering style. Note that since this is an immediate rendering API,
|
* @private
|
||||||
* any `zIndex` on the provided style will be ignored.
|
|
||||||
*
|
|
||||||
* @param {ol.style.Style} style The rendering style.
|
|
||||||
* @override
|
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.setStyle = function(style) {
|
this.center_ = center;
|
||||||
this.setFillStrokeStyle(style.getFill(), style.getStroke());
|
|
||||||
this.setImageStyle(style.getImage());
|
|
||||||
this.setTextStyle(style.getText());
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a geometry into the canvas. Call
|
* @private
|
||||||
* {@link ol.render.webgl.Immediate#setStyle} first to set the rendering style.
|
|
||||||
*
|
|
||||||
* @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render.
|
|
||||||
* @override
|
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawGeometry = function(geometry) {
|
this.extent_ = extent;
|
||||||
var type = geometry.getType();
|
|
||||||
switch (type) {
|
|
||||||
case ol.geom.GeometryType.POINT:
|
|
||||||
this.drawPoint(/** @type {ol.geom.Point} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.LINE_STRING:
|
|
||||||
this.drawLineString(/** @type {ol.geom.LineString} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.POLYGON:
|
|
||||||
this.drawPolygon(/** @type {ol.geom.Polygon} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.MULTI_POINT:
|
|
||||||
this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.MULTI_LINE_STRING:
|
|
||||||
this.drawMultiLineString(/** @type {ol.geom.MultiLineString} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.MULTI_POLYGON:
|
|
||||||
this.drawMultiPolygon(/** @type {ol.geom.MultiPolygon} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.GEOMETRY_COLLECTION:
|
|
||||||
this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
case ol.geom.GeometryType.CIRCLE:
|
|
||||||
this.drawCircle(/** @type {ol.geom.Circle} */ (geometry), null);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) {
|
this.pixelRatio_ = pixelRatio;
|
||||||
var geometry = style.getGeometryFunction()(feature);
|
|
||||||
if (!geometry ||
|
|
||||||
!ol.extent.intersects(this.extent_, geometry.getExtent())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setStyle(style);
|
|
||||||
this.drawGeometry(geometry);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawGeometryCollection = function(geometry, data) {
|
this.size_ = size;
|
||||||
var geometries = geometry.getGeometriesArray();
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
|
||||||
this.drawGeometry(geometries[i]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawPoint = function(geometry, data) {
|
this.rotation_ = rotation;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.ImageReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
|
|
||||||
replay.setImageStyle(this.imageStyle_);
|
|
||||||
replay.drawPoint(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
// default colors
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
|
||||||
var flatCoordinates = geometry.getFlatCoordinates();
|
|
||||||
var stride = geometry.getStride();
|
|
||||||
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawMultiPoint = function(geometry, data) {
|
this.resolution_ = resolution;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.ImageReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
|
|
||||||
replay.setImageStyle(this.imageStyle_);
|
|
||||||
replay.drawMultiPoint(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
|
||||||
var flatCoordinates = geometry.getFlatCoordinates();
|
|
||||||
var stride = geometry.getStride();
|
|
||||||
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.style.Image}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawLineString = function(geometry, data) {
|
this.imageStyle_ = null;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
|
|
||||||
replay.setFillStrokeStyle(null, this.strokeStyle_);
|
|
||||||
replay.drawLineString(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
|
||||||
var flatMidpoint = geometry.getFlatMidpoint();
|
|
||||||
this.drawText_(replayGroup, flatMidpoint, 0, 2, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.style.Fill}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawMultiLineString = function(geometry, data) {
|
this.fillStyle_ = null;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
|
|
||||||
replay.setFillStrokeStyle(null, this.strokeStyle_);
|
|
||||||
replay.drawMultiLineString(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
|
||||||
var flatMidpoints = geometry.getFlatMidpoints();
|
|
||||||
this.drawText_(replayGroup, flatMidpoints, 0, flatMidpoints.length, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.style.Stroke}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawPolygon = function(geometry, data) {
|
this.strokeStyle_ = null;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
|
|
||||||
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
|
||||||
replay.drawPolygon(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
|
||||||
var flatInteriorPoint = geometry.getFlatInteriorPoint();
|
|
||||||
this.drawText_(replayGroup, flatInteriorPoint, 0, 2, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.style.Text}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Immediate.prototype.drawMultiPolygon = function(geometry, data) {
|
this.textStyle_ = null;
|
||||||
var context = this.context_;
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
|
||||||
var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
|
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
|
|
||||||
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
|
||||||
replay.drawMultiPolygon(geometry, data);
|
|
||||||
replay.finish(context);
|
|
||||||
var opacity = 1;
|
|
||||||
var skippedFeatures = {};
|
|
||||||
var featureCallback;
|
|
||||||
var oneByOne = false;
|
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
|
||||||
oneByOne);
|
|
||||||
replay.getDeleteResourcesFunction(context)();
|
|
||||||
|
|
||||||
if (this.textStyle_) {
|
};
|
||||||
var flatInteriorPoints = geometry.getFlatInteriorPoints();
|
ol.inherits(ol.render.webgl.Immediate, ol.render.VectorContext);
|
||||||
this.drawText_(replayGroup, flatInteriorPoints, 0, flatInteriorPoints.length, 2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
|
||||||
*/
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
ol.render.webgl.Immediate.prototype.drawCircle = function(geometry, data) {
|
* @param {number} offset Offset.
|
||||||
var context = this.context_;
|
* @param {number} end End.
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
* @param {number} stride Stride.
|
||||||
var replay = /** @type {ol.render.webgl.CircleReplay} */ (
|
* @private
|
||||||
replayGroup.getReplay(0, ol.render.ReplayType.CIRCLE));
|
*/
|
||||||
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
|
||||||
replay.drawCircle(geometry, data);
|
flatCoordinates, offset, end, stride) {
|
||||||
replay.finish(context);
|
var context = this.context_;
|
||||||
var opacity = 1;
|
var replay = /** @type {ol.render.webgl.TextReplay} */ (
|
||||||
var skippedFeatures = {};
|
replayGroup.getReplay(0, ol.render.ReplayType.TEXT));
|
||||||
var featureCallback;
|
replay.setTextStyle(this.textStyle_);
|
||||||
var oneByOne = false;
|
replay.drawText(flatCoordinates, offset, end, stride, null, null);
|
||||||
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
replay.finish(context);
|
||||||
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
// default colors
|
||||||
oneByOne);
|
var opacity = 1;
|
||||||
replay.getDeleteResourcesFunction(context)();
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
if (this.textStyle_) {
|
var oneByOne = false;
|
||||||
this.drawText_(replayGroup, geometry.getCenter(), 0, 2, 2);
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
}
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
};
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Set the rendering style. Note that since this is an immediate rendering API,
|
||||||
*/
|
* any `zIndex` on the provided style will be ignored.
|
||||||
ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
|
*
|
||||||
this.imageStyle_ = imageStyle;
|
* @param {ol.style.Style} style The rendering style.
|
||||||
};
|
* @override
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.setStyle = function(style) {
|
||||||
|
this.setFillStrokeStyle(style.getFill(), style.getStroke());
|
||||||
|
this.setImageStyle(style.getImage());
|
||||||
|
this.setTextStyle(style.getText());
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Render a geometry into the canvas. Call
|
||||||
*/
|
* {@link ol.render.webgl.Immediate#setStyle} first to set the rendering style.
|
||||||
ol.render.webgl.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
*
|
||||||
this.fillStyle_ = fillStyle;
|
* @param {ol.geom.Geometry|ol.render.Feature} geometry The geometry to render.
|
||||||
this.strokeStyle_ = strokeStyle;
|
* @override
|
||||||
};
|
* @api
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawGeometry = function(geometry) {
|
||||||
|
var type = geometry.getType();
|
||||||
|
switch (type) {
|
||||||
|
case ol.geom.GeometryType.POINT:
|
||||||
|
this.drawPoint(/** @type {ol.geom.Point} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.LINE_STRING:
|
||||||
|
this.drawLineString(/** @type {ol.geom.LineString} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.POLYGON:
|
||||||
|
this.drawPolygon(/** @type {ol.geom.Polygon} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.MULTI_POINT:
|
||||||
|
this.drawMultiPoint(/** @type {ol.geom.MultiPoint} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.MULTI_LINE_STRING:
|
||||||
|
this.drawMultiLineString(/** @type {ol.geom.MultiLineString} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.MULTI_POLYGON:
|
||||||
|
this.drawMultiPolygon(/** @type {ol.geom.MultiPolygon} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.GEOMETRY_COLLECTION:
|
||||||
|
this.drawGeometryCollection(/** @type {ol.geom.GeometryCollection} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
case ol.geom.GeometryType.CIRCLE:
|
||||||
|
this.drawCircle(/** @type {ol.geom.Circle} */ (geometry), null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// pass
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
* @api
|
||||||
ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
|
*/
|
||||||
this.textStyle_ = textStyle;
|
ol.render.webgl.Immediate.prototype.drawFeature = function(feature, style) {
|
||||||
};
|
var geometry = style.getGeometryFunction()(feature);
|
||||||
|
if (!geometry ||
|
||||||
|
!ol.extent.intersects(this.extent_, geometry.getExtent())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.setStyle(style);
|
||||||
|
this.drawGeometry(geometry);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawGeometryCollection = function(geometry, data) {
|
||||||
|
var geometries = geometry.getGeometriesArray();
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||||
|
this.drawGeometry(geometries[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawPoint = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.ImageReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
|
||||||
|
replay.setImageStyle(this.imageStyle_);
|
||||||
|
replay.drawPoint(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
// default colors
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatCoordinates = geometry.getFlatCoordinates();
|
||||||
|
var stride = geometry.getStride();
|
||||||
|
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawMultiPoint = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.ImageReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.IMAGE));
|
||||||
|
replay.setImageStyle(this.imageStyle_);
|
||||||
|
replay.drawMultiPoint(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatCoordinates = geometry.getFlatCoordinates();
|
||||||
|
var stride = geometry.getStride();
|
||||||
|
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawLineString = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
|
||||||
|
replay.setFillStrokeStyle(null, this.strokeStyle_);
|
||||||
|
replay.drawLineString(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatMidpoint = geometry.getFlatMidpoint();
|
||||||
|
this.drawText_(replayGroup, flatMidpoint, 0, 2, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawMultiLineString = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.LineStringReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.LINE_STRING));
|
||||||
|
replay.setFillStrokeStyle(null, this.strokeStyle_);
|
||||||
|
replay.drawMultiLineString(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatMidpoints = geometry.getFlatMidpoints();
|
||||||
|
this.drawText_(replayGroup, flatMidpoints, 0, flatMidpoints.length, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawPolygon = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
|
||||||
|
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
||||||
|
replay.drawPolygon(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatInteriorPoint = geometry.getFlatInteriorPoint();
|
||||||
|
this.drawText_(replayGroup, flatInteriorPoint, 0, 2, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawMultiPolygon = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.PolygonReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.POLYGON));
|
||||||
|
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
||||||
|
replay.drawMultiPolygon(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
var flatInteriorPoints = geometry.getFlatInteriorPoints();
|
||||||
|
this.drawText_(replayGroup, flatInteriorPoints, 0, flatInteriorPoints.length, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.drawCircle = function(geometry, data) {
|
||||||
|
var context = this.context_;
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(1, this.extent_);
|
||||||
|
var replay = /** @type {ol.render.webgl.CircleReplay} */ (
|
||||||
|
replayGroup.getReplay(0, ol.render.ReplayType.CIRCLE));
|
||||||
|
replay.setFillStrokeStyle(this.fillStyle_, this.strokeStyle_);
|
||||||
|
replay.drawCircle(geometry, data);
|
||||||
|
replay.finish(context);
|
||||||
|
var opacity = 1;
|
||||||
|
var skippedFeatures = {};
|
||||||
|
var featureCallback;
|
||||||
|
var oneByOne = false;
|
||||||
|
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
|
||||||
|
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
|
||||||
|
oneByOne);
|
||||||
|
replay.getDeleteResourcesFunction(context)();
|
||||||
|
|
||||||
|
if (this.textStyle_) {
|
||||||
|
this.drawText_(replayGroup, geometry.getCenter(), 0, 2, 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
|
||||||
|
this.imageStyle_ = imageStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
||||||
|
this.fillStyle_ = fillStyle;
|
||||||
|
this.strokeStyle_ = strokeStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
|
||||||
|
this.textStyle_ = textStyle;
|
||||||
|
};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -6,125 +6,121 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\n\n\n\nuniform vec4 u_color;\nuniform float u_opacity;\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.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;uniform vec4 e;uniform float f;void main(void){gl_FragColor=e;float alpha=e.a*f;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.fragment = new ol.render.webgl.polygonreplay.defaultshader.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex.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 gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\n}\n\n\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){gl_Position=b*vec4(a,0.0,1.0);}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.vertex = new ol.render.webgl.polygonreplay.defaultshader.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Locations = function(gl, program) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment = function() {
|
this.u_color = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_color' : 'e');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Fragment, ol.webgl.Fragment);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\n\n\n\nuniform vec4 u_color;\nuniform float u_opacity;\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';
|
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;uniform vec4 e;uniform float f;void main(void){gl_FragColor=e;float alpha=e.a*f;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
this.u_opacity = gl.getUniformLocation(
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.fragment = new ol.render.webgl.polygonreplay.defaultshader.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex = function() {
|
this.u_projectionMatrix = gl.getUniformLocation(
|
||||||
ol.webgl.Vertex.call(this, ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.polygonreplay.defaultshader.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex.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 gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0);\n}\n\n\n';
|
this.a_position = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_position' : 'a');
|
||||||
|
};
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'attribute vec2 a;uniform mat4 b;uniform mat4 c;uniform mat4 d;void main(void){gl_Position=b*vec4(a,0.0,1.0);}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex.DEBUG_SOURCE :
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.vertex = new ol.render.webgl.polygonreplay.defaultshader.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Locations = function(gl, program) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_color = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_color' : 'e');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'd');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'c');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_opacity = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_projectionMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_position = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'a');
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,358 +8,354 @@ goog.require('ol.vec.Mat4');
|
|||||||
goog.require('ol.webgl');
|
goog.require('ol.webgl');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
/**
|
* @abstract
|
||||||
* @constructor
|
* @extends {ol.render.VectorContext}
|
||||||
* @abstract
|
* @param {number} tolerance Tolerance.
|
||||||
* @extends {ol.render.VectorContext}
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
* @param {number} tolerance Tolerance.
|
* @struct
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
*/
|
||||||
* @struct
|
ol.render.webgl.Replay = function(tolerance, maxExtent) {
|
||||||
*/
|
ol.render.VectorContext.call(this);
|
||||||
ol.render.webgl.Replay = function(tolerance, maxExtent) {
|
|
||||||
ol.render.VectorContext.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.tolerance = tolerance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @const
|
|
||||||
* @type {ol.Extent}
|
|
||||||
*/
|
|
||||||
this.maxExtent = maxExtent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The origin of the coordinate system for the point coordinates sent to
|
|
||||||
* the GPU. To eliminate jitter caused by precision problems in the GPU
|
|
||||||
* we use the "Rendering Relative to Eye" technique described in the "3D
|
|
||||||
* Engine Design for Virtual Globes" book.
|
|
||||||
* @protected
|
|
||||||
* @type {ol.Coordinate}
|
|
||||||
*/
|
|
||||||
this.origin = ol.extent.getCenter(maxExtent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.projectionMatrix_ = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.offsetRotateMatrix_ = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.offsetScaleMatrix_ = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.tmpMat4_ = ol.vec.Mat4.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.indices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {?ol.webgl.Buffer}
|
|
||||||
*/
|
|
||||||
this.indicesBuffer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start index per feature (the index).
|
|
||||||
* @protected
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.startIndices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start index per feature (the feature).
|
|
||||||
* @protected
|
|
||||||
* @type {Array.<ol.Feature|ol.render.Feature>}
|
|
||||||
*/
|
|
||||||
this.startIndicesFeature = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.vertices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {?ol.webgl.Buffer}
|
|
||||||
*/
|
|
||||||
this.verticesBuffer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional parameter for PolygonReplay instances.
|
|
||||||
* @protected
|
|
||||||
* @type {ol.render.webgl.LineStringReplay|undefined}
|
|
||||||
*/
|
|
||||||
this.lineStringReplay = undefined;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.Replay, ol.render.VectorContext);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @param {ol.webgl.Context} context WebGL context.
|
|
||||||
* @return {function()} Delete resources function.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.getDeleteResourcesFunction = function(context) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.finish = function(context) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {ol.Size} size Size.
|
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @return {ol.render.webgl.circlereplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.texturereplay.defaultshader.Locations} Locations.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.render.webgl.circlereplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
|
||||||
ol.render.webgl.texturereplay.defaultshader.Locations} locations Locations.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.shutDownProgram = function(gl, locations) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {boolean} hitDetection Hit detection mode.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @abstract
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
|
||||||
* this extent are checked.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
* @type {number}
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
|
||||||
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
|
||||||
* this extent are checked.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Replay.prototype.drawHitDetectionReplay = function(gl, context, skippedFeaturesHash,
|
this.tolerance = tolerance;
|
||||||
featureCallback, oneByOne, opt_hitExtent) {
|
|
||||||
if (!oneByOne) {
|
|
||||||
// draw all hit-detection features in "once" (by texture group)
|
|
||||||
return this.drawHitDetectionReplayAll(gl, context,
|
|
||||||
skippedFeaturesHash, featureCallback);
|
|
||||||
} else {
|
|
||||||
// draw hit-detection features one by one
|
|
||||||
return this.drawHitDetectionReplayOneByOne(gl, context,
|
|
||||||
skippedFeaturesHash, featureCallback, opt_hitExtent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
* @const
|
||||||
* @param {ol.webgl.Context} context Context.
|
* @type {ol.Extent}
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Replay.prototype.drawHitDetectionReplayAll = function(gl, context, skippedFeaturesHash,
|
this.maxExtent = maxExtent;
|
||||||
featureCallback) {
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
||||||
this.drawReplay(gl, context, skippedFeaturesHash, true);
|
|
||||||
|
|
||||||
var result = featureCallback(null);
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.webgl.Context} context Context.
|
* The origin of the coordinate system for the point coordinates sent to
|
||||||
* @param {ol.Coordinate} center Center.
|
* the GPU. To eliminate jitter caused by precision problems in the GPU
|
||||||
* @param {number} resolution Resolution.
|
* we use the "Rendering Relative to Eye" technique described in the "3D
|
||||||
* @param {number} rotation Rotation.
|
* Engine Design for Virtual Globes" book.
|
||||||
* @param {ol.Size} size Size.
|
* @protected
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
* @type {ol.Coordinate}
|
||||||
* @param {number} opacity Global opacity.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
|
||||||
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
|
||||||
* this extent are checked.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.Replay.prototype.replay = function(context,
|
this.origin = ol.extent.getCenter(maxExtent);
|
||||||
center, resolution, rotation, size, pixelRatio,
|
|
||||||
opacity, skippedFeaturesHash,
|
|
||||||
featureCallback, oneByOne, opt_hitExtent) {
|
|
||||||
var gl = context.getGL();
|
|
||||||
var tmpStencil, tmpStencilFunc, tmpStencilMaskVal, tmpStencilRef, tmpStencilMask,
|
|
||||||
tmpStencilOpFail, tmpStencilOpPass, tmpStencilOpZFail;
|
|
||||||
|
|
||||||
if (this.lineStringReplay) {
|
/**
|
||||||
tmpStencil = gl.isEnabled(gl.STENCIL_TEST);
|
* @private
|
||||||
tmpStencilFunc = gl.getParameter(gl.STENCIL_FUNC);
|
* @type {ol.Transform}
|
||||||
tmpStencilMaskVal = gl.getParameter(gl.STENCIL_VALUE_MASK);
|
*/
|
||||||
tmpStencilRef = gl.getParameter(gl.STENCIL_REF);
|
this.projectionMatrix_ = ol.transform.create();
|
||||||
tmpStencilMask = gl.getParameter(gl.STENCIL_WRITEMASK);
|
|
||||||
tmpStencilOpFail = gl.getParameter(gl.STENCIL_FAIL);
|
|
||||||
tmpStencilOpPass = gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS);
|
|
||||||
tmpStencilOpZFail = gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL);
|
|
||||||
|
|
||||||
gl.enable(gl.STENCIL_TEST);
|
/**
|
||||||
gl.clear(gl.STENCIL_BUFFER_BIT);
|
* @private
|
||||||
gl.stencilMask(255);
|
* @type {ol.Transform}
|
||||||
gl.stencilFunc(gl.ALWAYS, 1, 255);
|
*/
|
||||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
|
this.offsetRotateMatrix_ = ol.transform.create();
|
||||||
|
|
||||||
this.lineStringReplay.replay(context,
|
/**
|
||||||
center, resolution, rotation, size, pixelRatio,
|
* @private
|
||||||
opacity, skippedFeaturesHash,
|
* @type {ol.Transform}
|
||||||
featureCallback, oneByOne, opt_hitExtent);
|
*/
|
||||||
|
this.offsetScaleMatrix_ = ol.transform.create();
|
||||||
|
|
||||||
gl.stencilMask(0);
|
/**
|
||||||
gl.stencilFunc(gl.NOTEQUAL, 1, 255);
|
* @private
|
||||||
}
|
* @type {Array.<number>}
|
||||||
|
*/
|
||||||
|
this.tmpMat4_ = ol.vec.Mat4.create();
|
||||||
|
|
||||||
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.verticesBuffer);
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {Array.<number>}
|
||||||
|
*/
|
||||||
|
this.indices = [];
|
||||||
|
|
||||||
context.bindBuffer(ol.webgl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {?ol.webgl.Buffer}
|
||||||
|
*/
|
||||||
|
this.indicesBuffer = null;
|
||||||
|
|
||||||
var locations = this.setUpProgram(gl, context, size, pixelRatio);
|
/**
|
||||||
|
* Start index per feature (the index).
|
||||||
|
* @protected
|
||||||
|
* @type {Array.<number>}
|
||||||
|
*/
|
||||||
|
this.startIndices = [];
|
||||||
|
|
||||||
// set the "uniform" values
|
/**
|
||||||
var projectionMatrix = ol.transform.reset(this.projectionMatrix_);
|
* Start index per feature (the feature).
|
||||||
ol.transform.scale(projectionMatrix, 2 / (resolution * size[0]), 2 / (resolution * size[1]));
|
* @protected
|
||||||
ol.transform.rotate(projectionMatrix, -rotation);
|
* @type {Array.<ol.Feature|ol.render.Feature>}
|
||||||
ol.transform.translate(projectionMatrix, -(center[0] - this.origin[0]), -(center[1] - this.origin[1]));
|
*/
|
||||||
|
this.startIndicesFeature = [];
|
||||||
|
|
||||||
var offsetScaleMatrix = ol.transform.reset(this.offsetScaleMatrix_);
|
/**
|
||||||
ol.transform.scale(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
|
* @protected
|
||||||
|
* @type {Array.<number>}
|
||||||
|
*/
|
||||||
|
this.vertices = [];
|
||||||
|
|
||||||
var offsetRotateMatrix = ol.transform.reset(this.offsetRotateMatrix_);
|
/**
|
||||||
if (rotation !== 0) {
|
* @protected
|
||||||
ol.transform.rotate(offsetRotateMatrix, -rotation);
|
* @type {?ol.webgl.Buffer}
|
||||||
}
|
*/
|
||||||
|
this.verticesBuffer = null;
|
||||||
|
|
||||||
gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
|
/**
|
||||||
ol.vec.Mat4.fromTransform(this.tmpMat4_, projectionMatrix));
|
* Optional parameter for PolygonReplay instances.
|
||||||
gl.uniformMatrix4fv(locations.u_offsetScaleMatrix, false,
|
* @protected
|
||||||
ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetScaleMatrix));
|
* @type {ol.render.webgl.LineStringReplay|undefined}
|
||||||
gl.uniformMatrix4fv(locations.u_offsetRotateMatrix, false,
|
*/
|
||||||
ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetRotateMatrix));
|
this.lineStringReplay = undefined;
|
||||||
gl.uniform1f(locations.u_opacity, opacity);
|
|
||||||
|
|
||||||
// draw!
|
};
|
||||||
var result;
|
ol.inherits(ol.render.webgl.Replay, ol.render.VectorContext);
|
||||||
if (featureCallback === undefined) {
|
|
||||||
this.drawReplay(gl, context, skippedFeaturesHash, false);
|
|
||||||
} else {
|
|
||||||
// draw feature by feature for the hit-detection
|
|
||||||
result = this.drawHitDetectionReplay(gl, context, skippedFeaturesHash,
|
|
||||||
featureCallback, oneByOne, opt_hitExtent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// disable the vertex attrib arrays
|
|
||||||
this.shutDownProgram(gl, locations);
|
|
||||||
|
|
||||||
if (this.lineStringReplay) {
|
/**
|
||||||
if (!tmpStencil) {
|
* @abstract
|
||||||
gl.disable(gl.STENCIL_TEST);
|
* @param {ol.webgl.Context} context WebGL context.
|
||||||
}
|
* @return {function()} Delete resources function.
|
||||||
gl.clear(gl.STENCIL_BUFFER_BIT);
|
*/
|
||||||
gl.stencilFunc(/** @type {number} */ (tmpStencilFunc),
|
ol.render.webgl.Replay.prototype.getDeleteResourcesFunction = function(context) {};
|
||||||
/** @type {number} */ (tmpStencilRef), /** @type {number} */ (tmpStencilMaskVal));
|
|
||||||
gl.stencilMask(/** @type {number} */ (tmpStencilMask));
|
|
||||||
gl.stencilOp(/** @type {number} */ (tmpStencilOpFail),
|
|
||||||
/** @type {number} */ (tmpStencilOpZFail), /** @type {number} */ (tmpStencilOpPass));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.finish = function(context) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {ol.Size} size Size.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @return {ol.render.webgl.circlereplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Locations} Locations.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.render.webgl.circlereplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Locations} locations Locations.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.shutDownProgram = function(gl, locations) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {boolean} hitDetection Hit detection mode.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
|
* this extent are checked.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash, featureCallback, opt_hitExtent) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
|
* this extent are checked.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.drawHitDetectionReplay = function(gl, context, skippedFeaturesHash,
|
||||||
|
featureCallback, oneByOne, opt_hitExtent) {
|
||||||
|
if (!oneByOne) {
|
||||||
|
// draw all hit-detection features in "once" (by texture group)
|
||||||
|
return this.drawHitDetectionReplayAll(gl, context,
|
||||||
|
skippedFeaturesHash, featureCallback);
|
||||||
|
} else {
|
||||||
|
// draw hit-detection features one by one
|
||||||
|
return this.drawHitDetectionReplayOneByOne(gl, context,
|
||||||
|
skippedFeaturesHash, featureCallback, opt_hitExtent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.drawHitDetectionReplayAll = function(gl, context, skippedFeaturesHash,
|
||||||
|
featureCallback) {
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
this.drawReplay(gl, context, skippedFeaturesHash, true);
|
||||||
|
|
||||||
|
var result = featureCallback(null);
|
||||||
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
};
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {number} start Start index.
|
|
||||||
* @param {number} end End index.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.Replay.prototype.drawElements = function(
|
|
||||||
gl, context, start, end) {
|
|
||||||
var elementType = context.hasOESElementIndexUint ?
|
|
||||||
ol.webgl.UNSIGNED_INT : ol.webgl.UNSIGNED_SHORT;
|
|
||||||
var elementSize = context.hasOESElementIndexUint ? 4 : 2;
|
|
||||||
|
|
||||||
var numItems = end - start;
|
/**
|
||||||
var offsetInBytes = start * elementSize;
|
* @param {ol.webgl.Context} context Context.
|
||||||
gl.drawElements(ol.webgl.TRIANGLES, numItems, elementType, offsetInBytes);
|
* @param {ol.Coordinate} center Center.
|
||||||
};
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} rotation Rotation.
|
||||||
|
* @param {ol.Size} size Size.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {number} opacity Global opacity.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
|
* this extent are checked.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.replay = function(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, skippedFeaturesHash,
|
||||||
|
featureCallback, oneByOne, opt_hitExtent) {
|
||||||
|
var gl = context.getGL();
|
||||||
|
var tmpStencil, tmpStencilFunc, tmpStencilMaskVal, tmpStencilRef, tmpStencilMask,
|
||||||
|
tmpStencilOpFail, tmpStencilOpPass, tmpStencilOpZFail;
|
||||||
|
|
||||||
}
|
if (this.lineStringReplay) {
|
||||||
|
tmpStencil = gl.isEnabled(gl.STENCIL_TEST);
|
||||||
|
tmpStencilFunc = gl.getParameter(gl.STENCIL_FUNC);
|
||||||
|
tmpStencilMaskVal = gl.getParameter(gl.STENCIL_VALUE_MASK);
|
||||||
|
tmpStencilRef = gl.getParameter(gl.STENCIL_REF);
|
||||||
|
tmpStencilMask = gl.getParameter(gl.STENCIL_WRITEMASK);
|
||||||
|
tmpStencilOpFail = gl.getParameter(gl.STENCIL_FAIL);
|
||||||
|
tmpStencilOpPass = gl.getParameter(gl.STENCIL_PASS_DEPTH_PASS);
|
||||||
|
tmpStencilOpZFail = gl.getParameter(gl.STENCIL_PASS_DEPTH_FAIL);
|
||||||
|
|
||||||
|
gl.enable(gl.STENCIL_TEST);
|
||||||
|
gl.clear(gl.STENCIL_BUFFER_BIT);
|
||||||
|
gl.stencilMask(255);
|
||||||
|
gl.stencilFunc(gl.ALWAYS, 1, 255);
|
||||||
|
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
|
||||||
|
|
||||||
|
this.lineStringReplay.replay(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, skippedFeaturesHash,
|
||||||
|
featureCallback, oneByOne, opt_hitExtent);
|
||||||
|
|
||||||
|
gl.stencilMask(0);
|
||||||
|
gl.stencilFunc(gl.NOTEQUAL, 1, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.verticesBuffer);
|
||||||
|
|
||||||
|
context.bindBuffer(ol.webgl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer);
|
||||||
|
|
||||||
|
var locations = this.setUpProgram(gl, context, size, pixelRatio);
|
||||||
|
|
||||||
|
// set the "uniform" values
|
||||||
|
var projectionMatrix = ol.transform.reset(this.projectionMatrix_);
|
||||||
|
ol.transform.scale(projectionMatrix, 2 / (resolution * size[0]), 2 / (resolution * size[1]));
|
||||||
|
ol.transform.rotate(projectionMatrix, -rotation);
|
||||||
|
ol.transform.translate(projectionMatrix, -(center[0] - this.origin[0]), -(center[1] - this.origin[1]));
|
||||||
|
|
||||||
|
var offsetScaleMatrix = ol.transform.reset(this.offsetScaleMatrix_);
|
||||||
|
ol.transform.scale(offsetScaleMatrix, 2 / size[0], 2 / size[1]);
|
||||||
|
|
||||||
|
var offsetRotateMatrix = ol.transform.reset(this.offsetRotateMatrix_);
|
||||||
|
if (rotation !== 0) {
|
||||||
|
ol.transform.rotate(offsetRotateMatrix, -rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
|
||||||
|
ol.vec.Mat4.fromTransform(this.tmpMat4_, projectionMatrix));
|
||||||
|
gl.uniformMatrix4fv(locations.u_offsetScaleMatrix, false,
|
||||||
|
ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetScaleMatrix));
|
||||||
|
gl.uniformMatrix4fv(locations.u_offsetRotateMatrix, false,
|
||||||
|
ol.vec.Mat4.fromTransform(this.tmpMat4_, offsetRotateMatrix));
|
||||||
|
gl.uniform1f(locations.u_opacity, opacity);
|
||||||
|
|
||||||
|
// draw!
|
||||||
|
var result;
|
||||||
|
if (featureCallback === undefined) {
|
||||||
|
this.drawReplay(gl, context, skippedFeaturesHash, false);
|
||||||
|
} else {
|
||||||
|
// draw feature by feature for the hit-detection
|
||||||
|
result = this.drawHitDetectionReplay(gl, context, skippedFeaturesHash,
|
||||||
|
featureCallback, oneByOne, opt_hitExtent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// disable the vertex attrib arrays
|
||||||
|
this.shutDownProgram(gl, locations);
|
||||||
|
|
||||||
|
if (this.lineStringReplay) {
|
||||||
|
if (!tmpStencil) {
|
||||||
|
gl.disable(gl.STENCIL_TEST);
|
||||||
|
}
|
||||||
|
gl.clear(gl.STENCIL_BUFFER_BIT);
|
||||||
|
gl.stencilFunc(/** @type {number} */ (tmpStencilFunc),
|
||||||
|
/** @type {number} */ (tmpStencilRef), /** @type {number} */ (tmpStencilMaskVal));
|
||||||
|
gl.stencilMask(/** @type {number} */ (tmpStencilMask));
|
||||||
|
gl.stencilOp(/** @type {number} */ (tmpStencilOpFail),
|
||||||
|
/** @type {number} */ (tmpStencilOpZFail), /** @type {number} */ (tmpStencilOpPass));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {number} start Start index.
|
||||||
|
* @param {number} end End index.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.Replay.prototype.drawElements = function(
|
||||||
|
gl, context, start, end) {
|
||||||
|
var elementType = context.hasOESElementIndexUint ?
|
||||||
|
ol.webgl.UNSIGNED_INT : ol.webgl.UNSIGNED_SHORT;
|
||||||
|
var elementSize = context.hasOESElementIndexUint ? 4 : 2;
|
||||||
|
|
||||||
|
var numItems = end - start;
|
||||||
|
var offsetInBytes = start * elementSize;
|
||||||
|
gl.drawElements(ol.webgl.TRIANGLES, numItems, elementType, offsetInBytes);
|
||||||
|
};
|
||||||
|
|||||||
@@ -13,313 +13,309 @@ goog.require('ol.render.webgl.PolygonReplay');
|
|||||||
goog.require('ol.render.webgl.TextReplay');
|
goog.require('ol.render.webgl.TextReplay');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.render.ReplayGroup}
|
||||||
|
* @param {number} tolerance Tolerance.
|
||||||
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
|
* @param {number=} opt_renderBuffer Render buffer.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup = function(tolerance, maxExtent, opt_renderBuffer) {
|
||||||
|
ol.render.ReplayGroup.call(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {ol.Extent}
|
||||||
* @extends {ol.render.ReplayGroup}
|
* @private
|
||||||
* @param {number} tolerance Tolerance.
|
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
|
||||||
* @param {number=} opt_renderBuffer Render buffer.
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ReplayGroup = function(tolerance, maxExtent, opt_renderBuffer) {
|
this.maxExtent_ = maxExtent;
|
||||||
ol.render.ReplayGroup.call(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {ol.Extent}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.maxExtent_ = maxExtent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.tolerance_ = tolerance;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.renderBuffer_ = opt_renderBuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {!Object.<string,
|
|
||||||
* Object.<ol.render.ReplayType, ol.render.webgl.Replay>>}
|
|
||||||
*/
|
|
||||||
this.replaysByZIndex_ = {};
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.ReplayGroup, ol.render.ReplayGroup);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.webgl.Context} context WebGL context.
|
* @type {number}
|
||||||
* @return {function()} Delete resources function.
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ReplayGroup.prototype.getDeleteResourcesFunction = function(context) {
|
this.tolerance_ = tolerance;
|
||||||
var functions = [];
|
|
||||||
var zKey;
|
|
||||||
for (zKey in this.replaysByZIndex_) {
|
|
||||||
var replays = this.replaysByZIndex_[zKey];
|
|
||||||
var replayKey;
|
|
||||||
for (replayKey in replays) {
|
|
||||||
functions.push(
|
|
||||||
replays[replayKey].getDeleteResourcesFunction(context));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return function() {
|
|
||||||
var length = functions.length;
|
|
||||||
var result;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
result = functions[i].apply(this, arguments);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.webgl.Context} context Context.
|
* @type {number|undefined}
|
||||||
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ReplayGroup.prototype.finish = function(context) {
|
this.renderBuffer_ = opt_renderBuffer;
|
||||||
var zKey;
|
|
||||||
for (zKey in this.replaysByZIndex_) {
|
|
||||||
var replays = this.replaysByZIndex_[zKey];
|
|
||||||
var replayKey;
|
|
||||||
for (replayKey in replays) {
|
|
||||||
replays[replayKey].finish(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.prototype.getReplay = function(zIndex, replayType) {
|
|
||||||
var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';
|
|
||||||
var replays = this.replaysByZIndex_[zIndexKey];
|
|
||||||
if (replays === undefined) {
|
|
||||||
replays = {};
|
|
||||||
this.replaysByZIndex_[zIndexKey] = replays;
|
|
||||||
}
|
|
||||||
var replay = replays[replayType];
|
|
||||||
if (replay === undefined) {
|
|
||||||
/**
|
|
||||||
* @type {Function}
|
|
||||||
*/
|
|
||||||
var Constructor = ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
|
|
||||||
replay = new Constructor(this.tolerance_, this.maxExtent_);
|
|
||||||
replays[replayType] = replay;
|
|
||||||
}
|
|
||||||
return replay;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.prototype.isEmpty = function() {
|
|
||||||
return ol.obj.isEmpty(this.replaysByZIndex_);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {number} opacity Global opacity.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.prototype.replay = function(context,
|
|
||||||
center, resolution, rotation, size, pixelRatio,
|
|
||||||
opacity, skippedFeaturesHash) {
|
|
||||||
/** @type {Array.<number>} */
|
|
||||||
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
|
||||||
zs.sort(ol.array.numberSafeCompareFunction);
|
|
||||||
|
|
||||||
var i, ii, j, jj, replays, replay;
|
|
||||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
|
||||||
replays = this.replaysByZIndex_[zs[i].toString()];
|
|
||||||
for (j = 0, jj = ol.render.replay.ORDER.length; j < jj; ++j) {
|
|
||||||
replay = replays[ol.render.replay.ORDER[j]];
|
|
||||||
if (replay !== undefined) {
|
|
||||||
replay.replay(context,
|
|
||||||
center, resolution, rotation, size, pixelRatio,
|
|
||||||
opacity, skippedFeaturesHash,
|
|
||||||
undefined, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {ol.webgl.Context} context Context.
|
* @type {!Object.<string,
|
||||||
* @param {ol.Coordinate} center Center.
|
* Object.<ol.render.ReplayType, ol.render.webgl.Replay>>}
|
||||||
* @param {number} resolution Resolution.
|
|
||||||
* @param {number} rotation Rotation.
|
|
||||||
* @param {ol.Size} size Size.
|
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {number} opacity Global opacity.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
|
||||||
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
|
||||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
|
||||||
* this extent are checked.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template T
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
|
this.replaysByZIndex_ = {};
|
||||||
center, resolution, rotation, size, pixelRatio, opacity,
|
|
||||||
skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent) {
|
|
||||||
/** @type {Array.<number>} */
|
|
||||||
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
|
||||||
zs.sort(function(a, b) {
|
|
||||||
return b - a;
|
|
||||||
});
|
|
||||||
|
|
||||||
var i, ii, j, replays, replay, result;
|
};
|
||||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
ol.inherits(ol.render.webgl.ReplayGroup, ol.render.ReplayGroup);
|
||||||
replays = this.replaysByZIndex_[zs[i].toString()];
|
|
||||||
for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
|
|
||||||
replay = replays[ol.render.replay.ORDER[j]];
|
/**
|
||||||
if (replay !== undefined) {
|
* @param {ol.webgl.Context} context WebGL context.
|
||||||
result = replay.replay(context,
|
* @return {function()} Delete resources function.
|
||||||
center, resolution, rotation, size, pixelRatio, opacity,
|
*/
|
||||||
skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent);
|
ol.render.webgl.ReplayGroup.prototype.getDeleteResourcesFunction = function(context) {
|
||||||
|
var functions = [];
|
||||||
|
var zKey;
|
||||||
|
for (zKey in this.replaysByZIndex_) {
|
||||||
|
var replays = this.replaysByZIndex_[zKey];
|
||||||
|
var replayKey;
|
||||||
|
for (replayKey in replays) {
|
||||||
|
functions.push(
|
||||||
|
replays[replayKey].getDeleteResourcesFunction(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return function() {
|
||||||
|
var length = functions.length;
|
||||||
|
var result;
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
result = functions[i].apply(this, arguments);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.finish = function(context) {
|
||||||
|
var zKey;
|
||||||
|
for (zKey in this.replaysByZIndex_) {
|
||||||
|
var replays = this.replaysByZIndex_[zKey];
|
||||||
|
var replayKey;
|
||||||
|
for (replayKey in replays) {
|
||||||
|
replays[replayKey].finish(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.getReplay = function(zIndex, replayType) {
|
||||||
|
var zIndexKey = zIndex !== undefined ? zIndex.toString() : '0';
|
||||||
|
var replays = this.replaysByZIndex_[zIndexKey];
|
||||||
|
if (replays === undefined) {
|
||||||
|
replays = {};
|
||||||
|
this.replaysByZIndex_[zIndexKey] = replays;
|
||||||
|
}
|
||||||
|
var replay = replays[replayType];
|
||||||
|
if (replay === undefined) {
|
||||||
|
/**
|
||||||
|
* @type {Function}
|
||||||
|
*/
|
||||||
|
var Constructor = ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_[replayType];
|
||||||
|
replay = new Constructor(this.tolerance_, this.maxExtent_);
|
||||||
|
replays[replayType] = replay;
|
||||||
|
}
|
||||||
|
return replay;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.isEmpty = function() {
|
||||||
|
return ol.obj.isEmpty(this.replaysByZIndex_);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {number} opacity Global opacity.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.replay = function(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, skippedFeaturesHash) {
|
||||||
|
/** @type {Array.<number>} */
|
||||||
|
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
||||||
|
zs.sort(ol.array.numberSafeCompareFunction);
|
||||||
|
|
||||||
|
var i, ii, j, jj, replays, replay;
|
||||||
|
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||||
|
replays = this.replaysByZIndex_[zs[i].toString()];
|
||||||
|
for (j = 0, jj = ol.render.replay.ORDER.length; j < jj; ++j) {
|
||||||
|
replay = replays[ol.render.replay.ORDER[j]];
|
||||||
|
if (replay !== undefined) {
|
||||||
|
replay.replay(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, skippedFeaturesHash,
|
||||||
|
undefined, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @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 {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {number} opacity Global opacity.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||||
|
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||||
|
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||||
|
* this extent are checked.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.replayHitDetection_ = function(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio, opacity,
|
||||||
|
skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent) {
|
||||||
|
/** @type {Array.<number>} */
|
||||||
|
var zs = Object.keys(this.replaysByZIndex_).map(Number);
|
||||||
|
zs.sort(function(a, b) {
|
||||||
|
return b - a;
|
||||||
|
});
|
||||||
|
|
||||||
|
var i, ii, j, replays, replay, result;
|
||||||
|
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||||
|
replays = this.replaysByZIndex_[zs[i].toString()];
|
||||||
|
for (j = ol.render.replay.ORDER.length - 1; j >= 0; --j) {
|
||||||
|
replay = replays[ol.render.replay.ORDER[j]];
|
||||||
|
if (replay !== undefined) {
|
||||||
|
result = replay.replay(context,
|
||||||
|
center, resolution, rotation, size, pixelRatio, opacity,
|
||||||
|
skippedFeaturesHash, featureCallback, oneByOne, opt_hitExtent);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
|
* @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 {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {number} opacity Global opacity.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} callback Feature callback.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
|
ol.render.webgl.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
|
||||||
|
coordinate, context, center, resolution, rotation, size, pixelRatio,
|
||||||
|
opacity, skippedFeaturesHash,
|
||||||
|
callback) {
|
||||||
|
var gl = context.getGL();
|
||||||
|
gl.bindFramebuffer(
|
||||||
|
gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {ol.Extent}
|
||||||
|
*/
|
||||||
|
var hitExtent;
|
||||||
|
if (this.renderBuffer_ !== undefined) {
|
||||||
|
// build an extent around the coordinate, so that only features that
|
||||||
|
// intersect this extent are checked
|
||||||
|
hitExtent = ol.extent.buffer(
|
||||||
|
ol.extent.createOrUpdateFromCoordinate(coordinate),
|
||||||
|
resolution * this.renderBuffer_);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.replayHitDetection_(context,
|
||||||
|
coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
|
||||||
|
pixelRatio, opacity, skippedFeaturesHash,
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
|
* @return {?} Callback result.
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
var imageData = new Uint8Array(4);
|
||||||
|
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
||||||
|
|
||||||
|
if (imageData[3] > 0) {
|
||||||
|
var result = callback(feature);
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, true, hitExtent);
|
||||||
}
|
};
|
||||||
return undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.Coordinate} coordinate Coordinate.
|
* @param {ol.Coordinate} coordinate Coordinate.
|
||||||
* @param {ol.webgl.Context} context Context.
|
* @param {ol.webgl.Context} context Context.
|
||||||
* @param {ol.Coordinate} center Center.
|
* @param {ol.Coordinate} center Center.
|
||||||
* @param {number} resolution Resolution.
|
* @param {number} resolution Resolution.
|
||||||
* @param {number} rotation Rotation.
|
* @param {number} rotation Rotation.
|
||||||
* @param {ol.Size} size Size.
|
* @param {ol.Size} size Size.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {number} opacity Global opacity.
|
* @param {number} opacity Global opacity.
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
* to skip.
|
* to skip.
|
||||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} callback Feature callback.
|
* @return {boolean} Is there a feature at the given coordinate?
|
||||||
* @return {T|undefined} Callback result.
|
*/
|
||||||
* @template T
|
ol.render.webgl.ReplayGroup.prototype.hasFeatureAtCoordinate = function(
|
||||||
*/
|
coordinate, context, center, resolution, rotation, size, pixelRatio,
|
||||||
ol.render.webgl.ReplayGroup.prototype.forEachFeatureAtCoordinate = function(
|
opacity, skippedFeaturesHash) {
|
||||||
coordinate, context, center, resolution, rotation, size, pixelRatio,
|
var gl = context.getGL();
|
||||||
opacity, skippedFeaturesHash,
|
gl.bindFramebuffer(
|
||||||
callback) {
|
gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
|
||||||
var gl = context.getGL();
|
|
||||||
gl.bindFramebuffer(
|
|
||||||
gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
|
|
||||||
|
|
||||||
|
var hasFeature = this.replayHitDetection_(context,
|
||||||
|
coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
|
||||||
|
pixelRatio, opacity, skippedFeaturesHash,
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
|
* @return {boolean} Is there a feature?
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
var imageData = new Uint8Array(4);
|
||||||
|
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
||||||
|
return imageData[3] > 0;
|
||||||
|
}, false);
|
||||||
|
|
||||||
/**
|
return hasFeature !== undefined;
|
||||||
* @type {ol.Extent}
|
};
|
||||||
*/
|
|
||||||
var hitExtent;
|
|
||||||
if (this.renderBuffer_ !== undefined) {
|
|
||||||
// build an extent around the coordinate, so that only features that
|
|
||||||
// intersect this extent are checked
|
|
||||||
hitExtent = ol.extent.buffer(
|
|
||||||
ol.extent.createOrUpdateFromCoordinate(coordinate),
|
|
||||||
resolution * this.renderBuffer_);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.replayHitDetection_(context,
|
/**
|
||||||
coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
|
* @const
|
||||||
pixelRatio, opacity, skippedFeaturesHash,
|
* @private
|
||||||
/**
|
* @type {Array.<number>}
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
*/
|
||||||
* @return {?} Callback result.
|
ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_ = [1, 1];
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
var imageData = new Uint8Array(4);
|
|
||||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
|
||||||
|
|
||||||
if (imageData[3] > 0) {
|
/**
|
||||||
var result = callback(feature);
|
* @const
|
||||||
if (result) {
|
* @private
|
||||||
return result;
|
* @type {Object.<ol.render.ReplayType,
|
||||||
}
|
* function(new: ol.render.webgl.Replay, number,
|
||||||
}
|
* ol.Extent)>}
|
||||||
}, true, hitExtent);
|
*/
|
||||||
};
|
ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_ = {
|
||||||
|
'Circle': ol.render.webgl.CircleReplay,
|
||||||
|
'Image': ol.render.webgl.ImageReplay,
|
||||||
/**
|
'LineString': ol.render.webgl.LineStringReplay,
|
||||||
* @param {ol.Coordinate} coordinate Coordinate.
|
'Polygon': ol.render.webgl.PolygonReplay,
|
||||||
* @param {ol.webgl.Context} context Context.
|
'Text': ol.render.webgl.TextReplay
|
||||||
* @param {ol.Coordinate} center Center.
|
};
|
||||||
* @param {number} resolution Resolution.
|
|
||||||
* @param {number} rotation Rotation.
|
|
||||||
* @param {ol.Size} size Size.
|
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {number} opacity Global opacity.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @return {boolean} Is there a feature at the given coordinate?
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.prototype.hasFeatureAtCoordinate = function(
|
|
||||||
coordinate, context, center, resolution, rotation, size, pixelRatio,
|
|
||||||
opacity, skippedFeaturesHash) {
|
|
||||||
var gl = context.getGL();
|
|
||||||
gl.bindFramebuffer(
|
|
||||||
gl.FRAMEBUFFER, context.getHitDetectionFramebuffer());
|
|
||||||
|
|
||||||
var hasFeature = this.replayHitDetection_(context,
|
|
||||||
coordinate, resolution, rotation, ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_,
|
|
||||||
pixelRatio, opacity, skippedFeaturesHash,
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
|
||||||
* @return {boolean} Is there a feature?
|
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
var imageData = new Uint8Array(4);
|
|
||||||
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
|
||||||
return imageData[3] > 0;
|
|
||||||
}, false);
|
|
||||||
|
|
||||||
return hasFeature !== undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @private
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_ = [1, 1];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @private
|
|
||||||
* @type {Object.<ol.render.ReplayType,
|
|
||||||
* function(new: ol.render.webgl.Replay, number,
|
|
||||||
* ol.Extent)>}
|
|
||||||
*/
|
|
||||||
ol.render.webgl.ReplayGroup.BATCH_CONSTRUCTORS_ = {
|
|
||||||
'Circle': ol.render.webgl.CircleReplay,
|
|
||||||
'Image': ol.render.webgl.ImageReplay,
|
|
||||||
'LineString': ol.render.webgl.LineStringReplay,
|
|
||||||
'Polygon': ol.render.webgl.PolygonReplay,
|
|
||||||
'Text': ol.render.webgl.TextReplay
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,446 +10,442 @@ goog.require('ol.style.AtlasManager');
|
|||||||
goog.require('ol.webgl.Buffer');
|
goog.require('ol.webgl.Buffer');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
/**
|
* @extends {ol.render.webgl.TextureReplay}
|
||||||
* @constructor
|
* @param {number} tolerance Tolerance.
|
||||||
* @extends {ol.render.webgl.TextureReplay}
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
* @param {number} tolerance Tolerance.
|
* @struct
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
*/
|
||||||
* @struct
|
ol.render.webgl.TextReplay = function(tolerance, maxExtent) {
|
||||||
*/
|
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
||||||
ol.render.webgl.TextReplay = function(tolerance, maxExtent) {
|
|
||||||
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<HTMLCanvasElement>}
|
|
||||||
*/
|
|
||||||
this.images_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<WebGLTexture>}
|
|
||||||
*/
|
|
||||||
this.textures_ = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {HTMLCanvasElement}
|
|
||||||
*/
|
|
||||||
this.measureCanvas_ = ol.dom.createCanvasContext2D(0, 0).canvas;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {{strokeColor: (ol.ColorLike|null),
|
|
||||||
* lineCap: (string|undefined),
|
|
||||||
* lineDash: Array.<number>,
|
|
||||||
* lineDashOffset: (number|undefined),
|
|
||||||
* lineJoin: (string|undefined),
|
|
||||||
* lineWidth: number,
|
|
||||||
* miterLimit: (number|undefined),
|
|
||||||
* fillColor: (ol.ColorLike|null),
|
|
||||||
* font: (string|undefined),
|
|
||||||
* scale: (number|undefined)}}
|
|
||||||
*/
|
|
||||||
this.state_ = {
|
|
||||||
strokeColor: null,
|
|
||||||
lineCap: undefined,
|
|
||||||
lineDash: null,
|
|
||||||
lineDashOffset: undefined,
|
|
||||||
lineJoin: undefined,
|
|
||||||
lineWidth: 0,
|
|
||||||
miterLimit: undefined,
|
|
||||||
fillColor: null,
|
|
||||||
font: undefined,
|
|
||||||
scale: undefined
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.text_ = '';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.textAlign_ = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.textBaseline_ = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.offsetX_ = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.offsetY_ = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, ol.WebglGlyphAtlas>}
|
|
||||||
*/
|
|
||||||
this.atlases_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.WebglGlyphAtlas|undefined}
|
|
||||||
*/
|
|
||||||
this.currAtlas_ = undefined;
|
|
||||||
|
|
||||||
this.scale = 1;
|
|
||||||
|
|
||||||
this.opacity = 1;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.TextReplay, ol.render.webgl.TextureReplay);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextReplay.prototype.drawText = function(flatCoordinates, offset,
|
|
||||||
end, stride, geometry, feature) {
|
|
||||||
if (this.text_) {
|
|
||||||
this.startIndices.push(this.indices.length);
|
|
||||||
this.startIndicesFeature.push(feature);
|
|
||||||
|
|
||||||
var glyphAtlas = this.currAtlas_;
|
|
||||||
var lines = this.text_.split('\n');
|
|
||||||
var textSize = this.getTextSize_(lines);
|
|
||||||
var i, ii, j, jj, currX, currY, charArr, charInfo;
|
|
||||||
var anchorX = Math.round(textSize[0] * this.textAlign_ - this.offsetX_);
|
|
||||||
var anchorY = Math.round(textSize[1] * this.textBaseline_ - this.offsetY_);
|
|
||||||
var lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;
|
|
||||||
|
|
||||||
for (i = 0, ii = lines.length; i < ii; ++i) {
|
|
||||||
currX = 0;
|
|
||||||
currY = glyphAtlas.height * i;
|
|
||||||
charArr = lines[i].split('');
|
|
||||||
|
|
||||||
for (j = 0, jj = charArr.length; j < jj; ++j) {
|
|
||||||
charInfo = glyphAtlas.atlas.getInfo(charArr[j]);
|
|
||||||
|
|
||||||
if (charInfo) {
|
|
||||||
var image = charInfo.image;
|
|
||||||
|
|
||||||
this.anchorX = anchorX - currX;
|
|
||||||
this.anchorY = anchorY - currY;
|
|
||||||
this.originX = j === 0 ? charInfo.offsetX - lineWidth : charInfo.offsetX;
|
|
||||||
this.originY = charInfo.offsetY;
|
|
||||||
this.height = glyphAtlas.height;
|
|
||||||
this.width = j === 0 || j === charArr.length - 1 ?
|
|
||||||
glyphAtlas.width[charArr[j]] + lineWidth : glyphAtlas.width[charArr[j]];
|
|
||||||
this.imageHeight = image.height;
|
|
||||||
this.imageWidth = image.width;
|
|
||||||
|
|
||||||
var currentImage;
|
|
||||||
if (this.images_.length === 0) {
|
|
||||||
this.images_.push(image);
|
|
||||||
} else {
|
|
||||||
currentImage = this.images_[this.images_.length - 1];
|
|
||||||
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
|
||||||
this.groupIndices.push(this.indices.length);
|
|
||||||
this.images_.push(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.drawText_(flatCoordinates, offset, end, stride);
|
|
||||||
}
|
|
||||||
currX += this.width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Array.<string>} lines Label to draw split to lines.
|
* @type {Array.<HTMLCanvasElement>}
|
||||||
* @return {Array.<number>} Size of the label in pixels.
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
|
this.images_ = [];
|
||||||
var self = this;
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Array.<WebGLTexture>}
|
||||||
|
*/
|
||||||
|
this.textures_ = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {HTMLCanvasElement}
|
||||||
|
*/
|
||||||
|
this.measureCanvas_ = ol.dom.createCanvasContext2D(0, 0).canvas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {{strokeColor: (ol.ColorLike|null),
|
||||||
|
* lineCap: (string|undefined),
|
||||||
|
* lineDash: Array.<number>,
|
||||||
|
* lineDashOffset: (number|undefined),
|
||||||
|
* lineJoin: (string|undefined),
|
||||||
|
* lineWidth: number,
|
||||||
|
* miterLimit: (number|undefined),
|
||||||
|
* fillColor: (ol.ColorLike|null),
|
||||||
|
* font: (string|undefined),
|
||||||
|
* scale: (number|undefined)}}
|
||||||
|
*/
|
||||||
|
this.state_ = {
|
||||||
|
strokeColor: null,
|
||||||
|
lineCap: undefined,
|
||||||
|
lineDash: null,
|
||||||
|
lineDashOffset: undefined,
|
||||||
|
lineJoin: undefined,
|
||||||
|
lineWidth: 0,
|
||||||
|
miterLimit: undefined,
|
||||||
|
fillColor: null,
|
||||||
|
font: undefined,
|
||||||
|
scale: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.text_ = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.textAlign_ = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.textBaseline_ = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.offsetX_ = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.offsetY_ = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<string, ol.WebglGlyphAtlas>}
|
||||||
|
*/
|
||||||
|
this.atlases_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {ol.WebglGlyphAtlas|undefined}
|
||||||
|
*/
|
||||||
|
this.currAtlas_ = undefined;
|
||||||
|
|
||||||
|
this.scale = 1;
|
||||||
|
|
||||||
|
this.opacity = 1;
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.TextReplay, ol.render.webgl.TextureReplay);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextReplay.prototype.drawText = function(flatCoordinates, offset,
|
||||||
|
end, stride, geometry, feature) {
|
||||||
|
if (this.text_) {
|
||||||
|
this.startIndices.push(this.indices.length);
|
||||||
|
this.startIndicesFeature.push(feature);
|
||||||
|
|
||||||
var glyphAtlas = this.currAtlas_;
|
var glyphAtlas = this.currAtlas_;
|
||||||
var textHeight = lines.length * glyphAtlas.height;
|
var lines = this.text_.split('\n');
|
||||||
//Split every line to an array of chars, sum up their width, and select the longest.
|
var textSize = this.getTextSize_(lines);
|
||||||
var textWidth = lines.map(function(str) {
|
var i, ii, j, jj, currX, currY, charArr, charInfo;
|
||||||
var sum = 0;
|
var anchorX = Math.round(textSize[0] * this.textAlign_ - this.offsetX_);
|
||||||
var i, ii;
|
var anchorY = Math.round(textSize[1] * this.textBaseline_ - this.offsetY_);
|
||||||
for (i = 0, ii = str.length; i < ii; ++i) {
|
var lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;
|
||||||
var curr = str[i];
|
|
||||||
if (!glyphAtlas.width[curr]) {
|
for (i = 0, ii = lines.length; i < ii; ++i) {
|
||||||
self.addCharToAtlas_(curr);
|
currX = 0;
|
||||||
|
currY = glyphAtlas.height * i;
|
||||||
|
charArr = lines[i].split('');
|
||||||
|
|
||||||
|
for (j = 0, jj = charArr.length; j < jj; ++j) {
|
||||||
|
charInfo = glyphAtlas.atlas.getInfo(charArr[j]);
|
||||||
|
|
||||||
|
if (charInfo) {
|
||||||
|
var image = charInfo.image;
|
||||||
|
|
||||||
|
this.anchorX = anchorX - currX;
|
||||||
|
this.anchorY = anchorY - currY;
|
||||||
|
this.originX = j === 0 ? charInfo.offsetX - lineWidth : charInfo.offsetX;
|
||||||
|
this.originY = charInfo.offsetY;
|
||||||
|
this.height = glyphAtlas.height;
|
||||||
|
this.width = j === 0 || j === charArr.length - 1 ?
|
||||||
|
glyphAtlas.width[charArr[j]] + lineWidth : glyphAtlas.width[charArr[j]];
|
||||||
|
this.imageHeight = image.height;
|
||||||
|
this.imageWidth = image.width;
|
||||||
|
|
||||||
|
var currentImage;
|
||||||
|
if (this.images_.length === 0) {
|
||||||
|
this.images_.push(image);
|
||||||
|
} else {
|
||||||
|
currentImage = this.images_[this.images_.length - 1];
|
||||||
|
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
||||||
|
this.groupIndices.push(this.indices.length);
|
||||||
|
this.images_.push(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawText_(flatCoordinates, offset, end, stride);
|
||||||
}
|
}
|
||||||
sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;
|
currX += this.width;
|
||||||
}
|
}
|
||||||
return sum;
|
}
|
||||||
}).reduce(function(max, curr) {
|
}
|
||||||
return Math.max(max, curr);
|
};
|
||||||
});
|
|
||||||
|
|
||||||
return [textWidth, textHeight];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
* @param {Array.<string>} lines Label to draw split to lines.
|
||||||
* @param {number} offset Offset.
|
* @return {Array.<number>} Size of the label in pixels.
|
||||||
* @param {number} end End.
|
*/
|
||||||
* @param {number} stride Stride.
|
ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
|
||||||
*/
|
var self = this;
|
||||||
ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
|
var glyphAtlas = this.currAtlas_;
|
||||||
end, stride) {
|
var textHeight = lines.length * glyphAtlas.height;
|
||||||
|
//Split every line to an array of chars, sum up their width, and select the longest.
|
||||||
|
var textWidth = lines.map(function(str) {
|
||||||
|
var sum = 0;
|
||||||
var i, ii;
|
var i, ii;
|
||||||
for (i = offset, ii = end; i < ii; i += stride) {
|
for (i = 0, ii = str.length; i < ii; ++i) {
|
||||||
this.drawCoordinates(flatCoordinates, offset, end, stride);
|
var curr = str[i];
|
||||||
}
|
if (!glyphAtlas.width[curr]) {
|
||||||
};
|
self.addCharToAtlas_(curr);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {string} char Character.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextReplay.prototype.addCharToAtlas_ = function(char) {
|
|
||||||
if (char.length === 1) {
|
|
||||||
var glyphAtlas = this.currAtlas_;
|
|
||||||
var state = this.state_;
|
|
||||||
var mCtx = this.measureCanvas_.getContext('2d');
|
|
||||||
mCtx.font = state.font;
|
|
||||||
var width = Math.ceil(mCtx.measureText(char).width * state.scale);
|
|
||||||
|
|
||||||
var info = glyphAtlas.atlas.add(char, width, glyphAtlas.height,
|
|
||||||
function(ctx, x, y) {
|
|
||||||
//Parameterize the canvas
|
|
||||||
ctx.font = /** @type {string} */ (state.font);
|
|
||||||
ctx.fillStyle = state.fillColor;
|
|
||||||
ctx.strokeStyle = state.strokeColor;
|
|
||||||
ctx.lineWidth = state.lineWidth;
|
|
||||||
ctx.lineCap = /*** @type {string} */ (state.lineCap);
|
|
||||||
ctx.lineJoin = /** @type {string} */ (state.lineJoin);
|
|
||||||
ctx.miterLimit = /** @type {number} */ (state.miterLimit);
|
|
||||||
ctx.textAlign = 'left';
|
|
||||||
ctx.textBaseline = 'top';
|
|
||||||
if (ol.has.CANVAS_LINE_DASH && state.lineDash) {
|
|
||||||
//FIXME: use pixelRatio
|
|
||||||
ctx.setLineDash(state.lineDash);
|
|
||||||
ctx.lineDashOffset = /** @type {number} */ (state.lineDashOffset);
|
|
||||||
}
|
|
||||||
if (state.scale !== 1) {
|
|
||||||
//FIXME: use pixelRatio
|
|
||||||
ctx.setTransform(/** @type {number} */ (state.scale), 0, 0,
|
|
||||||
/** @type {number} */ (state.scale), 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Draw the character on the canvas
|
|
||||||
if (state.strokeColor) {
|
|
||||||
ctx.strokeText(char, x, y);
|
|
||||||
}
|
|
||||||
if (state.fillColor) {
|
|
||||||
ctx.fillText(char, x, y);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
glyphAtlas.width[char] = width;
|
|
||||||
}
|
}
|
||||||
|
sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;
|
||||||
}
|
}
|
||||||
};
|
return sum;
|
||||||
|
}).reduce(function(max, curr) {
|
||||||
|
return Math.max(max, curr);
|
||||||
|
});
|
||||||
|
|
||||||
|
return [textWidth, textHeight];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
*/
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
ol.render.webgl.TextReplay.prototype.finish = function(context) {
|
* @param {number} offset Offset.
|
||||||
var gl = context.getGL();
|
* @param {number} end End.
|
||||||
|
* @param {number} stride Stride.
|
||||||
this.groupIndices.push(this.indices.length);
|
*/
|
||||||
this.hitDetectionGroupIndices = this.groupIndices;
|
ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
|
||||||
|
end, stride) {
|
||||||
// create, bind, and populate the vertices buffer
|
var i, ii;
|
||||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
for (i = offset, ii = end; i < ii; i += stride) {
|
||||||
|
this.drawCoordinates(flatCoordinates, offset, end, stride);
|
||||||
// create, bind, and populate the indices buffer
|
}
|
||||||
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
};
|
||||||
|
|
||||||
// create textures
|
|
||||||
/** @type {Object.<string, WebGLTexture>} */
|
|
||||||
var texturePerImage = {};
|
|
||||||
|
|
||||||
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
|
||||||
|
|
||||||
this.state_ = {
|
|
||||||
strokeColor: null,
|
|
||||||
lineCap: undefined,
|
|
||||||
lineDash: null,
|
|
||||||
lineDashOffset: undefined,
|
|
||||||
lineJoin: undefined,
|
|
||||||
lineWidth: 0,
|
|
||||||
miterLimit: undefined,
|
|
||||||
fillColor: null,
|
|
||||||
font: undefined,
|
|
||||||
scale: undefined
|
|
||||||
};
|
|
||||||
this.text_ = '';
|
|
||||||
this.textAlign_ = undefined;
|
|
||||||
this.textBaseline_ = undefined;
|
|
||||||
this.offsetX_ = undefined;
|
|
||||||
this.offsetY_ = undefined;
|
|
||||||
this.images_ = null;
|
|
||||||
this.atlases_ = {};
|
|
||||||
this.currAtlas_ = undefined;
|
|
||||||
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
*/
|
* @param {string} char Character.
|
||||||
ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
|
*/
|
||||||
|
ol.render.webgl.TextReplay.prototype.addCharToAtlas_ = function(char) {
|
||||||
|
if (char.length === 1) {
|
||||||
|
var glyphAtlas = this.currAtlas_;
|
||||||
var state = this.state_;
|
var state = this.state_;
|
||||||
var textFillStyle = textStyle.getFill();
|
var mCtx = this.measureCanvas_.getContext('2d');
|
||||||
var textStrokeStyle = textStyle.getStroke();
|
mCtx.font = state.font;
|
||||||
if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {
|
var width = Math.ceil(mCtx.measureText(char).width * state.scale);
|
||||||
this.text_ = '';
|
|
||||||
|
var info = glyphAtlas.atlas.add(char, width, glyphAtlas.height,
|
||||||
|
function(ctx, x, y) {
|
||||||
|
//Parameterize the canvas
|
||||||
|
ctx.font = /** @type {string} */ (state.font);
|
||||||
|
ctx.fillStyle = state.fillColor;
|
||||||
|
ctx.strokeStyle = state.strokeColor;
|
||||||
|
ctx.lineWidth = state.lineWidth;
|
||||||
|
ctx.lineCap = /*** @type {string} */ (state.lineCap);
|
||||||
|
ctx.lineJoin = /** @type {string} */ (state.lineJoin);
|
||||||
|
ctx.miterLimit = /** @type {number} */ (state.miterLimit);
|
||||||
|
ctx.textAlign = 'left';
|
||||||
|
ctx.textBaseline = 'top';
|
||||||
|
if (ol.has.CANVAS_LINE_DASH && state.lineDash) {
|
||||||
|
//FIXME: use pixelRatio
|
||||||
|
ctx.setLineDash(state.lineDash);
|
||||||
|
ctx.lineDashOffset = /** @type {number} */ (state.lineDashOffset);
|
||||||
|
}
|
||||||
|
if (state.scale !== 1) {
|
||||||
|
//FIXME: use pixelRatio
|
||||||
|
ctx.setTransform(/** @type {number} */ (state.scale), 0, 0,
|
||||||
|
/** @type {number} */ (state.scale), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw the character on the canvas
|
||||||
|
if (state.strokeColor) {
|
||||||
|
ctx.strokeText(char, x, y);
|
||||||
|
}
|
||||||
|
if (state.fillColor) {
|
||||||
|
ctx.fillText(char, x, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
glyphAtlas.width[char] = width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextReplay.prototype.finish = function(context) {
|
||||||
|
var gl = context.getGL();
|
||||||
|
|
||||||
|
this.groupIndices.push(this.indices.length);
|
||||||
|
this.hitDetectionGroupIndices = this.groupIndices;
|
||||||
|
|
||||||
|
// create, bind, and populate the vertices buffer
|
||||||
|
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||||
|
|
||||||
|
// create, bind, and populate the indices buffer
|
||||||
|
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
||||||
|
|
||||||
|
// create textures
|
||||||
|
/** @type {Object.<string, WebGLTexture>} */
|
||||||
|
var texturePerImage = {};
|
||||||
|
|
||||||
|
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
||||||
|
|
||||||
|
this.state_ = {
|
||||||
|
strokeColor: null,
|
||||||
|
lineCap: undefined,
|
||||||
|
lineDash: null,
|
||||||
|
lineDashOffset: undefined,
|
||||||
|
lineJoin: undefined,
|
||||||
|
lineWidth: 0,
|
||||||
|
miterLimit: undefined,
|
||||||
|
fillColor: null,
|
||||||
|
font: undefined,
|
||||||
|
scale: undefined
|
||||||
|
};
|
||||||
|
this.text_ = '';
|
||||||
|
this.textAlign_ = undefined;
|
||||||
|
this.textBaseline_ = undefined;
|
||||||
|
this.offsetX_ = undefined;
|
||||||
|
this.offsetY_ = undefined;
|
||||||
|
this.images_ = null;
|
||||||
|
this.atlases_ = {};
|
||||||
|
this.currAtlas_ = undefined;
|
||||||
|
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
|
||||||
|
var state = this.state_;
|
||||||
|
var textFillStyle = textStyle.getFill();
|
||||||
|
var textStrokeStyle = textStyle.getStroke();
|
||||||
|
if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {
|
||||||
|
this.text_ = '';
|
||||||
|
} else {
|
||||||
|
if (!textFillStyle) {
|
||||||
|
state.fillColor = null;
|
||||||
} else {
|
} else {
|
||||||
if (!textFillStyle) {
|
var textFillStyleColor = textFillStyle.getColor();
|
||||||
state.fillColor = null;
|
state.fillColor = ol.colorlike.asColorLike(textFillStyleColor ?
|
||||||
|
textFillStyleColor : ol.render.webgl.defaultFillStyle);
|
||||||
|
}
|
||||||
|
if (!textStrokeStyle) {
|
||||||
|
state.strokeColor = null;
|
||||||
|
state.lineWidth = 0;
|
||||||
|
} else {
|
||||||
|
var textStrokeStyleColor = textStrokeStyle.getColor();
|
||||||
|
state.strokeColor = ol.colorlike.asColorLike(textStrokeStyleColor ?
|
||||||
|
textStrokeStyleColor : ol.render.webgl.defaultStrokeStyle);
|
||||||
|
state.lineWidth = textStrokeStyle.getWidth() || ol.render.webgl.defaultLineWidth;
|
||||||
|
state.lineCap = textStrokeStyle.getLineCap() || ol.render.webgl.defaultLineCap;
|
||||||
|
state.lineDashOffset = textStrokeStyle.getLineDashOffset() || ol.render.webgl.defaultLineDashOffset;
|
||||||
|
state.lineJoin = textStrokeStyle.getLineJoin() || ol.render.webgl.defaultLineJoin;
|
||||||
|
state.miterLimit = textStrokeStyle.getMiterLimit() || ol.render.webgl.defaultMiterLimit;
|
||||||
|
var lineDash = textStrokeStyle.getLineDash();
|
||||||
|
state.lineDash = lineDash ? lineDash.slice() : ol.render.webgl.defaultLineDash;
|
||||||
|
}
|
||||||
|
state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
|
||||||
|
state.scale = textStyle.getScale() || 1;
|
||||||
|
this.text_ = /** @type {string} */ (textStyle.getText());
|
||||||
|
var textAlign = ol.render.webgl.TextReplay.Align_[textStyle.getTextAlign()];
|
||||||
|
var textBaseline = ol.render.webgl.TextReplay.Align_[textStyle.getTextBaseline()];
|
||||||
|
this.textAlign_ = textAlign === undefined ?
|
||||||
|
ol.render.webgl.defaultTextAlign : textAlign;
|
||||||
|
this.textBaseline_ = textBaseline === undefined ?
|
||||||
|
ol.render.webgl.defaultTextBaseline : textBaseline;
|
||||||
|
this.offsetX_ = textStyle.getOffsetX() || 0;
|
||||||
|
this.offsetY_ = textStyle.getOffsetY() || 0;
|
||||||
|
this.rotateWithView = !!textStyle.getRotateWithView();
|
||||||
|
this.rotation = textStyle.getRotation() || 0;
|
||||||
|
|
||||||
|
this.currAtlas_ = this.getAtlas_(state);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @param {Object} state Font attributes.
|
||||||
|
* @return {ol.WebglGlyphAtlas} Glyph atlas.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextReplay.prototype.getAtlas_ = function(state) {
|
||||||
|
var params = [];
|
||||||
|
var i;
|
||||||
|
for (i in state) {
|
||||||
|
if (state[i] || state[i] === 0) {
|
||||||
|
if (Array.isArray(state[i])) {
|
||||||
|
params = params.concat(state[i]);
|
||||||
} else {
|
} else {
|
||||||
var textFillStyleColor = textFillStyle.getColor();
|
params.push(state[i]);
|
||||||
state.fillColor = ol.colorlike.asColorLike(textFillStyleColor ?
|
|
||||||
textFillStyleColor : ol.render.webgl.defaultFillStyle);
|
|
||||||
}
|
|
||||||
if (!textStrokeStyle) {
|
|
||||||
state.strokeColor = null;
|
|
||||||
state.lineWidth = 0;
|
|
||||||
} else {
|
|
||||||
var textStrokeStyleColor = textStrokeStyle.getColor();
|
|
||||||
state.strokeColor = ol.colorlike.asColorLike(textStrokeStyleColor ?
|
|
||||||
textStrokeStyleColor : ol.render.webgl.defaultStrokeStyle);
|
|
||||||
state.lineWidth = textStrokeStyle.getWidth() || ol.render.webgl.defaultLineWidth;
|
|
||||||
state.lineCap = textStrokeStyle.getLineCap() || ol.render.webgl.defaultLineCap;
|
|
||||||
state.lineDashOffset = textStrokeStyle.getLineDashOffset() || ol.render.webgl.defaultLineDashOffset;
|
|
||||||
state.lineJoin = textStrokeStyle.getLineJoin() || ol.render.webgl.defaultLineJoin;
|
|
||||||
state.miterLimit = textStrokeStyle.getMiterLimit() || ol.render.webgl.defaultMiterLimit;
|
|
||||||
var lineDash = textStrokeStyle.getLineDash();
|
|
||||||
state.lineDash = lineDash ? lineDash.slice() : ol.render.webgl.defaultLineDash;
|
|
||||||
}
|
|
||||||
state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
|
|
||||||
state.scale = textStyle.getScale() || 1;
|
|
||||||
this.text_ = /** @type {string} */ (textStyle.getText());
|
|
||||||
var textAlign = ol.render.webgl.TextReplay.Align_[textStyle.getTextAlign()];
|
|
||||||
var textBaseline = ol.render.webgl.TextReplay.Align_[textStyle.getTextBaseline()];
|
|
||||||
this.textAlign_ = textAlign === undefined ?
|
|
||||||
ol.render.webgl.defaultTextAlign : textAlign;
|
|
||||||
this.textBaseline_ = textBaseline === undefined ?
|
|
||||||
ol.render.webgl.defaultTextBaseline : textBaseline;
|
|
||||||
this.offsetX_ = textStyle.getOffsetX() || 0;
|
|
||||||
this.offsetY_ = textStyle.getOffsetY() || 0;
|
|
||||||
this.rotateWithView = !!textStyle.getRotateWithView();
|
|
||||||
this.rotation = textStyle.getRotation() || 0;
|
|
||||||
|
|
||||||
this.currAtlas_ = this.getAtlas_(state);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @param {Object} state Font attributes.
|
|
||||||
* @return {ol.WebglGlyphAtlas} Glyph atlas.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextReplay.prototype.getAtlas_ = function(state) {
|
|
||||||
var params = [];
|
|
||||||
var i;
|
|
||||||
for (i in state) {
|
|
||||||
if (state[i] || state[i] === 0) {
|
|
||||||
if (Array.isArray(state[i])) {
|
|
||||||
params = params.concat(state[i]);
|
|
||||||
} else {
|
|
||||||
params.push(state[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var hash = this.calculateHash_(params);
|
}
|
||||||
if (!this.atlases_[hash]) {
|
var hash = this.calculateHash_(params);
|
||||||
var mCtx = this.measureCanvas_.getContext('2d');
|
if (!this.atlases_[hash]) {
|
||||||
mCtx.font = state.font;
|
var mCtx = this.measureCanvas_.getContext('2d');
|
||||||
var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
|
mCtx.font = state.font;
|
||||||
state.lineWidth / 2) * state.scale);
|
var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
|
||||||
|
state.lineWidth / 2) * state.scale);
|
||||||
|
|
||||||
this.atlases_[hash] = {
|
this.atlases_[hash] = {
|
||||||
atlas: new ol.style.AtlasManager({
|
atlas: new ol.style.AtlasManager({
|
||||||
space: state.lineWidth + 1
|
space: state.lineWidth + 1
|
||||||
}),
|
}),
|
||||||
width: {},
|
width: {},
|
||||||
height: height
|
height: height
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return this.atlases_[hash];
|
return this.atlases_[hash];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @param {Array.<string|number>} params Array of parameters.
|
* @param {Array.<string|number>} params Array of parameters.
|
||||||
* @return {string} Hash string.
|
* @return {string} Hash string.
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
|
ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
|
||||||
//TODO: Create a more performant, reliable, general hash function.
|
//TODO: Create a more performant, reliable, general hash function.
|
||||||
var i, ii;
|
var i, ii;
|
||||||
var hash = '';
|
var hash = '';
|
||||||
for (i = 0, ii = params.length; i < ii; ++i) {
|
for (i = 0, ii = params.length; i < ii; ++i) {
|
||||||
hash += params[i];
|
hash += params[i];
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
||||||
return this.textures_;
|
return this.textures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
||||||
return this.textures_;
|
return this.textures_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextReplay.Align_ = {
|
ol.render.webgl.TextReplay.Align_ = {
|
||||||
left: 0,
|
left: 0,
|
||||||
end: 0,
|
end: 0,
|
||||||
center: 0.5,
|
center: 0.5,
|
||||||
right: 1,
|
right: 1,
|
||||||
start: 1,
|
start: 1,
|
||||||
top: 0,
|
top: 0,
|
||||||
middle: 0.5,
|
middle: 0.5,
|
||||||
hanging: 0.2,
|
hanging: 0.2,
|
||||||
alphabetic: 0.8,
|
alphabetic: 0.8,
|
||||||
ideographic: 0.8,
|
ideographic: 0.8,
|
||||||
bottom: 1
|
bottom: 1
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,490 +8,487 @@ goog.require('ol.render.webgl.Replay');
|
|||||||
goog.require('ol.webgl');
|
goog.require('ol.webgl');
|
||||||
goog.require('ol.webgl.Context');
|
goog.require('ol.webgl.Context');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @abstract
|
||||||
|
* @extends {ol.render.webgl.Replay}
|
||||||
|
* @param {number} tolerance Tolerance.
|
||||||
|
* @param {ol.Extent} maxExtent Max extent.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay = function(tolerance, maxExtent) {
|
||||||
|
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {number|undefined}
|
||||||
* @abstract
|
|
||||||
* @extends {ol.render.webgl.Replay}
|
|
||||||
* @param {number} tolerance Tolerance.
|
|
||||||
* @param {ol.Extent} maxExtent Max extent.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextureReplay = function(tolerance, maxExtent) {
|
|
||||||
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.anchorX = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.anchorY = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<number>}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.groupIndices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<number>}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.hitDetectionGroupIndices = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.height = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.imageHeight = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.imageWidth = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {ol.render.webgl.texturereplay.defaultshader.Locations}
|
|
||||||
*/
|
|
||||||
this.defaultLocations = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.opacity = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.originX = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.originY = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {boolean|undefined}
|
|
||||||
*/
|
|
||||||
this.rotateWithView = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.rotation = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.scale = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this.width = undefined;
|
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.TextureReplay, ol.render.webgl.Replay);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextureReplay.prototype.getDeleteResourcesFunction = function(context) {
|
|
||||||
var verticesBuffer = this.verticesBuffer;
|
|
||||||
var indicesBuffer = this.indicesBuffer;
|
|
||||||
var textures = this.getTextures(true);
|
|
||||||
var gl = context.getGL();
|
|
||||||
return function() {
|
|
||||||
if (!gl.isContextLost()) {
|
|
||||||
var i, ii;
|
|
||||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
|
||||||
gl.deleteTexture(textures[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
context.deleteBuffer(verticesBuffer);
|
|
||||||
context.deleteBuffer(indicesBuffer);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
|
||||||
* @param {number} offset Offset.
|
|
||||||
* @param {number} end End.
|
|
||||||
* @param {number} stride Stride.
|
|
||||||
* @return {number} My end.
|
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.drawCoordinates = function(flatCoordinates, offset, end, stride) {
|
this.anchorX = undefined;
|
||||||
var anchorX = /** @type {number} */ (this.anchorX);
|
|
||||||
var anchorY = /** @type {number} */ (this.anchorY);
|
|
||||||
var height = /** @type {number} */ (this.height);
|
|
||||||
var imageHeight = /** @type {number} */ (this.imageHeight);
|
|
||||||
var imageWidth = /** @type {number} */ (this.imageWidth);
|
|
||||||
var opacity = /** @type {number} */ (this.opacity);
|
|
||||||
var originX = /** @type {number} */ (this.originX);
|
|
||||||
var originY = /** @type {number} */ (this.originY);
|
|
||||||
var rotateWithView = this.rotateWithView ? 1.0 : 0.0;
|
|
||||||
// this.rotation_ is anti-clockwise, but rotation is clockwise
|
|
||||||
var rotation = /** @type {number} */ (-this.rotation);
|
|
||||||
var scale = /** @type {number} */ (this.scale);
|
|
||||||
var width = /** @type {number} */ (this.width);
|
|
||||||
var cos = Math.cos(rotation);
|
|
||||||
var sin = Math.sin(rotation);
|
|
||||||
var numIndices = this.indices.length;
|
|
||||||
var numVertices = this.vertices.length;
|
|
||||||
var i, n, offsetX, offsetY, x, y;
|
|
||||||
for (i = offset; i < end; i += stride) {
|
|
||||||
x = flatCoordinates[i] - this.origin[0];
|
|
||||||
y = flatCoordinates[i + 1] - this.origin[1];
|
|
||||||
|
|
||||||
// There are 4 vertices per [x, y] point, one for each corner of the
|
/**
|
||||||
// rectangle we're going to draw. We'd use 1 vertex per [x, y] point if
|
* @type {number|undefined}
|
||||||
// WebGL supported Geometry Shaders (which can emit new vertices), but that
|
* @protected
|
||||||
// is not currently the case.
|
*/
|
||||||
//
|
this.anchorY = undefined;
|
||||||
// And each vertex includes 8 values: the x and y coordinates, the x and
|
|
||||||
// y offsets used to calculate the position of the corner, the u and
|
|
||||||
// v texture coordinates for the corner, the opacity, and whether the
|
|
||||||
// the image should be rotated with the view (rotateWithView).
|
|
||||||
|
|
||||||
n = numVertices / 8;
|
/**
|
||||||
|
* @type {Array.<number>}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.groupIndices = [];
|
||||||
|
|
||||||
// bottom-left corner
|
/**
|
||||||
offsetX = -scale * anchorX;
|
* @type {Array.<number>}
|
||||||
offsetY = -scale * (height - anchorY);
|
* @protected
|
||||||
this.vertices[numVertices++] = x;
|
*/
|
||||||
this.vertices[numVertices++] = y;
|
this.hitDetectionGroupIndices = [];
|
||||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
|
||||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
|
||||||
this.vertices[numVertices++] = originX / imageWidth;
|
|
||||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
|
||||||
this.vertices[numVertices++] = opacity;
|
|
||||||
this.vertices[numVertices++] = rotateWithView;
|
|
||||||
|
|
||||||
// bottom-right corner
|
/**
|
||||||
offsetX = scale * (width - anchorX);
|
* @type {number|undefined}
|
||||||
offsetY = -scale * (height - anchorY);
|
* @protected
|
||||||
this.vertices[numVertices++] = x;
|
*/
|
||||||
this.vertices[numVertices++] = y;
|
this.height = undefined;
|
||||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
|
||||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
|
||||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
|
||||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
|
||||||
this.vertices[numVertices++] = opacity;
|
|
||||||
this.vertices[numVertices++] = rotateWithView;
|
|
||||||
|
|
||||||
// top-right corner
|
/**
|
||||||
offsetX = scale * (width - anchorX);
|
* @type {number|undefined}
|
||||||
offsetY = scale * anchorY;
|
* @protected
|
||||||
this.vertices[numVertices++] = x;
|
*/
|
||||||
this.vertices[numVertices++] = y;
|
this.imageHeight = undefined;
|
||||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
|
||||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
|
||||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
|
||||||
this.vertices[numVertices++] = originY / imageHeight;
|
|
||||||
this.vertices[numVertices++] = opacity;
|
|
||||||
this.vertices[numVertices++] = rotateWithView;
|
|
||||||
|
|
||||||
// top-left corner
|
|
||||||
offsetX = -scale * anchorX;
|
|
||||||
offsetY = scale * anchorY;
|
|
||||||
this.vertices[numVertices++] = x;
|
|
||||||
this.vertices[numVertices++] = y;
|
|
||||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
|
||||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
|
||||||
this.vertices[numVertices++] = originX / imageWidth;
|
|
||||||
this.vertices[numVertices++] = originY / imageHeight;
|
|
||||||
this.vertices[numVertices++] = opacity;
|
|
||||||
this.vertices[numVertices++] = rotateWithView;
|
|
||||||
|
|
||||||
this.indices[numIndices++] = n;
|
|
||||||
this.indices[numIndices++] = n + 1;
|
|
||||||
this.indices[numIndices++] = n + 2;
|
|
||||||
this.indices[numIndices++] = n;
|
|
||||||
this.indices[numIndices++] = n + 2;
|
|
||||||
this.indices[numIndices++] = n + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return numVertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number|undefined}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.imageWidth = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
* @param {Array.<WebGLTexture>} textures Textures.
|
* @type {ol.render.webgl.texturereplay.defaultshader.Locations}
|
||||||
* @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
|
|
||||||
* Images.
|
|
||||||
* @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
|
|
||||||
* @param {WebGLRenderingContext} gl Gl.
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.createTextures = function(textures, images, texturePerImage, gl) {
|
this.defaultLocations = null;
|
||||||
var texture, image, uid, i;
|
|
||||||
var ii = images.length;
|
|
||||||
for (i = 0; i < ii; ++i) {
|
|
||||||
image = images[i];
|
|
||||||
|
|
||||||
uid = ol.getUid(image).toString();
|
|
||||||
if (uid in texturePerImage) {
|
|
||||||
texture = texturePerImage[uid];
|
|
||||||
} else {
|
|
||||||
texture = ol.webgl.Context.createTexture(
|
|
||||||
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
|
||||||
texturePerImage[uid] = texture;
|
|
||||||
}
|
|
||||||
textures[i] = texture;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @protected
|
||||||
|
* @type {number|undefined}
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
this.opacity = undefined;
|
||||||
// get the program
|
|
||||||
var fragmentShader = ol.render.webgl.texturereplay.defaultshader.fragment;
|
|
||||||
var vertexShader = ol.render.webgl.texturereplay.defaultshader.vertex;
|
|
||||||
var program = context.getProgram(fragmentShader, vertexShader);
|
|
||||||
|
|
||||||
// get the locations
|
/**
|
||||||
var locations;
|
* @type {number|undefined}
|
||||||
if (!this.defaultLocations) {
|
* @protected
|
||||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
*/
|
||||||
locations = new ol.render.webgl.texturereplay.defaultshader.Locations(gl, program);
|
this.originX = undefined;
|
||||||
this.defaultLocations = locations;
|
|
||||||
|
/**
|
||||||
|
* @type {number|undefined}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.originY = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {boolean|undefined}
|
||||||
|
*/
|
||||||
|
this.rotateWithView = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.rotation = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.scale = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number|undefined}
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
this.width = undefined;
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.TextureReplay, ol.render.webgl.Replay);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay.prototype.getDeleteResourcesFunction = function(context) {
|
||||||
|
var verticesBuffer = this.verticesBuffer;
|
||||||
|
var indicesBuffer = this.indicesBuffer;
|
||||||
|
var textures = this.getTextures(true);
|
||||||
|
var gl = context.getGL();
|
||||||
|
return function() {
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
var i, ii;
|
||||||
|
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||||
|
gl.deleteTexture(textures[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.deleteBuffer(verticesBuffer);
|
||||||
|
context.deleteBuffer(indicesBuffer);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||||
|
* @param {number} offset Offset.
|
||||||
|
* @param {number} end End.
|
||||||
|
* @param {number} stride Stride.
|
||||||
|
* @return {number} My end.
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay.prototype.drawCoordinates = function(flatCoordinates, offset, end, stride) {
|
||||||
|
var anchorX = /** @type {number} */ (this.anchorX);
|
||||||
|
var anchorY = /** @type {number} */ (this.anchorY);
|
||||||
|
var height = /** @type {number} */ (this.height);
|
||||||
|
var imageHeight = /** @type {number} */ (this.imageHeight);
|
||||||
|
var imageWidth = /** @type {number} */ (this.imageWidth);
|
||||||
|
var opacity = /** @type {number} */ (this.opacity);
|
||||||
|
var originX = /** @type {number} */ (this.originX);
|
||||||
|
var originY = /** @type {number} */ (this.originY);
|
||||||
|
var rotateWithView = this.rotateWithView ? 1.0 : 0.0;
|
||||||
|
// this.rotation_ is anti-clockwise, but rotation is clockwise
|
||||||
|
var rotation = /** @type {number} */ (-this.rotation);
|
||||||
|
var scale = /** @type {number} */ (this.scale);
|
||||||
|
var width = /** @type {number} */ (this.width);
|
||||||
|
var cos = Math.cos(rotation);
|
||||||
|
var sin = Math.sin(rotation);
|
||||||
|
var numIndices = this.indices.length;
|
||||||
|
var numVertices = this.vertices.length;
|
||||||
|
var i, n, offsetX, offsetY, x, y;
|
||||||
|
for (i = offset; i < end; i += stride) {
|
||||||
|
x = flatCoordinates[i] - this.origin[0];
|
||||||
|
y = flatCoordinates[i + 1] - this.origin[1];
|
||||||
|
|
||||||
|
// There are 4 vertices per [x, y] point, one for each corner of the
|
||||||
|
// rectangle we're going to draw. We'd use 1 vertex per [x, y] point if
|
||||||
|
// WebGL supported Geometry Shaders (which can emit new vertices), but that
|
||||||
|
// is not currently the case.
|
||||||
|
//
|
||||||
|
// And each vertex includes 8 values: the x and y coordinates, the x and
|
||||||
|
// y offsets used to calculate the position of the corner, the u and
|
||||||
|
// v texture coordinates for the corner, the opacity, and whether the
|
||||||
|
// the image should be rotated with the view (rotateWithView).
|
||||||
|
|
||||||
|
n = numVertices / 8;
|
||||||
|
|
||||||
|
// bottom-left corner
|
||||||
|
offsetX = -scale * anchorX;
|
||||||
|
offsetY = -scale * (height - anchorY);
|
||||||
|
this.vertices[numVertices++] = x;
|
||||||
|
this.vertices[numVertices++] = y;
|
||||||
|
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||||
|
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||||
|
this.vertices[numVertices++] = originX / imageWidth;
|
||||||
|
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||||
|
this.vertices[numVertices++] = opacity;
|
||||||
|
this.vertices[numVertices++] = rotateWithView;
|
||||||
|
|
||||||
|
// bottom-right corner
|
||||||
|
offsetX = scale * (width - anchorX);
|
||||||
|
offsetY = -scale * (height - anchorY);
|
||||||
|
this.vertices[numVertices++] = x;
|
||||||
|
this.vertices[numVertices++] = y;
|
||||||
|
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||||
|
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||||
|
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||||
|
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||||
|
this.vertices[numVertices++] = opacity;
|
||||||
|
this.vertices[numVertices++] = rotateWithView;
|
||||||
|
|
||||||
|
// top-right corner
|
||||||
|
offsetX = scale * (width - anchorX);
|
||||||
|
offsetY = scale * anchorY;
|
||||||
|
this.vertices[numVertices++] = x;
|
||||||
|
this.vertices[numVertices++] = y;
|
||||||
|
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||||
|
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||||
|
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||||
|
this.vertices[numVertices++] = originY / imageHeight;
|
||||||
|
this.vertices[numVertices++] = opacity;
|
||||||
|
this.vertices[numVertices++] = rotateWithView;
|
||||||
|
|
||||||
|
// top-left corner
|
||||||
|
offsetX = -scale * anchorX;
|
||||||
|
offsetY = scale * anchorY;
|
||||||
|
this.vertices[numVertices++] = x;
|
||||||
|
this.vertices[numVertices++] = y;
|
||||||
|
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||||
|
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||||
|
this.vertices[numVertices++] = originX / imageWidth;
|
||||||
|
this.vertices[numVertices++] = originY / imageHeight;
|
||||||
|
this.vertices[numVertices++] = opacity;
|
||||||
|
this.vertices[numVertices++] = rotateWithView;
|
||||||
|
|
||||||
|
this.indices[numIndices++] = n;
|
||||||
|
this.indices[numIndices++] = n + 1;
|
||||||
|
this.indices[numIndices++] = n + 2;
|
||||||
|
this.indices[numIndices++] = n;
|
||||||
|
this.indices[numIndices++] = n + 2;
|
||||||
|
this.indices[numIndices++] = n + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return numVertices;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @param {Array.<WebGLTexture>} textures Textures.
|
||||||
|
* @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
|
||||||
|
* Images.
|
||||||
|
* @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
|
||||||
|
* @param {WebGLRenderingContext} gl Gl.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay.prototype.createTextures = function(textures, images, texturePerImage, gl) {
|
||||||
|
var texture, image, uid, i;
|
||||||
|
var ii = images.length;
|
||||||
|
for (i = 0; i < ii; ++i) {
|
||||||
|
image = images[i];
|
||||||
|
|
||||||
|
uid = ol.getUid(image).toString();
|
||||||
|
if (uid in texturePerImage) {
|
||||||
|
texture = texturePerImage[uid];
|
||||||
} else {
|
} else {
|
||||||
locations = this.defaultLocations;
|
texture = ol.webgl.Context.createTexture(
|
||||||
|
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||||
|
texturePerImage[uid] = texture;
|
||||||
}
|
}
|
||||||
|
textures[i] = texture;
|
||||||
// use the program (FIXME: use the return value)
|
}
|
||||||
context.useProgram(program);
|
};
|
||||||
|
|
||||||
// enable the vertex attrib arrays
|
|
||||||
gl.enableVertexAttribArray(locations.a_position);
|
|
||||||
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
|
||||||
false, 32, 0);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_offsets);
|
|
||||||
gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT,
|
|
||||||
false, 32, 8);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_texCoord);
|
|
||||||
gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT,
|
|
||||||
false, 32, 16);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_opacity);
|
|
||||||
gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT,
|
|
||||||
false, 32, 24);
|
|
||||||
|
|
||||||
gl.enableVertexAttribArray(locations.a_rotateWithView);
|
|
||||||
gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT,
|
|
||||||
false, 32, 28);
|
|
||||||
|
|
||||||
return locations;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
|
ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||||
gl.disableVertexAttribArray(locations.a_position);
|
// get the program
|
||||||
gl.disableVertexAttribArray(locations.a_offsets);
|
var fragmentShader = ol.render.webgl.texturereplay.defaultshader.fragment;
|
||||||
gl.disableVertexAttribArray(locations.a_texCoord);
|
var vertexShader = ol.render.webgl.texturereplay.defaultshader.vertex;
|
||||||
gl.disableVertexAttribArray(locations.a_opacity);
|
var program = context.getProgram(fragmentShader, vertexShader);
|
||||||
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
|
||||||
};
|
// get the locations
|
||||||
|
var locations;
|
||||||
|
if (!this.defaultLocations) {
|
||||||
|
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||||
|
locations = new ol.render.webgl.texturereplay.defaultshader.Locations(gl, program);
|
||||||
|
this.defaultLocations = locations;
|
||||||
|
} else {
|
||||||
|
locations = this.defaultLocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use the program (FIXME: use the return value)
|
||||||
|
context.useProgram(program);
|
||||||
|
|
||||||
|
// enable the vertex attrib arrays
|
||||||
|
gl.enableVertexAttribArray(locations.a_position);
|
||||||
|
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
||||||
|
false, 32, 0);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(locations.a_offsets);
|
||||||
|
gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT,
|
||||||
|
false, 32, 8);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(locations.a_texCoord);
|
||||||
|
gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT,
|
||||||
|
false, 32, 16);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(locations.a_opacity);
|
||||||
|
gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT,
|
||||||
|
false, 32, 24);
|
||||||
|
|
||||||
|
gl.enableVertexAttribArray(locations.a_rotateWithView);
|
||||||
|
gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT,
|
||||||
|
false, 32, 28);
|
||||||
|
|
||||||
|
return locations;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||||
var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
|
gl.disableVertexAttribArray(locations.a_position);
|
||||||
var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
|
gl.disableVertexAttribArray(locations.a_offsets);
|
||||||
|
gl.disableVertexAttribArray(locations.a_texCoord);
|
||||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
gl.disableVertexAttribArray(locations.a_opacity);
|
||||||
this.drawReplaySkipping(
|
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
||||||
gl, context, skippedFeaturesHash, textures, groupIndices);
|
};
|
||||||
} else {
|
|
||||||
var i, ii, start;
|
|
||||||
for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {
|
|
||||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
|
||||||
var end = groupIndices[i];
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
start = end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw the replay while paying attention to skipped features.
|
* @inheritDoc
|
||||||
*
|
*/
|
||||||
* This functions creates groups of features that can be drawn to together,
|
ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||||
* so that the number of `drawElements` calls is minimized.
|
var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
|
||||||
*
|
var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
|
||||||
* For example given the following texture groups:
|
|
||||||
*
|
|
||||||
* Group 1: A B C
|
|
||||||
* Group 2: D [E] F G
|
|
||||||
*
|
|
||||||
* If feature E should be skipped, the following `drawElements` calls will be
|
|
||||||
* made:
|
|
||||||
*
|
|
||||||
* drawElements with feature A, B and C
|
|
||||||
* drawElements with feature D
|
|
||||||
* drawElements with feature F and G
|
|
||||||
*
|
|
||||||
* @protected
|
|
||||||
* @param {WebGLRenderingContext} gl gl.
|
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
|
||||||
* to skip.
|
|
||||||
* @param {Array.<WebGLTexture>} textures Textures.
|
|
||||||
* @param {Array.<number>} groupIndices Texture group indices.
|
|
||||||
*/
|
|
||||||
ol.render.webgl.TextureReplay.prototype.drawReplaySkipping = function(gl, context, skippedFeaturesHash, textures,
|
|
||||||
groupIndices) {
|
|
||||||
var featureIndex = 0;
|
|
||||||
|
|
||||||
var i, ii;
|
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
this.drawReplaySkipping(
|
||||||
|
gl, context, skippedFeaturesHash, textures, groupIndices);
|
||||||
|
} else {
|
||||||
|
var i, ii, start;
|
||||||
|
for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {
|
||||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||||
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
var end = groupIndices[i];
|
||||||
var groupEnd = groupIndices[i];
|
this.drawElements(gl, context, start, end);
|
||||||
|
start = end;
|
||||||
var start = groupStart;
|
|
||||||
var end = groupStart;
|
|
||||||
while (featureIndex < this.startIndices.length &&
|
|
||||||
this.startIndices[featureIndex] <= groupEnd) {
|
|
||||||
var feature = this.startIndicesFeature[featureIndex];
|
|
||||||
|
|
||||||
var featureUid = ol.getUid(feature).toString();
|
|
||||||
if (skippedFeaturesHash[featureUid] !== undefined) {
|
|
||||||
// feature should be skipped
|
|
||||||
if (start !== end) {
|
|
||||||
// draw the features so far
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
}
|
|
||||||
// continue with the next feature
|
|
||||||
start = (featureIndex === this.startIndices.length - 1) ?
|
|
||||||
groupEnd : this.startIndices[featureIndex + 1];
|
|
||||||
end = start;
|
|
||||||
} else {
|
|
||||||
// the feature is not skipped, augment the end index
|
|
||||||
end = (featureIndex === this.startIndices.length - 1) ?
|
|
||||||
groupEnd : this.startIndices[featureIndex + 1];
|
|
||||||
}
|
|
||||||
featureIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start !== end) {
|
|
||||||
// draw the remaining features (in case there was no skipped feature
|
|
||||||
// in this texture group, all features of a group are drawn together)
|
|
||||||
this.drawElements(gl, context, start, end);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* Draw the replay while paying attention to skipped features.
|
||||||
*/
|
*
|
||||||
ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
* This functions creates groups of features that can be drawn to together,
|
||||||
featureCallback, opt_hitExtent) {
|
* so that the number of `drawElements` calls is minimized.
|
||||||
var i, groupStart, start, end, feature, featureUid;
|
*
|
||||||
var featureIndex = this.startIndices.length - 1;
|
* For example given the following texture groups:
|
||||||
var hitDetectionTextures = this.getHitDetectionTextures();
|
*
|
||||||
for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
|
* Group 1: A B C
|
||||||
gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
|
* Group 2: D [E] F G
|
||||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
|
*
|
||||||
end = this.hitDetectionGroupIndices[i];
|
* If feature E should be skipped, the following `drawElements` calls will be
|
||||||
|
* made:
|
||||||
|
*
|
||||||
|
* drawElements with feature A, B and C
|
||||||
|
* drawElements with feature D
|
||||||
|
* drawElements with feature F and G
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @param {WebGLRenderingContext} gl gl.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||||
|
* to skip.
|
||||||
|
* @param {Array.<WebGLTexture>} textures Textures.
|
||||||
|
* @param {Array.<number>} groupIndices Texture group indices.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay.prototype.drawReplaySkipping = function(gl, context, skippedFeaturesHash, textures,
|
||||||
|
groupIndices) {
|
||||||
|
var featureIndex = 0;
|
||||||
|
|
||||||
// draw all features for this texture group
|
var i, ii;
|
||||||
while (featureIndex >= 0 &&
|
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||||
this.startIndices[featureIndex] >= groupStart) {
|
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||||
start = this.startIndices[featureIndex];
|
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
||||||
feature = this.startIndicesFeature[featureIndex];
|
var groupEnd = groupIndices[i];
|
||||||
featureUid = ol.getUid(feature).toString();
|
|
||||||
|
|
||||||
if (skippedFeaturesHash[featureUid] === undefined &&
|
var start = groupStart;
|
||||||
feature.getGeometry() &&
|
var end = groupStart;
|
||||||
(opt_hitExtent === undefined || ol.extent.intersects(
|
while (featureIndex < this.startIndices.length &&
|
||||||
/** @type {Array<number>} */ (opt_hitExtent),
|
this.startIndices[featureIndex] <= groupEnd) {
|
||||||
feature.getGeometry().getExtent()))) {
|
var feature = this.startIndicesFeature[featureIndex];
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
||||||
|
var featureUid = ol.getUid(feature).toString();
|
||||||
|
if (skippedFeaturesHash[featureUid] !== undefined) {
|
||||||
|
// feature should be skipped
|
||||||
|
if (start !== end) {
|
||||||
|
// draw the features so far
|
||||||
this.drawElements(gl, context, start, end);
|
this.drawElements(gl, context, start, end);
|
||||||
|
|
||||||
var result = featureCallback(feature);
|
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// continue with the next feature
|
||||||
|
start = (featureIndex === this.startIndices.length - 1) ?
|
||||||
|
groupEnd : this.startIndices[featureIndex + 1];
|
||||||
end = start;
|
end = start;
|
||||||
featureIndex--;
|
} else {
|
||||||
|
// the feature is not skipped, augment the end index
|
||||||
|
end = (featureIndex === this.startIndices.length - 1) ?
|
||||||
|
groupEnd : this.startIndices[featureIndex + 1];
|
||||||
}
|
}
|
||||||
|
featureIndex++;
|
||||||
}
|
}
|
||||||
return undefined;
|
|
||||||
};
|
if (start !== end) {
|
||||||
|
// draw the remaining features (in case there was no skipped feature
|
||||||
|
// in this texture group, all features of a group are drawn together)
|
||||||
|
this.drawElements(gl, context, start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.TextureReplay.prototype.finish = function(context) {
|
ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||||
this.anchorX = undefined;
|
featureCallback, opt_hitExtent) {
|
||||||
this.anchorY = undefined;
|
var i, groupStart, start, end, feature, featureUid;
|
||||||
this.height = undefined;
|
var featureIndex = this.startIndices.length - 1;
|
||||||
this.imageHeight = undefined;
|
var hitDetectionTextures = this.getHitDetectionTextures();
|
||||||
this.imageWidth = undefined;
|
for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
|
||||||
this.indices = null;
|
gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
|
||||||
this.opacity = undefined;
|
groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
|
||||||
this.originX = undefined;
|
end = this.hitDetectionGroupIndices[i];
|
||||||
this.originY = undefined;
|
|
||||||
this.rotateWithView = undefined;
|
// draw all features for this texture group
|
||||||
this.rotation = undefined;
|
while (featureIndex >= 0 &&
|
||||||
this.scale = undefined;
|
this.startIndices[featureIndex] >= groupStart) {
|
||||||
this.vertices = null;
|
start = this.startIndices[featureIndex];
|
||||||
this.width = undefined;
|
feature = this.startIndicesFeature[featureIndex];
|
||||||
};
|
featureUid = ol.getUid(feature).toString();
|
||||||
|
|
||||||
|
if (skippedFeaturesHash[featureUid] === undefined &&
|
||||||
|
feature.getGeometry() &&
|
||||||
|
(opt_hitExtent === undefined || ol.extent.intersects(
|
||||||
|
/** @type {Array<number>} */ (opt_hitExtent),
|
||||||
|
feature.getGeometry().getExtent()))) {
|
||||||
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
this.drawElements(gl, context, start, end);
|
||||||
|
|
||||||
|
var result = featureCallback(feature);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end = start;
|
||||||
|
featureIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @inheritDoc
|
||||||
* @protected
|
*/
|
||||||
* @param {boolean=} opt_all Return hit detection textures with regular ones.
|
ol.render.webgl.TextureReplay.prototype.finish = function(context) {
|
||||||
* @returns {Array.<WebGLTexture>} Textures.
|
this.anchorX = undefined;
|
||||||
*/
|
this.anchorY = undefined;
|
||||||
ol.render.webgl.TextureReplay.prototype.getTextures = function(opt_all) {};
|
this.height = undefined;
|
||||||
|
this.imageHeight = undefined;
|
||||||
|
this.imageWidth = undefined;
|
||||||
|
this.indices = null;
|
||||||
|
this.opacity = undefined;
|
||||||
|
this.originX = undefined;
|
||||||
|
this.originY = undefined;
|
||||||
|
this.rotateWithView = undefined;
|
||||||
|
this.rotation = undefined;
|
||||||
|
this.scale = undefined;
|
||||||
|
this.vertices = null;
|
||||||
|
this.width = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @abstract
|
||||||
* @protected
|
* @protected
|
||||||
* @returns {Array.<WebGLTexture>} Textures.
|
* @param {boolean=} opt_all Return hit detection textures with regular ones.
|
||||||
*/
|
* @returns {Array.<WebGLTexture>} Textures.
|
||||||
ol.render.webgl.TextureReplay.prototype.getHitDetectionTextures = function() {};
|
*/
|
||||||
}
|
ol.render.webgl.TextureReplay.prototype.getTextures = function(opt_all) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @protected
|
||||||
|
* @returns {Array.<WebGLTexture>} Textures.
|
||||||
|
*/
|
||||||
|
ol.render.webgl.TextureReplay.prototype.getHitDetectionTextures = function() {};
|
||||||
|
|||||||
@@ -6,149 +6,145 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\nvarying float v_opacity;\n\nuniform float u_opacity;\nuniform sampler2D u_image;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_image, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n float alpha = texColor.a * v_opacity * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.fragment = new ol.render.webgl.texturereplay.defaultshader.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\nvarying float v_opacity;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nattribute vec2 a_offsets;\nattribute float a_opacity;\nattribute float a_rotateWithView;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n if (a_rotateWithView == 1.0) {\n offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n }\n vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n v_texCoord = a_texCoord;\n v_opacity = a_opacity;\n}\n\n\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.vertex = new ol.render.webgl.texturereplay.defaultshader.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment = function() {
|
this.u_image = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\nvarying float v_opacity;\n\nuniform float u_opacity;\nuniform sampler2D u_image;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_image, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n float alpha = texColor.a * v_opacity * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n';
|
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
this.u_opacity = gl.getUniformLocation(
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||||
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.texturereplay.defaultshader.fragment = new ol.render.webgl.texturereplay.defaultshader.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex = function() {
|
this.u_projectionMatrix = gl.getUniformLocation(
|
||||||
ol.webgl.Vertex.call(this, ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||||
};
|
|
||||||
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\nvarying float v_opacity;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nattribute vec2 a_offsets;\nattribute float a_opacity;\nattribute float a_rotateWithView;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n if (a_rotateWithView == 1.0) {\n offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n }\n vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n v_texCoord = a_texCoord;\n v_opacity = a_opacity;\n}\n\n\n';
|
this.a_offsets = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_offsets' : 'e');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}';
|
this.a_opacity = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_opacity' : 'f');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
this.a_position = gl.getAttribLocation(
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
|
||||||
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.render.webgl.texturereplay.defaultshader.vertex = new ol.render.webgl.texturereplay.defaultshader.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {number}
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
|
this.a_rotateWithView = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {WebGLUniformLocation}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
this.u_image = gl.getUniformLocation(
|
this.a_texCoord = gl.getAttribLocation(
|
||||||
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
||||||
|
};
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_opacity = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_projectionMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_offsets = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_offsets' : 'e');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_opacity = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_opacity' : 'f');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_position = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_rotateWithView = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_texCoord = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,125 +6,121 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, ol.renderer.webgl.defaultmapshader.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.defaultmapshader.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform float u_opacity;\nuniform sampler2D u_texture;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_texture, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n gl_FragColor.a = texColor.a * u_opacity;\n}\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;uniform float f;uniform sampler2D g;void main(void){vec4 texColor=texture2D(g,a);gl_FragColor.rgb=texColor.rgb;gl_FragColor.a=texColor.a*f;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE :
|
||||||
|
ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.renderer.webgl.defaultmapshader.fragment = new ol.renderer.webgl.defaultmapshader.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, ol.renderer.webgl.defaultmapshader.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.defaultmapshader.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\n\nuniform mat4 u_texCoordMatrix;\nuniform mat4 u_projectionMatrix;\n\nvoid main(void) {\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\n v_texCoord = (u_texCoordMatrix * vec4(a_texCoord, 0., 1.)).st;\n}\n\n\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform mat4 d;uniform mat4 e;void main(void){gl_Position=e*vec4(b,0.,1.);a=(d*vec4(c,0.,1.)).st;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE :
|
||||||
|
ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.renderer.webgl.defaultmapshader.vertex = new ol.renderer.webgl.defaultmapshader.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.defaultmapshader.Locations = function(gl, program) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment = function() {
|
this.u_opacity = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, ol.renderer.webgl.defaultmapshader.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.defaultmapshader.Fragment, ol.webgl.Fragment);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform float u_opacity;\nuniform sampler2D u_texture;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_texture, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n gl_FragColor.a = texColor.a * u_opacity;\n}\n';
|
this.u_projectionMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;uniform float f;uniform sampler2D g;void main(void){vec4 texColor=texture2D(g,a);gl_FragColor.rgb=texColor.rgb;gl_FragColor.a=texColor.a*f;}';
|
this.u_texCoordMatrix = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
this.u_texture = gl.getUniformLocation(
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'u_texture' : 'g');
|
||||||
ol.renderer.webgl.defaultmapshader.Fragment.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.renderer.webgl.defaultmapshader.fragment = new ol.renderer.webgl.defaultmapshader.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {number}
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex = function() {
|
this.a_position = gl.getAttribLocation(
|
||||||
ol.webgl.Vertex.call(this, ol.renderer.webgl.defaultmapshader.Vertex.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.defaultmapshader.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\n\nuniform mat4 u_texCoordMatrix;\nuniform mat4 u_projectionMatrix;\n\nvoid main(void) {\n gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);\n v_texCoord = (u_texCoordMatrix * vec4(a_texCoord, 0., 1.)).st;\n}\n\n\n';
|
this.a_texCoord = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||||
|
};
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform mat4 d;uniform mat4 e;void main(void){gl_Position=e*vec4(b,0.,1.);a=(d*vec4(c,0.,1.)).st;}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex.DEBUG_SOURCE :
|
|
||||||
ol.renderer.webgl.defaultmapshader.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.renderer.webgl.defaultmapshader.vertex = new ol.renderer.webgl.defaultmapshader.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.defaultmapshader.Locations = function(gl, program) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_opacity = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_projectionMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'e');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_texCoordMatrix = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_texCoordMatrix' : 'd');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_texture = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_texture' : 'g');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_position = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_texCoord = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,324 +14,320 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.Context');
|
goog.require('ol.webgl.Context');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.renderer.webgl.Layer}
|
||||||
|
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||||
|
* @param {ol.layer.Image} imageLayer Tile layer.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) {
|
||||||
|
|
||||||
|
ol.renderer.webgl.Layer.call(this, mapRenderer, imageLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* The last rendered image.
|
||||||
* @extends {ol.renderer.webgl.Layer}
|
* @private
|
||||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
* @type {?ol.ImageBase}
|
||||||
* @param {ol.layer.Image} imageLayer Tile layer.
|
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) {
|
this.image_ = null;
|
||||||
|
|
||||||
ol.renderer.webgl.Layer.call(this, mapRenderer, imageLayer);
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {CanvasRenderingContext2D}
|
||||||
|
*/
|
||||||
|
this.hitCanvasContext_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last rendered image.
|
* @private
|
||||||
* @private
|
* @type {?ol.Transform}
|
||||||
* @type {?ol.ImageBase}
|
*/
|
||||||
*/
|
this.hitTransformationMatrix_ = null;
|
||||||
this.image_ = null;
|
|
||||||
|
|
||||||
/**
|
};
|
||||||
* @private
|
ol.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
|
||||||
* @type {CanvasRenderingContext2D}
|
|
||||||
*/
|
|
||||||
this.hitCanvasContext_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
/**
|
||||||
* @type {?ol.Transform}
|
* Determine if this renderer handles the provided layer.
|
||||||
*/
|
* @param {ol.renderer.Type} type The renderer type.
|
||||||
|
* @param {ol.layer.Layer} layer The candidate layer.
|
||||||
|
* @return {boolean} The renderer can render the layer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer['handles'] = function(type, layer) {
|
||||||
|
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.IMAGE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a layer renderer.
|
||||||
|
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
||||||
|
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
||||||
|
* @return {ol.renderer.webgl.ImageLayer} The layer renderer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer['create'] = function(mapRenderer, layer) {
|
||||||
|
return new ol.renderer.webgl.ImageLayer(
|
||||||
|
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
||||||
|
/** @type {ol.layer.Image} */ (layer)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.ImageBase} image Image.
|
||||||
|
* @private
|
||||||
|
* @return {WebGLTexture} Texture.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) {
|
||||||
|
|
||||||
|
// We meet the conditions to work with non-power of two textures.
|
||||||
|
// http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support
|
||||||
|
// http://learningwebgl.com/blog/?p=2101
|
||||||
|
|
||||||
|
var imageElement = image.getImage();
|
||||||
|
var gl = this.mapRenderer.getGL();
|
||||||
|
|
||||||
|
return ol.webgl.Context.createTexture(
|
||||||
|
gl, imageElement, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
|
||||||
|
var layer = this.getLayer();
|
||||||
|
var source = layer.getSource();
|
||||||
|
var resolution = frameState.viewState.resolution;
|
||||||
|
var rotation = frameState.viewState.rotation;
|
||||||
|
var skippedFeatureUids = frameState.skippedFeatureUids;
|
||||||
|
return source.forEachFeatureAtCoordinate(
|
||||||
|
coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
|
* @return {?} Callback result.
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
return callback.call(thisArg, feature, layer);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
||||||
|
|
||||||
|
var gl = this.mapRenderer.getGL();
|
||||||
|
|
||||||
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var viewCenter = viewState.center;
|
||||||
|
var viewResolution = viewState.resolution;
|
||||||
|
var viewRotation = viewState.rotation;
|
||||||
|
|
||||||
|
var image = this.image_;
|
||||||
|
var texture = this.texture;
|
||||||
|
var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
|
||||||
|
var imageSource = imageLayer.getSource();
|
||||||
|
|
||||||
|
var hints = frameState.viewHints;
|
||||||
|
|
||||||
|
var renderedExtent = frameState.extent;
|
||||||
|
if (layerState.extent !== undefined) {
|
||||||
|
renderedExtent = ol.extent.getIntersection(
|
||||||
|
renderedExtent, layerState.extent);
|
||||||
|
}
|
||||||
|
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
|
||||||
|
!ol.extent.isEmpty(renderedExtent)) {
|
||||||
|
var projection = viewState.projection;
|
||||||
|
if (!ol.ENABLE_RASTER_REPROJECTION) {
|
||||||
|
var sourceProjection = imageSource.getProjection();
|
||||||
|
if (sourceProjection) {
|
||||||
|
projection = sourceProjection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var image_ = imageSource.getImage(renderedExtent, viewResolution,
|
||||||
|
pixelRatio, projection);
|
||||||
|
if (image_) {
|
||||||
|
var loaded = this.loadImage(image_);
|
||||||
|
if (loaded) {
|
||||||
|
image = image_;
|
||||||
|
texture = this.createTexture_(image_);
|
||||||
|
if (this.texture) {
|
||||||
|
/**
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLTexture} texture Texture.
|
||||||
|
*/
|
||||||
|
var postRenderFunction = function(gl, texture) {
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
gl.deleteTexture(texture);
|
||||||
|
}
|
||||||
|
}.bind(null, gl, this.texture);
|
||||||
|
frameState.postRenderFunctions.push(
|
||||||
|
/** @type {ol.PostRenderFunction} */ (postRenderFunction)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image) {
|
||||||
|
var canvas = this.mapRenderer.getContext().getCanvas();
|
||||||
|
|
||||||
|
this.updateProjectionMatrix_(canvas.width, canvas.height,
|
||||||
|
pixelRatio, viewCenter, viewResolution, viewRotation,
|
||||||
|
image.getExtent());
|
||||||
this.hitTransformationMatrix_ = null;
|
this.hitTransformationMatrix_ = null;
|
||||||
|
|
||||||
};
|
// Translate and scale to flip the Y coord.
|
||||||
ol.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
|
var texCoordMatrix = this.texCoordMatrix;
|
||||||
|
ol.transform.reset(texCoordMatrix);
|
||||||
|
ol.transform.scale(texCoordMatrix, 1, -1);
|
||||||
|
ol.transform.translate(texCoordMatrix, 0, -1);
|
||||||
|
|
||||||
|
this.image_ = image;
|
||||||
|
this.texture = texture;
|
||||||
|
|
||||||
|
this.updateAttributions(frameState.attributions, image.getAttributions());
|
||||||
|
this.updateLogos(frameState, imageSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!image;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this renderer handles the provided layer.
|
* @param {number} canvasWidth Canvas width.
|
||||||
* @param {ol.renderer.Type} type The renderer type.
|
* @param {number} canvasHeight Canvas height.
|
||||||
* @param {ol.layer.Layer} layer The candidate layer.
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @return {boolean} The renderer can render the layer.
|
* @param {ol.Coordinate} viewCenter View center.
|
||||||
*/
|
* @param {number} viewResolution View resolution.
|
||||||
ol.renderer.webgl.ImageLayer['handles'] = function(type, layer) {
|
* @param {number} viewRotation View rotation.
|
||||||
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.IMAGE;
|
* @param {ol.Extent} imageExtent Image extent.
|
||||||
};
|
* @private
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = function(canvasWidth, canvasHeight, pixelRatio,
|
||||||
|
viewCenter, viewResolution, viewRotation, imageExtent) {
|
||||||
|
|
||||||
|
var canvasExtentWidth = canvasWidth * viewResolution;
|
||||||
|
var canvasExtentHeight = canvasHeight * viewResolution;
|
||||||
|
|
||||||
|
var projectionMatrix = this.projectionMatrix;
|
||||||
|
ol.transform.reset(projectionMatrix);
|
||||||
|
ol.transform.scale(projectionMatrix,
|
||||||
|
pixelRatio * 2 / canvasExtentWidth,
|
||||||
|
pixelRatio * 2 / canvasExtentHeight);
|
||||||
|
ol.transform.rotate(projectionMatrix, -viewRotation);
|
||||||
|
ol.transform.translate(projectionMatrix,
|
||||||
|
imageExtent[0] - viewCenter[0],
|
||||||
|
imageExtent[1] - viewCenter[1]);
|
||||||
|
ol.transform.scale(projectionMatrix,
|
||||||
|
(imageExtent[2] - imageExtent[0]) / 2,
|
||||||
|
(imageExtent[3] - imageExtent[1]) / 2);
|
||||||
|
ol.transform.translate(projectionMatrix, 1, 1);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a layer renderer.
|
* @inheritDoc
|
||||||
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
*/
|
||||||
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
|
||||||
* @return {ol.renderer.webgl.ImageLayer} The layer renderer.
|
var hasFeature = this.forEachFeatureAtCoordinate(
|
||||||
*/
|
coordinate, frameState, 0, ol.functions.TRUE, this);
|
||||||
ol.renderer.webgl.ImageLayer['create'] = function(mapRenderer, layer) {
|
return hasFeature !== undefined;
|
||||||
return new ol.renderer.webgl.ImageLayer(
|
};
|
||||||
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
|
||||||
/** @type {ol.layer.Image} */ (layer)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.ImageBase} image Image.
|
* @inheritDoc
|
||||||
* @private
|
*/
|
||||||
* @return {WebGLTexture} Texture.
|
ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
||||||
*/
|
if (!this.image_ || !this.image_.getImage()) {
|
||||||
ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) {
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
// We meet the conditions to work with non-power of two textures.
|
if (this.getLayer().getSource() instanceof ol.source.ImageVector) {
|
||||||
// http://www.khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences#Non-Power_of_Two_Texture_Support
|
// for ImageVector sources use the original hit-detection logic,
|
||||||
// http://learningwebgl.com/blog/?p=2101
|
// so that for example also transparent polygons are detected
|
||||||
|
var coordinate = ol.transform.apply(
|
||||||
var imageElement = image.getImage();
|
frameState.pixelToCoordinateTransform, pixel.slice());
|
||||||
var gl = this.mapRenderer.getGL();
|
|
||||||
|
|
||||||
return ol.webgl.Context.createTexture(
|
|
||||||
gl, imageElement, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.ImageLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
|
|
||||||
var layer = this.getLayer();
|
|
||||||
var source = layer.getSource();
|
|
||||||
var resolution = frameState.viewState.resolution;
|
|
||||||
var rotation = frameState.viewState.rotation;
|
|
||||||
var skippedFeatureUids = frameState.skippedFeatureUids;
|
|
||||||
return source.forEachFeatureAtCoordinate(
|
|
||||||
coordinate, resolution, rotation, hitTolerance, skippedFeatureUids,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
|
||||||
* @return {?} Callback result.
|
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
return callback.call(thisArg, feature, layer);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.ImageLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
|
||||||
|
|
||||||
var gl = this.mapRenderer.getGL();
|
|
||||||
|
|
||||||
var pixelRatio = frameState.pixelRatio;
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var viewCenter = viewState.center;
|
|
||||||
var viewResolution = viewState.resolution;
|
|
||||||
var viewRotation = viewState.rotation;
|
|
||||||
|
|
||||||
var image = this.image_;
|
|
||||||
var texture = this.texture;
|
|
||||||
var imageLayer = /** @type {ol.layer.Image} */ (this.getLayer());
|
|
||||||
var imageSource = imageLayer.getSource();
|
|
||||||
|
|
||||||
var hints = frameState.viewHints;
|
|
||||||
|
|
||||||
var renderedExtent = frameState.extent;
|
|
||||||
if (layerState.extent !== undefined) {
|
|
||||||
renderedExtent = ol.extent.getIntersection(
|
|
||||||
renderedExtent, layerState.extent);
|
|
||||||
}
|
|
||||||
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
|
|
||||||
!ol.extent.isEmpty(renderedExtent)) {
|
|
||||||
var projection = viewState.projection;
|
|
||||||
if (!ol.ENABLE_RASTER_REPROJECTION) {
|
|
||||||
var sourceProjection = imageSource.getProjection();
|
|
||||||
if (sourceProjection) {
|
|
||||||
projection = sourceProjection;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var image_ = imageSource.getImage(renderedExtent, viewResolution,
|
|
||||||
pixelRatio, projection);
|
|
||||||
if (image_) {
|
|
||||||
var loaded = this.loadImage(image_);
|
|
||||||
if (loaded) {
|
|
||||||
image = image_;
|
|
||||||
texture = this.createTexture_(image_);
|
|
||||||
if (this.texture) {
|
|
||||||
/**
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLTexture} texture Texture.
|
|
||||||
*/
|
|
||||||
var postRenderFunction = function(gl, texture) {
|
|
||||||
if (!gl.isContextLost()) {
|
|
||||||
gl.deleteTexture(texture);
|
|
||||||
}
|
|
||||||
}.bind(null, gl, this.texture);
|
|
||||||
frameState.postRenderFunctions.push(
|
|
||||||
/** @type {ol.PostRenderFunction} */ (postRenderFunction)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image) {
|
|
||||||
var canvas = this.mapRenderer.getContext().getCanvas();
|
|
||||||
|
|
||||||
this.updateProjectionMatrix_(canvas.width, canvas.height,
|
|
||||||
pixelRatio, viewCenter, viewResolution, viewRotation,
|
|
||||||
image.getExtent());
|
|
||||||
this.hitTransformationMatrix_ = null;
|
|
||||||
|
|
||||||
// Translate and scale to flip the Y coord.
|
|
||||||
var texCoordMatrix = this.texCoordMatrix;
|
|
||||||
ol.transform.reset(texCoordMatrix);
|
|
||||||
ol.transform.scale(texCoordMatrix, 1, -1);
|
|
||||||
ol.transform.translate(texCoordMatrix, 0, -1);
|
|
||||||
|
|
||||||
this.image_ = image;
|
|
||||||
this.texture = texture;
|
|
||||||
|
|
||||||
this.updateAttributions(frameState.attributions, image.getAttributions());
|
|
||||||
this.updateLogos(frameState, imageSource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !!image;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} canvasWidth Canvas width.
|
|
||||||
* @param {number} canvasHeight Canvas height.
|
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {ol.Coordinate} viewCenter View center.
|
|
||||||
* @param {number} viewResolution View resolution.
|
|
||||||
* @param {number} viewRotation View rotation.
|
|
||||||
* @param {ol.Extent} imageExtent Image extent.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = function(canvasWidth, canvasHeight, pixelRatio,
|
|
||||||
viewCenter, viewResolution, viewRotation, imageExtent) {
|
|
||||||
|
|
||||||
var canvasExtentWidth = canvasWidth * viewResolution;
|
|
||||||
var canvasExtentHeight = canvasHeight * viewResolution;
|
|
||||||
|
|
||||||
var projectionMatrix = this.projectionMatrix;
|
|
||||||
ol.transform.reset(projectionMatrix);
|
|
||||||
ol.transform.scale(projectionMatrix,
|
|
||||||
pixelRatio * 2 / canvasExtentWidth,
|
|
||||||
pixelRatio * 2 / canvasExtentHeight);
|
|
||||||
ol.transform.rotate(projectionMatrix, -viewRotation);
|
|
||||||
ol.transform.translate(projectionMatrix,
|
|
||||||
imageExtent[0] - viewCenter[0],
|
|
||||||
imageExtent[1] - viewCenter[1]);
|
|
||||||
ol.transform.scale(projectionMatrix,
|
|
||||||
(imageExtent[2] - imageExtent[0]) / 2,
|
|
||||||
(imageExtent[3] - imageExtent[1]) / 2);
|
|
||||||
ol.transform.translate(projectionMatrix, 1, 1);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
|
|
||||||
var hasFeature = this.forEachFeatureAtCoordinate(
|
var hasFeature = this.forEachFeatureAtCoordinate(
|
||||||
coordinate, frameState, 0, ol.functions.TRUE, this);
|
coordinate, frameState, 0, ol.functions.TRUE, this);
|
||||||
return hasFeature !== undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (hasFeature) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), null);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var imageSize =
|
||||||
|
[this.image_.getImage().width, this.image_.getImage().height];
|
||||||
|
|
||||||
/**
|
if (!this.hitTransformationMatrix_) {
|
||||||
* @inheritDoc
|
this.hitTransformationMatrix_ = this.getHitTransformationMatrix_(
|
||||||
*/
|
frameState.size, imageSize);
|
||||||
ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
}
|
||||||
if (!this.image_ || !this.image_.getImage()) {
|
|
||||||
|
var pixelOnFrameBuffer = ol.transform.apply(
|
||||||
|
this.hitTransformationMatrix_, pixel.slice());
|
||||||
|
|
||||||
|
if (pixelOnFrameBuffer[0] < 0 || pixelOnFrameBuffer[0] > imageSize[0] ||
|
||||||
|
pixelOnFrameBuffer[1] < 0 || pixelOnFrameBuffer[1] > imageSize[1]) {
|
||||||
|
// outside the image, no need to check
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getLayer().getSource() instanceof ol.source.ImageVector) {
|
if (!this.hitCanvasContext_) {
|
||||||
// for ImageVector sources use the original hit-detection logic,
|
this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
|
||||||
// so that for example also transparent polygons are detected
|
|
||||||
var coordinate = ol.transform.apply(
|
|
||||||
frameState.pixelToCoordinateTransform, pixel.slice());
|
|
||||||
var hasFeature = this.forEachFeatureAtCoordinate(
|
|
||||||
coordinate, frameState, 0, ol.functions.TRUE, this);
|
|
||||||
|
|
||||||
if (hasFeature) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), null);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var imageSize =
|
|
||||||
[this.image_.getImage().width, this.image_.getImage().height];
|
|
||||||
|
|
||||||
if (!this.hitTransformationMatrix_) {
|
|
||||||
this.hitTransformationMatrix_ = this.getHitTransformationMatrix_(
|
|
||||||
frameState.size, imageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
var pixelOnFrameBuffer = ol.transform.apply(
|
|
||||||
this.hitTransformationMatrix_, pixel.slice());
|
|
||||||
|
|
||||||
if (pixelOnFrameBuffer[0] < 0 || pixelOnFrameBuffer[0] > imageSize[0] ||
|
|
||||||
pixelOnFrameBuffer[1] < 0 || pixelOnFrameBuffer[1] > imageSize[1]) {
|
|
||||||
// outside the image, no need to check
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.hitCanvasContext_) {
|
|
||||||
this.hitCanvasContext_ = ol.dom.createCanvasContext2D(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.hitCanvasContext_.clearRect(0, 0, 1, 1);
|
|
||||||
this.hitCanvasContext_.drawImage(this.image_.getImage(),
|
|
||||||
pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1, 0, 0, 1, 1);
|
|
||||||
|
|
||||||
var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
|
|
||||||
if (imageData[3] > 0) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), imageData);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
this.hitCanvasContext_.clearRect(0, 0, 1, 1);
|
||||||
|
this.hitCanvasContext_.drawImage(this.image_.getImage(),
|
||||||
|
pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1, 0, 0, 1, 1);
|
||||||
|
|
||||||
|
var imageData = this.hitCanvasContext_.getImageData(0, 0, 1, 1).data;
|
||||||
|
if (imageData[3] > 0) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), imageData);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The transformation matrix to get the pixel on the image for a
|
* The transformation matrix to get the pixel on the image for a
|
||||||
* pixel on the map.
|
* pixel on the map.
|
||||||
* @param {ol.Size} mapSize The map size.
|
* @param {ol.Size} mapSize The map size.
|
||||||
* @param {ol.Size} imageSize The image size.
|
* @param {ol.Size} imageSize The image size.
|
||||||
* @return {ol.Transform} The transformation matrix.
|
* @return {ol.Transform} The transformation matrix.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) {
|
ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) {
|
||||||
// the first matrix takes a map pixel, flips the y-axis and scales to
|
// the first matrix takes a map pixel, flips the y-axis and scales to
|
||||||
// a range between -1 ... 1
|
// a range between -1 ... 1
|
||||||
var mapCoordTransform = ol.transform.create();
|
var mapCoordTransform = ol.transform.create();
|
||||||
ol.transform.translate(mapCoordTransform, -1, -1);
|
ol.transform.translate(mapCoordTransform, -1, -1);
|
||||||
ol.transform.scale(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);
|
ol.transform.scale(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);
|
||||||
ol.transform.translate(mapCoordTransform, 0, mapSize[1]);
|
ol.transform.translate(mapCoordTransform, 0, mapSize[1]);
|
||||||
ol.transform.scale(mapCoordTransform, 1, -1);
|
ol.transform.scale(mapCoordTransform, 1, -1);
|
||||||
|
|
||||||
// the second matrix is the inverse of the projection matrix used in the
|
// the second matrix is the inverse of the projection matrix used in the
|
||||||
// shader for drawing
|
// shader for drawing
|
||||||
var projectionMatrixInv = ol.transform.invert(this.projectionMatrix.slice());
|
var projectionMatrixInv = ol.transform.invert(this.projectionMatrix.slice());
|
||||||
|
|
||||||
// the third matrix scales to the image dimensions and flips the y-axis again
|
// the third matrix scales to the image dimensions and flips the y-axis again
|
||||||
var transform = ol.transform.create();
|
var transform = ol.transform.create();
|
||||||
ol.transform.translate(transform, 0, imageSize[1]);
|
ol.transform.translate(transform, 0, imageSize[1]);
|
||||||
ol.transform.scale(transform, 1, -1);
|
ol.transform.scale(transform, 1, -1);
|
||||||
ol.transform.scale(transform, imageSize[0] / 2, imageSize[1] / 2);
|
ol.transform.scale(transform, imageSize[0] / 2, imageSize[1] / 2);
|
||||||
ol.transform.translate(transform, 1, 1);
|
ol.transform.translate(transform, 1, 1);
|
||||||
|
|
||||||
ol.transform.multiply(transform, projectionMatrixInv);
|
ol.transform.multiply(transform, projectionMatrixInv);
|
||||||
ol.transform.multiply(transform, mapCoordTransform);
|
ol.transform.multiply(transform, mapCoordTransform);
|
||||||
|
|
||||||
return transform;
|
return transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,260 +13,256 @@ goog.require('ol.webgl.Buffer');
|
|||||||
goog.require('ol.webgl.Context');
|
goog.require('ol.webgl.Context');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @abstract
|
||||||
|
* @extends {ol.renderer.Layer}
|
||||||
|
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||||
|
* @param {ol.layer.Layer} layer Layer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Layer = function(mapRenderer, layer) {
|
||||||
|
|
||||||
|
ol.renderer.Layer.call(this, layer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
|
||||||
* @abstract
|
|
||||||
* @extends {ol.renderer.Layer}
|
|
||||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
|
||||||
* @param {ol.layer.Layer} layer Layer.
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.Layer = function(mapRenderer, layer) {
|
|
||||||
|
|
||||||
ol.renderer.Layer.call(this, layer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {ol.renderer.webgl.Map}
|
|
||||||
*/
|
|
||||||
this.mapRenderer = mapRenderer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.webgl.Buffer}
|
|
||||||
*/
|
|
||||||
this.arrayBuffer_ = new ol.webgl.Buffer([
|
|
||||||
-1, -1, 0, 0,
|
|
||||||
1, -1, 1, 0,
|
|
||||||
-1, 1, 0, 1,
|
|
||||||
1, 1, 1, 1
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {WebGLTexture}
|
|
||||||
*/
|
|
||||||
this.texture = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {WebGLFramebuffer}
|
|
||||||
*/
|
|
||||||
this.framebuffer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {number|undefined}
|
|
||||||
*/
|
|
||||||
this.framebufferDimension = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.texCoordMatrix = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @type {ol.Transform}
|
|
||||||
*/
|
|
||||||
this.projectionMatrix = ol.transform.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Array.<number>}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.tmpMat4_ = ol.vec.Mat4.create();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.renderer.webgl.defaultmapshader.Locations}
|
|
||||||
*/
|
|
||||||
this.defaultLocations_ = null;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
|
||||||
* @param {number} framebufferDimension Framebuffer dimension.
|
|
||||||
* @protected
|
* @protected
|
||||||
|
* @type {ol.renderer.webgl.Map}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Layer.prototype.bindFramebuffer = function(frameState, framebufferDimension) {
|
this.mapRenderer = mapRenderer;
|
||||||
|
|
||||||
var gl = this.mapRenderer.getGL();
|
|
||||||
|
|
||||||
if (this.framebufferDimension === undefined ||
|
|
||||||
this.framebufferDimension != framebufferDimension) {
|
|
||||||
/**
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLFramebuffer} framebuffer Framebuffer.
|
|
||||||
* @param {WebGLTexture} texture Texture.
|
|
||||||
*/
|
|
||||||
var postRenderFunction = function(gl, framebuffer, texture) {
|
|
||||||
if (!gl.isContextLost()) {
|
|
||||||
gl.deleteFramebuffer(framebuffer);
|
|
||||||
gl.deleteTexture(texture);
|
|
||||||
}
|
|
||||||
}.bind(null, gl, this.framebuffer, this.texture);
|
|
||||||
|
|
||||||
frameState.postRenderFunctions.push(
|
|
||||||
/** @type {ol.PostRenderFunction} */ (postRenderFunction)
|
|
||||||
);
|
|
||||||
|
|
||||||
var texture = ol.webgl.Context.createEmptyTexture(
|
|
||||||
gl, framebufferDimension, framebufferDimension);
|
|
||||||
|
|
||||||
var framebuffer = gl.createFramebuffer();
|
|
||||||
gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, framebuffer);
|
|
||||||
gl.framebufferTexture2D(ol.webgl.FRAMEBUFFER,
|
|
||||||
ol.webgl.COLOR_ATTACHMENT0, ol.webgl.TEXTURE_2D, texture, 0);
|
|
||||||
|
|
||||||
this.texture = texture;
|
|
||||||
this.framebuffer = framebuffer;
|
|
||||||
this.framebufferDimension = framebufferDimension;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, this.framebuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
* @private
|
||||||
* @param {ol.LayerState} layerState Layer state.
|
* @type {ol.webgl.Buffer}
|
||||||
* @param {ol.webgl.Context} context Context.
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Layer.prototype.composeFrame = function(frameState, layerState, context) {
|
this.arrayBuffer_ = new ol.webgl.Buffer([
|
||||||
|
-1, -1, 0, 0,
|
||||||
this.dispatchComposeEvent_(
|
1, -1, 1, 0,
|
||||||
ol.render.EventType.PRECOMPOSE, context, frameState);
|
-1, 1, 0, 1,
|
||||||
|
1, 1, 1, 1
|
||||||
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
]);
|
||||||
|
|
||||||
var gl = context.getGL();
|
|
||||||
|
|
||||||
var fragmentShader = ol.renderer.webgl.defaultmapshader.fragment;
|
|
||||||
var vertexShader = ol.renderer.webgl.defaultmapshader.vertex;
|
|
||||||
|
|
||||||
var program = context.getProgram(fragmentShader, vertexShader);
|
|
||||||
|
|
||||||
var locations;
|
|
||||||
if (!this.defaultLocations_) {
|
|
||||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
|
||||||
locations = new ol.renderer.webgl.defaultmapshader.Locations(gl, program);
|
|
||||||
this.defaultLocations_ = locations;
|
|
||||||
} else {
|
|
||||||
locations = this.defaultLocations_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context.useProgram(program)) {
|
|
||||||
gl.enableVertexAttribArray(locations.a_position);
|
|
||||||
gl.vertexAttribPointer(
|
|
||||||
locations.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
|
|
||||||
gl.enableVertexAttribArray(locations.a_texCoord);
|
|
||||||
gl.vertexAttribPointer(
|
|
||||||
locations.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
|
|
||||||
gl.uniform1i(locations.u_texture, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.uniformMatrix4fv(locations.u_texCoordMatrix, false,
|
|
||||||
ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getTexCoordMatrix()));
|
|
||||||
gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
|
|
||||||
ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getProjectionMatrix()));
|
|
||||||
gl.uniform1f(locations.u_opacity, layerState.opacity);
|
|
||||||
gl.bindTexture(ol.webgl.TEXTURE_2D, this.getTexture());
|
|
||||||
gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
this.dispatchComposeEvent_(
|
|
||||||
ol.render.EventType.POSTCOMPOSE, context, frameState);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.render.EventType} type Event type.
|
* @protected
|
||||||
* @param {ol.webgl.Context} context WebGL context.
|
* @type {WebGLTexture}
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
*/
|
||||||
|
this.texture = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {WebGLFramebuffer}
|
||||||
|
*/
|
||||||
|
this.framebuffer = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {number|undefined}
|
||||||
|
*/
|
||||||
|
this.framebufferDimension = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {ol.Transform}
|
||||||
|
*/
|
||||||
|
this.texCoordMatrix = ol.transform.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @protected
|
||||||
|
* @type {ol.Transform}
|
||||||
|
*/
|
||||||
|
this.projectionMatrix = ol.transform.create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Array.<number>}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState) {
|
this.tmpMat4_ = ol.vec.Mat4.create();
|
||||||
var layer = this.getLayer();
|
|
||||||
if (layer.hasListener(type)) {
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var resolution = viewState.resolution;
|
|
||||||
var pixelRatio = frameState.pixelRatio;
|
|
||||||
var extent = frameState.extent;
|
|
||||||
var center = viewState.center;
|
|
||||||
var rotation = viewState.rotation;
|
|
||||||
var size = frameState.size;
|
|
||||||
|
|
||||||
var render = new ol.render.webgl.Immediate(
|
|
||||||
context, center, resolution, rotation, size, extent, pixelRatio);
|
|
||||||
var composeEvent = new ol.render.Event(
|
|
||||||
type, render, frameState, null, context);
|
|
||||||
layer.dispatchEvent(composeEvent);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!ol.Transform} Matrix.
|
* @private
|
||||||
|
* @type {ol.renderer.webgl.defaultmapshader.Locations}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = function() {
|
this.defaultLocations_ = null;
|
||||||
return this.texCoordMatrix;
|
|
||||||
};
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {WebGLTexture} Texture.
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
*/
|
* @param {number} framebufferDimension Framebuffer dimension.
|
||||||
ol.renderer.webgl.Layer.prototype.getTexture = function() {
|
* @protected
|
||||||
return this.texture;
|
*/
|
||||||
};
|
ol.renderer.webgl.Layer.prototype.bindFramebuffer = function(frameState, framebufferDimension) {
|
||||||
|
|
||||||
|
var gl = this.mapRenderer.getGL();
|
||||||
|
|
||||||
|
if (this.framebufferDimension === undefined ||
|
||||||
|
this.framebufferDimension != framebufferDimension) {
|
||||||
|
/**
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLFramebuffer} framebuffer Framebuffer.
|
||||||
|
* @param {WebGLTexture} texture Texture.
|
||||||
|
*/
|
||||||
|
var postRenderFunction = function(gl, framebuffer, texture) {
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
gl.deleteFramebuffer(framebuffer);
|
||||||
|
gl.deleteTexture(texture);
|
||||||
|
}
|
||||||
|
}.bind(null, gl, this.framebuffer, this.texture);
|
||||||
|
|
||||||
|
frameState.postRenderFunctions.push(
|
||||||
|
/** @type {ol.PostRenderFunction} */ (postRenderFunction)
|
||||||
|
);
|
||||||
|
|
||||||
|
var texture = ol.webgl.Context.createEmptyTexture(
|
||||||
|
gl, framebufferDimension, framebufferDimension);
|
||||||
|
|
||||||
|
var framebuffer = gl.createFramebuffer();
|
||||||
|
gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, framebuffer);
|
||||||
|
gl.framebufferTexture2D(ol.webgl.FRAMEBUFFER,
|
||||||
|
ol.webgl.COLOR_ATTACHMENT0, ol.webgl.TEXTURE_2D, texture, 0);
|
||||||
|
|
||||||
|
this.texture = texture;
|
||||||
|
this.framebuffer = framebuffer;
|
||||||
|
this.framebufferDimension = framebufferDimension;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
gl.bindFramebuffer(ol.webgl.FRAMEBUFFER, this.framebuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {!ol.Transform} Matrix.
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
*/
|
* @param {ol.LayerState} layerState Layer state.
|
||||||
ol.renderer.webgl.Layer.prototype.getProjectionMatrix = function() {
|
* @param {ol.webgl.Context} context Context.
|
||||||
return this.projectionMatrix;
|
*/
|
||||||
};
|
ol.renderer.webgl.Layer.prototype.composeFrame = function(frameState, layerState, context) {
|
||||||
|
|
||||||
|
this.dispatchComposeEvent_(
|
||||||
|
ol.render.EventType.PRECOMPOSE, context, frameState);
|
||||||
|
|
||||||
|
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.arrayBuffer_);
|
||||||
|
|
||||||
|
var gl = context.getGL();
|
||||||
|
|
||||||
|
var fragmentShader = ol.renderer.webgl.defaultmapshader.fragment;
|
||||||
|
var vertexShader = ol.renderer.webgl.defaultmapshader.vertex;
|
||||||
|
|
||||||
|
var program = context.getProgram(fragmentShader, vertexShader);
|
||||||
|
|
||||||
|
var locations;
|
||||||
|
if (!this.defaultLocations_) {
|
||||||
|
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||||
|
locations = new ol.renderer.webgl.defaultmapshader.Locations(gl, program);
|
||||||
|
this.defaultLocations_ = locations;
|
||||||
|
} else {
|
||||||
|
locations = this.defaultLocations_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.useProgram(program)) {
|
||||||
|
gl.enableVertexAttribArray(locations.a_position);
|
||||||
|
gl.vertexAttribPointer(
|
||||||
|
locations.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
|
||||||
|
gl.enableVertexAttribArray(locations.a_texCoord);
|
||||||
|
gl.vertexAttribPointer(
|
||||||
|
locations.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
|
||||||
|
gl.uniform1i(locations.u_texture, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.uniformMatrix4fv(locations.u_texCoordMatrix, false,
|
||||||
|
ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getTexCoordMatrix()));
|
||||||
|
gl.uniformMatrix4fv(locations.u_projectionMatrix, false,
|
||||||
|
ol.vec.Mat4.fromTransform(this.tmpMat4_, this.getProjectionMatrix()));
|
||||||
|
gl.uniform1f(locations.u_opacity, layerState.opacity);
|
||||||
|
gl.bindTexture(ol.webgl.TEXTURE_2D, this.getTexture());
|
||||||
|
gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
this.dispatchComposeEvent_(
|
||||||
|
ol.render.EventType.POSTCOMPOSE, context, frameState);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle webglcontextlost.
|
* @param {ol.render.EventType} type Event type.
|
||||||
*/
|
* @param {ol.webgl.Context} context WebGL context.
|
||||||
ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() {
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
this.texture = null;
|
* @private
|
||||||
this.framebuffer = null;
|
*/
|
||||||
this.framebufferDimension = undefined;
|
ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState) {
|
||||||
};
|
var layer = this.getLayer();
|
||||||
|
if (layer.hasListener(type)) {
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var resolution = viewState.resolution;
|
||||||
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var extent = frameState.extent;
|
||||||
|
var center = viewState.center;
|
||||||
|
var rotation = viewState.rotation;
|
||||||
|
var size = frameState.size;
|
||||||
|
|
||||||
|
var render = new ol.render.webgl.Immediate(
|
||||||
|
context, center, resolution, rotation, size, extent, pixelRatio);
|
||||||
|
var composeEvent = new ol.render.Event(
|
||||||
|
type, render, frameState, null, context);
|
||||||
|
layer.dispatchEvent(composeEvent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @return {!ol.Transform} Matrix.
|
||||||
* @param {olx.FrameState} frameState Frame state.
|
*/
|
||||||
* @param {ol.LayerState} layerState Layer state.
|
ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = function() {
|
||||||
* @param {ol.webgl.Context} context Context.
|
return this.texCoordMatrix;
|
||||||
* @return {boolean} whether composeFrame should be called.
|
};
|
||||||
*/
|
|
||||||
ol.renderer.webgl.Layer.prototype.prepareFrame = function(frameState, layerState, context) {};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @return {WebGLTexture} Texture.
|
||||||
* @param {ol.Pixel} pixel Pixel.
|
*/
|
||||||
* @param {olx.FrameState} frameState FrameState.
|
ol.renderer.webgl.Layer.prototype.getTexture = function() {
|
||||||
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
|
return this.texture;
|
||||||
* callback.
|
};
|
||||||
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
|
||||||
* @return {T|undefined} Callback result.
|
|
||||||
* @template S,T,U
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
* @return {!ol.Transform} Matrix.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Layer.prototype.getProjectionMatrix = function() {
|
||||||
|
return this.projectionMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle webglcontextlost.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() {
|
||||||
|
this.texture = null;
|
||||||
|
this.framebuffer = null;
|
||||||
|
this.framebufferDimension = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @param {olx.FrameState} frameState Frame state.
|
||||||
|
* @param {ol.LayerState} layerState Layer state.
|
||||||
|
* @param {ol.webgl.Context} context Context.
|
||||||
|
* @return {boolean} whether composeFrame should be called.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Layer.prototype.prepareFrame = function(frameState, layerState, context) {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @abstract
|
||||||
|
* @param {ol.Pixel} pixel Pixel.
|
||||||
|
* @param {olx.FrameState} frameState FrameState.
|
||||||
|
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback Layer
|
||||||
|
* callback.
|
||||||
|
* @param {S} thisArg Value to use as `this` when executing `callback`.
|
||||||
|
* @return {T|undefined} Callback result.
|
||||||
|
* @template S,T,U
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.Layer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,395 +19,391 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.Buffer');
|
goog.require('ol.webgl.Buffer');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.renderer.webgl.Layer}
|
||||||
|
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||||
|
* @param {ol.layer.Tile} tileLayer Tile layer.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||||
|
|
||||||
|
ol.renderer.webgl.Layer.call(this, mapRenderer, tileLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @private
|
||||||
* @extends {ol.renderer.webgl.Layer}
|
* @type {ol.webgl.Fragment}
|
||||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
|
||||||
* @param {ol.layer.Tile} tileLayer Tile layer.
|
|
||||||
* @api
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
this.fragmentShader_ = ol.renderer.webgl.tilelayershader.fragment;
|
||||||
|
|
||||||
ol.renderer.webgl.Layer.call(this, mapRenderer, tileLayer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.webgl.Fragment}
|
|
||||||
*/
|
|
||||||
this.fragmentShader_ = ol.renderer.webgl.tilelayershader.fragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.webgl.Vertex}
|
|
||||||
*/
|
|
||||||
this.vertexShader_ = ol.renderer.webgl.tilelayershader.vertex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.renderer.webgl.tilelayershader.Locations}
|
|
||||||
*/
|
|
||||||
this.locations_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.webgl.Buffer}
|
|
||||||
*/
|
|
||||||
this.renderArrayBuffer_ = new ol.webgl.Buffer([
|
|
||||||
0, 0, 0, 1,
|
|
||||||
1, 0, 1, 1,
|
|
||||||
0, 1, 0, 0,
|
|
||||||
1, 1, 1, 0
|
|
||||||
]);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.TileRange}
|
|
||||||
*/
|
|
||||||
this.renderedTileRange_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Extent}
|
|
||||||
*/
|
|
||||||
this.renderedFramebufferExtent_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.renderedRevision_ = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Size}
|
|
||||||
*/
|
|
||||||
this.tmpSize_ = [0, 0];
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if this renderer handles the provided layer.
|
* @private
|
||||||
* @param {ol.renderer.Type} type The renderer type.
|
* @type {ol.webgl.Vertex}
|
||||||
* @param {ol.layer.Layer} layer The candidate layer.
|
|
||||||
* @return {boolean} The renderer can render the layer.
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer['handles'] = function(type, layer) {
|
this.vertexShader_ = ol.renderer.webgl.tilelayershader.vertex;
|
||||||
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.TILE;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a layer renderer.
|
* @private
|
||||||
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
* @type {ol.renderer.webgl.tilelayershader.Locations}
|
||||||
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
|
||||||
* @return {ol.renderer.webgl.TileLayer} The layer renderer.
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer['create'] = function(mapRenderer, layer) {
|
this.locations_ = null;
|
||||||
return new ol.renderer.webgl.TileLayer(
|
|
||||||
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
|
||||||
/** @type {ol.layer.Tile} */ (layer)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.webgl.Buffer}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
this.renderArrayBuffer_ = new ol.webgl.Buffer([
|
||||||
var context = this.mapRenderer.getContext();
|
0, 0, 0, 1,
|
||||||
context.deleteBuffer(this.renderArrayBuffer_);
|
1, 0, 1, 1,
|
||||||
ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
|
0, 1, 0, 0,
|
||||||
};
|
1, 1, 1, 0
|
||||||
|
]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {ol.TileRange}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = function(source, projection, tiles) {
|
this.renderedTileRange_ = null;
|
||||||
var mapRenderer = this.mapRenderer;
|
|
||||||
|
|
||||||
return (
|
/**
|
||||||
/**
|
* @private
|
||||||
* @param {number} zoom Zoom level.
|
* @type {ol.Extent}
|
||||||
* @param {ol.TileRange} tileRange Tile range.
|
*/
|
||||||
* @return {boolean} The tile range is fully loaded.
|
this.renderedFramebufferExtent_ = null;
|
||||||
*/
|
|
||||||
function(zoom, tileRange) {
|
/**
|
||||||
function callback(tile) {
|
* @private
|
||||||
var loaded = mapRenderer.isTileTextureLoaded(tile);
|
* @type {number}
|
||||||
if (loaded) {
|
*/
|
||||||
if (!tiles[zoom]) {
|
this.renderedRevision_ = -1;
|
||||||
tiles[zoom] = {};
|
|
||||||
}
|
/**
|
||||||
tiles[zoom][tile.tileCoord.toString()] = tile;
|
* @private
|
||||||
|
* @type {ol.Size}
|
||||||
|
*/
|
||||||
|
this.tmpSize_ = [0, 0];
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.TileLayer, ol.renderer.webgl.Layer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this renderer handles the provided layer.
|
||||||
|
* @param {ol.renderer.Type} type The renderer type.
|
||||||
|
* @param {ol.layer.Layer} layer The candidate layer.
|
||||||
|
* @return {boolean} The renderer can render the layer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer['handles'] = function(type, layer) {
|
||||||
|
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.TILE;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a layer renderer.
|
||||||
|
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
||||||
|
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
||||||
|
* @return {ol.renderer.webgl.TileLayer} The layer renderer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer['create'] = function(mapRenderer, layer) {
|
||||||
|
return new ol.renderer.webgl.TileLayer(
|
||||||
|
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
||||||
|
/** @type {ol.layer.Tile} */ (layer)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
||||||
|
var context = this.mapRenderer.getContext();
|
||||||
|
context.deleteBuffer(this.renderArrayBuffer_);
|
||||||
|
ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = function(source, projection, tiles) {
|
||||||
|
var mapRenderer = this.mapRenderer;
|
||||||
|
|
||||||
|
return (
|
||||||
|
/**
|
||||||
|
* @param {number} zoom Zoom level.
|
||||||
|
* @param {ol.TileRange} tileRange Tile range.
|
||||||
|
* @return {boolean} The tile range is fully loaded.
|
||||||
|
*/
|
||||||
|
function(zoom, tileRange) {
|
||||||
|
function callback(tile) {
|
||||||
|
var loaded = mapRenderer.isTileTextureLoaded(tile);
|
||||||
|
if (loaded) {
|
||||||
|
if (!tiles[zoom]) {
|
||||||
|
tiles[zoom] = {};
|
||||||
}
|
}
|
||||||
return loaded;
|
tiles[zoom][tile.tileCoord.toString()] = tile;
|
||||||
}
|
}
|
||||||
return source.forEachLoadedTile(projection, zoom, tileRange, callback);
|
return loaded;
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
|
|
||||||
ol.renderer.webgl.Layer.prototype.handleWebGLContextLost.call(this);
|
|
||||||
this.locations_ = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
|
||||||
|
|
||||||
var mapRenderer = this.mapRenderer;
|
|
||||||
var gl = context.getGL();
|
|
||||||
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var projection = viewState.projection;
|
|
||||||
|
|
||||||
var tileLayer = /** @type {ol.layer.Tile} */ (this.getLayer());
|
|
||||||
var tileSource = tileLayer.getSource();
|
|
||||||
var tileGrid = tileSource.getTileGridForProjection(projection);
|
|
||||||
var z = tileGrid.getZForResolution(viewState.resolution);
|
|
||||||
var tileResolution = tileGrid.getResolution(z);
|
|
||||||
|
|
||||||
var tilePixelSize =
|
|
||||||
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
|
|
||||||
var pixelRatio = tilePixelSize[0] /
|
|
||||||
ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
|
|
||||||
var tilePixelResolution = tileResolution / pixelRatio;
|
|
||||||
var tileGutter = tileSource.getTilePixelRatio(pixelRatio) * tileSource.getGutter(projection);
|
|
||||||
|
|
||||||
var center = viewState.center;
|
|
||||||
var extent = frameState.extent;
|
|
||||||
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
|
||||||
extent, tileResolution);
|
|
||||||
|
|
||||||
var framebufferExtent;
|
|
||||||
if (this.renderedTileRange_ &&
|
|
||||||
this.renderedTileRange_.equals(tileRange) &&
|
|
||||||
this.renderedRevision_ == tileSource.getRevision()) {
|
|
||||||
framebufferExtent = this.renderedFramebufferExtent_;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
var tileRangeSize = tileRange.getSize();
|
|
||||||
|
|
||||||
var maxDimension = Math.max(
|
|
||||||
tileRangeSize[0] * tilePixelSize[0],
|
|
||||||
tileRangeSize[1] * tilePixelSize[1]);
|
|
||||||
var framebufferDimension = ol.math.roundUpToPowerOfTwo(maxDimension);
|
|
||||||
var framebufferExtentDimension = tilePixelResolution * framebufferDimension;
|
|
||||||
var origin = tileGrid.getOrigin(z);
|
|
||||||
var minX = origin[0] +
|
|
||||||
tileRange.minX * tilePixelSize[0] * tilePixelResolution;
|
|
||||||
var minY = origin[1] +
|
|
||||||
tileRange.minY * tilePixelSize[1] * tilePixelResolution;
|
|
||||||
framebufferExtent = [
|
|
||||||
minX, minY,
|
|
||||||
minX + framebufferExtentDimension, minY + framebufferExtentDimension
|
|
||||||
];
|
|
||||||
|
|
||||||
this.bindFramebuffer(frameState, framebufferDimension);
|
|
||||||
gl.viewport(0, 0, framebufferDimension, framebufferDimension);
|
|
||||||
|
|
||||||
gl.clearColor(0, 0, 0, 0);
|
|
||||||
gl.clear(ol.webgl.COLOR_BUFFER_BIT);
|
|
||||||
gl.disable(ol.webgl.BLEND);
|
|
||||||
|
|
||||||
var program = context.getProgram(this.fragmentShader_, this.vertexShader_);
|
|
||||||
context.useProgram(program);
|
|
||||||
if (!this.locations_) {
|
|
||||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
|
||||||
this.locations_ = new ol.renderer.webgl.tilelayershader.Locations(gl, program);
|
|
||||||
}
|
}
|
||||||
|
return source.forEachLoadedTile(projection, zoom, tileRange, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.renderArrayBuffer_);
|
|
||||||
gl.enableVertexAttribArray(this.locations_.a_position);
|
|
||||||
gl.vertexAttribPointer(
|
|
||||||
this.locations_.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
|
|
||||||
gl.enableVertexAttribArray(this.locations_.a_texCoord);
|
|
||||||
gl.vertexAttribPointer(
|
|
||||||
this.locations_.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
|
|
||||||
gl.uniform1i(this.locations_.u_texture, 0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Object.<number, Object.<string, ol.Tile>>}
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
var tilesToDrawByZ = {};
|
ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
|
||||||
tilesToDrawByZ[z] = {};
|
ol.renderer.webgl.Layer.prototype.handleWebGLContextLost.call(this);
|
||||||
|
this.locations_ = null;
|
||||||
|
};
|
||||||
|
|
||||||
var findLoadedTiles = this.createLoadedTileFinder(
|
|
||||||
tileSource, projection, tilesToDrawByZ);
|
|
||||||
|
|
||||||
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
|
/**
|
||||||
var allTilesLoaded = true;
|
* @inheritDoc
|
||||||
var tmpExtent = ol.extent.createEmpty();
|
*/
|
||||||
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
|
ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
||||||
var childTileRange, drawable, fullyLoaded, tile, tileState;
|
|
||||||
var x, y, tileExtent;
|
|
||||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
|
||||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
|
||||||
|
|
||||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
var mapRenderer = this.mapRenderer;
|
||||||
if (layerState.extent !== undefined) {
|
var gl = context.getGL();
|
||||||
// ignore tiles outside layer extent
|
|
||||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
var viewState = frameState.viewState;
|
||||||
if (!ol.extent.intersects(tileExtent, layerState.extent)) {
|
var projection = viewState.projection;
|
||||||
continue;
|
|
||||||
}
|
var tileLayer = /** @type {ol.layer.Tile} */ (this.getLayer());
|
||||||
}
|
var tileSource = tileLayer.getSource();
|
||||||
tileState = tile.getState();
|
var tileGrid = tileSource.getTileGridForProjection(projection);
|
||||||
drawable = tileState == ol.TileState.LOADED ||
|
var z = tileGrid.getZForResolution(viewState.resolution);
|
||||||
tileState == ol.TileState.EMPTY ||
|
var tileResolution = tileGrid.getResolution(z);
|
||||||
tileState == ol.TileState.ERROR && !useInterimTilesOnError;
|
|
||||||
if (!drawable) {
|
var tilePixelSize =
|
||||||
tile = tile.getInterimTile();
|
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
|
||||||
}
|
var pixelRatio = tilePixelSize[0] /
|
||||||
tileState = tile.getState();
|
ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
|
||||||
if (tileState == ol.TileState.LOADED) {
|
var tilePixelResolution = tileResolution / pixelRatio;
|
||||||
if (mapRenderer.isTileTextureLoaded(tile)) {
|
var tileGutter = tileSource.getTilePixelRatio(pixelRatio) * tileSource.getGutter(projection);
|
||||||
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
|
|
||||||
continue;
|
var center = viewState.center;
|
||||||
}
|
var extent = frameState.extent;
|
||||||
} else if (tileState == ol.TileState.EMPTY ||
|
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
|
||||||
(tileState == ol.TileState.ERROR &&
|
extent, tileResolution);
|
||||||
!useInterimTilesOnError)) {
|
|
||||||
|
var framebufferExtent;
|
||||||
|
if (this.renderedTileRange_ &&
|
||||||
|
this.renderedTileRange_.equals(tileRange) &&
|
||||||
|
this.renderedRevision_ == tileSource.getRevision()) {
|
||||||
|
framebufferExtent = this.renderedFramebufferExtent_;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var tileRangeSize = tileRange.getSize();
|
||||||
|
|
||||||
|
var maxDimension = Math.max(
|
||||||
|
tileRangeSize[0] * tilePixelSize[0],
|
||||||
|
tileRangeSize[1] * tilePixelSize[1]);
|
||||||
|
var framebufferDimension = ol.math.roundUpToPowerOfTwo(maxDimension);
|
||||||
|
var framebufferExtentDimension = tilePixelResolution * framebufferDimension;
|
||||||
|
var origin = tileGrid.getOrigin(z);
|
||||||
|
var minX = origin[0] +
|
||||||
|
tileRange.minX * tilePixelSize[0] * tilePixelResolution;
|
||||||
|
var minY = origin[1] +
|
||||||
|
tileRange.minY * tilePixelSize[1] * tilePixelResolution;
|
||||||
|
framebufferExtent = [
|
||||||
|
minX, minY,
|
||||||
|
minX + framebufferExtentDimension, minY + framebufferExtentDimension
|
||||||
|
];
|
||||||
|
|
||||||
|
this.bindFramebuffer(frameState, framebufferDimension);
|
||||||
|
gl.viewport(0, 0, framebufferDimension, framebufferDimension);
|
||||||
|
|
||||||
|
gl.clearColor(0, 0, 0, 0);
|
||||||
|
gl.clear(ol.webgl.COLOR_BUFFER_BIT);
|
||||||
|
gl.disable(ol.webgl.BLEND);
|
||||||
|
|
||||||
|
var program = context.getProgram(this.fragmentShader_, this.vertexShader_);
|
||||||
|
context.useProgram(program);
|
||||||
|
if (!this.locations_) {
|
||||||
|
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||||
|
this.locations_ = new ol.renderer.webgl.tilelayershader.Locations(gl, program);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.renderArrayBuffer_);
|
||||||
|
gl.enableVertexAttribArray(this.locations_.a_position);
|
||||||
|
gl.vertexAttribPointer(
|
||||||
|
this.locations_.a_position, 2, ol.webgl.FLOAT, false, 16, 0);
|
||||||
|
gl.enableVertexAttribArray(this.locations_.a_texCoord);
|
||||||
|
gl.vertexAttribPointer(
|
||||||
|
this.locations_.a_texCoord, 2, ol.webgl.FLOAT, false, 16, 8);
|
||||||
|
gl.uniform1i(this.locations_.u_texture, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object.<number, Object.<string, ol.Tile>>}
|
||||||
|
*/
|
||||||
|
var tilesToDrawByZ = {};
|
||||||
|
tilesToDrawByZ[z] = {};
|
||||||
|
|
||||||
|
var findLoadedTiles = this.createLoadedTileFinder(
|
||||||
|
tileSource, projection, tilesToDrawByZ);
|
||||||
|
|
||||||
|
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
|
||||||
|
var allTilesLoaded = true;
|
||||||
|
var tmpExtent = ol.extent.createEmpty();
|
||||||
|
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
|
||||||
|
var childTileRange, drawable, fullyLoaded, tile, tileState;
|
||||||
|
var x, y, tileExtent;
|
||||||
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
|
|
||||||
|
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||||
|
if (layerState.extent !== undefined) {
|
||||||
|
// ignore tiles outside layer extent
|
||||||
|
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||||
|
if (!ol.extent.intersects(tileExtent, layerState.extent)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
allTilesLoaded = false;
|
tileState = tile.getState();
|
||||||
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
|
drawable = tileState == ol.TileState.LOADED ||
|
||||||
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
|
tileState == ol.TileState.EMPTY ||
|
||||||
if (!fullyLoaded) {
|
tileState == ol.TileState.ERROR && !useInterimTilesOnError;
|
||||||
childTileRange = tileGrid.getTileCoordChildTileRange(
|
if (!drawable) {
|
||||||
tile.tileCoord, tmpTileRange, tmpExtent);
|
tile = tile.getInterimTile();
|
||||||
if (childTileRange) {
|
}
|
||||||
findLoadedTiles(z + 1, childTileRange);
|
tileState = tile.getState();
|
||||||
}
|
if (tileState == ol.TileState.LOADED) {
|
||||||
|
if (mapRenderer.isTileTextureLoaded(tile)) {
|
||||||
|
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
} else if (tileState == ol.TileState.EMPTY ||
|
||||||
|
(tileState == ol.TileState.ERROR &&
|
||||||
|
!useInterimTilesOnError)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
allTilesLoaded = false;
|
||||||
|
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
|
||||||
|
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
|
||||||
|
if (!fullyLoaded) {
|
||||||
|
childTileRange = tileGrid.getTileCoordChildTileRange(
|
||||||
|
tile.tileCoord, tmpTileRange, tmpExtent);
|
||||||
|
if (childTileRange) {
|
||||||
|
findLoadedTiles(z + 1, childTileRange);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {Array.<number>} */
|
}
|
||||||
var zs = Object.keys(tilesToDrawByZ).map(Number);
|
|
||||||
zs.sort(ol.array.numberSafeCompareFunction);
|
/** @type {Array.<number>} */
|
||||||
var u_tileOffset = new Float32Array(4);
|
var zs = Object.keys(tilesToDrawByZ).map(Number);
|
||||||
var i, ii, tileKey, tilesToDraw;
|
zs.sort(ol.array.numberSafeCompareFunction);
|
||||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
var u_tileOffset = new Float32Array(4);
|
||||||
tilesToDraw = tilesToDrawByZ[zs[i]];
|
var i, ii, tileKey, tilesToDraw;
|
||||||
for (tileKey in tilesToDraw) {
|
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||||
tile = tilesToDraw[tileKey];
|
tilesToDraw = tilesToDrawByZ[zs[i]];
|
||||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
for (tileKey in tilesToDraw) {
|
||||||
u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /
|
tile = tilesToDraw[tileKey];
|
||||||
framebufferExtentDimension;
|
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||||
u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /
|
u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /
|
||||||
framebufferExtentDimension;
|
framebufferExtentDimension;
|
||||||
u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /
|
u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /
|
||||||
framebufferExtentDimension - 1;
|
framebufferExtentDimension;
|
||||||
u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /
|
u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /
|
||||||
framebufferExtentDimension - 1;
|
framebufferExtentDimension - 1;
|
||||||
gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
|
u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /
|
||||||
mapRenderer.bindTileTexture(tile, tilePixelSize,
|
framebufferExtentDimension - 1;
|
||||||
tileGutter * pixelRatio, ol.webgl.LINEAR, ol.webgl.LINEAR);
|
gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
|
||||||
gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
|
mapRenderer.bindTileTexture(tile, tilePixelSize,
|
||||||
}
|
tileGutter * pixelRatio, ol.webgl.LINEAR, ol.webgl.LINEAR);
|
||||||
|
gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allTilesLoaded) {
|
|
||||||
this.renderedTileRange_ = tileRange;
|
|
||||||
this.renderedFramebufferExtent_ = framebufferExtent;
|
|
||||||
this.renderedRevision_ = tileSource.getRevision();
|
|
||||||
} else {
|
|
||||||
this.renderedTileRange_ = null;
|
|
||||||
this.renderedFramebufferExtent_ = null;
|
|
||||||
this.renderedRevision_ = -1;
|
|
||||||
frameState.animate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
if (allTilesLoaded) {
|
||||||
var tileTextureQueue = mapRenderer.getTileTextureQueue();
|
this.renderedTileRange_ = tileRange;
|
||||||
this.manageTilePyramid(
|
this.renderedFramebufferExtent_ = framebufferExtent;
|
||||||
frameState, tileSource, tileGrid, pixelRatio, projection, extent, z,
|
this.renderedRevision_ = tileSource.getRevision();
|
||||||
tileLayer.getPreload(),
|
|
||||||
/**
|
|
||||||
* @param {ol.Tile} tile Tile.
|
|
||||||
*/
|
|
||||||
function(tile) {
|
|
||||||
if (tile.getState() == ol.TileState.LOADED &&
|
|
||||||
!mapRenderer.isTileTextureLoaded(tile) &&
|
|
||||||
!tileTextureQueue.isKeyQueued(tile.getKey())) {
|
|
||||||
tileTextureQueue.enqueue([
|
|
||||||
tile,
|
|
||||||
tileGrid.getTileCoordCenter(tile.tileCoord),
|
|
||||||
tileGrid.getResolution(tile.tileCoord[0]),
|
|
||||||
tilePixelSize, tileGutter * pixelRatio
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
this.scheduleExpireCache(frameState, tileSource);
|
|
||||||
this.updateLogos(frameState, tileSource);
|
|
||||||
|
|
||||||
var texCoordMatrix = this.texCoordMatrix;
|
|
||||||
ol.transform.reset(texCoordMatrix);
|
|
||||||
ol.transform.translate(texCoordMatrix,
|
|
||||||
(Math.round(center[0] / tileResolution) * tileResolution - framebufferExtent[0]) /
|
|
||||||
(framebufferExtent[2] - framebufferExtent[0]),
|
|
||||||
(Math.round(center[1] / tileResolution) * tileResolution - framebufferExtent[1]) /
|
|
||||||
(framebufferExtent[3] - framebufferExtent[1]));
|
|
||||||
if (viewState.rotation !== 0) {
|
|
||||||
ol.transform.rotate(texCoordMatrix, viewState.rotation);
|
|
||||||
}
|
|
||||||
ol.transform.scale(texCoordMatrix,
|
|
||||||
frameState.size[0] * viewState.resolution /
|
|
||||||
(framebufferExtent[2] - framebufferExtent[0]),
|
|
||||||
frameState.size[1] * viewState.resolution /
|
|
||||||
(framebufferExtent[3] - framebufferExtent[1]));
|
|
||||||
ol.transform.translate(texCoordMatrix, -0.5, -0.5);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
|
||||||
if (!this.framebuffer) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pixelOnMapScaled = [
|
|
||||||
pixel[0] / frameState.size[0],
|
|
||||||
(frameState.size[1] - pixel[1]) / frameState.size[1]];
|
|
||||||
|
|
||||||
var pixelOnFrameBufferScaled = ol.transform.apply(
|
|
||||||
this.texCoordMatrix, pixelOnMapScaled.slice());
|
|
||||||
var pixelOnFrameBuffer = [
|
|
||||||
pixelOnFrameBufferScaled[0] * this.framebufferDimension,
|
|
||||||
pixelOnFrameBufferScaled[1] * this.framebufferDimension];
|
|
||||||
|
|
||||||
var gl = this.mapRenderer.getContext().getGL();
|
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
|
|
||||||
var imageData = new Uint8Array(4);
|
|
||||||
gl.readPixels(pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1,
|
|
||||||
gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
|
||||||
|
|
||||||
if (imageData[3] > 0) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), imageData);
|
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
this.renderedTileRange_ = null;
|
||||||
|
this.renderedFramebufferExtent_ = null;
|
||||||
|
this.renderedRevision_ = -1;
|
||||||
|
frameState.animate = true;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||||
|
var tileTextureQueue = mapRenderer.getTileTextureQueue();
|
||||||
|
this.manageTilePyramid(
|
||||||
|
frameState, tileSource, tileGrid, pixelRatio, projection, extent, z,
|
||||||
|
tileLayer.getPreload(),
|
||||||
|
/**
|
||||||
|
* @param {ol.Tile} tile Tile.
|
||||||
|
*/
|
||||||
|
function(tile) {
|
||||||
|
if (tile.getState() == ol.TileState.LOADED &&
|
||||||
|
!mapRenderer.isTileTextureLoaded(tile) &&
|
||||||
|
!tileTextureQueue.isKeyQueued(tile.getKey())) {
|
||||||
|
tileTextureQueue.enqueue([
|
||||||
|
tile,
|
||||||
|
tileGrid.getTileCoordCenter(tile.tileCoord),
|
||||||
|
tileGrid.getResolution(tile.tileCoord[0]),
|
||||||
|
tilePixelSize, tileGutter * pixelRatio
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
this.scheduleExpireCache(frameState, tileSource);
|
||||||
|
this.updateLogos(frameState, tileSource);
|
||||||
|
|
||||||
|
var texCoordMatrix = this.texCoordMatrix;
|
||||||
|
ol.transform.reset(texCoordMatrix);
|
||||||
|
ol.transform.translate(texCoordMatrix,
|
||||||
|
(Math.round(center[0] / tileResolution) * tileResolution - framebufferExtent[0]) /
|
||||||
|
(framebufferExtent[2] - framebufferExtent[0]),
|
||||||
|
(Math.round(center[1] / tileResolution) * tileResolution - framebufferExtent[1]) /
|
||||||
|
(framebufferExtent[3] - framebufferExtent[1]));
|
||||||
|
if (viewState.rotation !== 0) {
|
||||||
|
ol.transform.rotate(texCoordMatrix, viewState.rotation);
|
||||||
|
}
|
||||||
|
ol.transform.scale(texCoordMatrix,
|
||||||
|
frameState.size[0] * viewState.resolution /
|
||||||
|
(framebufferExtent[2] - framebufferExtent[0]),
|
||||||
|
frameState.size[1] * viewState.resolution /
|
||||||
|
(framebufferExtent[3] - framebufferExtent[1]));
|
||||||
|
ol.transform.translate(texCoordMatrix, -0.5, -0.5);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
||||||
|
if (!this.framebuffer) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pixelOnMapScaled = [
|
||||||
|
pixel[0] / frameState.size[0],
|
||||||
|
(frameState.size[1] - pixel[1]) / frameState.size[1]];
|
||||||
|
|
||||||
|
var pixelOnFrameBufferScaled = ol.transform.apply(
|
||||||
|
this.texCoordMatrix, pixelOnMapScaled.slice());
|
||||||
|
var pixelOnFrameBuffer = [
|
||||||
|
pixelOnFrameBufferScaled[0] * this.framebufferDimension,
|
||||||
|
pixelOnFrameBufferScaled[1] * this.framebufferDimension];
|
||||||
|
|
||||||
|
var gl = this.mapRenderer.getContext().getGL();
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
|
||||||
|
var imageData = new Uint8Array(4);
|
||||||
|
gl.readPixels(pixelOnFrameBuffer[0], pixelOnFrameBuffer[1], 1, 1,
|
||||||
|
gl.RGBA, gl.UNSIGNED_BYTE, imageData);
|
||||||
|
|
||||||
|
if (imageData[3] > 0) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), imageData);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,113 +6,109 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, ol.renderer.webgl.tilelayershader.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.tilelayershader.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform sampler2D u_texture;\n\nvoid main(void) {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n}\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE :
|
||||||
|
ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.renderer.webgl.tilelayershader.fragment = new ol.renderer.webgl.tilelayershader.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, ol.renderer.webgl.tilelayershader.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.tilelayershader.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nuniform vec4 u_tileOffset;\n\nvoid main(void) {\n gl_Position = vec4(a_position * u_tileOffset.xy + u_tileOffset.zw, 0., 1.);\n v_texCoord = a_texCoord;\n}\n\n\n';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform vec4 d;void main(void){gl_Position=vec4(b*d.xy+d.zw,0.,1.);a=c;}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE :
|
||||||
|
ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
ol.renderer.webgl.tilelayershader.vertex = new ol.renderer.webgl.tilelayershader.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.tilelayershader.Locations = function(gl, program) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.tilelayershader.Fragment = function() {
|
this.u_texture = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, ol.renderer.webgl.tilelayershader.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? 'u_texture' : 'e');
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.tilelayershader.Fragment, ol.webgl.Fragment);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {WebGLUniformLocation}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\n\n\nuniform sampler2D u_texture;\n\nvoid main(void) {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n}\n';
|
this.u_tileOffset = gl.getUniformLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'u_tileOffset' : 'd');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;uniform sampler2D e;void main(void){gl_FragColor=texture2D(e,a);}';
|
this.a_position = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.tilelayershader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
this.a_texCoord = gl.getAttribLocation(
|
||||||
ol.renderer.webgl.tilelayershader.Fragment.DEBUG_SOURCE :
|
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
||||||
ol.renderer.webgl.tilelayershader.Fragment.OPTIMIZED_SOURCE;
|
};
|
||||||
|
|
||||||
|
|
||||||
ol.renderer.webgl.tilelayershader.fragment = new ol.renderer.webgl.tilelayershader.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex = function() {
|
|
||||||
ol.webgl.Vertex.call(this, ol.renderer.webgl.tilelayershader.Vertex.SOURCE);
|
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.tilelayershader.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\n\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nuniform vec4 u_tileOffset;\n\nvoid main(void) {\n gl_Position = vec4(a_position * u_tileOffset.xy + u_tileOffset.zw, 0., 1.);\n v_texCoord = a_texCoord;\n}\n\n\n';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;attribute vec2 b;attribute vec2 c;uniform vec4 d;void main(void){gl_Position=vec4(b*d.xy+d.zw,0.,1.);a=c;}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex.DEBUG_SOURCE :
|
|
||||||
ol.renderer.webgl.tilelayershader.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
ol.renderer.webgl.tilelayershader.vertex = new ol.renderer.webgl.tilelayershader.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.tilelayershader.Locations = function(gl, program) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_texture = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_texture' : 'e');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.u_tileOffset = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'u_tileOffset' : 'd');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_position = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.a_texCoord = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'c');
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -11,337 +11,333 @@ goog.require('ol.renderer.webgl.Layer');
|
|||||||
goog.require('ol.transform');
|
goog.require('ol.transform');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.renderer.webgl.Layer}
|
||||||
|
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||||
|
* @param {ol.layer.Vector} vectorLayer Vector layer.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer = function(mapRenderer, vectorLayer) {
|
||||||
|
|
||||||
|
ol.renderer.webgl.Layer.call(this, mapRenderer, vectorLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
|
||||||
* @extends {ol.renderer.webgl.Layer}
|
|
||||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
|
||||||
* @param {ol.layer.Vector} vectorLayer Vector layer.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer = function(mapRenderer, vectorLayer) {
|
|
||||||
|
|
||||||
ol.renderer.webgl.Layer.call(this, mapRenderer, vectorLayer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.dirty_ = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.renderedRevision_ = -1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.renderedResolution_ = NaN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.Extent}
|
|
||||||
*/
|
|
||||||
this.renderedExtent_ = ol.extent.createEmpty();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {function(ol.Feature, ol.Feature): number|null}
|
|
||||||
*/
|
|
||||||
this.renderedRenderOrder_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {ol.render.webgl.ReplayGroup}
|
|
||||||
*/
|
|
||||||
this.replayGroup_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The last layer state.
|
|
||||||
* @private
|
|
||||||
* @type {?ol.LayerState}
|
|
||||||
*/
|
|
||||||
this.layerState_ = null;
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.renderer.webgl.VectorLayer, ol.renderer.webgl.Layer);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if this renderer handles the provided layer.
|
|
||||||
* @param {ol.renderer.Type} type The renderer type.
|
|
||||||
* @param {ol.layer.Layer} layer The candidate layer.
|
|
||||||
* @return {boolean} The renderer can render the layer.
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer['handles'] = function(type, layer) {
|
|
||||||
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.VECTOR;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a layer renderer.
|
|
||||||
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
|
||||||
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
|
||||||
* @return {ol.renderer.webgl.VectorLayer} The layer renderer.
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer['create'] = function(mapRenderer, layer) {
|
|
||||||
return new ol.renderer.webgl.VectorLayer(
|
|
||||||
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
|
||||||
/** @type {ol.layer.Vector} */ (layer)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) {
|
|
||||||
this.layerState_ = layerState;
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var replayGroup = this.replayGroup_;
|
|
||||||
var size = frameState.size;
|
|
||||||
var pixelRatio = frameState.pixelRatio;
|
|
||||||
var gl = this.mapRenderer.getGL();
|
|
||||||
if (replayGroup && !replayGroup.isEmpty()) {
|
|
||||||
gl.enable(gl.SCISSOR_TEST);
|
|
||||||
gl.scissor(0, 0, size[0] * pixelRatio, size[1] * pixelRatio);
|
|
||||||
replayGroup.replay(context,
|
|
||||||
viewState.center, viewState.resolution, viewState.rotation,
|
|
||||||
size, pixelRatio, layerState.opacity,
|
|
||||||
layerState.managed ? frameState.skippedFeatureUids : {});
|
|
||||||
gl.disable(gl.SCISSOR_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer.prototype.disposeInternal = function() {
|
|
||||||
var replayGroup = this.replayGroup_;
|
|
||||||
if (replayGroup) {
|
|
||||||
var context = this.mapRenderer.getContext();
|
|
||||||
replayGroup.getDeleteResourcesFunction(context)();
|
|
||||||
this.replayGroup_ = null;
|
|
||||||
}
|
|
||||||
ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
|
|
||||||
if (!this.replayGroup_ || !this.layerState_) {
|
|
||||||
return undefined;
|
|
||||||
} else {
|
|
||||||
var context = this.mapRenderer.getContext();
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var layer = this.getLayer();
|
|
||||||
var layerState = this.layerState_;
|
|
||||||
/** @type {Object.<string, boolean>} */
|
|
||||||
var features = {};
|
|
||||||
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,
|
|
||||||
context, viewState.center, viewState.resolution, viewState.rotation,
|
|
||||||
frameState.size, frameState.pixelRatio, layerState.opacity,
|
|
||||||
{},
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
|
||||||
* @return {?} Callback result.
|
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
var key = ol.getUid(feature).toString();
|
|
||||||
if (!(key in features)) {
|
|
||||||
features[key] = true;
|
|
||||||
return callback.call(thisArg, feature, layer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
|
|
||||||
if (!this.replayGroup_ || !this.layerState_) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var context = this.mapRenderer.getContext();
|
|
||||||
var viewState = frameState.viewState;
|
|
||||||
var layerState = this.layerState_;
|
|
||||||
return this.replayGroup_.hasFeatureAtCoordinate(coordinate,
|
|
||||||
context, viewState.center, viewState.resolution, viewState.rotation,
|
|
||||||
frameState.size, frameState.pixelRatio, layerState.opacity,
|
|
||||||
frameState.skippedFeatureUids);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @inheritDoc
|
|
||||||
*/
|
|
||||||
ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
|
||||||
var coordinate = ol.transform.apply(
|
|
||||||
frameState.pixelToCoordinateTransform, pixel.slice());
|
|
||||||
var hasFeature = this.hasFeatureAtCoordinate(coordinate, frameState);
|
|
||||||
|
|
||||||
if (hasFeature) {
|
|
||||||
return callback.call(thisArg, this.getLayer(), null);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle changes in image style state.
|
|
||||||
* @param {ol.events.Event} event Image style change event.
|
|
||||||
* @private
|
* @private
|
||||||
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
|
this.dirty_ = false;
|
||||||
this.renderIfReadyAndVisible();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @private
|
||||||
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.VectorLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
this.renderedRevision_ = -1;
|
||||||
|
|
||||||
var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
|
/**
|
||||||
var vectorSource = vectorLayer.getSource();
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.renderedResolution_ = NaN;
|
||||||
|
|
||||||
this.updateAttributions(
|
/**
|
||||||
frameState.attributions, vectorSource.getAttributions());
|
* @private
|
||||||
this.updateLogos(frameState, vectorSource);
|
* @type {ol.Extent}
|
||||||
|
*/
|
||||||
|
this.renderedExtent_ = ol.extent.createEmpty();
|
||||||
|
|
||||||
var animating = frameState.viewHints[ol.ViewHint.ANIMATING];
|
/**
|
||||||
var interacting = frameState.viewHints[ol.ViewHint.INTERACTING];
|
* @private
|
||||||
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
|
* @type {function(ol.Feature, ol.Feature): number|null}
|
||||||
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
|
*/
|
||||||
|
this.renderedRenderOrder_ = null;
|
||||||
|
|
||||||
if (!this.dirty_ && (!updateWhileAnimating && animating) ||
|
/**
|
||||||
(!updateWhileInteracting && interacting)) {
|
* @private
|
||||||
return true;
|
* @type {ol.render.webgl.ReplayGroup}
|
||||||
}
|
*/
|
||||||
|
this.replayGroup_ = null;
|
||||||
|
|
||||||
var frameStateExtent = frameState.extent;
|
/**
|
||||||
|
* The last layer state.
|
||||||
|
* @private
|
||||||
|
* @type {?ol.LayerState}
|
||||||
|
*/
|
||||||
|
this.layerState_ = null;
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.renderer.webgl.VectorLayer, ol.renderer.webgl.Layer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if this renderer handles the provided layer.
|
||||||
|
* @param {ol.renderer.Type} type The renderer type.
|
||||||
|
* @param {ol.layer.Layer} layer The candidate layer.
|
||||||
|
* @return {boolean} The renderer can render the layer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer['handles'] = function(type, layer) {
|
||||||
|
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.VECTOR;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a layer renderer.
|
||||||
|
* @param {ol.renderer.Map} mapRenderer The map renderer.
|
||||||
|
* @param {ol.layer.Layer} layer The layer to be rendererd.
|
||||||
|
* @return {ol.renderer.webgl.VectorLayer} The layer renderer.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer['create'] = function(mapRenderer, layer) {
|
||||||
|
return new ol.renderer.webgl.VectorLayer(
|
||||||
|
/** @type {ol.renderer.webgl.Map} */ (mapRenderer),
|
||||||
|
/** @type {ol.layer.Vector} */ (layer)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.composeFrame = function(frameState, layerState, context) {
|
||||||
|
this.layerState_ = layerState;
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var replayGroup = this.replayGroup_;
|
||||||
|
var size = frameState.size;
|
||||||
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var gl = this.mapRenderer.getGL();
|
||||||
|
if (replayGroup && !replayGroup.isEmpty()) {
|
||||||
|
gl.enable(gl.SCISSOR_TEST);
|
||||||
|
gl.scissor(0, 0, size[0] * pixelRatio, size[1] * pixelRatio);
|
||||||
|
replayGroup.replay(context,
|
||||||
|
viewState.center, viewState.resolution, viewState.rotation,
|
||||||
|
size, pixelRatio, layerState.opacity,
|
||||||
|
layerState.managed ? frameState.skippedFeatureUids : {});
|
||||||
|
gl.disable(gl.SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.disposeInternal = function() {
|
||||||
|
var replayGroup = this.replayGroup_;
|
||||||
|
if (replayGroup) {
|
||||||
|
var context = this.mapRenderer.getContext();
|
||||||
|
replayGroup.getDeleteResourcesFunction(context)();
|
||||||
|
this.replayGroup_ = null;
|
||||||
|
}
|
||||||
|
ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate = function(coordinate, frameState, hitTolerance, callback, thisArg) {
|
||||||
|
if (!this.replayGroup_ || !this.layerState_) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
var context = this.mapRenderer.getContext();
|
||||||
var viewState = frameState.viewState;
|
var viewState = frameState.viewState;
|
||||||
var projection = viewState.projection;
|
var layer = this.getLayer();
|
||||||
var resolution = viewState.resolution;
|
var layerState = this.layerState_;
|
||||||
var pixelRatio = frameState.pixelRatio;
|
/** @type {Object.<string, boolean>} */
|
||||||
var vectorLayerRevision = vectorLayer.getRevision();
|
var features = {};
|
||||||
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
|
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,
|
||||||
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
|
context, viewState.center, viewState.resolution, viewState.rotation,
|
||||||
|
frameState.size, frameState.pixelRatio, layerState.opacity,
|
||||||
|
{},
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||||
|
* @return {?} Callback result.
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
var key = ol.getUid(feature).toString();
|
||||||
|
if (!(key in features)) {
|
||||||
|
features[key] = true;
|
||||||
|
return callback.call(thisArg, feature, layer);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (vectorLayerRenderOrder === undefined) {
|
|
||||||
vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
var extent = ol.extent.buffer(frameStateExtent,
|
/**
|
||||||
vectorLayerRenderBuffer * resolution);
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
|
||||||
|
if (!this.replayGroup_ || !this.layerState_) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
var context = this.mapRenderer.getContext();
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var layerState = this.layerState_;
|
||||||
|
return this.replayGroup_.hasFeatureAtCoordinate(coordinate,
|
||||||
|
context, viewState.center, viewState.resolution, viewState.rotation,
|
||||||
|
frameState.size, frameState.pixelRatio, layerState.opacity,
|
||||||
|
frameState.skippedFeatureUids);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (!this.dirty_ &&
|
|
||||||
this.renderedResolution_ == resolution &&
|
|
||||||
this.renderedRevision_ == vectorLayerRevision &&
|
|
||||||
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
|
||||||
ol.extent.containsExtent(this.renderedExtent_, extent)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.replayGroup_) {
|
/**
|
||||||
frameState.postRenderFunctions.push(
|
* @inheritDoc
|
||||||
this.replayGroup_.getDeleteResourcesFunction(context));
|
*/
|
||||||
}
|
ol.renderer.webgl.VectorLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
||||||
|
var coordinate = ol.transform.apply(
|
||||||
|
frameState.pixelToCoordinateTransform, pixel.slice());
|
||||||
|
var hasFeature = this.hasFeatureAtCoordinate(coordinate, frameState);
|
||||||
|
|
||||||
this.dirty_ = false;
|
if (hasFeature) {
|
||||||
|
return callback.call(thisArg, this.getLayer(), null);
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var replayGroup = new ol.render.webgl.ReplayGroup(
|
|
||||||
ol.renderer.vector.getTolerance(resolution, pixelRatio),
|
|
||||||
extent, vectorLayer.getRenderBuffer());
|
|
||||||
vectorSource.loadFeatures(extent, resolution, projection);
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature} feature Feature.
|
|
||||||
* @this {ol.renderer.webgl.VectorLayer}
|
|
||||||
*/
|
|
||||||
var renderFeature = function(feature) {
|
|
||||||
var styles;
|
|
||||||
var styleFunction = feature.getStyleFunction();
|
|
||||||
if (styleFunction) {
|
|
||||||
styles = styleFunction.call(feature, resolution);
|
|
||||||
} else {
|
|
||||||
styleFunction = vectorLayer.getStyleFunction();
|
|
||||||
if (styleFunction) {
|
|
||||||
styles = styleFunction(feature, resolution);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (styles) {
|
|
||||||
var dirty = this.renderFeature(
|
|
||||||
feature, resolution, pixelRatio, styles, replayGroup);
|
|
||||||
this.dirty_ = this.dirty_ || dirty;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (vectorLayerRenderOrder) {
|
|
||||||
/** @type {Array.<ol.Feature>} */
|
|
||||||
var features = [];
|
|
||||||
vectorSource.forEachFeatureInExtent(extent,
|
|
||||||
/**
|
|
||||||
* @param {ol.Feature} feature Feature.
|
|
||||||
*/
|
|
||||||
function(feature) {
|
|
||||||
features.push(feature);
|
|
||||||
}, this);
|
|
||||||
features.sort(vectorLayerRenderOrder);
|
|
||||||
features.forEach(renderFeature, this);
|
|
||||||
} else {
|
|
||||||
vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
|
|
||||||
}
|
|
||||||
replayGroup.finish(context);
|
|
||||||
|
|
||||||
this.renderedResolution_ = resolution;
|
/**
|
||||||
this.renderedRevision_ = vectorLayerRevision;
|
* Handle changes in image style state.
|
||||||
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
* @param {ol.events.Event} event Image style change event.
|
||||||
this.renderedExtent_ = extent;
|
* @private
|
||||||
this.replayGroup_ = replayGroup;
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
|
||||||
|
this.renderIfReadyAndVisible();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
||||||
|
|
||||||
|
var vectorLayer = /** @type {ol.layer.Vector} */ (this.getLayer());
|
||||||
|
var vectorSource = vectorLayer.getSource();
|
||||||
|
|
||||||
|
this.updateAttributions(
|
||||||
|
frameState.attributions, vectorSource.getAttributions());
|
||||||
|
this.updateLogos(frameState, vectorSource);
|
||||||
|
|
||||||
|
var animating = frameState.viewHints[ol.ViewHint.ANIMATING];
|
||||||
|
var interacting = frameState.viewHints[ol.ViewHint.INTERACTING];
|
||||||
|
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
|
||||||
|
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
|
||||||
|
|
||||||
|
if (!this.dirty_ && (!updateWhileAnimating && animating) ||
|
||||||
|
(!updateWhileInteracting && interacting)) {
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
var frameStateExtent = frameState.extent;
|
||||||
|
var viewState = frameState.viewState;
|
||||||
|
var projection = viewState.projection;
|
||||||
|
var resolution = viewState.resolution;
|
||||||
|
var pixelRatio = frameState.pixelRatio;
|
||||||
|
var vectorLayerRevision = vectorLayer.getRevision();
|
||||||
|
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
|
||||||
|
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
|
||||||
|
|
||||||
|
if (vectorLayerRenderOrder === undefined) {
|
||||||
|
vectorLayerRenderOrder = ol.renderer.vector.defaultOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
var extent = ol.extent.buffer(frameStateExtent,
|
||||||
|
vectorLayerRenderBuffer * resolution);
|
||||||
|
|
||||||
|
if (!this.dirty_ &&
|
||||||
|
this.renderedResolution_ == resolution &&
|
||||||
|
this.renderedRevision_ == vectorLayerRevision &&
|
||||||
|
this.renderedRenderOrder_ == vectorLayerRenderOrder &&
|
||||||
|
ol.extent.containsExtent(this.renderedExtent_, extent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.replayGroup_) {
|
||||||
|
frameState.postRenderFunctions.push(
|
||||||
|
this.replayGroup_.getDeleteResourcesFunction(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dirty_ = false;
|
||||||
|
|
||||||
|
var replayGroup = new ol.render.webgl.ReplayGroup(
|
||||||
|
ol.renderer.vector.getTolerance(resolution, pixelRatio),
|
||||||
|
extent, vectorLayer.getRenderBuffer());
|
||||||
|
vectorSource.loadFeatures(extent, resolution, projection);
|
||||||
/**
|
/**
|
||||||
* @param {ol.Feature} feature Feature.
|
* @param {ol.Feature} feature Feature.
|
||||||
* @param {number} resolution Resolution.
|
* @this {ol.renderer.webgl.VectorLayer}
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
|
||||||
* @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
|
|
||||||
* styles.
|
|
||||||
* @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
|
|
||||||
* @return {boolean} `true` if an image is loading.
|
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
|
var renderFeature = function(feature) {
|
||||||
if (!styles) {
|
var styles;
|
||||||
return false;
|
var styleFunction = feature.getStyleFunction();
|
||||||
}
|
if (styleFunction) {
|
||||||
var loading = false;
|
styles = styleFunction.call(feature, resolution);
|
||||||
if (Array.isArray(styles)) {
|
|
||||||
for (var i = styles.length - 1, ii = 0; i >= ii; --i) {
|
|
||||||
loading = ol.renderer.vector.renderFeature(
|
|
||||||
replayGroup, feature, styles[i],
|
|
||||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
|
||||||
this.handleStyleImageChange_, this) || loading;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
styleFunction = vectorLayer.getStyleFunction();
|
||||||
|
if (styleFunction) {
|
||||||
|
styles = styleFunction(feature, resolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (styles) {
|
||||||
|
var dirty = this.renderFeature(
|
||||||
|
feature, resolution, pixelRatio, styles, replayGroup);
|
||||||
|
this.dirty_ = this.dirty_ || dirty;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (vectorLayerRenderOrder) {
|
||||||
|
/** @type {Array.<ol.Feature>} */
|
||||||
|
var features = [];
|
||||||
|
vectorSource.forEachFeatureInExtent(extent,
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
*/
|
||||||
|
function(feature) {
|
||||||
|
features.push(feature);
|
||||||
|
}, this);
|
||||||
|
features.sort(vectorLayerRenderOrder);
|
||||||
|
features.forEach(renderFeature, this);
|
||||||
|
} else {
|
||||||
|
vectorSource.forEachFeatureInExtent(extent, renderFeature, this);
|
||||||
|
}
|
||||||
|
replayGroup.finish(context);
|
||||||
|
|
||||||
|
this.renderedResolution_ = resolution;
|
||||||
|
this.renderedRevision_ = vectorLayerRevision;
|
||||||
|
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
||||||
|
this.renderedExtent_ = extent;
|
||||||
|
this.replayGroup_ = replayGroup;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
|
* @param {(ol.style.Style|Array.<ol.style.Style>)} styles The style or array of
|
||||||
|
* styles.
|
||||||
|
* @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
|
||||||
|
* @return {boolean} `true` if an image is loading.
|
||||||
|
*/
|
||||||
|
ol.renderer.webgl.VectorLayer.prototype.renderFeature = function(feature, resolution, pixelRatio, styles, replayGroup) {
|
||||||
|
if (!styles) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var loading = false;
|
||||||
|
if (Array.isArray(styles)) {
|
||||||
|
for (var i = styles.length - 1, ii = 0; i >= ii; --i) {
|
||||||
loading = ol.renderer.vector.renderFeature(
|
loading = ol.renderer.vector.renderFeature(
|
||||||
replayGroup, feature, styles,
|
replayGroup, feature, styles[i],
|
||||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
this.handleStyleImageChange_, this) || loading;
|
this.handleStyleImageChange_, this) || loading;
|
||||||
}
|
}
|
||||||
return loading;
|
} else {
|
||||||
};
|
loading = ol.renderer.vector.renderFeature(
|
||||||
|
replayGroup, feature, styles,
|
||||||
}
|
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||||
|
this.handleStyleImageChange_, this) || loading;
|
||||||
|
}
|
||||||
|
return loading;
|
||||||
|
};
|
||||||
|
|||||||
418
src/ol/webgl.js
418
src/ol/webgl.js
@@ -3,292 +3,288 @@ goog.provide('ol.webgl');
|
|||||||
goog.require('ol');
|
goog.require('ol');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/** Constants taken from goog.webgl
|
||||||
|
*/
|
||||||
|
|
||||||
/** Constants taken from goog.webgl
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.ONE = 1;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.ONE = 1;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.SRC_ALPHA = 0x0302;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.SRC_ALPHA = 0x0302;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.COLOR_ATTACHMENT0 = 0x8CE0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.COLOR_ATTACHMENT0 = 0x8CE0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.COLOR_BUFFER_BIT = 0x00004000;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.COLOR_BUFFER_BIT = 0x00004000;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TRIANGLES = 0x0004;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TRIANGLES = 0x0004;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TRIANGLE_STRIP = 0x0005;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TRIANGLE_STRIP = 0x0005;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.ONE_MINUS_SRC_ALPHA = 0x0303;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.ONE_MINUS_SRC_ALPHA = 0x0303;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.ARRAY_BUFFER = 0x8892;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.ARRAY_BUFFER = 0x8892;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.ELEMENT_ARRAY_BUFFER = 0x8893;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.ELEMENT_ARRAY_BUFFER = 0x8893;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.STREAM_DRAW = 0x88E0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.STREAM_DRAW = 0x88E0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.STATIC_DRAW = 0x88E4;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.STATIC_DRAW = 0x88E4;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.DYNAMIC_DRAW = 0x88E8;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.DYNAMIC_DRAW = 0x88E8;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.CULL_FACE = 0x0B44;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.CULL_FACE = 0x0B44;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.BLEND = 0x0BE2;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.BLEND = 0x0BE2;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.STENCIL_TEST = 0x0B90;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.STENCIL_TEST = 0x0B90;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.DEPTH_TEST = 0x0B71;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.DEPTH_TEST = 0x0B71;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.SCISSOR_TEST = 0x0C11;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.SCISSOR_TEST = 0x0C11;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.UNSIGNED_BYTE = 0x1401;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.UNSIGNED_BYTE = 0x1401;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.UNSIGNED_SHORT = 0x1403;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.UNSIGNED_SHORT = 0x1403;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.UNSIGNED_INT = 0x1405;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.UNSIGNED_INT = 0x1405;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.FLOAT = 0x1406;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.FLOAT = 0x1406;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.RGBA = 0x1908;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.RGBA = 0x1908;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.FRAGMENT_SHADER = 0x8B30;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.FRAGMENT_SHADER = 0x8B30;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.VERTEX_SHADER = 0x8B31;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.VERTEX_SHADER = 0x8B31;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.LINK_STATUS = 0x8B82;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.LINK_STATUS = 0x8B82;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.LINEAR = 0x2601;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.LINEAR = 0x2601;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE_MAG_FILTER = 0x2800;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE_MAG_FILTER = 0x2800;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE_MIN_FILTER = 0x2801;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE_MIN_FILTER = 0x2801;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE_WRAP_S = 0x2802;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE_WRAP_S = 0x2802;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE_WRAP_T = 0x2803;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE_WRAP_T = 0x2803;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE_2D = 0x0DE1;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE_2D = 0x0DE1;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.TEXTURE0 = 0x84C0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.TEXTURE0 = 0x84C0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.CLAMP_TO_EDGE = 0x812F;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.CLAMP_TO_EDGE = 0x812F;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.COMPILE_STATUS = 0x8B81;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.COMPILE_STATUS = 0x8B81;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
ol.webgl.FRAMEBUFFER = 0x8D40;
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
ol.webgl.FRAMEBUFFER = 0x8D40;
|
|
||||||
|
|
||||||
|
/** end of goog.webgl constants
|
||||||
|
*/
|
||||||
|
|
||||||
/** end of goog.webgl constants
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @private
|
||||||
|
* @type {Array.<string>}
|
||||||
|
*/
|
||||||
|
ol.webgl.CONTEXT_IDS_ = [
|
||||||
|
'experimental-webgl',
|
||||||
|
'webgl',
|
||||||
|
'webkit-3d',
|
||||||
|
'moz-webgl'
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @private
|
|
||||||
* @type {Array.<string>}
|
|
||||||
*/
|
|
||||||
ol.webgl.CONTEXT_IDS_ = [
|
|
||||||
'experimental-webgl',
|
|
||||||
'webgl',
|
|
||||||
'webkit-3d',
|
|
||||||
'moz-webgl'
|
|
||||||
];
|
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
* @param {HTMLCanvasElement} canvas Canvas.
|
||||||
* @param {HTMLCanvasElement} canvas Canvas.
|
* @param {Object=} opt_attributes Attributes.
|
||||||
* @param {Object=} opt_attributes Attributes.
|
* @return {WebGLRenderingContext} WebGL rendering context.
|
||||||
* @return {WebGLRenderingContext} WebGL rendering context.
|
*/
|
||||||
*/
|
ol.webgl.getContext = function(canvas, opt_attributes) {
|
||||||
ol.webgl.getContext = function(canvas, opt_attributes) {
|
var context, i, ii = ol.webgl.CONTEXT_IDS_.length;
|
||||||
var context, i, ii = ol.webgl.CONTEXT_IDS_.length;
|
for (i = 0; i < ii; ++i) {
|
||||||
for (i = 0; i < ii; ++i) {
|
try {
|
||||||
try {
|
context = canvas.getContext(ol.webgl.CONTEXT_IDS_[i], opt_attributes);
|
||||||
context = canvas.getContext(ol.webgl.CONTEXT_IDS_[i], opt_attributes);
|
if (context) {
|
||||||
if (context) {
|
return /** @type {!WebGLRenderingContext} */ (context);
|
||||||
return /** @type {!WebGLRenderingContext} */ (context);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// pass
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// pass
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
};
|
return null;
|
||||||
|
};
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,56 +4,52 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl');
|
goog.require('ol.webgl');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {Array.<number>=} opt_arr Array.
|
||||||
|
* @param {number=} opt_usage Usage.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.webgl.Buffer = function(opt_arr, opt_usage) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
|
||||||
* @param {Array.<number>=} opt_arr Array.
|
|
||||||
* @param {number=} opt_usage Usage.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
ol.webgl.Buffer = function(opt_arr, opt_usage) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Array.<number>}
|
|
||||||
*/
|
|
||||||
this.arr_ = opt_arr !== undefined ? opt_arr : [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.usage_ = opt_usage !== undefined ?
|
|
||||||
opt_usage : ol.webgl.Buffer.Usage_.STATIC_DRAW;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {Array.<number>} Array.
|
|
||||||
*/
|
|
||||||
ol.webgl.Buffer.prototype.getArray = function() {
|
|
||||||
return this.arr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {number} Usage.
|
|
||||||
*/
|
|
||||||
ol.webgl.Buffer.prototype.getUsage = function() {
|
|
||||||
return this.usage_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum {number}
|
|
||||||
* @private
|
* @private
|
||||||
|
* @type {Array.<number>}
|
||||||
*/
|
*/
|
||||||
ol.webgl.Buffer.Usage_ = {
|
this.arr_ = opt_arr !== undefined ? opt_arr : [];
|
||||||
STATIC_DRAW: ol.webgl.STATIC_DRAW,
|
|
||||||
STREAM_DRAW: ol.webgl.STREAM_DRAW,
|
|
||||||
DYNAMIC_DRAW: ol.webgl.DYNAMIC_DRAW
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.usage_ = opt_usage !== undefined ?
|
||||||
|
opt_usage : ol.webgl.Buffer.Usage_.STATIC_DRAW;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Array.<number>} Array.
|
||||||
|
*/
|
||||||
|
ol.webgl.Buffer.prototype.getArray = function() {
|
||||||
|
return this.arr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Usage.
|
||||||
|
*/
|
||||||
|
ol.webgl.Buffer.prototype.getUsage = function() {
|
||||||
|
return this.usage_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.webgl.Buffer.Usage_ = {
|
||||||
|
STATIC_DRAW: ol.webgl.STATIC_DRAW,
|
||||||
|
STREAM_DRAW: ol.webgl.STREAM_DRAW,
|
||||||
|
DYNAMIC_DRAW: ol.webgl.DYNAMIC_DRAW
|
||||||
|
};
|
||||||
|
|||||||
@@ -9,367 +9,363 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.ContextEventType');
|
goog.require('ol.webgl.ContextEventType');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @classdesc
|
||||||
|
* A WebGL context for accessing low-level WebGL capabilities.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.Disposable}
|
||||||
|
* @param {HTMLCanvasElement} canvas Canvas.
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context = function(canvas, gl) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @classdesc
|
* @private
|
||||||
* A WebGL context for accessing low-level WebGL capabilities.
|
* @type {HTMLCanvasElement}
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.Disposable}
|
|
||||||
* @param {HTMLCanvasElement} canvas Canvas.
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
*/
|
*/
|
||||||
ol.webgl.Context = function(canvas, gl) {
|
this.canvas_ = canvas;
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {HTMLCanvasElement}
|
|
||||||
*/
|
|
||||||
this.canvas_ = canvas;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {WebGLRenderingContext}
|
|
||||||
*/
|
|
||||||
this.gl_ = gl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, ol.WebglBufferCacheEntry>}
|
|
||||||
*/
|
|
||||||
this.bufferCache_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, WebGLShader>}
|
|
||||||
*/
|
|
||||||
this.shaderCache_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {Object.<string, WebGLProgram>}
|
|
||||||
*/
|
|
||||||
this.programCache_ = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {WebGLProgram}
|
|
||||||
*/
|
|
||||||
this.currentProgram_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {WebGLFramebuffer}
|
|
||||||
*/
|
|
||||||
this.hitDetectionFramebuffer_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {WebGLTexture}
|
|
||||||
*/
|
|
||||||
this.hitDetectionTexture_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {WebGLRenderbuffer}
|
|
||||||
*/
|
|
||||||
this.hitDetectionRenderbuffer_ = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.hasOESElementIndexUint = ol.array.includes(
|
|
||||||
ol.WEBGL_EXTENSIONS, 'OES_element_index_uint');
|
|
||||||
|
|
||||||
// use the OES_element_index_uint extension if available
|
|
||||||
if (this.hasOESElementIndexUint) {
|
|
||||||
gl.getExtension('OES_element_index_uint');
|
|
||||||
}
|
|
||||||
|
|
||||||
ol.events.listen(this.canvas_, ol.webgl.ContextEventType.LOST,
|
|
||||||
this.handleWebGLContextLost, this);
|
|
||||||
ol.events.listen(this.canvas_, ol.webgl.ContextEventType.RESTORED,
|
|
||||||
this.handleWebGLContextRestored, this);
|
|
||||||
|
|
||||||
};
|
|
||||||
ol.inherits(ol.webgl.Context, ol.Disposable);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just bind the buffer if it's in the cache. Otherwise create
|
* @private
|
||||||
* the WebGL buffer, bind it, populate it, and add an entry to
|
* @type {WebGLRenderingContext}
|
||||||
* the cache.
|
|
||||||
* @param {number} target Target.
|
|
||||||
* @param {ol.webgl.Buffer} buf Buffer.
|
|
||||||
*/
|
*/
|
||||||
ol.webgl.Context.prototype.bindBuffer = function(target, buf) {
|
this.gl_ = gl;
|
||||||
var gl = this.getGL();
|
|
||||||
var arr = buf.getArray();
|
|
||||||
var bufferKey = String(ol.getUid(buf));
|
|
||||||
if (bufferKey in this.bufferCache_) {
|
|
||||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
|
||||||
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
|
||||||
} else {
|
|
||||||
var buffer = gl.createBuffer();
|
|
||||||
gl.bindBuffer(target, buffer);
|
|
||||||
var /** @type {ArrayBufferView} */ arrayBuffer;
|
|
||||||
if (target == ol.webgl.ARRAY_BUFFER) {
|
|
||||||
arrayBuffer = new Float32Array(arr);
|
|
||||||
} else if (target == ol.webgl.ELEMENT_ARRAY_BUFFER) {
|
|
||||||
arrayBuffer = this.hasOESElementIndexUint ?
|
|
||||||
new Uint32Array(arr) : new Uint16Array(arr);
|
|
||||||
}
|
|
||||||
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
|
||||||
this.bufferCache_[bufferKey] = {
|
|
||||||
buf: buf,
|
|
||||||
buffer: buffer
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ol.webgl.Buffer} buf Buffer.
|
* @private
|
||||||
|
* @type {Object.<string, ol.WebglBufferCacheEntry>}
|
||||||
*/
|
*/
|
||||||
ol.webgl.Context.prototype.deleteBuffer = function(buf) {
|
this.bufferCache_ = {};
|
||||||
var gl = this.getGL();
|
|
||||||
var bufferKey = String(ol.getUid(buf));
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<string, WebGLShader>}
|
||||||
|
*/
|
||||||
|
this.shaderCache_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {Object.<string, WebGLProgram>}
|
||||||
|
*/
|
||||||
|
this.programCache_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {WebGLProgram}
|
||||||
|
*/
|
||||||
|
this.currentProgram_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {WebGLFramebuffer}
|
||||||
|
*/
|
||||||
|
this.hitDetectionFramebuffer_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {WebGLTexture}
|
||||||
|
*/
|
||||||
|
this.hitDetectionTexture_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {WebGLRenderbuffer}
|
||||||
|
*/
|
||||||
|
this.hitDetectionRenderbuffer_ = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.hasOESElementIndexUint = ol.array.includes(
|
||||||
|
ol.WEBGL_EXTENSIONS, 'OES_element_index_uint');
|
||||||
|
|
||||||
|
// use the OES_element_index_uint extension if available
|
||||||
|
if (this.hasOESElementIndexUint) {
|
||||||
|
gl.getExtension('OES_element_index_uint');
|
||||||
|
}
|
||||||
|
|
||||||
|
ol.events.listen(this.canvas_, ol.webgl.ContextEventType.LOST,
|
||||||
|
this.handleWebGLContextLost, this);
|
||||||
|
ol.events.listen(this.canvas_, ol.webgl.ContextEventType.RESTORED,
|
||||||
|
this.handleWebGLContextRestored, this);
|
||||||
|
|
||||||
|
};
|
||||||
|
ol.inherits(ol.webgl.Context, ol.Disposable);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just bind the buffer if it's in the cache. Otherwise create
|
||||||
|
* the WebGL buffer, bind it, populate it, and add an entry to
|
||||||
|
* the cache.
|
||||||
|
* @param {number} target Target.
|
||||||
|
* @param {ol.webgl.Buffer} buf Buffer.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.bindBuffer = function(target, buf) {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var arr = buf.getArray();
|
||||||
|
var bufferKey = String(ol.getUid(buf));
|
||||||
|
if (bufferKey in this.bufferCache_) {
|
||||||
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||||
if (!gl.isContextLost()) {
|
gl.bindBuffer(target, bufferCacheEntry.buffer);
|
||||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
} else {
|
||||||
|
var buffer = gl.createBuffer();
|
||||||
|
gl.bindBuffer(target, buffer);
|
||||||
|
var /** @type {ArrayBufferView} */ arrayBuffer;
|
||||||
|
if (target == ol.webgl.ARRAY_BUFFER) {
|
||||||
|
arrayBuffer = new Float32Array(arr);
|
||||||
|
} else if (target == ol.webgl.ELEMENT_ARRAY_BUFFER) {
|
||||||
|
arrayBuffer = this.hasOESElementIndexUint ?
|
||||||
|
new Uint32Array(arr) : new Uint16Array(arr);
|
||||||
}
|
}
|
||||||
delete this.bufferCache_[bufferKey];
|
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
||||||
};
|
this.bufferCache_[bufferKey] = {
|
||||||
|
buf: buf,
|
||||||
|
buffer: buffer
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @param {ol.webgl.Buffer} buf Buffer.
|
||||||
*/
|
*/
|
||||||
ol.webgl.Context.prototype.disposeInternal = function() {
|
ol.webgl.Context.prototype.deleteBuffer = function(buf) {
|
||||||
ol.events.unlistenAll(this.canvas_);
|
var gl = this.getGL();
|
||||||
|
var bufferKey = String(ol.getUid(buf));
|
||||||
|
var bufferCacheEntry = this.bufferCache_[bufferKey];
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||||
|
}
|
||||||
|
delete this.bufferCache_[bufferKey];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.disposeInternal = function() {
|
||||||
|
ol.events.unlistenAll(this.canvas_);
|
||||||
|
var gl = this.getGL();
|
||||||
|
if (!gl.isContextLost()) {
|
||||||
|
var key;
|
||||||
|
for (key in this.bufferCache_) {
|
||||||
|
gl.deleteBuffer(this.bufferCache_[key].buffer);
|
||||||
|
}
|
||||||
|
for (key in this.programCache_) {
|
||||||
|
gl.deleteProgram(this.programCache_[key]);
|
||||||
|
}
|
||||||
|
for (key in this.shaderCache_) {
|
||||||
|
gl.deleteShader(this.shaderCache_[key]);
|
||||||
|
}
|
||||||
|
// delete objects for hit-detection
|
||||||
|
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
|
||||||
|
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
|
||||||
|
gl.deleteTexture(this.hitDetectionTexture_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {HTMLCanvasElement} Canvas.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getCanvas = function() {
|
||||||
|
return this.canvas_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the WebGL rendering context
|
||||||
|
* @return {WebGLRenderingContext} The rendering context.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getGL = function() {
|
||||||
|
return this.gl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frame buffer for hit detection.
|
||||||
|
* @return {WebGLFramebuffer} The hit detection frame buffer.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getHitDetectionFramebuffer = function() {
|
||||||
|
if (!this.hitDetectionFramebuffer_) {
|
||||||
|
this.initHitDetectionFramebuffer_();
|
||||||
|
}
|
||||||
|
return this.hitDetectionFramebuffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get shader from the cache if it's in the cache. Otherwise, create
|
||||||
|
* the WebGL shader, compile it, and add entry to cache.
|
||||||
|
* @param {ol.webgl.Shader} shaderObject Shader object.
|
||||||
|
* @return {WebGLShader} Shader.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getShader = function(shaderObject) {
|
||||||
|
var shaderKey = String(ol.getUid(shaderObject));
|
||||||
|
if (shaderKey in this.shaderCache_) {
|
||||||
|
return this.shaderCache_[shaderKey];
|
||||||
|
} else {
|
||||||
var gl = this.getGL();
|
var gl = this.getGL();
|
||||||
if (!gl.isContextLost()) {
|
var shader = gl.createShader(shaderObject.getType());
|
||||||
var key;
|
gl.shaderSource(shader, shaderObject.getSource());
|
||||||
for (key in this.bufferCache_) {
|
gl.compileShader(shader);
|
||||||
gl.deleteBuffer(this.bufferCache_[key].buffer);
|
this.shaderCache_[shaderKey] = shader;
|
||||||
}
|
return shader;
|
||||||
for (key in this.programCache_) {
|
}
|
||||||
gl.deleteProgram(this.programCache_[key]);
|
};
|
||||||
}
|
|
||||||
for (key in this.shaderCache_) {
|
|
||||||
gl.deleteShader(this.shaderCache_[key]);
|
|
||||||
}
|
|
||||||
// delete objects for hit-detection
|
|
||||||
gl.deleteFramebuffer(this.hitDetectionFramebuffer_);
|
|
||||||
gl.deleteRenderbuffer(this.hitDetectionRenderbuffer_);
|
|
||||||
gl.deleteTexture(this.hitDetectionTexture_);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {HTMLCanvasElement} Canvas.
|
* Get the program from the cache if it's in the cache. Otherwise create
|
||||||
*/
|
* the WebGL program, attach the shaders to it, and add an entry to the
|
||||||
ol.webgl.Context.prototype.getCanvas = function() {
|
* cache.
|
||||||
return this.canvas_;
|
* @param {ol.webgl.Fragment} fragmentShaderObject Fragment shader.
|
||||||
};
|
* @param {ol.webgl.Vertex} vertexShaderObject Vertex shader.
|
||||||
|
* @return {WebGLProgram} Program.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.prototype.getProgram = function(
|
||||||
|
fragmentShaderObject, vertexShaderObject) {
|
||||||
|
var programKey =
|
||||||
|
ol.getUid(fragmentShaderObject) + '/' + ol.getUid(vertexShaderObject);
|
||||||
|
if (programKey in this.programCache_) {
|
||||||
|
return this.programCache_[programKey];
|
||||||
|
} else {
|
||||||
|
var gl = this.getGL();
|
||||||
|
var program = gl.createProgram();
|
||||||
|
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
||||||
|
gl.attachShader(program, this.getShader(vertexShaderObject));
|
||||||
|
gl.linkProgram(program);
|
||||||
|
this.programCache_[programKey] = program;
|
||||||
|
return program;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the WebGL rendering context
|
* FIXME empy description for jsdoc
|
||||||
* @return {WebGLRenderingContext} The rendering context.
|
*/
|
||||||
* @api
|
ol.webgl.Context.prototype.handleWebGLContextLost = function() {
|
||||||
*/
|
ol.obj.clear(this.bufferCache_);
|
||||||
ol.webgl.Context.prototype.getGL = function() {
|
ol.obj.clear(this.shaderCache_);
|
||||||
return this.gl_;
|
ol.obj.clear(this.programCache_);
|
||||||
};
|
this.currentProgram_ = null;
|
||||||
|
this.hitDetectionFramebuffer_ = null;
|
||||||
|
this.hitDetectionTexture_ = null;
|
||||||
|
this.hitDetectionRenderbuffer_ = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the frame buffer for hit detection.
|
* FIXME empy description for jsdoc
|
||||||
* @return {WebGLFramebuffer} The hit detection frame buffer.
|
*/
|
||||||
*/
|
ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
|
||||||
ol.webgl.Context.prototype.getHitDetectionFramebuffer = function() {
|
};
|
||||||
if (!this.hitDetectionFramebuffer_) {
|
|
||||||
this.initHitDetectionFramebuffer_();
|
|
||||||
}
|
|
||||||
return this.hitDetectionFramebuffer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get shader from the cache if it's in the cache. Otherwise, create
|
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
||||||
* the WebGL shader, compile it, and add entry to cache.
|
* @private
|
||||||
* @param {ol.webgl.Shader} shaderObject Shader object.
|
*/
|
||||||
* @return {WebGLShader} Shader.
|
ol.webgl.Context.prototype.initHitDetectionFramebuffer_ = function() {
|
||||||
*/
|
var gl = this.gl_;
|
||||||
ol.webgl.Context.prototype.getShader = function(shaderObject) {
|
var framebuffer = gl.createFramebuffer();
|
||||||
var shaderKey = String(ol.getUid(shaderObject));
|
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||||
if (shaderKey in this.shaderCache_) {
|
|
||||||
return this.shaderCache_[shaderKey];
|
var texture = ol.webgl.Context.createEmptyTexture(gl, 1, 1);
|
||||||
} else {
|
var renderbuffer = gl.createRenderbuffer();
|
||||||
var gl = this.getGL();
|
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
||||||
var shader = gl.createShader(shaderObject.getType());
|
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
|
||||||
gl.shaderSource(shader, shaderObject.getSource());
|
gl.framebufferTexture2D(
|
||||||
gl.compileShader(shader);
|
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||||
this.shaderCache_[shaderKey] = shader;
|
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
|
||||||
return shader;
|
gl.RENDERBUFFER, renderbuffer);
|
||||||
}
|
|
||||||
};
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
|
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
|
||||||
|
this.hitDetectionFramebuffer_ = framebuffer;
|
||||||
|
this.hitDetectionTexture_ = texture;
|
||||||
|
this.hitDetectionRenderbuffer_ = renderbuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the program from the cache if it's in the cache. Otherwise create
|
* Use a program. If the program is already in use, this will return `false`.
|
||||||
* the WebGL program, attach the shaders to it, and add an entry to the
|
* @param {WebGLProgram} program Program.
|
||||||
* cache.
|
* @return {boolean} Changed.
|
||||||
* @param {ol.webgl.Fragment} fragmentShaderObject Fragment shader.
|
* @api
|
||||||
* @param {ol.webgl.Vertex} vertexShaderObject Vertex shader.
|
*/
|
||||||
* @return {WebGLProgram} Program.
|
ol.webgl.Context.prototype.useProgram = function(program) {
|
||||||
*/
|
if (program == this.currentProgram_) {
|
||||||
ol.webgl.Context.prototype.getProgram = function(
|
return false;
|
||||||
fragmentShaderObject, vertexShaderObject) {
|
} else {
|
||||||
var programKey =
|
var gl = this.getGL();
|
||||||
ol.getUid(fragmentShaderObject) + '/' + ol.getUid(vertexShaderObject);
|
gl.useProgram(program);
|
||||||
if (programKey in this.programCache_) {
|
this.currentProgram_ = program;
|
||||||
return this.programCache_[programKey];
|
return true;
|
||||||
} else {
|
}
|
||||||
var gl = this.getGL();
|
};
|
||||||
var program = gl.createProgram();
|
|
||||||
gl.attachShader(program, this.getShader(fragmentShaderObject));
|
|
||||||
gl.attachShader(program, this.getShader(vertexShaderObject));
|
|
||||||
gl.linkProgram(program);
|
|
||||||
this.programCache_[programKey] = program;
|
|
||||||
return program;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME empy description for jsdoc
|
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
||||||
*/
|
* @param {number=} opt_wrapS wrapS.
|
||||||
ol.webgl.Context.prototype.handleWebGLContextLost = function() {
|
* @param {number=} opt_wrapT wrapT.
|
||||||
ol.obj.clear(this.bufferCache_);
|
* @return {WebGLTexture} The texture.
|
||||||
ol.obj.clear(this.shaderCache_);
|
* @private
|
||||||
ol.obj.clear(this.programCache_);
|
*/
|
||||||
this.currentProgram_ = null;
|
ol.webgl.Context.createTexture_ = function(gl, opt_wrapS, opt_wrapT) {
|
||||||
this.hitDetectionFramebuffer_ = null;
|
var texture = gl.createTexture();
|
||||||
this.hitDetectionTexture_ = null;
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||||
this.hitDetectionRenderbuffer_ = null;
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||||
};
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||||
|
|
||||||
|
if (opt_wrapS !== undefined) {
|
||||||
|
gl.texParameteri(
|
||||||
|
ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_S, opt_wrapS);
|
||||||
|
}
|
||||||
|
if (opt_wrapT !== undefined) {
|
||||||
|
gl.texParameteri(
|
||||||
|
ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_T, opt_wrapT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME empy description for jsdoc
|
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
||||||
*/
|
* @param {number} width Width.
|
||||||
ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
|
* @param {number} height Height.
|
||||||
};
|
* @param {number=} opt_wrapS wrapS.
|
||||||
|
* @param {number=} opt_wrapT wrapT.
|
||||||
|
* @return {WebGLTexture} The texture.
|
||||||
|
*/
|
||||||
|
ol.webgl.Context.createEmptyTexture = function(
|
||||||
|
gl, width, height, opt_wrapS, opt_wrapT) {
|
||||||
|
var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
|
||||||
|
null);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
||||||
* @private
|
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
|
||||||
*/
|
* @param {number=} opt_wrapS wrapS.
|
||||||
ol.webgl.Context.prototype.initHitDetectionFramebuffer_ = function() {
|
* @param {number=} opt_wrapT wrapT.
|
||||||
var gl = this.gl_;
|
* @return {WebGLTexture} The texture.
|
||||||
var framebuffer = gl.createFramebuffer();
|
*/
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
ol.webgl.Context.createTexture = function(gl, image, opt_wrapS, opt_wrapT) {
|
||||||
|
var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
var texture = ol.webgl.Context.createEmptyTexture(gl, 1, 1);
|
return texture;
|
||||||
var renderbuffer = gl.createRenderbuffer();
|
};
|
||||||
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
|
|
||||||
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 1, 1);
|
|
||||||
gl.framebufferTexture2D(
|
|
||||||
gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
||||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
|
|
||||||
gl.RENDERBUFFER, renderbuffer);
|
|
||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
||||||
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
|
||||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
||||||
|
|
||||||
this.hitDetectionFramebuffer_ = framebuffer;
|
|
||||||
this.hitDetectionTexture_ = texture;
|
|
||||||
this.hitDetectionRenderbuffer_ = renderbuffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use a program. If the program is already in use, this will return `false`.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @return {boolean} Changed.
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
ol.webgl.Context.prototype.useProgram = function(program) {
|
|
||||||
if (program == this.currentProgram_) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var gl = this.getGL();
|
|
||||||
gl.useProgram(program);
|
|
||||||
this.currentProgram_ = program;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
|
||||||
* @param {number=} opt_wrapS wrapS.
|
|
||||||
* @param {number=} opt_wrapT wrapT.
|
|
||||||
* @return {WebGLTexture} The texture.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
ol.webgl.Context.createTexture_ = function(gl, opt_wrapS, opt_wrapT) {
|
|
||||||
var texture = gl.createTexture();
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
||||||
|
|
||||||
if (opt_wrapS !== undefined) {
|
|
||||||
gl.texParameteri(
|
|
||||||
ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_S, opt_wrapS);
|
|
||||||
}
|
|
||||||
if (opt_wrapT !== undefined) {
|
|
||||||
gl.texParameteri(
|
|
||||||
ol.webgl.TEXTURE_2D, ol.webgl.TEXTURE_WRAP_T, opt_wrapT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
|
||||||
* @param {number} width Width.
|
|
||||||
* @param {number} height Height.
|
|
||||||
* @param {number=} opt_wrapS wrapS.
|
|
||||||
* @param {number=} opt_wrapT wrapT.
|
|
||||||
* @return {WebGLTexture} The texture.
|
|
||||||
*/
|
|
||||||
ol.webgl.Context.createEmptyTexture = function(
|
|
||||||
gl, width, height, opt_wrapS, opt_wrapT) {
|
|
||||||
var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
|
|
||||||
gl.texImage2D(
|
|
||||||
gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
|
|
||||||
null);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {WebGLRenderingContext} gl WebGL rendering context.
|
|
||||||
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
|
|
||||||
* @param {number=} opt_wrapS wrapS.
|
|
||||||
* @param {number=} opt_wrapT wrapT.
|
|
||||||
* @return {WebGLTexture} The texture.
|
|
||||||
*/
|
|
||||||
ol.webgl.Context.createTexture = function(gl, image, opt_wrapS, opt_wrapT) {
|
|
||||||
var texture = ol.webgl.Context.createTexture_(gl, opt_wrapS, opt_wrapT);
|
|
||||||
gl.texImage2D(
|
|
||||||
gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
||||||
|
|
||||||
return texture;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,25 +5,21 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.Shader');
|
goog.require('ol.webgl.Shader');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
/**
|
* @extends {ol.webgl.Shader}
|
||||||
* @constructor
|
* @param {string} source Source.
|
||||||
* @extends {ol.webgl.Shader}
|
* @struct
|
||||||
* @param {string} source Source.
|
*/
|
||||||
* @struct
|
ol.webgl.Fragment = function(source) {
|
||||||
*/
|
ol.webgl.Shader.call(this, source);
|
||||||
ol.webgl.Fragment = function(source) {
|
};
|
||||||
ol.webgl.Shader.call(this, source);
|
ol.inherits(ol.webgl.Fragment, ol.webgl.Shader);
|
||||||
};
|
|
||||||
ol.inherits(ol.webgl.Fragment, ol.webgl.Shader);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.webgl.Fragment.prototype.getType = function() {
|
ol.webgl.Fragment.prototype.getType = function() {
|
||||||
return ol.webgl.FRAGMENT_SHADER;
|
return ol.webgl.FRAGMENT_SHADER;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,43 +4,39 @@ goog.require('ol');
|
|||||||
goog.require('ol.functions');
|
goog.require('ol.functions');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @abstract
|
||||||
|
* @param {string} source Source.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
ol.webgl.Shader = function(source) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @private
|
||||||
* @abstract
|
* @type {string}
|
||||||
* @param {string} source Source.
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
ol.webgl.Shader = function(source) {
|
this.source_ = source;
|
||||||
|
|
||||||
/**
|
};
|
||||||
* @private
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.source_ = source;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @abstract
|
||||||
* @return {number} Type.
|
* @return {number} Type.
|
||||||
*/
|
*/
|
||||||
ol.webgl.Shader.prototype.getType = function() {};
|
ol.webgl.Shader.prototype.getType = function() {};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {string} Source.
|
* @return {string} Source.
|
||||||
*/
|
*/
|
||||||
ol.webgl.Shader.prototype.getSource = function() {
|
ol.webgl.Shader.prototype.getSource = function() {
|
||||||
return this.source_;
|
return this.source_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {boolean} Is animated?
|
* @return {boolean} Is animated?
|
||||||
*/
|
*/
|
||||||
ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE;
|
ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE;
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,105 +6,101 @@ goog.require('ol');
|
|||||||
goog.require('ol.webgl.Fragment');
|
goog.require('ol.webgl.Fragment');
|
||||||
goog.require('ol.webgl.Vertex');
|
goog.require('ol.webgl.Vertex');
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Fragment}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
{{className}}.Fragment = function() {
|
||||||
|
ol.webgl.Fragment.call(this, {{className}}.Fragment.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits({{className}}.Fragment, ol.webgl.Fragment);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Fragment.DEBUG_SOURCE = 'precision mediump float;\n{{{getOriginalFragmentSource}}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;{{{getFragmentSource}}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
{{className}}.Fragment.DEBUG_SOURCE :
|
||||||
|
{{className}}.Fragment.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
{{className}}.fragment = new {{className}}.Fragment();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @extends {ol.webgl.Vertex}
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
{{className}}.Vertex = function() {
|
||||||
|
ol.webgl.Vertex.call(this, {{className}}.Vertex.SOURCE);
|
||||||
|
};
|
||||||
|
ol.inherits({{className}}.Vertex, ol.webgl.Vertex);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Vertex.DEBUG_SOURCE = '{{{getOriginalVertexSource}}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Vertex.OPTIMIZED_SOURCE = '{{{getVertexSource}}}';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @const
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
{{className}}.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||||
|
{{className}}.Vertex.DEBUG_SOURCE :
|
||||||
|
{{className}}.Vertex.OPTIMIZED_SOURCE;
|
||||||
|
|
||||||
|
|
||||||
|
{{className}}.vertex = new {{className}}.Vertex();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param {WebGLRenderingContext} gl GL.
|
||||||
|
* @param {WebGLProgram} program Program.
|
||||||
|
* @struct
|
||||||
|
*/
|
||||||
|
{{namespace}}.Locations = function(gl, program) {
|
||||||
|
{{#getUniforms}}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @type {WebGLUniformLocation}
|
||||||
* @extends {ol.webgl.Fragment}
|
|
||||||
* @struct
|
|
||||||
*/
|
*/
|
||||||
{{className}}.Fragment = function() {
|
this.{{originalName}} = gl.getUniformLocation(
|
||||||
ol.webgl.Fragment.call(this, {{className}}.Fragment.SOURCE);
|
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||||
};
|
{{/getUniforms}}
|
||||||
ol.inherits({{className}}.Fragment, ol.webgl.Fragment);
|
{{#getAttributes}}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @const
|
* @type {number}
|
||||||
* @type {string}
|
|
||||||
*/
|
*/
|
||||||
{{className}}.Fragment.DEBUG_SOURCE = 'precision mediump float;\n{{{getOriginalFragmentSource}}}';
|
this.{{originalName}} = gl.getAttribLocation(
|
||||||
|
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||||
|
{{/getAttributes}}
|
||||||
/**
|
};
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
{{className}}.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;{{{getFragmentSource}}}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
{{className}}.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
|
||||||
{{className}}.Fragment.DEBUG_SOURCE :
|
|
||||||
{{className}}.Fragment.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
{{className}}.fragment = new {{className}}.Fragment();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @extends {ol.webgl.Vertex}
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
{{className}}.Vertex = function() {
|
|
||||||
ol.webgl.Vertex.call(this, {{className}}.Vertex.SOURCE);
|
|
||||||
};
|
|
||||||
ol.inherits({{className}}.Vertex, ol.webgl.Vertex);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
{{className}}.Vertex.DEBUG_SOURCE = '{{{getOriginalVertexSource}}}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
{{className}}.Vertex.OPTIMIZED_SOURCE = '{{{getVertexSource}}}';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @const
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
{{className}}.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
|
||||||
{{className}}.Vertex.DEBUG_SOURCE :
|
|
||||||
{{className}}.Vertex.OPTIMIZED_SOURCE;
|
|
||||||
|
|
||||||
|
|
||||||
{{className}}.vertex = new {{className}}.Vertex();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
* @param {WebGLRenderingContext} gl GL.
|
|
||||||
* @param {WebGLProgram} program Program.
|
|
||||||
* @struct
|
|
||||||
*/
|
|
||||||
{{namespace}}.Locations = function(gl, program) {
|
|
||||||
{{#getUniforms}}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {WebGLUniformLocation}
|
|
||||||
*/
|
|
||||||
this.{{originalName}} = gl.getUniformLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
|
||||||
{{/getUniforms}}
|
|
||||||
{{#getAttributes}}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.{{originalName}} = gl.getAttribLocation(
|
|
||||||
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
|
||||||
{{/getAttributes}}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,25 +5,21 @@ goog.require('ol.webgl');
|
|||||||
goog.require('ol.webgl.Shader');
|
goog.require('ol.webgl.Shader');
|
||||||
|
|
||||||
|
|
||||||
if (ol.ENABLE_WEBGL) {
|
/**
|
||||||
|
* @constructor
|
||||||
/**
|
* @extends {ol.webgl.Shader}
|
||||||
* @constructor
|
* @param {string} source Source.
|
||||||
* @extends {ol.webgl.Shader}
|
* @struct
|
||||||
* @param {string} source Source.
|
*/
|
||||||
* @struct
|
ol.webgl.Vertex = function(source) {
|
||||||
*/
|
ol.webgl.Shader.call(this, source);
|
||||||
ol.webgl.Vertex = function(source) {
|
};
|
||||||
ol.webgl.Shader.call(this, source);
|
ol.inherits(ol.webgl.Vertex, ol.webgl.Shader);
|
||||||
};
|
|
||||||
ol.inherits(ol.webgl.Vertex, ol.webgl.Shader);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.webgl.Vertex.prototype.getType = function() {
|
ol.webgl.Vertex.prototype.getType = function() {
|
||||||
return ol.webgl.VERTEX_SHADER;
|
return ol.webgl.VERTEX_SHADER;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user