docs: TileRenderer

This commit is contained in:
Hannes Janetzek 2014-02-05 00:35:11 +01:00
parent ae24860d1e
commit 77c933b7d8

View File

@ -51,6 +51,9 @@ public class TileRenderer extends LayerRenderer {
private static final boolean debugOverdraw = false; private static final boolean debugOverdraw = false;
/** fade-in time */
private static final float FADE_TIME = 500;
private final TileManager mTileManager; private final TileManager mTileManager;
private int mUploadSerial; private int mUploadSerial;
@ -65,8 +68,10 @@ public class TileRenderer extends LayerRenderer {
private int mRenderOverdraw; private int mRenderOverdraw;
private float mRenderAlpha; private float mRenderAlpha;
// Current number of frames drawn, used to not draw a /**
// tile twice per frame. * Current number of frames drawn, used to not draw a
* tile twice per frame.
*/
private int mDrawSerial; private int mDrawSerial;
private int mClipMode; private int mClipMode;
@ -98,7 +103,7 @@ public class TileRenderer extends LayerRenderer {
return; return;
} }
// get current tiles to draw /* get current tiles to draw */
boolean tilesChanged; boolean tilesChanged;
synchronized (tilelock) { synchronized (tilelock) {
tilesChanged = mTileManager.getActiveTiles(mDrawTiles); tilesChanged = mTileManager.getActiveTiles(mDrawTiles);
@ -107,14 +112,12 @@ public class TileRenderer extends LayerRenderer {
if (mDrawTiles.cnt == 0) if (mDrawTiles.cnt == 0)
return; return;
// keep constant while rendering frame /* keep constant while rendering frame */
mRenderAlpha = mAlpha; mRenderAlpha = mAlpha;
mRenderOverdraw = mOverdraw; mRenderOverdraw = mOverdraw;
/** /* discard depth projection from tilt, depth buffer
* discard depth projection from tilt, depth buffer * is used for clipping */
* is used for clipping
*/
mViewProj.copy(m.proj); mViewProj.copy(m.proj);
mViewProj.setValue(10, 0); mViewProj.setValue(10, 0);
mViewProj.setValue(14, 0); mViewProj.setValue(14, 0);
@ -129,7 +132,7 @@ public class TileRenderer extends LayerRenderer {
tileCnt += mNumTileHolder; tileCnt += mNumTileHolder;
// prepare tiles for rendering /* prepare tiles for rendering */
if (compileTileLayers(tiles, tileCnt) > 0) { if (compileTileLayers(tiles, tileCnt) > 0) {
mUploadSerial++; mUploadSerial++;
BufferObject.checkBufferUsage(false); BufferObject.checkBufferUsage(false);
@ -146,25 +149,24 @@ public class TileRenderer extends LayerRenderer {
} }
} }
/** draw visible tiles */ /* draw visible tiles */
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible && t.state == STATE_READY) if (t.isVisible && t.state == STATE_READY)
drawTile(t, pos); drawTile(t, pos);
} }
/** /* draw parent or children as proxy for visibile tiles that dont
* draw parent or children as proxy for visibile tiles that dont
* have data yet. Proxies are clipped to the region where nothing * have data yet. Proxies are clipped to the region where nothing
* was drawn to depth buffer. * was drawn to depth buffer.
* TODO draw proxies for placeholder * TODO draw proxies for placeholder */
*/
if (mClipMode > 1) { if (mClipMode > 1) {
mClipMode = 3; mClipMode = 3;
//GL.glClear(GL20.GL_DEPTH_BUFFER_BIT); //GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
GL.glDepthFunc(GL20.GL_LESS); GL.glDepthFunc(GL20.GL_LESS);
/** draw child or parent proxies */ /* draw child or parent proxies */
boolean preferParent = (pos.getZoomScale() < 1.5) boolean preferParent = (pos.getZoomScale() < 1.5)
|| (pos.zoomLevel < tiles[0].zoomLevel); || (pos.zoomLevel < tiles[0].zoomLevel);
@ -177,7 +179,7 @@ public class TileRenderer extends LayerRenderer {
} }
} }
/** draw grandparents */ /* draw grandparents */
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible if (t.isVisible
@ -188,7 +190,7 @@ public class TileRenderer extends LayerRenderer {
GL.glDepthMask(false); GL.glDepthMask(false);
} }
/** make sure stencil buffer write is disabled */ /* make sure stencil buffer write is disabled */
GL.glStencilMask(0x00); GL.glStencilMask(0x00);
mDrawSerial++; mDrawSerial++;
@ -197,12 +199,12 @@ public class TileRenderer extends LayerRenderer {
@Override @Override
protected void render(MapPosition position, Matrices matrices) { protected void render(MapPosition position, Matrices matrices) {
// render in update() so that tiles cannot vanish in between. /* render in update() so that tiles cannot vanish in between. */
} }
public void clearTiles() { public void clearTiles() {
// Clear all references to MapTiles as all current /* Clear all references to MapTiles as all current
// tiles will also be removed from TileManager. * tiles will also be removed from TileManager. */
mDrawTiles = new TileSet(); mDrawTiles = new TileSet();
} }
@ -225,7 +227,7 @@ public class TileRenderer extends LayerRenderer {
} }
if (tile.holder != null) { if (tile.holder != null) {
// load tile that is referenced by this holder /* load tile that is referenced by this holder */
if (tile.holder.state == STATE_NEW_DATA) if (tile.holder.state == STATE_NEW_DATA)
uploadCnt += uploadTileData(tile.holder); uploadCnt += uploadTileData(tile.holder);
@ -233,13 +235,13 @@ public class TileRenderer extends LayerRenderer {
continue; continue;
} }
// check near relatives than can serve as proxy /* check near relatives than can serve as proxy */
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
MapTile t = tile.node.parent.item; MapTile t = tile.node.parent.item;
if (t.state == STATE_NEW_DATA) if (t.state == STATE_NEW_DATA)
uploadCnt += uploadTileData(t); uploadCnt += uploadTileData(t);
// dont load child proxies /* dont load child proxies */
continue; continue;
} }
@ -258,7 +260,7 @@ public class TileRenderer extends LayerRenderer {
private static int uploadTileData(MapTile tile) { private static int uploadTileData(MapTile tile) {
tile.state = STATE_READY; tile.state = STATE_READY;
// tile might contain extrusion or label layers /* tile might contain extrusion or label layers */
if (tile.layers == null) if (tile.layers == null)
return 1; return 1;
@ -286,7 +288,7 @@ public class TileRenderer extends LayerRenderer {
/** set tile isVisible flag true for tiles that intersect view */ /** set tile isVisible flag true for tiles that intersect view */
private void updateTileVisibility(MapPosition pos, float[] box) { private void updateTileVisibility(MapPosition pos, float[] box) {
// lock tiles while updating isVisible state /* lock tiles while updating isVisible state */
synchronized (tilelock) { synchronized (tilelock) {
MapTile[] tiles = mDrawTiles.tiles; MapTile[] tiles = mDrawTiles.tiles;
@ -295,10 +297,10 @@ public class TileRenderer extends LayerRenderer {
for (int i = 0; i < mDrawTiles.cnt; i++) for (int i = 0; i < mDrawTiles.cnt; i++)
tiles[i].isVisible = false; tiles[i].isVisible = false;
// count placeholder tiles /* count placeholder tiles */
mNumTileHolder = 0; mNumTileHolder = 0;
// check visibile tiles /* check visibile tiles */
mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, box); mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, box);
} }
} }
@ -318,21 +320,21 @@ public class TileRenderer extends LayerRenderer {
int prevSerial = tileSet.serial; int prevSerial = tileSet.serial;
// ensure tiles keep visible state /* ensure tiles keep visible state */
synchronized (tilelock) { synchronized (tilelock) {
MapTile[] newTiles = mDrawTiles.tiles; MapTile[] newTiles = mDrawTiles.tiles;
int cnt = mDrawTiles.cnt; int cnt = mDrawTiles.cnt;
// unlock previous tiles /* unlock previous tiles */
tileSet.releaseTiles(); tileSet.releaseTiles();
// ensure same size /* ensure same size */
if (tileSet.tiles.length != newTiles.length) { if (tileSet.tiles.length != newTiles.length) {
tileSet.tiles = new MapTile[newTiles.length]; tileSet.tiles = new MapTile[newTiles.length];
} }
// lock tiles to not be removed from cache /* lock tiles to not be removed from cache */
tileSet.cnt = 0; tileSet.cnt = 0;
for (int i = 0; i < cnt; i++) { for (int i = 0; i < cnt; i++) {
MapTile t = newTiles[i]; MapTile t = newTiles[i];
@ -352,8 +354,8 @@ public class TileRenderer extends LayerRenderer {
tileSet.releaseTiles(); tileSet.releaseTiles();
} }
/* package */int mNumTileHolder; int mNumTileHolder;
/* package */TileSet mDrawTiles = new TileSet(); TileSet mDrawTiles = new TileSet();
/** scanline fill class used to check tile visibility */ /** scanline fill class used to check tile visibility */
private final ScanBox mScanBox = new ScanBox() { private final ScanBox mScanBox = new ScanBox() {
@ -368,8 +370,8 @@ public class TileRenderer extends LayerRenderer {
t.isVisible = true; t.isVisible = true;
} }
// add placeholder tiles to show both sides /* add placeholder tiles to show both sides
// of date line. a little too complicated... * of date line. a little too complicated... */
int xmax = 1 << mZoom; int xmax = 1 << mZoom;
if (x1 >= 0 && x2 < xmax) if (x1 >= 0 && x2 < xmax)
return; return;
@ -438,13 +440,13 @@ public class TileRenderer extends LayerRenderer {
} }
private void drawTile(MapTile tile, MapPosition pos) { private void drawTile(MapTile tile, MapPosition pos) {
/** ensure to draw parents only once */ /* ensure to draw parents only once */
if (tile.lastDraw == mDrawSerial) if (tile.lastDraw == mDrawSerial)
return; return;
tile.lastDraw = mDrawSerial; tile.lastDraw = mDrawSerial;
/** use holder proxy when it is set */ /* use holder proxy when it is set */
MapTile t = tile.holder == null ? tile : tile.holder; MapTile t = tile.holder == null ? tile : tile.holder;
if (t.layers == null || t.layers.vbo == null) if (t.layers == null || t.layers.vbo == null)
@ -453,14 +455,14 @@ public class TileRenderer extends LayerRenderer {
t.layers.vbo.bind(); t.layers.vbo.bind();
/** place tile relative to map position */ /* place tile relative to map position */
int z = tile.zoomLevel; int z = tile.zoomLevel;
float div = FastMath.pow(z - pos.zoomLevel); float div = FastMath.pow(z - pos.zoomLevel);
double tileScale = Tile.SIZE * pos.scale; double tileScale = Tile.SIZE * pos.scale;
float x = (float) ((tile.x - pos.x) * tileScale); float x = (float) ((tile.x - pos.x) * tileScale);
float y = (float) ((tile.y - pos.y) * tileScale); float y = (float) ((tile.y - pos.y) * tileScale);
/** scale relative to zoom-level of this tile */ /* scale relative to zoom-level of this tile */
float scale = (float) (pos.scale / (1 << z)); float scale = (float) (pos.scale / (1 << z));
Matrices m = mMatrices; Matrices m = mMatrices;
@ -478,7 +480,7 @@ public class TileRenderer extends LayerRenderer {
continue; continue;
} }
if (!clipped) { if (!clipped) {
// draw stencil buffer clip region /* draw stencil buffer clip region */
PolygonLayer.Renderer.draw(null, m, pos, div, true, mode); PolygonLayer.Renderer.draw(null, m, pos, div, true, mode);
clipped = true; clipped = true;
} }
@ -494,7 +496,7 @@ public class TileRenderer extends LayerRenderer {
l = MeshLayer.Renderer.draw(l, m, pos); l = MeshLayer.Renderer.draw(l, m, pos);
continue; continue;
} }
// just in case /* just in case */
l = l.next; l = l.next;
} }
@ -525,8 +527,8 @@ public class TileRenderer extends LayerRenderer {
return; return;
} }
if (mRenderOverdraw != 0 && MapRenderer.frametime - t.fadeTime < 500) { if (mRenderOverdraw != 0 && MapRenderer.frametime - t.fadeTime < FADE_TIME) {
float fade = 1 - (MapRenderer.frametime - t.fadeTime) / 500f; float fade = 1 - (MapRenderer.frametime - t.fadeTime) / FADE_TIME;
PolygonLayer.Renderer.drawOver(m, mRenderOverdraw, fade * fade); PolygonLayer.Renderer.drawOver(m, mRenderOverdraw, fade * fade);
MapRenderer.animate(); MapRenderer.animate();
} else { } else {
@ -557,12 +559,12 @@ public class TileRenderer extends LayerRenderer {
MapTile proxy; MapTile proxy;
if (!preferParent) { if (!preferParent) {
// prefer drawing children /* prefer drawing children */
if (drawProxyChild(tile, pos) == 4) if (drawProxyChild(tile, pos) == 4)
return; return;
if (parent) { if (parent) {
// draw parent proxy /* draw parent proxy */
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
proxy = r.parent.item; proxy = r.parent.item;
if (proxy.state == STATE_READY) { if (proxy.state == STATE_READY) {
@ -571,7 +573,7 @@ public class TileRenderer extends LayerRenderer {
} }
} }
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
// check if parent was already drawn /* check if parent was already drawn */
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
proxy = r.parent.item; proxy = r.parent.item;
if (proxy.state == STATE_READY) if (proxy.state == STATE_READY)
@ -583,7 +585,7 @@ public class TileRenderer extends LayerRenderer {
drawTile(proxy, pos); drawTile(proxy, pos);
} }
} else { } else {
// prefer drawing parent /* prefer drawing parent */
if (parent) { if (parent) {
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
proxy = r.parent.item; proxy = r.parent.item;
@ -597,13 +599,13 @@ public class TileRenderer extends LayerRenderer {
drawProxyChild(tile, pos); drawProxyChild(tile, pos);
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
// check if parent was already drawn /* check if parent was already drawn */
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
proxy = r.parent.item; proxy = r.parent.item;
if (proxy.state == STATE_READY) if (proxy.state == STATE_READY)
return; return;
} }
// this will do nothing, just to check /* this will do nothing, just to check */
if (drawProxyChild(tile, pos) > 0) if (drawProxyChild(tile, pos) > 0)
return; return;