Merge pull request #7148 from ahocevar/webgl-define
Remove ol.ENABLE_WEBGL wrap from WebGL files
This commit is contained in:
@@ -3,103 +3,99 @@ goog.provide('ol.render.webgl');
|
||||
goog.require('ol');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultFont = '10px sans-serif';
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultFont = '10px sans-serif';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultLineCap = 'round';
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultLineCap = 'round';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
ol.render.webgl.defaultLineDash = [];
|
||||
/**
|
||||
* @const
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
ol.render.webgl.defaultLineDash = [];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultLineDashOffset = 0;
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultLineDashOffset = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultLineJoin = 'round';
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultLineJoin = 'round';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultMiterLimit = 10;
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultMiterLimit = 10;
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextAlign = 0.5;
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextAlign = 0.5;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextBaseline = 0.5;
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextBaseline = 0.5;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultLineWidth = 1;
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultLineWidth = 1;
|
||||
|
||||
/**
|
||||
* Calculates the orientation of a triangle based on the determinant method.
|
||||
* @param {number} x1 First X coordinate.
|
||||
* @param {number} y1 First Y coordinate.
|
||||
* @param {number} x2 Second X coordinate.
|
||||
* @param {number} y2 Second Y coordinate.
|
||||
* @param {number} x3 Third X coordinate.
|
||||
* @param {number} y3 Third Y coordinate.
|
||||
* @return {boolean|undefined} Triangle is clockwise.
|
||||
*/
|
||||
ol.render.webgl.triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
|
||||
var area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
|
||||
return (area <= ol.render.webgl.EPSILON && area >= -ol.render.webgl.EPSILON) ?
|
||||
undefined : area > 0;
|
||||
};
|
||||
/**
|
||||
* Calculates the orientation of a triangle based on the determinant method.
|
||||
* @param {number} x1 First X coordinate.
|
||||
* @param {number} y1 First Y coordinate.
|
||||
* @param {number} x2 Second X coordinate.
|
||||
* @param {number} y2 Second Y coordinate.
|
||||
* @param {number} x3 Third X coordinate.
|
||||
* @param {number} y3 Third Y coordinate.
|
||||
* @return {boolean|undefined} Triangle is clockwise.
|
||||
*/
|
||||
ol.render.webgl.triangleIsCounterClockwise = function(x1, y1, x2, y2, x3, y3) {
|
||||
var area = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
|
||||
return (area <= ol.render.webgl.EPSILON && area >= -ol.render.webgl.EPSILON) ?
|
||||
undefined : area > 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.EPSILON = Number.EPSILON || 2.220446049250313e-16;
|
||||
|
||||
}
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.EPSILON = Number.EPSILON || 2.220446049250313e-16;
|
||||
|
||||
@@ -13,412 +13,408 @@ goog.require('ol.webgl');
|
||||
goog.require('ol.webgl.Buffer');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.render.webgl.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.render.webgl.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.CircleReplay = function(tolerance, maxExtent) {
|
||||
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
* @type {ol.render.webgl.circlereplay.defaultshader.Locations}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
this.defaultLocations_ = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {Array.<Array.<Array.<number>|number>>}
|
||||
*/
|
||||
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.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
|
||||
* @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.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
|
||||
**/
|
||||
ol.render.webgl.CircleReplay.prototype.finish = function(context) {
|
||||
// create, bind, and populate the vertices buffer
|
||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// get the program
|
||||
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
|
||||
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
||||
// 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_;
|
||||
}
|
||||
|
||||
this.startIndices.push(this.indices.length);
|
||||
context.useProgram(program);
|
||||
|
||||
//Clean up, if there is nothing to draw
|
||||
if (this.styleIndices_.length === 0 && this.styles_.length > 0) {
|
||||
this.styles_ = [];
|
||||
}
|
||||
// enable the vertex attrib arrays
|
||||
gl.enableVertexAttribArray(locations.a_position);
|
||||
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
||||
false, 16, 0);
|
||||
|
||||
this.vertices = null;
|
||||
this.indices = null;
|
||||
};
|
||||
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.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
|
||||
*/
|
||||
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.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// get the program
|
||||
var fragmentShader, vertexShader;
|
||||
fragmentShader = ol.render.webgl.circlereplay.defaultshader.fragment;
|
||||
vertexShader = ol.render.webgl.circlereplay.defaultshader.vertex;
|
||||
var program = context.getProgram(fragmentShader, vertexShader);
|
||||
|
||||
// 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];
|
||||
/**
|
||||
* @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]));
|
||||
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() &&
|
||||
(opt_hitExtent === undefined || ol.extent.intersects(
|
||||
/** @type {Array<number>} */ (opt_hitExtent),
|
||||
feature.getGeometry().getExtent()))) {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
/**
|
||||
* @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) {
|
||||
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);
|
||||
|
||||
var result = featureCallback(feature);
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
featureIndex--;
|
||||
end = start;
|
||||
end = featureStart;
|
||||
}
|
||||
featureIndex--;
|
||||
start = featureStart;
|
||||
}
|
||||
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);
|
||||
}
|
||||
end = featureStart;
|
||||
}
|
||||
featureIndex--;
|
||||
start = featureStart;
|
||||
}
|
||||
if (start !== end) {
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
start = end = groupStart;
|
||||
if (start !== end) {
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
};
|
||||
start = end = groupStart;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {Array.<number>} color Color.
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setFillStyle_ = function(gl, color) {
|
||||
gl.uniform4fv(this.defaultLocations_.u_fillColor, color);
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {Array.<number>} color Color.
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setFillStyle_ = function(gl, color) {
|
||||
gl.uniform4fv(this.defaultLocations_.u_fillColor, color);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {Array.<number>} color Color.
|
||||
* @param {number} lineWidth Line width.
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth) {
|
||||
gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);
|
||||
gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {Array.<number>} color Color.
|
||||
* @param {number} lineWidth Line width.
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setStrokeStyle_ = function(gl, color, lineWidth) {
|
||||
gl.uniform4fv(this.defaultLocations_.u_strokeColor, color);
|
||||
gl.uniform1f(this.defaultLocations_.u_lineWidth, lineWidth);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
||||
var strokeStyleColor, strokeStyleWidth;
|
||||
if (strokeStyle) {
|
||||
var strokeStyleLineDash = strokeStyle.getLineDash();
|
||||
this.state_.lineDash = strokeStyleLineDash ?
|
||||
strokeStyleLineDash : ol.render.webgl.defaultLineDash;
|
||||
var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
|
||||
this.state_.lineDashOffset = strokeStyleLineDashOffset ?
|
||||
strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
|
||||
strokeStyleColor = strokeStyle.getColor();
|
||||
if (!(strokeStyleColor instanceof CanvasGradient) &&
|
||||
!(strokeStyleColor instanceof CanvasPattern)) {
|
||||
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) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.CircleReplay.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
||||
var strokeStyleColor, strokeStyleWidth;
|
||||
if (strokeStyle) {
|
||||
var strokeStyleLineDash = strokeStyle.getLineDash();
|
||||
this.state_.lineDash = strokeStyleLineDash ?
|
||||
strokeStyleLineDash : ol.render.webgl.defaultLineDash;
|
||||
var strokeStyleLineDashOffset = strokeStyle.getLineDashOffset();
|
||||
this.state_.lineDashOffset = strokeStyleLineDashOffset ?
|
||||
strokeStyleLineDashOffset : ol.render.webgl.defaultLineDashOffset;
|
||||
strokeStyleColor = strokeStyle.getColor();
|
||||
if (!(strokeStyleColor instanceof CanvasGradient) &&
|
||||
!(strokeStyleColor instanceof CanvasPattern)) {
|
||||
strokeStyleColor = ol.color.asArray(strokeStyleColor).map(function(c, i) {
|
||||
return i != 3 ? c / 255 : c;
|
||||
}) || ol.render.webgl.defaultFillStyle;
|
||||
}) || ol.render.webgl.defaultStrokeStyle;
|
||||
} else {
|
||||
fillStyleColor = ol.render.webgl.defaultFillStyle;
|
||||
strokeStyleColor = ol.render.webgl.defaultStrokeStyle;
|
||||
}
|
||||
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]);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
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;
|
||||
}) || 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.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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_fillColor = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'm');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.u_size = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_size' : 'p');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
ol.render.webgl.circlereplay.defaultshader.Locations = function(gl, program) {
|
||||
this.u_strokeColor = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_strokeColor' : 'o');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_fillColor = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_fillColor' : 'n');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_instruction = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_instruction' : 'f');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_lineWidth = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_lineWidth' : 'k');
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'e');
|
||||
|
||||
/**
|
||||
* @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' : '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');
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @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');
|
||||
|
||||
|
||||
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
|
||||
* @extends {ol.render.webgl.TextureReplay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||
* @protected
|
||||
*/
|
||||
ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
|
||||
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);
|
||||
|
||||
this.images_ = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||
* @protected
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
|
||||
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);
|
||||
};
|
||||
|
||||
this.hitDetectionImages_ = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @type {Array.<WebGLTexture>}
|
||||
* @private
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
this.textures_ = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @type {Array.<WebGLTexture>}
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.finish = function(context) {
|
||||
var gl = context.getGL();
|
||||
this.hitDetectionTextures_ = [];
|
||||
|
||||
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);
|
||||
};
|
||||
};
|
||||
ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay);
|
||||
|
||||
|
||||
/**
|
||||
* @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();
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawMultiPoint = function(multiPointGeometry, feature) {
|
||||
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);
|
||||
};
|
||||
|
||||
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);
|
||||
} 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);
|
||||
} 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.anchorY = anchor[1];
|
||||
this.height = size[1];
|
||||
this.imageHeight = imageSize[1];
|
||||
this.imageWidth = imageSize[0];
|
||||
this.opacity = opacity;
|
||||
this.originX = origin[0];
|
||||
this.originY = origin[1];
|
||||
this.rotation = rotation;
|
||||
this.rotateWithView = rotateWithView;
|
||||
this.scale = scale;
|
||||
this.width = size[0];
|
||||
};
|
||||
this.anchorX = anchor[0];
|
||||
this.anchorY = anchor[1];
|
||||
this.height = size[1];
|
||||
this.imageHeight = imageSize[1];
|
||||
this.imageWidth = imageSize[0];
|
||||
this.opacity = opacity;
|
||||
this.originX = origin[0];
|
||||
this.originY = origin[1];
|
||||
this.rotation = rotation;
|
||||
this.rotateWithView = rotateWithView;
|
||||
this.scale = scale;
|
||||
this.width = size[0];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
|
||||
return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
|
||||
return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.hitDetectionTextures_;
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.hitDetectionTextures_;
|
||||
};
|
||||
|
||||
@@ -8,410 +8,406 @@ goog.require('ol.render.VectorContext');
|
||||
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
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
|
||||
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)();
|
||||
};
|
||||
|
||||
this.context_ = context;
|
||||
|
||||
/**
|
||||
* Set the rendering style. Note that since this is an immediate rendering API,
|
||||
* any `zIndex` on the provided style will be ignored.
|
||||
*
|
||||
* @param {ol.style.Style} style The rendering style.
|
||||
* @override
|
||||
* @api
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setStyle = function(style) {
|
||||
this.setFillStrokeStyle(style.getFill(), style.getStroke());
|
||||
this.setImageStyle(style.getImage());
|
||||
this.setTextStyle(style.getText());
|
||||
};
|
||||
|
||||
this.center_ = center;
|
||||
|
||||
/**
|
||||
* Render a geometry into the canvas. Call
|
||||
* {@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
|
||||
* @private
|
||||
*/
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
this.extent_ = extent;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api
|
||||
* @private
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
this.pixelRatio_ = pixelRatio;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
*/
|
||||
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]);
|
||||
}
|
||||
};
|
||||
|
||||
this.size_ = size;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.rotation_ = rotation;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.resolution_ = resolution;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.style.Image}
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.imageStyle_ = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.style.Fill}
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.fillStyle_ = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.style.Stroke}
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.strokeStyle_ = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.style.Text}
|
||||
*/
|
||||
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)();
|
||||
this.textStyle_ = null;
|
||||
|
||||
if (this.textStyle_) {
|
||||
var flatInteriorPoints = geometry.getFlatInteriorPoints();
|
||||
this.drawText_(replayGroup, flatInteriorPoints, 0, flatInteriorPoints.length, 2);
|
||||
}
|
||||
};
|
||||
};
|
||||
ol.inherits(ol.render.webgl.Immediate, ol.render.VectorContext);
|
||||
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
|
||||
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)();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setImageStyle = function(imageStyle) {
|
||||
this.imageStyle_ = imageStyle;
|
||||
};
|
||||
/**
|
||||
* Set the rendering style. Note that since this is an immediate rendering API,
|
||||
* 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.setFillStrokeStyle(style.getFill(), style.getStroke());
|
||||
this.setImageStyle(style.getImage());
|
||||
this.setTextStyle(style.getText());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setFillStrokeStyle = function(fillStyle, strokeStyle) {
|
||||
this.fillStyle_ = fillStyle;
|
||||
this.strokeStyle_ = strokeStyle;
|
||||
};
|
||||
/**
|
||||
* Render a geometry into the canvas. Call
|
||||
* {@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) {
|
||||
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
|
||||
*/
|
||||
ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
|
||||
this.textStyle_ = textStyle;
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api
|
||||
*/
|
||||
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.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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_color = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_color' : 'e');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'b');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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) {
|
||||
|
||||
/**
|
||||
* @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');
|
||||
};
|
||||
|
||||
}
|
||||
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');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @extends {ol.render.VectorContext}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
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) {};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @extends {ol.render.VectorContext}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.Replay = function(tolerance, maxExtent) {
|
||||
ol.render.VectorContext.call(this);
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @type {number}
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.tolerance = tolerance;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @const
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
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;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
this.maxExtent = maxExtent;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* 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}
|
||||
*/
|
||||
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;
|
||||
this.origin = ol.extent.getCenter(maxExtent);
|
||||
|
||||
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);
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.projectionMatrix_ = ol.transform.create();
|
||||
|
||||
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);
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
this.offsetRotateMatrix_ = ol.transform.create();
|
||||
|
||||
this.lineStringReplay.replay(context,
|
||||
center, resolution, rotation, size, pixelRatio,
|
||||
opacity, skippedFeaturesHash,
|
||||
featureCallback, oneByOne, opt_hitExtent);
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Transform}
|
||||
*/
|
||||
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_);
|
||||
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]));
|
||||
/**
|
||||
* Start index per feature (the feature).
|
||||
* @protected
|
||||
* @type {Array.<ol.Feature|ol.render.Feature>}
|
||||
*/
|
||||
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) {
|
||||
ol.transform.rotate(offsetRotateMatrix, -rotation);
|
||||
}
|
||||
/**
|
||||
* @protected
|
||||
* @type {?ol.webgl.Buffer}
|
||||
*/
|
||||
this.verticesBuffer = null;
|
||||
|
||||
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);
|
||||
/**
|
||||
* Optional parameter for PolygonReplay instances.
|
||||
* @protected
|
||||
* @type {ol.render.webgl.LineStringReplay|undefined}
|
||||
*/
|
||||
this.lineStringReplay = undefined;
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
ol.inherits(ol.render.webgl.Replay, ol.render.VectorContext);
|
||||
|
||||
// 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));
|
||||
}
|
||||
/**
|
||||
* @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
|
||||
* @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;
|
||||
};
|
||||
} 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;
|
||||
gl.drawElements(ol.webgl.TRIANGLES, numItems, elementType, offsetInBytes);
|
||||
};
|
||||
/**
|
||||
* @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.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');
|
||||
|
||||
|
||||
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
|
||||
* @extends {ol.render.ReplayGroup}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @param {number=} opt_renderBuffer Render buffer.
|
||||
* @struct
|
||||
* @type {ol.Extent}
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.ReplayGroup = function(tolerance, maxExtent, opt_renderBuffer) {
|
||||
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);
|
||||
|
||||
this.maxExtent_ = maxExtent;
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Context} context WebGL context.
|
||||
* @return {function()} Delete resources function.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
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;
|
||||
};
|
||||
};
|
||||
|
||||
this.tolerance_ = tolerance;
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.renderBuffer_ = opt_renderBuffer;
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @type {!Object.<string,
|
||||
* Object.<ol.render.ReplayType, ol.render.webgl.Replay>>}
|
||||
*/
|
||||
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;
|
||||
});
|
||||
this.replaysByZIndex_ = {};
|
||||
|
||||
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);
|
||||
};
|
||||
ol.inherits(ol.render.webgl.ReplayGroup, ol.render.ReplayGroup);
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Context} context WebGL context.
|
||||
* @return {function()} Delete resources function.
|
||||
*/
|
||||
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) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
}, true, hitExtent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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());
|
||||
/**
|
||||
* @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.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @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 hasFeature !== undefined;
|
||||
};
|
||||
|
||||
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);
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
ol.render.webgl.ReplayGroup.HIT_DETECTION_SIZE_ = [1, 1];
|
||||
|
||||
if (imageData[3] > 0) {
|
||||
var result = callback(feature);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}, true, hitExtent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @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
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @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');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.render.webgl.TextureReplay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.render.webgl.TextureReplay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.TextReplay = function(tolerance, maxExtent) {
|
||||
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string>} lines Label to draw split to lines.
|
||||
* @return {Array.<number>} Size of the label in pixels.
|
||||
* @type {Array.<HTMLCanvasElement>}
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
|
||||
var self = this;
|
||||
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 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;
|
||||
for (i = 0, ii = str.length; i < ii; ++i) {
|
||||
var curr = str[i];
|
||||
if (!glyphAtlas.width[curr]) {
|
||||
self.addCharToAtlas_(curr);
|
||||
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);
|
||||
}
|
||||
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
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
|
||||
end, stride) {
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string>} lines Label to draw split to lines.
|
||||
* @return {Array.<number>} Size of the label in pixels.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
|
||||
var self = this;
|
||||
var glyphAtlas = this.currAtlas_;
|
||||
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;
|
||||
for (i = offset, ii = end; i < ii; i += stride) {
|
||||
this.drawCoordinates(flatCoordinates, offset, end, stride);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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;
|
||||
for (i = 0, ii = str.length; i < ii; ++i) {
|
||||
var curr = str[i];
|
||||
if (!glyphAtlas.width[curr]) {
|
||||
self.addCharToAtlas_(curr);
|
||||
}
|
||||
sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;
|
||||
}
|
||||
};
|
||||
return sum;
|
||||
}).reduce(function(max, curr) {
|
||||
return Math.max(max, curr);
|
||||
});
|
||||
|
||||
return [textWidth, textHeight];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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);
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
|
||||
end, stride) {
|
||||
var i, ii;
|
||||
for (i = offset, ii = end; i < ii; i += stride) {
|
||||
this.drawCoordinates(flatCoordinates, offset, end, stride);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
|
||||
/**
|
||||
* @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 textFillStyle = textStyle.getFill();
|
||||
var textStrokeStyle = textStyle.getStroke();
|
||||
if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {
|
||||
this.text_ = '';
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
if (!textFillStyle) {
|
||||
state.fillColor = null;
|
||||
var textFillStyleColor = textFillStyle.getColor();
|
||||
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 {
|
||||
var textFillStyleColor = textFillStyle.getColor();
|
||||
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]);
|
||||
}
|
||||
params.push(state[i]);
|
||||
}
|
||||
}
|
||||
var hash = this.calculateHash_(params);
|
||||
if (!this.atlases_[hash]) {
|
||||
var mCtx = this.measureCanvas_.getContext('2d');
|
||||
mCtx.font = state.font;
|
||||
var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
|
||||
state.lineWidth / 2) * state.scale);
|
||||
}
|
||||
var hash = this.calculateHash_(params);
|
||||
if (!this.atlases_[hash]) {
|
||||
var mCtx = this.measureCanvas_.getContext('2d');
|
||||
mCtx.font = state.font;
|
||||
var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
|
||||
state.lineWidth / 2) * state.scale);
|
||||
|
||||
this.atlases_[hash] = {
|
||||
atlas: new ol.style.AtlasManager({
|
||||
space: state.lineWidth + 1
|
||||
}),
|
||||
width: {},
|
||||
height: height
|
||||
};
|
||||
}
|
||||
return this.atlases_[hash];
|
||||
};
|
||||
this.atlases_[hash] = {
|
||||
atlas: new ol.style.AtlasManager({
|
||||
space: state.lineWidth + 1
|
||||
}),
|
||||
width: {},
|
||||
height: height
|
||||
};
|
||||
}
|
||||
return this.atlases_[hash];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string|number>} params Array of parameters.
|
||||
* @return {string} Hash string.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
|
||||
//TODO: Create a more performant, reliable, general hash function.
|
||||
var i, ii;
|
||||
var hash = '';
|
||||
for (i = 0, ii = params.length; i < ii; ++i) {
|
||||
hash += params[i];
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string|number>} params Array of parameters.
|
||||
* @return {string} Hash string.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
|
||||
//TODO: Create a more performant, reliable, general hash function.
|
||||
var i, ii;
|
||||
var hash = '';
|
||||
for (i = 0, ii = params.length; i < ii; ++i) {
|
||||
hash += params[i];
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
||||
return this.textures_;
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
||||
return this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.textures_;
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.TextReplay.Align_ = {
|
||||
left: 0,
|
||||
end: 0,
|
||||
center: 0.5,
|
||||
right: 1,
|
||||
start: 1,
|
||||
top: 0,
|
||||
middle: 0.5,
|
||||
hanging: 0.2,
|
||||
alphabetic: 0.8,
|
||||
ideographic: 0.8,
|
||||
bottom: 1
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.TextReplay.Align_ = {
|
||||
left: 0,
|
||||
end: 0,
|
||||
center: 0.5,
|
||||
right: 1,
|
||||
start: 1,
|
||||
top: 0,
|
||||
middle: 0.5,
|
||||
hanging: 0.2,
|
||||
alphabetic: 0.8,
|
||||
ideographic: 0.8,
|
||||
bottom: 1
|
||||
};
|
||||
|
||||
@@ -8,490 +8,487 @@ goog.require('ol.render.webgl.Replay');
|
||||
goog.require('ol.webgl');
|
||||
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
|
||||
* @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.
|
||||
* @type {number|undefined}
|
||||
* @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];
|
||||
this.anchorX = undefined;
|
||||
|
||||
// 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).
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.anchorY = undefined;
|
||||
|
||||
n = numVertices / 8;
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @protected
|
||||
*/
|
||||
this.groupIndices = [];
|
||||
|
||||
// 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;
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @protected
|
||||
*/
|
||||
this.hitDetectionGroupIndices = [];
|
||||
|
||||
// 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;
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.height = undefined;
|
||||
|
||||
// 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;
|
||||
};
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.imageHeight = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.imageWidth = undefined;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {Array.<WebGLTexture>} textures Textures.
|
||||
* @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
|
||||
* Images.
|
||||
* @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
|
||||
* @param {WebGLRenderingContext} gl Gl.
|
||||
* @type {ol.render.webgl.texturereplay.defaultshader.Locations}
|
||||
*/
|
||||
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 {
|
||||
texture = ol.webgl.Context.createTexture(
|
||||
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||
texturePerImage[uid] = texture;
|
||||
}
|
||||
textures[i] = texture;
|
||||
}
|
||||
};
|
||||
|
||||
this.defaultLocations = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @protected
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// 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);
|
||||
this.opacity = undefined;
|
||||
|
||||
// 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;
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
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 {
|
||||
locations = this.defaultLocations;
|
||||
texture = ol.webgl.Context.createTexture(
|
||||
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||
texturePerImage[uid] = 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;
|
||||
};
|
||||
textures[i] = texture;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||
gl.disableVertexAttribArray(locations.a_position);
|
||||
gl.disableVertexAttribArray(locations.a_offsets);
|
||||
gl.disableVertexAttribArray(locations.a_texCoord);
|
||||
gl.disableVertexAttribArray(locations.a_opacity);
|
||||
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// 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;
|
||||
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
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||
var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
|
||||
var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
|
||||
|
||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||
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]);
|
||||
var end = groupIndices[i];
|
||||
this.drawElements(gl, context, start, end);
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||
gl.disableVertexAttribArray(locations.a_position);
|
||||
gl.disableVertexAttribArray(locations.a_offsets);
|
||||
gl.disableVertexAttribArray(locations.a_texCoord);
|
||||
gl.disableVertexAttribArray(locations.a_opacity);
|
||||
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw the replay while paying attention to skipped features.
|
||||
*
|
||||
* This functions creates groups of features that can be drawn to together,
|
||||
* so that the number of `drawElements` calls is minimized.
|
||||
*
|
||||
* 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;
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||
var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
|
||||
var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
|
||||
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||
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]);
|
||||
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
||||
var groupEnd = groupIndices[i];
|
||||
|
||||
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);
|
||||
}
|
||||
var end = groupIndices[i];
|
||||
this.drawElements(gl, context, start, end);
|
||||
start = end;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||
featureCallback, opt_hitExtent) {
|
||||
var i, groupStart, start, end, feature, featureUid;
|
||||
var featureIndex = this.startIndices.length - 1;
|
||||
var hitDetectionTextures = this.getHitDetectionTextures();
|
||||
for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
|
||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
|
||||
end = this.hitDetectionGroupIndices[i];
|
||||
/**
|
||||
* Draw the replay while paying attention to skipped features.
|
||||
*
|
||||
* This functions creates groups of features that can be drawn to together,
|
||||
* so that the number of `drawElements` calls is minimized.
|
||||
*
|
||||
* 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;
|
||||
|
||||
// draw all features for this texture group
|
||||
while (featureIndex >= 0 &&
|
||||
this.startIndices[featureIndex] >= groupStart) {
|
||||
start = this.startIndices[featureIndex];
|
||||
feature = this.startIndicesFeature[featureIndex];
|
||||
featureUid = ol.getUid(feature).toString();
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
||||
var groupEnd = groupIndices[i];
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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;
|
||||
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
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.finish = function(context) {
|
||||
this.anchorX = undefined;
|
||||
this.anchorY = undefined;
|
||||
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;
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||
featureCallback, opt_hitExtent) {
|
||||
var i, groupStart, start, end, feature, featureUid;
|
||||
var featureIndex = this.startIndices.length - 1;
|
||||
var hitDetectionTextures = this.getHitDetectionTextures();
|
||||
for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
|
||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
|
||||
end = this.hitDetectionGroupIndices[i];
|
||||
|
||||
// draw all features for this texture group
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
end = start;
|
||||
featureIndex--;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @protected
|
||||
* @param {boolean=} opt_all Return hit detection textures with regular ones.
|
||||
* @returns {Array.<WebGLTexture>} Textures.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.getTextures = function(opt_all) {};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.finish = function(context) {
|
||||
this.anchorX = undefined;
|
||||
this.anchorY = undefined;
|
||||
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
|
||||
* @protected
|
||||
* @returns {Array.<WebGLTexture>} Textures.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.getHitDetectionTextures = function() {};
|
||||
}
|
||||
/**
|
||||
* @abstract
|
||||
* @protected
|
||||
* @param {boolean=} opt_all Return hit detection textures with regular ones.
|
||||
* @returns {Array.<WebGLTexture>} Textures.
|
||||
*/
|
||||
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.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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
|
||||
this.a_rotateWithView = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
|
||||
/**
|
||||
* @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');
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @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.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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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();
|
||||
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_texture' : 'g');
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
* @type {number}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'b');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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) {
|
||||
|
||||
/**
|
||||
* @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');
|
||||
};
|
||||
|
||||
}
|
||||
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');
|
||||
|
||||
|
||||
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
|
||||
* @extends {ol.renderer.webgl.Layer}
|
||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.Image} imageLayer Tile layer.
|
||||
* @api
|
||||
* The last rendered image.
|
||||
* @private
|
||||
* @type {?ol.ImageBase}
|
||||
*/
|
||||
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
|
||||
* @type {?ol.ImageBase}
|
||||
*/
|
||||
this.image_ = null;
|
||||
/**
|
||||
* @private
|
||||
* @type {?ol.Transform}
|
||||
*/
|
||||
this.hitTransformationMatrix_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.hitCanvasContext_ = null;
|
||||
};
|
||||
ol.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
/**
|
||||
* @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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
);
|
||||
};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.hasFeatureAtCoordinate = function(coordinate, frameState) {
|
||||
var hasFeature = this.forEachFeatureAtCoordinate(
|
||||
coordinate, frameState, 0, ol.functions.TRUE, this);
|
||||
return hasFeature !== undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.ImageBase} image Image.
|
||||
* @private
|
||||
* @return {WebGLTexture} Texture.
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.createTexture_ = function(image) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
||||
if (!this.image_ || !this.image_.getImage()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// 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) {
|
||||
if (this.getLayer().getSource() instanceof ol.source.ImageVector) {
|
||||
// for ImageVector sources use the original hit-detection logic,
|
||||
// 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);
|
||||
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];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
|
||||
if (!this.image_ || !this.image_.getImage()) {
|
||||
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.getLayer().getSource() instanceof ol.source.ImageVector) {
|
||||
// for ImageVector sources use the original hit-detection logic,
|
||||
// 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The transformation matrix to get the pixel on the image for a
|
||||
* pixel on the map.
|
||||
* @param {ol.Size} mapSize The map size.
|
||||
* @param {ol.Size} imageSize The image size.
|
||||
* @return {ol.Transform} The transformation matrix.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) {
|
||||
// the first matrix takes a map pixel, flips the y-axis and scales to
|
||||
// a range between -1 ... 1
|
||||
var mapCoordTransform = ol.transform.create();
|
||||
ol.transform.translate(mapCoordTransform, -1, -1);
|
||||
ol.transform.scale(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);
|
||||
ol.transform.translate(mapCoordTransform, 0, mapSize[1]);
|
||||
ol.transform.scale(mapCoordTransform, 1, -1);
|
||||
/**
|
||||
* The transformation matrix to get the pixel on the image for a
|
||||
* pixel on the map.
|
||||
* @param {ol.Size} mapSize The map size.
|
||||
* @param {ol.Size} imageSize The image size.
|
||||
* @return {ol.Transform} The transformation matrix.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.webgl.ImageLayer.prototype.getHitTransformationMatrix_ = function(mapSize, imageSize) {
|
||||
// the first matrix takes a map pixel, flips the y-axis and scales to
|
||||
// a range between -1 ... 1
|
||||
var mapCoordTransform = ol.transform.create();
|
||||
ol.transform.translate(mapCoordTransform, -1, -1);
|
||||
ol.transform.scale(mapCoordTransform, 2 / mapSize[0], 2 / mapSize[1]);
|
||||
ol.transform.translate(mapCoordTransform, 0, mapSize[1]);
|
||||
ol.transform.scale(mapCoordTransform, 1, -1);
|
||||
|
||||
// the second matrix is the inverse of the projection matrix used in the
|
||||
// shader for drawing
|
||||
var projectionMatrixInv = ol.transform.invert(this.projectionMatrix.slice());
|
||||
// the second matrix is the inverse of the projection matrix used in the
|
||||
// shader for drawing
|
||||
var projectionMatrixInv = ol.transform.invert(this.projectionMatrix.slice());
|
||||
|
||||
// the third matrix scales to the image dimensions and flips the y-axis again
|
||||
var transform = ol.transform.create();
|
||||
ol.transform.translate(transform, 0, imageSize[1]);
|
||||
ol.transform.scale(transform, 1, -1);
|
||||
ol.transform.scale(transform, imageSize[0] / 2, imageSize[1] / 2);
|
||||
ol.transform.translate(transform, 1, 1);
|
||||
// the third matrix scales to the image dimensions and flips the y-axis again
|
||||
var transform = ol.transform.create();
|
||||
ol.transform.translate(transform, 0, imageSize[1]);
|
||||
ol.transform.scale(transform, 1, -1);
|
||||
ol.transform.scale(transform, imageSize[0] / 2, imageSize[1] / 2);
|
||||
ol.transform.translate(transform, 1, 1);
|
||||
|
||||
ol.transform.multiply(transform, projectionMatrixInv);
|
||||
ol.transform.multiply(transform, mapCoordTransform);
|
||||
ol.transform.multiply(transform, projectionMatrixInv);
|
||||
ol.transform.multiply(transform, mapCoordTransform);
|
||||
|
||||
return transform;
|
||||
};
|
||||
|
||||
}
|
||||
return transform;
|
||||
};
|
||||
|
||||
@@ -13,260 +13,256 @@ goog.require('ol.webgl.Buffer');
|
||||
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
|
||||
* @type {ol.renderer.webgl.Map}
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.mapRenderer = mapRenderer;
|
||||
|
||||
/**
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.LayerState} layerState Layer state.
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @private
|
||||
* @type {ol.webgl.Buffer}
|
||||
*/
|
||||
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);
|
||||
|
||||
};
|
||||
|
||||
this.arrayBuffer_ = new ol.webgl.Buffer([
|
||||
-1, -1, 0, 0,
|
||||
1, -1, 1, 0,
|
||||
-1, 1, 0, 1,
|
||||
1, 1, 1, 1
|
||||
]);
|
||||
|
||||
/**
|
||||
* @param {ol.render.EventType} type Event type.
|
||||
* @param {ol.webgl.Context} context WebGL context.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @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
|
||||
*/
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
this.tmpMat4_ = ol.vec.Mat4.create();
|
||||
|
||||
/**
|
||||
* @return {!ol.Transform} Matrix.
|
||||
* @private
|
||||
* @type {ol.renderer.webgl.defaultmapshader.Locations}
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = function() {
|
||||
return this.texCoordMatrix;
|
||||
};
|
||||
this.defaultLocations_ = null;
|
||||
|
||||
};
|
||||
ol.inherits(ol.renderer.webgl.Layer, ol.renderer.Layer);
|
||||
|
||||
|
||||
/**
|
||||
* @return {WebGLTexture} Texture.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getTexture = function() {
|
||||
return this.texture;
|
||||
};
|
||||
/**
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {number} framebufferDimension Framebuffer dimension.
|
||||
* @protected
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getProjectionMatrix = function() {
|
||||
return this.projectionMatrix;
|
||||
};
|
||||
/**
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.LayerState} layerState Layer state.
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = function() {
|
||||
this.texture = null;
|
||||
this.framebuffer = null;
|
||||
this.framebufferDimension = undefined;
|
||||
};
|
||||
/**
|
||||
* @param {ol.render.EventType} type Event type.
|
||||
* @param {ol.webgl.Context} context WebGL context.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @private
|
||||
*/
|
||||
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
|
||||
* @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) {};
|
||||
/**
|
||||
* @return {!ol.Transform} Matrix.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = function() {
|
||||
return this.texCoordMatrix;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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) {};
|
||||
/**
|
||||
* @return {WebGLTexture} Texture.
|
||||
*/
|
||||
ol.renderer.webgl.Layer.prototype.getTexture = function() {
|
||||
return this.texture;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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');
|
||||
|
||||
|
||||
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
|
||||
* @extends {ol.renderer.webgl.Layer}
|
||||
* @param {ol.renderer.webgl.Map} mapRenderer Map renderer.
|
||||
* @param {ol.layer.Tile} tileLayer Tile layer.
|
||||
* @api
|
||||
* @private
|
||||
* @type {ol.webgl.Fragment}
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
||||
|
||||
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);
|
||||
|
||||
this.fragmentShader_ = ol.renderer.webgl.tilelayershader.fragment;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @private
|
||||
* @type {ol.webgl.Vertex}
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer['handles'] = function(type, layer) {
|
||||
return type === ol.renderer.Type.WEBGL && layer.getType() === ol.LayerType.TILE;
|
||||
};
|
||||
|
||||
this.vertexShader_ = ol.renderer.webgl.tilelayershader.vertex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @private
|
||||
* @type {ol.renderer.webgl.tilelayershader.Locations}
|
||||
*/
|
||||
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)
|
||||
);
|
||||
};
|
||||
|
||||
this.locations_ = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.webgl.Buffer}
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
|
||||
var context = this.mapRenderer.getContext();
|
||||
context.deleteBuffer(this.renderArrayBuffer_);
|
||||
ol.renderer.webgl.Layer.prototype.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
this.renderArrayBuffer_ = new ol.webgl.Buffer([
|
||||
0, 0, 0, 1,
|
||||
1, 0, 1, 1,
|
||||
0, 1, 0, 0,
|
||||
1, 1, 1, 0
|
||||
]);
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
* @type {ol.TileRange}
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder = function(source, projection, tiles) {
|
||||
var mapRenderer = this.mapRenderer;
|
||||
this.renderedTileRange_ = null;
|
||||
|
||||
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] = {};
|
||||
}
|
||||
tiles[zoom][tile.tileCoord.toString()] = tile;
|
||||
/**
|
||||
* @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.
|
||||
* @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);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @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 loaded;
|
||||
}
|
||||
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>>}
|
||||
*/
|
||||
var tilesToDrawByZ = {};
|
||||
tilesToDrawByZ[z] = {};
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
|
||||
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;
|
||||
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) {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerState, context) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
tileState = tile.getState();
|
||||
drawable = tileState == ol.TileState.LOADED ||
|
||||
tileState == ol.TileState.EMPTY ||
|
||||
tileState == ol.TileState.ERROR && !useInterimTilesOnError;
|
||||
if (!drawable) {
|
||||
tile = tile.getInterimTile();
|
||||
}
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
tileState = tile.getState();
|
||||
drawable = tileState == ol.TileState.LOADED ||
|
||||
tileState == ol.TileState.EMPTY ||
|
||||
tileState == ol.TileState.ERROR && !useInterimTilesOnError;
|
||||
if (!drawable) {
|
||||
tile = tile.getInterimTile();
|
||||
}
|
||||
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);
|
||||
var u_tileOffset = new Float32Array(4);
|
||||
var i, ii, tileKey, tilesToDraw;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
tilesToDraw = tilesToDrawByZ[zs[i]];
|
||||
for (tileKey in tilesToDraw) {
|
||||
tile = tilesToDraw[tileKey];
|
||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||
u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /
|
||||
framebufferExtentDimension;
|
||||
u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /
|
||||
framebufferExtentDimension;
|
||||
u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /
|
||||
framebufferExtentDimension - 1;
|
||||
u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /
|
||||
framebufferExtentDimension - 1;
|
||||
gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
|
||||
mapRenderer.bindTileTexture(tile, tilePixelSize,
|
||||
tileGutter * pixelRatio, ol.webgl.LINEAR, ol.webgl.LINEAR);
|
||||
gl.drawArrays(ol.webgl.TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Array.<number>} */
|
||||
var zs = Object.keys(tilesToDrawByZ).map(Number);
|
||||
zs.sort(ol.array.numberSafeCompareFunction);
|
||||
var u_tileOffset = new Float32Array(4);
|
||||
var i, ii, tileKey, tilesToDraw;
|
||||
for (i = 0, ii = zs.length; i < ii; ++i) {
|
||||
tilesToDraw = tilesToDrawByZ[zs[i]];
|
||||
for (tileKey in tilesToDraw) {
|
||||
tile = tilesToDraw[tileKey];
|
||||
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
|
||||
u_tileOffset[0] = 2 * (tileExtent[2] - tileExtent[0]) /
|
||||
framebufferExtentDimension;
|
||||
u_tileOffset[1] = 2 * (tileExtent[3] - tileExtent[1]) /
|
||||
framebufferExtentDimension;
|
||||
u_tileOffset[2] = 2 * (tileExtent[0] - framebufferExtent[0]) /
|
||||
framebufferExtentDimension - 1;
|
||||
u_tileOffset[3] = 2 * (tileExtent[1] - framebufferExtent[1]) /
|
||||
framebufferExtentDimension - 1;
|
||||
gl.uniform4fv(this.locations_.u_tileOffset, u_tileOffset);
|
||||
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);
|
||||
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);
|
||||
if (allTilesLoaded) {
|
||||
this.renderedTileRange_ = tileRange;
|
||||
this.renderedFramebufferExtent_ = framebufferExtent;
|
||||
this.renderedRevision_ = tileSource.getRevision();
|
||||
} 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.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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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);
|
||||
|
||||
this.u_texture = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_texture' : 'e');
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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 {string}
|
||||
* @type {number}
|
||||
*/
|
||||
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) {
|
||||
|
||||
/**
|
||||
* @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');
|
||||
};
|
||||
|
||||
}
|
||||
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');
|
||||
|
||||
|
||||
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
|
||||
* @type {boolean}
|
||||
*/
|
||||
ol.renderer.webgl.VectorLayer.prototype.handleStyleImageChange_ = function(event) {
|
||||
this.renderIfReadyAndVisible();
|
||||
};
|
||||
|
||||
this.dirty_ = false;
|
||||
|
||||
/**
|
||||
* @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());
|
||||
this.updateLogos(frameState, vectorSource);
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.renderedExtent_ = ol.extent.createEmpty();
|
||||
|
||||
var animating = frameState.viewHints[ol.ViewHint.ANIMATING];
|
||||
var interacting = frameState.viewHints[ol.ViewHint.INTERACTING];
|
||||
var updateWhileAnimating = vectorLayer.getUpdateWhileAnimating();
|
||||
var updateWhileInteracting = vectorLayer.getUpdateWhileInteracting();
|
||||
/**
|
||||
* @private
|
||||
* @type {function(ol.Feature, ol.Feature): number|null}
|
||||
*/
|
||||
this.renderedRenderOrder_ = null;
|
||||
|
||||
if (!this.dirty_ && (!updateWhileAnimating && animating) ||
|
||||
(!updateWhileInteracting && interacting)) {
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
* @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 projection = viewState.projection;
|
||||
var resolution = viewState.resolution;
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var vectorLayerRevision = vectorLayer.getRevision();
|
||||
var vectorLayerRenderBuffer = vectorLayer.getRenderBuffer();
|
||||
var vectorLayerRenderOrder = vectorLayer.getRenderOrder();
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
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(
|
||||
this.replayGroup_.getDeleteResourcesFunction(context));
|
||||
}
|
||||
/**
|
||||
* @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);
|
||||
|
||||
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;
|
||||
this.renderedRenderOrder_ = vectorLayerRenderOrder;
|
||||
this.renderedExtent_ = extent;
|
||||
this.replayGroup_ = replayGroup;
|
||||
/**
|
||||
* Handle changes in image style state.
|
||||
* @param {ol.events.Event} event Image style change event.
|
||||
* @private
|
||||
*/
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
||||
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 {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.
|
||||
* @this {ol.renderer.webgl.VectorLayer}
|
||||
*/
|
||||
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(
|
||||
replayGroup, feature, styles[i],
|
||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||
this.handleStyleImageChange_, this) || loading;
|
||||
}
|
||||
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;
|
||||
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(
|
||||
replayGroup, feature, styles,
|
||||
replayGroup, feature, styles[i],
|
||||
ol.renderer.vector.getSquaredTolerance(resolution, pixelRatio),
|
||||
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');
|
||||
|
||||
|
||||
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 {Object=} opt_attributes Attributes.
|
||||
* @return {WebGLRenderingContext} WebGL rendering context.
|
||||
*/
|
||||
ol.webgl.getContext = function(canvas, opt_attributes) {
|
||||
var context, i, ii = ol.webgl.CONTEXT_IDS_.length;
|
||||
for (i = 0; i < ii; ++i) {
|
||||
try {
|
||||
context = canvas.getContext(ol.webgl.CONTEXT_IDS_[i], opt_attributes);
|
||||
if (context) {
|
||||
return /** @type {!WebGLRenderingContext} */ (context);
|
||||
}
|
||||
} catch (e) {
|
||||
// pass
|
||||
/**
|
||||
* @param {HTMLCanvasElement} canvas Canvas.
|
||||
* @param {Object=} opt_attributes Attributes.
|
||||
* @return {WebGLRenderingContext} WebGL rendering context.
|
||||
*/
|
||||
ol.webgl.getContext = function(canvas, opt_attributes) {
|
||||
var context, i, ii = ol.webgl.CONTEXT_IDS_.length;
|
||||
for (i = 0; i < ii; ++i) {
|
||||
try {
|
||||
context = canvas.getContext(ol.webgl.CONTEXT_IDS_[i], opt_attributes);
|
||||
if (context) {
|
||||
return /** @type {!WebGLRenderingContext} */ (context);
|
||||
}
|
||||
} catch (e) {
|
||||
// pass
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
@@ -4,56 +4,52 @@ goog.require('ol');
|
||||
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
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
ol.webgl.Buffer.Usage_ = {
|
||||
STATIC_DRAW: ol.webgl.STATIC_DRAW,
|
||||
STREAM_DRAW: ol.webgl.STREAM_DRAW,
|
||||
DYNAMIC_DRAW: ol.webgl.DYNAMIC_DRAW
|
||||
};
|
||||
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
|
||||
*/
|
||||
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');
|
||||
|
||||
|
||||
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
|
||||
* A WebGL context for accessing low-level WebGL capabilities.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Disposable}
|
||||
* @param {HTMLCanvasElement} canvas Canvas.
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
ol.webgl.Context = function(canvas, gl) {
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
this.canvas_ = canvas;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @private
|
||||
* @type {WebGLRenderingContext}
|
||||
*/
|
||||
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];
|
||||
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
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
this.gl_ = gl;
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Buffer} buf Buffer.
|
||||
* @private
|
||||
* @type {Object.<string, ol.WebglBufferCacheEntry>}
|
||||
*/
|
||||
ol.webgl.Context.prototype.deleteBuffer = function(buf) {
|
||||
var gl = this.getGL();
|
||||
var bufferKey = String(ol.getUid(buf));
|
||||
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
|
||||
* 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];
|
||||
if (!gl.isContextLost()) {
|
||||
gl.deleteBuffer(bufferCacheEntry.buffer);
|
||||
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);
|
||||
}
|
||||
delete this.bufferCache_[bufferKey];
|
||||
};
|
||||
gl.bufferData(target, arrayBuffer, buf.getUsage());
|
||||
this.bufferCache_[bufferKey] = {
|
||||
buf: buf,
|
||||
buffer: buffer
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.webgl.Context.prototype.disposeInternal = function() {
|
||||
ol.events.unlistenAll(this.canvas_);
|
||||
/**
|
||||
* @param {ol.webgl.Buffer} buf Buffer.
|
||||
*/
|
||||
ol.webgl.Context.prototype.deleteBuffer = function(buf) {
|
||||
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();
|
||||
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_);
|
||||
}
|
||||
};
|
||||
var shader = gl.createShader(shaderObject.getType());
|
||||
gl.shaderSource(shader, shaderObject.getSource());
|
||||
gl.compileShader(shader);
|
||||
this.shaderCache_[shaderKey] = shader;
|
||||
return shader;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
ol.webgl.Context.prototype.getCanvas = function() {
|
||||
return this.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
|
||||
* cache.
|
||||
* @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
|
||||
* @return {WebGLRenderingContext} The rendering context.
|
||||
* @api
|
||||
*/
|
||||
ol.webgl.Context.prototype.getGL = function() {
|
||||
return this.gl_;
|
||||
};
|
||||
/**
|
||||
* FIXME empy description for jsdoc
|
||||
*/
|
||||
ol.webgl.Context.prototype.handleWebGLContextLost = function() {
|
||||
ol.obj.clear(this.bufferCache_);
|
||||
ol.obj.clear(this.shaderCache_);
|
||||
ol.obj.clear(this.programCache_);
|
||||
this.currentProgram_ = null;
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
this.hitDetectionTexture_ = null;
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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_;
|
||||
};
|
||||
/**
|
||||
* FIXME empy description for jsdoc
|
||||
*/
|
||||
ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 shader = gl.createShader(shaderObject.getType());
|
||||
gl.shaderSource(shader, shaderObject.getSource());
|
||||
gl.compileShader(shader);
|
||||
this.shaderCache_[shaderKey] = shader;
|
||||
return shader;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
||||
* @private
|
||||
*/
|
||||
ol.webgl.Context.prototype.initHitDetectionFramebuffer_ = function() {
|
||||
var gl = this.gl_;
|
||||
var framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
|
||||
var texture = ol.webgl.Context.createEmptyTexture(gl, 1, 1);
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* cache.
|
||||
* @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;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empy description for jsdoc
|
||||
*/
|
||||
ol.webgl.Context.prototype.handleWebGLContextLost = function() {
|
||||
ol.obj.clear(this.bufferCache_);
|
||||
ol.obj.clear(this.shaderCache_);
|
||||
ol.obj.clear(this.programCache_);
|
||||
this.currentProgram_ = null;
|
||||
this.hitDetectionFramebuffer_ = null;
|
||||
this.hitDetectionTexture_ = null;
|
||||
this.hitDetectionRenderbuffer_ = null;
|
||||
};
|
||||
/**
|
||||
* @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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FIXME empy description for jsdoc
|
||||
*/
|
||||
ol.webgl.Context.prototype.handleWebGLContextRestored = function() {
|
||||
};
|
||||
/**
|
||||
* @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;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a 1x1 pixel framebuffer for the hit-detection.
|
||||
* @private
|
||||
*/
|
||||
ol.webgl.Context.prototype.initHitDetectionFramebuffer_ = function() {
|
||||
var gl = this.gl_;
|
||||
var framebuffer = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
/**
|
||||
* @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);
|
||||
|
||||
var texture = ol.webgl.Context.createEmptyTexture(gl, 1, 1);
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
return texture;
|
||||
};
|
||||
|
||||
@@ -5,25 +5,21 @@ goog.require('ol.webgl');
|
||||
goog.require('ol.webgl.Shader');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Shader}
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
ol.webgl.Fragment = function(source) {
|
||||
ol.webgl.Shader.call(this, source);
|
||||
};
|
||||
ol.inherits(ol.webgl.Fragment, ol.webgl.Shader);
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Shader}
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
ol.webgl.Fragment = function(source) {
|
||||
ol.webgl.Shader.call(this, source);
|
||||
};
|
||||
ol.inherits(ol.webgl.Fragment, ol.webgl.Shader);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.webgl.Fragment.prototype.getType = function() {
|
||||
return ol.webgl.FRAGMENT_SHADER;
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.webgl.Fragment.prototype.getType = function() {
|
||||
return ol.webgl.FRAGMENT_SHADER;
|
||||
};
|
||||
|
||||
@@ -4,43 +4,39 @@ goog.require('ol');
|
||||
goog.require('ol.functions');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
ol.webgl.Shader = function(source) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
ol.webgl.Shader = function(source) {
|
||||
this.source_ = source;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.source_ = source;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {number} Type.
|
||||
*/
|
||||
ol.webgl.Shader.prototype.getType = function() {};
|
||||
/**
|
||||
* @abstract
|
||||
* @return {number} Type.
|
||||
*/
|
||||
ol.webgl.Shader.prototype.getType = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} Source.
|
||||
*/
|
||||
ol.webgl.Shader.prototype.getSource = function() {
|
||||
return this.source_;
|
||||
};
|
||||
/**
|
||||
* @return {string} Source.
|
||||
*/
|
||||
ol.webgl.Shader.prototype.getSource = function() {
|
||||
return this.source_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Is animated?
|
||||
*/
|
||||
ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE;
|
||||
|
||||
}
|
||||
/**
|
||||
* @return {boolean} Is animated?
|
||||
*/
|
||||
ol.webgl.Shader.prototype.isAnimated = ol.functions.FALSE;
|
||||
|
||||
@@ -6,105 +6,101 @@ goog.require('ol');
|
||||
goog.require('ol.webgl.Fragment');
|
||||
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
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
{{className}}.Fragment = function() {
|
||||
ol.webgl.Fragment.call(this, {{className}}.Fragment.SOURCE);
|
||||
};
|
||||
ol.inherits({{className}}.Fragment, ol.webgl.Fragment);
|
||||
|
||||
this.{{originalName}} = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/getUniforms}}
|
||||
{{#getAttributes}}
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {number}
|
||||
*/
|
||||
{{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}}
|
||||
|
||||
/**
|
||||
* @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}}
|
||||
};
|
||||
|
||||
}
|
||||
this.{{originalName}} = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? '{{originalName}}' : '{{shortName}}');
|
||||
{{/getAttributes}}
|
||||
};
|
||||
|
||||
@@ -5,25 +5,21 @@ goog.require('ol.webgl');
|
||||
goog.require('ol.webgl.Shader');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Shader}
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
ol.webgl.Vertex = function(source) {
|
||||
ol.webgl.Shader.call(this, source);
|
||||
};
|
||||
ol.inherits(ol.webgl.Vertex, ol.webgl.Shader);
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Shader}
|
||||
* @param {string} source Source.
|
||||
* @struct
|
||||
*/
|
||||
ol.webgl.Vertex = function(source) {
|
||||
ol.webgl.Shader.call(this, source);
|
||||
};
|
||||
ol.inherits(ol.webgl.Vertex, ol.webgl.Shader);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.webgl.Vertex.prototype.getType = function() {
|
||||
return ol.webgl.VERTEX_SHADER;
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.webgl.Vertex.prototype.getType = function() {
|
||||
return ol.webgl.VERTEX_SHADER;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,8 @@ const parentPackage = require('../package.json');
|
||||
const thisPackage = require('../package/package.json');
|
||||
|
||||
const defines = {
|
||||
'ol.ENABLE_WEBGL': false
|
||||
// Compiler defines go here, e.g.
|
||||
// 'ol.ENABLE_WEBGL': false
|
||||
};
|
||||
|
||||
function rename(name) {
|
||||
|
||||
Reference in New Issue
Block a user