Add ol.renderer.webgl.ImageLayer
This commit is contained in:
@@ -0,0 +1,220 @@
|
|||||||
|
goog.provide('ol.renderer.webgl.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.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);
|
||||||
|
var imageState = image_.getState();
|
||||||
|
var animate = false;
|
||||||
|
if (imageState == ol.ImageState.ERROR) {
|
||||||
|
// pass
|
||||||
|
} else if (imageState == ol.ImageState.IDLE) {
|
||||||
|
animate = true;
|
||||||
|
image_.load();
|
||||||
|
} else if (imageState == ol.ImageState.LOADING) {
|
||||||
|
animate = true;
|
||||||
|
} 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 (animate) {
|
||||||
|
frameState.animate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!goog.isNull(image)) {
|
||||||
|
goog.asserts.assert(!goog.isNull(texture));
|
||||||
|
|
||||||
|
var canvas = this.getMapRenderer().getCanvas();
|
||||||
|
|
||||||
|
var canvasExtentWidth = canvas.width * viewResolution;
|
||||||
|
var canvasExtentHeight = canvas.height * viewResolution;
|
||||||
|
|
||||||
|
var imageExtent = image.getExtent();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -97,6 +97,12 @@ ol.renderer.webgl.Layer.prototype.getTexCoordMatrix = goog.abstractMethod;
|
|||||||
ol.renderer.webgl.Layer.prototype.getTexture = 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
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,9 +14,11 @@ goog.require('goog.webgl');
|
|||||||
goog.require('ol.FrameState');
|
goog.require('ol.FrameState');
|
||||||
goog.require('ol.Size');
|
goog.require('ol.Size');
|
||||||
goog.require('ol.Tile');
|
goog.require('ol.Tile');
|
||||||
|
goog.require('ol.layer.ImageLayer');
|
||||||
goog.require('ol.layer.TileLayer');
|
goog.require('ol.layer.TileLayer');
|
||||||
goog.require('ol.renderer.Map');
|
goog.require('ol.renderer.Map');
|
||||||
goog.require('ol.renderer.webgl.FragmentShader');
|
goog.require('ol.renderer.webgl.FragmentShader');
|
||||||
|
goog.require('ol.renderer.webgl.ImageLayer');
|
||||||
goog.require('ol.renderer.webgl.TileLayer');
|
goog.require('ol.renderer.webgl.TileLayer');
|
||||||
goog.require('ol.renderer.webgl.VertexShader');
|
goog.require('ol.renderer.webgl.VertexShader');
|
||||||
goog.require('ol.structs.LRUCache');
|
goog.require('ol.structs.LRUCache');
|
||||||
@@ -79,11 +81,12 @@ ol.renderer.webgl.map.shader.Vertex = function() {
|
|||||||
'attribute vec2 aTexCoord;',
|
'attribute vec2 aTexCoord;',
|
||||||
'',
|
'',
|
||||||
'uniform mat4 uTexCoordMatrix;',
|
'uniform mat4 uTexCoordMatrix;',
|
||||||
|
'uniform mat4 uVertexCoordMatrix;',
|
||||||
'',
|
'',
|
||||||
'varying vec2 vTexCoord;',
|
'varying vec2 vTexCoord;',
|
||||||
'',
|
'',
|
||||||
'void main(void) {',
|
'void main(void) {',
|
||||||
' gl_Position = vec4(aPosition, 0., 1.);',
|
' gl_Position = uVertexCoordMatrix * vec4(aPosition, 0., 1.);',
|
||||||
' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;',
|
' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;',
|
||||||
'}'
|
'}'
|
||||||
].join('\n'));
|
].join('\n'));
|
||||||
@@ -159,7 +162,8 @@ ol.renderer.webgl.Map = function(container, map) {
|
|||||||
* uColorMatrix: WebGLUniformLocation,
|
* uColorMatrix: WebGLUniformLocation,
|
||||||
* uOpacity: WebGLUniformLocation,
|
* uOpacity: WebGLUniformLocation,
|
||||||
* uTexture: WebGLUniformLocation,
|
* uTexture: WebGLUniformLocation,
|
||||||
* uTexCoordMatrix: WebGLUniformLocation}|null}
|
* uTexCoordMatrix: WebGLUniformLocation,
|
||||||
|
* uVertexCoordMatrix: WebGLUniformLocation}|null}
|
||||||
*/
|
*/
|
||||||
this.locations_ = null;
|
this.locations_ = null;
|
||||||
|
|
||||||
@@ -270,12 +274,15 @@ ol.renderer.webgl.Map.prototype.bindTileTexture =
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
ol.renderer.webgl.Map.prototype.createLayerRenderer = function(layer) {
|
||||||
|
var layerRenderer = null;
|
||||||
if (layer instanceof ol.layer.TileLayer) {
|
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 {
|
} else {
|
||||||
goog.asserts.assert(false);
|
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'),
|
aTexCoord: gl.getAttribLocation(program, 'aTexCoord'),
|
||||||
uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),
|
uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'),
|
||||||
uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'),
|
uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'),
|
||||||
|
uVertexCoordMatrix: gl.getUniformLocation(program, 'uVertexCoordMatrix'),
|
||||||
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
|
uOpacity: gl.getUniformLocation(program, 'uOpacity'),
|
||||||
uTexture: gl.getUniformLocation(program, 'uTexture')
|
uTexture: gl.getUniformLocation(program, 'uTexture')
|
||||||
};
|
};
|
||||||
@@ -555,6 +563,9 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
|
|||||||
gl.uniformMatrix4fv(
|
gl.uniformMatrix4fv(
|
||||||
this.locations_.uTexCoordMatrix, false,
|
this.locations_.uTexCoordMatrix, false,
|
||||||
layerRenderer.getTexCoordMatrix());
|
layerRenderer.getTexCoordMatrix());
|
||||||
|
gl.uniformMatrix4fv(
|
||||||
|
this.locations_.uVertexCoordMatrix, false,
|
||||||
|
layerRenderer.getVertexCoordMatrix());
|
||||||
gl.uniformMatrix4fv(
|
gl.uniformMatrix4fv(
|
||||||
this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix());
|
this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix());
|
||||||
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
gl.uniform1f(this.locations_.uOpacity, layer.getOpacity());
|
||||||
|
|||||||
@@ -141,6 +141,12 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) {
|
|||||||
*/
|
*/
|
||||||
this.texCoordMatrix_ = goog.vec.Mat4.createNumber();
|
this.texCoordMatrix_ = goog.vec.Mat4.createNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @private
|
||||||
|
* @type {!goog.vec.Mat4.Number}
|
||||||
|
*/
|
||||||
|
this.vertexCoordMatrix_ = goog.vec.Mat4.createNumberIdentity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {ol.TileRange}
|
* @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.
|
* @return {ol.layer.TileLayer} Tile layer.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user