From 90b005a2fdf77f7e057d359f3472f09814057d12 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Sun, 19 Jan 2014 17:22:57 +0100 Subject: [PATCH 1/2] add MapRenderer.animate() to trigger animations on GL-Thread --- vtm/src/org/oscim/renderer/MapRenderer.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vtm/src/org/oscim/renderer/MapRenderer.java b/vtm/src/org/oscim/renderer/MapRenderer.java index 6e7ba379..09a7647c 100644 --- a/vtm/src/org/oscim/renderer/MapRenderer.java +++ b/vtm/src/org/oscim/renderer/MapRenderer.java @@ -280,6 +280,10 @@ public class MapRenderer { BufferObject.checkBufferUsage(true); // FIXME also throw out some textures etc } + if (rerender) { + mMap.render(); + rerender = false; + } } public static int depthOffset(MapTile t) { @@ -403,4 +407,13 @@ public class MapRenderer { GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, bind ? mQuadIndicesID : 0); } + private static boolean rerender; + + /** + * Trigger next redraw from GL-Thread. This should be used to animate + * LayerRenderers instead of calling Map.render(). + */ + public static void animate() { + rerender = true; + } } From aba6cc5778a3406ed492beb5cd769fcfdc478728 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Sun, 19 Jan 2014 17:52:24 +0100 Subject: [PATCH 2/2] add tile fade effect: use theme background color to overdraw tiles --- .../layers/tile/vector/VectorTileLayer.java | 8 +- .../oscim/renderer/elements/PolygonLayer.java | 4 +- vtm/src/org/oscim/tiling/MapTile.java | 1 + vtm/src/org/oscim/tiling/TileRenderer.java | 101 ++++++++++++------ 4 files changed, 79 insertions(+), 35 deletions(-) diff --git a/vtm/src/org/oscim/layers/tile/vector/VectorTileLayer.java b/vtm/src/org/oscim/layers/tile/vector/VectorTileLayer.java index bbc17cea..a580982a 100644 --- a/vtm/src/org/oscim/layers/tile/vector/VectorTileLayer.java +++ b/vtm/src/org/oscim/layers/tile/vector/VectorTileLayer.java @@ -78,10 +78,7 @@ public class VectorTileLayer extends TileLayer { mTileLoader.get(i).setTileDataSource(tileDataSource); } - //mTileManager.setZoomTable(mTileSource.getMapInfo().zoomLevel); - mMap.clearMap(); - resumeLoaders(); return true; @@ -91,12 +88,17 @@ public class VectorTileLayer extends TileLayer { * Set {@link IRenderTheme} used by {@link TileLoader} */ public void setRenderTheme(IRenderTheme theme) { + // wait for loaders to finish all current jobs to + // not change theme instance hold by loader instance + // while running pauseLoaders(true); mTileManager.clearJobs(); for (VectorTileLoader g : mTileLoader) g.setRenderTheme(theme); + mRenderLayer.setOverdrawColor(theme.getMapBackground()); + resumeLoaders(); } } diff --git a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java index ca8e8d1f..80ca79c8 100644 --- a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java +++ b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java @@ -432,7 +432,7 @@ public final class PolygonLayer extends RenderElement { } } - public static void drawOver(Matrices m, int color) { + public static void drawOver(Matrices m, int color, float alpha) { setShader(polyShader, m); /* @@ -441,7 +441,7 @@ public final class PolygonLayer extends RenderElement { */ if (color != 0) { - GLUtils.setColor(hPolygonColor[0], color, 1); + GLUtils.setColor(hPolygonColor[0], color, alpha); GLState.blend(true); } else { // disable drawing to framebuffer (will be re-enabled in fill) diff --git a/vtm/src/org/oscim/tiling/MapTile.java b/vtm/src/org/oscim/tiling/MapTile.java index 316309f9..a06054bf 100644 --- a/vtm/src/org/oscim/tiling/MapTile.java +++ b/vtm/src/org/oscim/tiling/MapTile.java @@ -94,6 +94,7 @@ public class MapTile extends Tile { * Tile is in view region. Set by TileRenderer. */ public boolean isVisible; + public long fadeTime; /** * Pointer to access relatives in QuadTree diff --git a/vtm/src/org/oscim/tiling/TileRenderer.java b/vtm/src/org/oscim/tiling/TileRenderer.java index 1d3f269c..f945e091 100644 --- a/vtm/src/org/oscim/tiling/TileRenderer.java +++ b/vtm/src/org/oscim/tiling/TileRenderer.java @@ -20,6 +20,7 @@ import static org.oscim.tiling.MapTile.STATE_NEW_DATA; import static org.oscim.tiling.MapTile.STATE_READY; import org.oscim.backend.GL20; +import org.oscim.backend.canvas.Color; import org.oscim.core.MapPosition; import org.oscim.core.Tile; import org.oscim.renderer.BufferObject; @@ -42,6 +43,8 @@ import org.slf4j.LoggerFactory; public class TileRenderer extends LayerRenderer { static final Logger log = LoggerFactory.getLogger(TileRenderer.class); + private static final boolean debugOverdraw = false; + private final TileManager mTileManager; private int mUploadSerial; @@ -56,16 +59,22 @@ public class TileRenderer extends LayerRenderer { private int mRenderOverdraw; private float mRenderAlpha; - public void setOverdrawColor(int color) { + /** + * Threadsafe + */ + public synchronized void setOverdrawColor(int color) { mOverdraw = color; } - public void setBitmapAlpha(float alpha) { + /** + * Threadsafe + */ + public synchronized void setBitmapAlpha(float alpha) { mAlpha = alpha; } /** - * synced with clearTiles + * synced with clearTiles, setOverdrawColor and setBitmapAlpha */ @Override protected synchronized void update(MapPosition pos, boolean positionChanged, Matrices m) { @@ -75,15 +84,19 @@ public class TileRenderer extends LayerRenderer { return; } + // get current tiles to draw boolean tilesChanged; synchronized (tilelock) { - // get current tiles to draw tilesChanged = mTileManager.getActiveTiles(mDrawTiles); } if (mDrawTiles.cnt == 0) return; + // keep constant while rendering frame + mRenderAlpha = mAlpha; + mRenderOverdraw = mOverdraw; + int tileCnt = mDrawTiles.cnt; MapTile[] tiles = mDrawTiles.tiles; @@ -93,16 +106,12 @@ public class TileRenderer extends LayerRenderer { tileCnt += mNumTileHolder; - /* prepare tile for rendering */ + // prepare tiles for rendering if (compileTileLayers(tiles, tileCnt) > 0) { mUploadSerial++; BufferObject.checkBufferUsage(false); } - // keep constant while rendering frame - mRenderAlpha = mAlpha; - mRenderOverdraw = mOverdraw; - draw(tiles, tileCnt, pos, m); } @@ -234,8 +243,8 @@ public class TileRenderer extends LayerRenderer { tileSet.releaseTiles(); // ensure same size - if (tileSet.tiles.length != mDrawTiles.tiles.length) { - tileSet.tiles = new MapTile[mDrawTiles.tiles.length]; + if (tileSet.tiles.length != newTiles.length) { + tileSet.tiles = new MapTile[newTiles.length]; } // lock tiles to not be removed from cache @@ -282,17 +291,13 @@ public class TileRenderer extends LayerRenderer { t.isVisible = true; } + // add placeholder tiles to show both sides + // of date line. a little too complicated... int xmax = 1 << mZoom; if (x1 >= 0 && x2 < xmax) return; - // add placeholder tiles to show both sides - // of date line. a little too complicated... - for (int x = x1; x < x2; x++) { - MapTile holder = null; - MapTile tile = null; - boolean found = false; - + O: for (int x = x1; x < x2; x++) { if (x >= 0 && x < xmax) continue; @@ -306,14 +311,10 @@ public class TileRenderer extends LayerRenderer { continue; for (int i = cnt; i < cnt + mNumTileHolder; i++) - if (tiles[i].tileX == x && tiles[i].tileY == y) { - found = true; - break; - } - - if (found) - continue; + if (tiles[i].tileX == x && tiles[i].tileY == y) + continue O; + MapTile tile = null; for (int i = 0; i < cnt; i++) if (tiles[i].tileX == xx && tiles[i].tileY == y) { tile = tiles[i]; @@ -327,7 +328,7 @@ public class TileRenderer extends LayerRenderer { //log.error(" + mNumTileHolder"); break; } - holder = new MapTile(x, y, (byte) mZoom); + MapTile holder = new MapTile(x, y, (byte) mZoom); holder.isVisible = true; holder.holder = tile; tile.isVisible = true; @@ -336,6 +337,29 @@ public class TileRenderer extends LayerRenderer { } }; + private long getMinFade(MapTile t) { + long maxFade = MapRenderer.frametime - 50; + + for (int c = 0; c < 4; c++) { + MapTile ci = t.rel.get(c); + if (ci == null) + continue; + + if (ci.state == MapTile.STATE_READY || ci.fadeTime > 0) + maxFade = Math.min(maxFade, ci.fadeTime); + } + MapTile p = t.rel.getParent(); + if (p != null && (p.state == MapTile.STATE_READY || p.fadeTime > 0)) { + maxFade = Math.min(maxFade, p.fadeTime); + + p = p.rel.getParent(); + if (p != null && (p.state == MapTile.STATE_READY || p.fadeTime > 0)) + maxFade = Math.min(maxFade, p.fadeTime); + } + + return maxFade; + } + // Counter increases polygon-offset for each tile drawn. private int mOffsetCnt; @@ -368,7 +392,6 @@ public class TileRenderer extends LayerRenderer { GL.glDepthMask(true); GL.glClear(GL20.GL_DEPTH_BUFFER_BIT); - GL.glDepthFunc(GL20.GL_LESS); // Draw visible tiles @@ -505,7 +528,27 @@ public class TileRenderer extends LayerRenderer { } } - PolygonLayer.Renderer.drawOver(m, mRenderOverdraw); + if (t.fadeTime == 0) + t.fadeTime = getMinFade(t); + + if (debugOverdraw) { + if (t.zoomLevel > pos.zoomLevel) + PolygonLayer.Renderer.drawOver(m, Color.BLUE, 0.5f); + else if (t.zoomLevel < pos.zoomLevel) + PolygonLayer.Renderer.drawOver(m, Color.RED, 0.5f); + else + PolygonLayer.Renderer.drawOver(m, Color.GREEN, 0.5f); + + return; + } + + if (mRenderOverdraw != 0 && MapRenderer.frametime - t.fadeTime < 500) { + float fade = 1 - (MapRenderer.frametime - t.fadeTime) / 500f; + PolygonLayer.Renderer.drawOver(m, mRenderOverdraw, fade * fade); + MapRenderer.animate(); + } else { + PolygonLayer.Renderer.drawOver(m, 0, 1); + } } private int drawProxyChild(MapTile tile, MapPosition pos) { @@ -590,7 +633,5 @@ public class TileRenderer extends LayerRenderer { @Override protected void render(MapPosition position, Matrices matrices) { - // TODO Auto-generated method stub - } }