Merge branch 'master' of github.com:openlayers/ol3 into vector

This commit is contained in:
Tim Schaub
2013-02-18 10:11:00 -07:00
39 changed files with 2739 additions and 79 deletions

View File

@@ -0,0 +1,115 @@
goog.provide('ol.renderer.canvas.ImageLayer');
goog.require('goog.vec.Mat4');
goog.require('ol.Image');
goog.require('ol.ImageState');
goog.require('ol.ViewHint');
goog.require('ol.layer.ImageLayer');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Layer');
/**
* @constructor
* @extends {ol.renderer.canvas.Layer}
* @param {ol.renderer.Map} mapRenderer Map renderer.
* @param {ol.layer.ImageLayer} imageLayer Single image layer.
*/
ol.renderer.canvas.ImageLayer = function(mapRenderer, imageLayer) {
goog.base(this, mapRenderer, imageLayer);
/**
* @private
* @type {?ol.Image}
*/
this.image_ = null;
/**
* @private
* @type {!goog.vec.Mat4.Number}
*/
this.transform_ = goog.vec.Mat4.createNumber();
};
goog.inherits(ol.renderer.canvas.ImageLayer, ol.renderer.canvas.Layer);
/**
* @inheritDoc
*/
ol.renderer.canvas.ImageLayer.prototype.getImage = function() {
return goog.isNull(this.image_) ?
null : this.image_.getImageElement(this);
};
/**
* @return {ol.layer.ImageLayer} Single image layer.
*/
ol.renderer.canvas.ImageLayer.prototype.getImageLayer = function() {
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
};
/**
* @inheritDoc
*/
ol.renderer.canvas.ImageLayer.prototype.getTransform = function() {
return this.transform_;
};
/**
* @inheritDoc
*/
ol.renderer.canvas.ImageLayer.prototype.renderFrame =
function(frameState, layerState) {
var view2DState = frameState.view2DState;
var viewCenter = view2DState.center;
var viewResolution = view2DState.resolution;
var viewRotation = view2DState.rotation;
var image;
var imageLayer = this.getImageLayer();
var imageSource = imageLayer.getImageSource();
var hints = frameState.viewHints;
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
image = imageSource.getImage(frameState.extent, viewResolution);
if (!goog.isNull(image)) {
var imageState = image.getState();
if (imageState == ol.ImageState.IDLE) {
goog.events.listenOnce(image, goog.events.EventType.CHANGE,
this.handleImageChange, false, this);
image.load();
} else if (imageState == ol.ImageState.LOADED) {
this.image_ = image;
}
}
}
if (!goog.isNull(this.image_)) {
image = this.image_;
var imageExtent = image.getExtent();
var imageResolution = image.getResolution();
var transform = this.transform_;
goog.vec.Mat4.makeIdentity(transform);
goog.vec.Mat4.translate(transform,
frameState.size.width / 2, frameState.size.height / 2, 0);
goog.vec.Mat4.rotateZ(transform, viewRotation);
goog.vec.Mat4.scale(
transform,
imageResolution / viewResolution,
imageResolution / viewResolution,
1);
goog.vec.Mat4.translate(
transform,
(imageExtent.minX - viewCenter.x) / imageResolution,
(viewCenter.y - imageExtent.maxY) / imageResolution,
0);
}
};

View File

@@ -7,9 +7,11 @@ goog.require('goog.dom');
goog.require('goog.style');
goog.require('goog.vec.Mat4');
goog.require('ol.Size');
goog.require('ol.layer.ImageLayer');
goog.require('ol.layer.TileLayer');
goog.require('ol.layer.Vector');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.ImageLayer');
goog.require('ol.renderer.canvas.TileLayer');
goog.require('ol.renderer.canvas.VectorLayer');
@@ -61,7 +63,9 @@ goog.inherits(ol.renderer.canvas.Map, ol.renderer.Map);
* @inheritDoc
*/
ol.renderer.canvas.Map.prototype.createLayerRenderer = function(layer) {
if (layer instanceof ol.layer.TileLayer) {
if (layer instanceof ol.layer.ImageLayer) {
return new ol.renderer.canvas.ImageLayer(this, layer);
} else if (layer instanceof ol.layer.TileLayer) {
return new ol.renderer.canvas.TileLayer(this, layer);
} else if (layer instanceof ol.layer.Vector) {
return new ol.renderer.canvas.VectorLayer(this, layer);

View File

@@ -0,0 +1,122 @@
goog.provide('ol.renderer.dom.ImageLayer');
goog.require('goog.dom');
goog.require('goog.vec.Mat4');
goog.require('ol.Image');
goog.require('ol.ImageState');
goog.require('ol.ViewHint');
goog.require('ol.dom');
goog.require('ol.layer.ImageLayer');
goog.require('ol.renderer.dom.Layer');
/**
* @constructor
* @extends {ol.renderer.dom.Layer}
* @param {ol.renderer.Map} mapRenderer Map renderer.
* @param {ol.layer.ImageLayer} imageLayer Image layer.
*/
ol.renderer.dom.ImageLayer = function(mapRenderer, imageLayer) {
var target = goog.dom.createElement(goog.dom.TagName.DIV);
target.className = 'ol-layer-image';
target.style.position = 'absolute';
goog.base(this, mapRenderer, imageLayer, target);
/**
* The last rendered image.
* @private
* @type {?ol.Image}
*/
this.image_ = null;
/**
* @private
* @type {goog.vec.Mat4.AnyType}
*/
this.transform_ = goog.vec.Mat4.createNumberIdentity();
};
goog.inherits(ol.renderer.dom.ImageLayer, ol.renderer.dom.Layer);
/**
* @return {ol.layer.ImageLayer} Image layer.
*/
ol.renderer.dom.ImageLayer.prototype.getImageLayer = function() {
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
};
/**
* @inheritDoc
*/
ol.renderer.dom.ImageLayer.prototype.renderFrame =
function(frameState, layerState) {
var view2DState = frameState.view2DState;
var viewCenter = view2DState.center;
var viewResolution = view2DState.resolution;
var viewRotation = view2DState.rotation;
var image = this.image_;
var imageLayer = this.getImageLayer();
var imageSource = imageLayer.getImageSource();
var hints = frameState.viewHints;
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
var image_ = imageSource.getImage(frameState.extent, viewResolution);
if (!goog.isNull(image_)) {
var imageState = image_.getState();
if (imageState == ol.ImageState.IDLE) {
goog.events.listenOnce(image_, goog.events.EventType.CHANGE,
this.handleImageChange, false, this);
image_.load();
} else if (imageState == ol.ImageState.LOADED) {
image = image_;
}
}
}
if (!goog.isNull(image)) {
var imageExtent = image.getExtent();
var imageResolution = image.getResolution();
var transform = goog.vec.Mat4.createNumber();
goog.vec.Mat4.makeIdentity(transform);
goog.vec.Mat4.translate(transform,
frameState.size.width / 2, frameState.size.height / 2, 0);
goog.vec.Mat4.rotateZ(transform, viewRotation);
goog.vec.Mat4.scale(
transform,
imageResolution / viewResolution,
imageResolution / viewResolution,
1);
goog.vec.Mat4.translate(
transform,
(imageExtent.minX - viewCenter.x) / imageResolution,
(viewCenter.y - imageExtent.maxY) / imageResolution,
0);
if (image != this.image_) {
var imageElement = image.getImageElement(this);
imageElement.style.position = 'absolute';
goog.dom.removeChildren(this.target);
goog.dom.appendChild(this.target, imageElement);
this.image_ = image;
}
this.setTransform(transform);
}
};
/**
* @param {goog.vec.Mat4.AnyType} transform Transform.
*/
ol.renderer.dom.ImageLayer.prototype.setTransform = function(transform) {
if (!goog.vec.Mat4.equals(transform, this.transform_)) {
ol.dom.transformElement2D(this.target, transform, 6);
goog.vec.Mat4.setFromArray(this.transform_, transform);
}
};

View File

@@ -5,8 +5,10 @@ goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.style');
goog.require('ol.layer.ImageLayer');
goog.require('ol.layer.TileLayer');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.dom.ImageLayer');
goog.require('ol.renderer.dom.TileLayer');
@@ -57,14 +59,15 @@ ol.renderer.dom.Map.prototype.addLayer = function(layer) {
* @inheritDoc
*/
ol.renderer.dom.Map.prototype.createLayerRenderer = function(layer) {
var layerRenderer;
if (layer instanceof ol.layer.TileLayer) {
var layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
return layerRenderer;
} else {
goog.asserts.assert(false);
return null;
layerRenderer = new ol.renderer.dom.TileLayer(this, layer);
} else if (layer instanceof ol.layer.ImageLayer) {
layerRenderer = new ol.renderer.dom.ImageLayer(this, layer);
}
goog.asserts.assert(goog.isDef(layerRenderer));
goog.dom.appendChild(this.layersPane_, layerRenderer.getTarget());
return layerRenderer;
};

View File

@@ -3,6 +3,8 @@ goog.provide('ol.renderer.Layer');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.FrameState');
goog.require('ol.Image');
goog.require('ol.ImageState');
goog.require('ol.Object');
goog.require('ol.Tile');
goog.require('ol.TileCoord');
@@ -119,6 +121,19 @@ ol.renderer.Layer.prototype.handleLayerContrastChange = goog.nullFunction;
ol.renderer.Layer.prototype.handleLayerHueChange = goog.nullFunction;
/**
* Handle changes in image state.
* @param {goog.events.Event} event Image change event.
* @protected
*/
ol.renderer.Layer.prototype.handleImageChange = function(event) {
var image = /** @type {ol.Image} */ (event.target);
if (image.getState() === ol.ImageState.LOADED) {
this.getMap().requestRenderFrame();
}
};
/**
* @protected
*/

View File

@@ -0,0 +1,234 @@
goog.provide('ol.renderer.webgl.ImageLayer');
goog.require('goog.vec.Mat4');
goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.Image');
goog.require('ol.ImageState');
goog.require('ol.ViewHint');
goog.require('ol.layer.ImageLayer');
goog.require('ol.renderer.webgl.Layer');
/**
* @constructor
* @extends {ol.renderer.webgl.Layer}
* @param {ol.renderer.Map} mapRenderer Map renderer.
* @param {ol.layer.ImageLayer} imageLayer Tile layer.
*/
ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) {
goog.base(this, mapRenderer, imageLayer);
/**
* The last rendered image.
* @private
* @type {?ol.Image}
*/
this.image_ = null;
/**
* The last rendered texture.
* @private
* @type {WebGLTexture}
*/
this.texture_ = null;
/**
* @private
* @type {!goog.vec.Mat4.Number}
*/
this.texCoordMatrix_ = goog.vec.Mat4.createNumberIdentity();
/**
* @private
* @type {!goog.vec.Mat4.Number}
*/
this.vertexCoordMatrix_ = goog.vec.Mat4.createNumber();
};
goog.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer);
/**
* @private
* @param {ol.Image} image Image.
* @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.getImageElement(this);
var gl = this.getMapRenderer().getGL();
var texture = gl.createTexture();
gl.bindTexture(goog.webgl.TEXTURE_2D, texture);
gl.texImage2D(goog.webgl.TEXTURE_2D, 0, goog.webgl.RGBA,
goog.webgl.RGBA, goog.webgl.UNSIGNED_BYTE, imageElement);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_WRAP_S,
goog.webgl.CLAMP_TO_EDGE);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_WRAP_T,
goog.webgl.CLAMP_TO_EDGE);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MIN_FILTER, goog.webgl.LINEAR);
gl.texParameteri(
goog.webgl.TEXTURE_2D, goog.webgl.TEXTURE_MAG_FILTER, goog.webgl.LINEAR);
return texture;
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.disposeInternal = function() {
var mapRenderer = this.getMapRenderer();
var gl = mapRenderer.getGL();
if (!gl.isContextLost()) {
gl.deleteTexture(this.texture_);
}
goog.base(this, 'disposeInternal');
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.getTexCoordMatrix = function() {
return this.texCoordMatrix_;
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.getTexture = function() {
return this.texture_;
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.getVertexCoordMatrix = function() {
return this.vertexCoordMatrix_;
};
/**
* @return {ol.layer.ImageLayer} Tile layer.
*/
ol.renderer.webgl.ImageLayer.prototype.getImageLayer = function() {
return /** @type {ol.layer.ImageLayer} */ (this.getLayer());
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.handleWebGLContextLost = function() {
this.texture_ = null;
};
/**
* @inheritDoc
*/
ol.renderer.webgl.ImageLayer.prototype.renderFrame =
function(frameState, layerState) {
var gl = this.getMapRenderer().getGL();
var view2DState = frameState.view2DState;
var viewCenter = view2DState.center;
var viewResolution = view2DState.resolution;
var viewRotation = view2DState.rotation;
var image = this.image_;
var texture = this.texture_;
var imageLayer = this.getImageLayer();
var imageSource = imageLayer.getImageSource();
var hints = frameState.viewHints;
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.PANNING]) {
var image_ = imageSource.getImage(frameState.extent, viewResolution);
if (!goog.isNull(image_)) {
var imageState = image_.getState();
if (imageState == ol.ImageState.IDLE) {
goog.events.listenOnce(image_, goog.events.EventType.CHANGE,
this.handleImageChange, false, this);
image_.load();
} else if (imageState == ol.ImageState.LOADED) {
image = image_;
texture = this.createTexture_(image_);
if (!goog.isNull(this.texture_)) {
frameState.postRenderFunctions.push(
goog.partial(function(gl, texture) {
if (!gl.isContextLost()) {
gl.deleteTexture(texture);
}
}, gl, this.texture_));
}
}
}
}
if (!goog.isNull(image)) {
goog.asserts.assert(!goog.isNull(texture));
var canvas = this.getMapRenderer().getCanvas();
this.updateVertexCoordMatrix_(canvas.width, canvas.height,
viewCenter, viewResolution, viewRotation, image.getExtent());
// Translate and scale to flip the Y coord.
var texCoordMatrix = this.texCoordMatrix_;
goog.vec.Mat4.makeIdentity(texCoordMatrix);
goog.vec.Mat4.scale(texCoordMatrix, 1, -1, 1);
goog.vec.Mat4.translate(texCoordMatrix, 0, -1, 0);
this.image_ = image;
this.texture_ = texture;
}
};
/**
* @private
* @param {number} canvasWidth Canvas width.
* @param {number} canvasHeight Canvas height.
* @param {ol.Coordinate} viewCenter View center.
* @param {number} viewResolution View resolution.
* @param {number} viewRotation View rotation.
* @param {ol.Extent} imageExtent Image extent.
*/
ol.renderer.webgl.ImageLayer.prototype.updateVertexCoordMatrix_ =
function(canvasWidth, canvasHeight, viewCenter,
viewResolution, viewRotation, imageExtent) {
var canvasExtentWidth = canvasWidth * viewResolution;
var canvasExtentHeight = canvasHeight * viewResolution;
var vertexCoordMatrix = this.vertexCoordMatrix_;
goog.vec.Mat4.makeIdentity(vertexCoordMatrix);
goog.vec.Mat4.scale(vertexCoordMatrix,
2 / canvasExtentWidth, 2 / canvasExtentHeight, 1);
goog.vec.Mat4.rotateZ(vertexCoordMatrix, -viewRotation);
goog.vec.Mat4.translate(vertexCoordMatrix,
imageExtent.minX - viewCenter.x,
imageExtent.minY - viewCenter.y,
0);
goog.vec.Mat4.scale(vertexCoordMatrix,
imageExtent.getWidth() / 2, imageExtent.getHeight() / 2, 1);
goog.vec.Mat4.translate(vertexCoordMatrix, 1, 1, 0);
};

View File

@@ -97,6 +97,12 @@ ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = goog.abstractMethod;
ol.renderer.webgl.Layer.prototype.getTexture = goog.abstractMethod;
/**
* @return {!goog.vec.Mat4.Number} Matrix.
*/
ol.renderer.webgl.Layer.prototype.getVertexCoordMatrix = goog.abstractMethod;
/**
* @inheritDoc
*/

View File

@@ -14,9 +14,11 @@ goog.require('goog.webgl');
goog.require('ol.FrameState');
goog.require('ol.Size');
goog.require('ol.Tile');
goog.require('ol.layer.ImageLayer');
goog.require('ol.layer.TileLayer');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.webgl.FragmentShader');
goog.require('ol.renderer.webgl.ImageLayer');
goog.require('ol.renderer.webgl.TileLayer');
goog.require('ol.renderer.webgl.VertexShader');
goog.require('ol.structs.LRUCache');
@@ -79,11 +81,12 @@ ol.renderer.webgl.map.shader.Vertex = function() {
'attribute vec2 aTexCoord;',
'',
'uniform mat4 uTexCoordMatrix;',
'uniform mat4 uVertexCoordMatrix;',
'',
'varying vec2 vTexCoord;',
'',
'void main(void) {',
' gl_Position = vec4(aPosition, 0., 1.);',
' gl_Position = uVertexCoordMatrix * vec4(aPosition, 0., 1.);',
' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;',
'}'
].join('\n'));
@@ -159,7 +162,8 @@ ol.renderer.webgl.Map = function(container, map) {
* uColorMatrix: WebGLUniformLocation,
* uOpacity: WebGLUniformLocation,
* uTexture: WebGLUniformLocation,
* uTexCoordMatrix: WebGLUniformLocation}|null}
* uTexCoordMatrix: WebGLUniformLocation,
* uVertexCoordMatrix: WebGLUniformLocation}|null}
*/
this.locations_ = null;
@@ -270,12 +274,15 @@ ol.renderer.webgl.Map.prototype.bindTileTexture =
* @inheritDoc
*/
ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
var layerRenderer = null;
if (layer instanceof ol.layer.TileLayer) {
return new ol.renderer.webgl.TileLayer(this, layer);
layerRenderer = new ol.renderer.webgl.TileLayer(this, layer);
} else if (layer instanceof ol.layer.ImageLayer) {
layerRenderer = new ol.renderer.webgl.ImageLayer(this, layer);
} else {
goog.asserts.assert(false);
return null;
}
return layerRenderer;
};
@@ -519,6 +526,7 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),
uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'),
uVertexCoordMatrix: gl.getUniformLocation(program, 'uVertexCoordMatrix'),
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
uTexture: gl.getUniformLocation(program, 'uTexture')
};
@@ -555,6 +563,9 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
gl.uniformMatrix4fv(
this.locations_.uTexCoordMatrix, false,
layerRenderer.getTexCoordMatrix());
gl.uniformMatrix4fv(
this.locations_.uVertexCoordMatrix, false,
layerRenderer.getVertexCoordMatrix());
gl.uniformMatrix4fv(
this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix());
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());

View File

@@ -141,6 +141,12 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
*/
this.texCoordMatrix_ = goog.vec.Mat4.createNumber();
/**
* @private
* @type {!goog.vec.Mat4.Number}
*/
this.vertexCoordMatrix_ = goog.vec.Mat4.createNumberIdentity();
/**
* @private
* @type {ol.TileRange}
@@ -237,6 +243,14 @@ ol.renderer.webgl.TileLayer.prototype.getTexture = function() {
};
/**
* @inheritDoc
*/
ol.renderer.webgl.TileLayer.prototype.getVertexCoordMatrix = function() {
return this.vertexCoordMatrix_;
};
/**
* @return {ol.layer.TileLayer} Tile layer.
*/