Implement frame state and animation architecture

This commit is contained in:
Tom Payne
2013-01-10 23:19:49 +01:00
parent 4ee411ebe2
commit f3cace499c
14 changed files with 417 additions and 160 deletions
+6 -2
View File
@@ -1,7 +1,11 @@
// FIXME move colorMatrix_ elsewhere?
goog.provide('ol.renderer.webgl.Layer');
goog.require('goog.vec.Mat4');
goog.require('ol.FrameState');
goog.require('ol.layer.Layer');
goog.require('ol.layer.LayerState');
goog.require('ol.renderer.Layer');
goog.require('ol.vec.Mat4');
@@ -179,8 +183,8 @@ ol.renderer.webgl.Layer.prototype.handleWebGLContextLost = goog.nullFunction;
/**
* Render.
* @param {number} time Time.
* @return {boolean} Request render frame.
* @param {ol.FrameState} frameState Frame state.
* @param {ol.layer.LayerState} layerState Layer state.
*/
ol.renderer.webgl.Layer.prototype.renderFrame = goog.abstractMethod;
+24 -52
View File
@@ -143,12 +143,6 @@ ol.renderer.webgl.Map = function(container, map) {
goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,
this.handleWebGLContextResourced, false, this);
/**
* @private
* @type {ol.Color}
*/
this.clearColor_ = new ol.Color(1, 1, 1, 1);
/**
* @private
* @type {{aPosition: number,
@@ -303,26 +297,6 @@ ol.renderer.webgl.Map.prototype.disposeInternal = function() {
};
/**
* @param {function(this: T, ol.layer.Layer, ol.renderer.webgl.Layer, number)} f
* Function.
* @param {T=} opt_obj Object.
* @template T
*/
ol.renderer.webgl.Map.prototype.forEachReadyVisibleLayer =
function(f, opt_obj) {
var layers = this.map.getLayers();
if (goog.isDef(layers)) {
layers.forEach(function(layer, index) {
if (layer.isReady() && layer.getVisible()) {
var layerRenderer = this.getLayerRenderer(layer);
f.call(opt_obj, layer, layerRenderer, index);
}
}, this);
}
};
/**
* @return {WebGLRenderingContext} GL.
*/
@@ -394,12 +368,6 @@ ol.renderer.webgl.Map.prototype.getShader = function(shaderObject) {
* @inheritDoc
*/
ol.renderer.webgl.Map.prototype.handleBackgroundColorChanged = function() {
var backgroundColor = this.getMap().getBackgroundColor();
this.clearColor_ = new ol.Color(
backgroundColor.r / 255,
backgroundColor.g / 255,
backgroundColor.b / 255,
backgroundColor.a / 255);
this.getMap().render();
};
@@ -522,34 +490,37 @@ ol.renderer.webgl.Map.prototype.removeLayerRenderer = function(layer) {
/**
* @inheritDoc
*/
ol.renderer.webgl.Map.prototype.renderFrame = function(time) {
ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) {
var map = this.getMap();
if (!map.isDef()) {
return;
var gl = this.getGL();
if (goog.isNull(frameState)) {
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, null);
gl.clearColor(0, 0, 0, 0);
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
return false;
}
var requestRenderFrame = false;
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
if (layerRenderer.renderFrame(time)) {
requestRenderFrame = true;
goog.array.forEach(frameState.layersArray, function(layer) {
var layerState = frameState.layerStates[goog.getUid(layer)];
if (!layerState.visible || !layerState.ready) {
return;
}
});
var layerRenderer = this.getLayerRenderer(layer);
layerRenderer.renderFrame(frameState, layerState);
}, this);
var size = /** @type {ol.Size} */ (this.getMap().getSize());
var size = frameState.size;
if (!this.canvasSize_.equals(size)) {
this.canvas_.width = size.width;
this.canvas_.height = size.height;
this.canvasSize_ = size;
}
var gl = this.getGL();
gl.bindFramebuffer(goog.webgl.FRAMEBUFFER, null);
gl.clearColor(this.clearColor_.r, this.clearColor_.g, this.clearColor_.b,
this.clearColor_.a);
var clearColor = frameState.backgroundColor;
gl.clearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
gl.clear(goog.webgl.COLOR_BUFFER_BIT);
gl.enable(goog.webgl.BLEND);
gl.viewport(0, 0, size.width, size.height);
@@ -589,7 +560,12 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(time) {
this.locations_.aTexCoord, 2, goog.webgl.FLOAT, false, 16, 8);
gl.uniform1i(this.locations_.uTexture, 0);
this.forEachReadyVisibleLayer(function(layer, layerRenderer) {
goog.array.forEach(frameState.layersArray, function(layer) {
var layerState = frameState.layerStates[goog.getUid(layer)];
if (!layerState.visible || !layerState.ready) {
return;
}
var layerRenderer = this.getLayerRenderer(layer);
gl.uniformMatrix4fv(
this.locations_.uMatrix, false, layerRenderer.getMatrix());
gl.uniformMatrix4fv(
@@ -599,10 +575,6 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(time) {
gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4);
}, this);
if (requestRenderFrame) {
this.getMap().requestRenderFrame();
}
};
+12 -25
View File
@@ -287,30 +287,21 @@ ol.renderer.webgl.TileLayer.prototype.handleWebGLContextLost = function() {
/**
* @inheritDoc
*/
ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
var requestRenderFrame = false;
ol.renderer.webgl.TileLayer.prototype.renderFrame =
function(frameState, layerState) {
var mapRenderer = this.getMapRenderer();
var map = this.getMap();
var gl = mapRenderer.getGL();
var view = map.getView().getView2D();
goog.asserts.assert(map.isDef());
var mapSize = map.getSize();
var mapCenter = view.getCenter();
var mapExtent = view.getExtent(mapSize);
var mapResolution = /** @type {number} */ (view.getResolution());
var mapRotatedExtent = view.getRotatedExtent(mapSize);
var mapRotation = view.getRotation();
var view2DState = frameState.view2DState;
var tileLayer = this.getLayer();
var tileSource = tileLayer.getTileSource();
var tileGrid = tileSource.getTileGrid();
var z = tileGrid.getZForResolution(mapResolution);
var z = tileGrid.getZForResolution(view2DState.resolution);
var tileResolution = tileGrid.getResolution(z);
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
mapRotatedExtent, tileResolution);
frameState.extent, tileResolution);
var framebufferExtent;
@@ -465,7 +456,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
if (!goog.array.isEmpty(tilesToLoad)) {
goog.events.listenOnce(
map,
this.getMap(),
ol.MapEventType.POSTRENDER,
goog.partial(function(mapRenderer, tilesToLoad) {
if (goog.DEBUG) {
@@ -488,25 +479,23 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
} else {
this.renderedTileRange_ = null;
this.renderedFramebufferExtent_ = null;
requestRenderFrame = true;
frameState.animate = true;
}
}
goog.vec.Mat4.makeIdentity(this.matrix_);
goog.vec.Mat4.translate(this.matrix_,
(mapCenter.x - framebufferExtent.minX) /
(view2DState.center.x - framebufferExtent.minX) /
(framebufferExtent.maxX - framebufferExtent.minX),
(mapCenter.y - framebufferExtent.minY) /
(view2DState.center.y - framebufferExtent.minY) /
(framebufferExtent.maxY - framebufferExtent.minY),
0);
if (goog.isDef(mapRotation)) {
goog.vec.Mat4.rotateZ(this.matrix_, mapRotation);
}
goog.vec.Mat4.rotateZ(this.matrix_, view2DState.rotation);
goog.vec.Mat4.scale(this.matrix_,
(mapExtent.maxX - mapExtent.minX) /
frameState.size.width * view2DState.resolution /
(framebufferExtent.maxX - framebufferExtent.minX),
(mapExtent.maxY - mapExtent.minY) /
frameState.size.height * view2DState.resolution /
(framebufferExtent.maxY - framebufferExtent.minY),
1);
goog.vec.Mat4.translate(this.matrix_,
@@ -514,6 +503,4 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = function(time) {
-0.5,
0);
return requestRenderFrame;
};