From 7466b6206fab5c848dcf75d5036038cb404f68a2 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Sat, 24 May 2014 22:02:16 +0200 Subject: [PATCH] extract ExtrusionLayers from ElementLayers --- .../org/oscim/layers/tile/s3db/S3DBLayer.java | 4 +- .../layers/tile/s3db/S3DBTileLoader.java | 42 ++-- .../layers/tile/vector/BuildingLayer.java | 21 +- .../org/oscim/renderer/ExtrusionRenderer.java | 210 +++++++----------- .../renderer/elements/ElementLayers.java | 24 -- .../renderer/elements/ExtrusionLayer.java | 16 +- .../renderer/elements/ExtrusionLayers.java | 111 +++++++++ 7 files changed, 232 insertions(+), 196 deletions(-) create mode 100644 vtm/src/org/oscim/renderer/elements/ExtrusionLayers.java diff --git a/vtm/src/org/oscim/layers/tile/s3db/S3DBLayer.java b/vtm/src/org/oscim/layers/tile/s3db/S3DBLayer.java index ceff241a..340a7022 100644 --- a/vtm/src/org/oscim/layers/tile/s3db/S3DBLayer.java +++ b/vtm/src/org/oscim/layers/tile/s3db/S3DBLayer.java @@ -47,7 +47,9 @@ public class S3DBLayer extends TileLayer { OffscreenRenderer or; public S3DBRenderer() { - mExtRenderer = new ExtrusionRenderer(this, SRC_ZOOM, SRC_ZOOM, true, false); + mExtRenderer = new ExtrusionRenderer(this, SRC_ZOOM, SRC_ZOOM, + true, false); + if (POST_FXAA) { or = new OffscreenRenderer(Mode.FXAA); or.setRenderer(mExtRenderer); diff --git a/vtm/src/org/oscim/layers/tile/s3db/S3DBTileLoader.java b/vtm/src/org/oscim/layers/tile/s3db/S3DBTileLoader.java index 59534e7b..eeeec45f 100644 --- a/vtm/src/org/oscim/layers/tile/s3db/S3DBTileLoader.java +++ b/vtm/src/org/oscim/layers/tile/s3db/S3DBTileLoader.java @@ -11,8 +11,9 @@ import org.oscim.core.Tag; import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.TileLoader; import org.oscim.layers.tile.TileManager; -import org.oscim.renderer.elements.ElementLayers; +import org.oscim.layers.tile.vector.BuildingLayer; import org.oscim.renderer.elements.ExtrusionLayer; +import org.oscim.renderer.elements.ExtrusionLayers; import org.oscim.tiling.ITileDataSource; import org.oscim.tiling.TileSource; import org.slf4j.Logger; @@ -59,22 +60,6 @@ class S3DBTileLoader extends TileLoader { protected boolean loadTile(MapTile tile) { mTile = tile; - double lat = MercatorProjection.toLatitude(tile.y); - mGroundScale = (float) MercatorProjection - .groundResolution(lat, 1 << mTile.zoomLevel); - - mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(247, 249, 250)); - - mLayers = new ExtrusionLayer(0, mGroundScale, Color.get(255, 254, 252)); - //mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(207, 209, 210)); - mRoofs.next = mLayers; - - ElementLayers layers = new ElementLayers(); - layers.setExtrusionLayers(mRoofs); - tile.data = layers; - - process(mTilePlane); - try { /* query database, which calls process() callback */ mTileDataSource.query(mTile, this); @@ -86,6 +71,24 @@ class S3DBTileLoader extends TileLoader { return true; } + private void initTile(MapTile tile) { + double lat = MercatorProjection.toLatitude(tile.y); + mGroundScale = (float) MercatorProjection + .groundResolution(lat, 1 << mTile.zoomLevel); + + mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(247, 249, 250)); + + mLayers = new ExtrusionLayer(0, mGroundScale, Color.get(255, 254, 252)); + //mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(207, 209, 210)); + mRoofs.next = mLayers; + + ExtrusionLayers layers = BuildingLayer.get(tile); + + layers.setLayers(mRoofs); + + process(mTilePlane); + } + String COLOR_KEY = "c"; String MATERIAL_KEY = "m"; String ROOF_KEY = "roof"; @@ -93,12 +96,15 @@ class S3DBTileLoader extends TileLoader { @Override public void process(MapElement element) { - //log.debug("TAG {}", element.tags); + if (element.type != GeometryType.TRIS) { log.debug("wrong type " + element.type); return; } + if (mLayers == null) + initTile(mTile); + boolean isRoof = element.tags.containsKey(ROOF_KEY); //if (isRoof) // log.debug(element.tags.toString()); diff --git a/vtm/src/org/oscim/layers/tile/vector/BuildingLayer.java b/vtm/src/org/oscim/layers/tile/vector/BuildingLayer.java index 964bbbe2..283a60bc 100644 --- a/vtm/src/org/oscim/layers/tile/vector/BuildingLayer.java +++ b/vtm/src/org/oscim/layers/tile/vector/BuildingLayer.java @@ -30,6 +30,7 @@ import org.oscim.renderer.OffscreenRenderer; import org.oscim.renderer.OffscreenRenderer.Mode; import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ExtrusionLayer; +import org.oscim.renderer.elements.ExtrusionLayers; import org.oscim.theme.styles.ExtrusionStyle; import org.oscim.theme.styles.RenderStyle; import org.oscim.utils.FastMath; @@ -43,6 +44,8 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook { private final static int MAX_ZOOM = 17; private final static boolean POST_AA = false; + private static final Object BUILDING_DATA = BuildingLayer.class.getName(); + private final int mMinZoom; private final int mMaxZoom; @@ -154,26 +157,34 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook { if (v != null) minHeight = Integer.parseInt(v); - ExtrusionLayer l = layers.getExtrusionLayers(); + ExtrusionLayers el = get(tile); - if (l == null) { + if (el.layers == null) { double lat = MercatorProjection.toLatitude(tile.y); float groundScale = (float) MercatorProjection .groundResolution(lat, 1 << tile.zoomLevel); - l = new ExtrusionLayer(0, groundScale, extrusion.colors); - layers.setExtrusionLayers(l); + el.layers = new ExtrusionLayer(0, groundScale, extrusion.colors); } /* 12m default */ if (height == 0) height = 12 * 100; - l.add(element, height, minHeight); + el.layers.add(element, height, minHeight); return true; } + public static ExtrusionLayers get(MapTile tile) { + ExtrusionLayers el = (ExtrusionLayers) tile.getData(BUILDING_DATA); + if (el == null) { + el = new ExtrusionLayers(tile); + tile.addData(BUILDING_DATA, el); + } + return el; + } + // private int multi; // @Override // public void onInputEvent(Event event, MotionEvent e) { diff --git a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java index 9b1682d6..7d8406e2 100644 --- a/vtm/src/org/oscim/renderer/ExtrusionRenderer.java +++ b/vtm/src/org/oscim/renderer/ExtrusionRenderer.java @@ -19,23 +19,21 @@ package org.oscim.renderer; import static org.oscim.layers.tile.MapTile.State.NEW_DATA; import static org.oscim.layers.tile.MapTile.State.READY; -import java.nio.ShortBuffer; - import org.oscim.backend.GL20; import org.oscim.core.Tile; import org.oscim.layers.tile.MapTile; import org.oscim.layers.tile.TileRenderer; import org.oscim.layers.tile.TileSet; +import org.oscim.layers.tile.vector.BuildingLayer; import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ExtrusionLayer; +import org.oscim.renderer.elements.ExtrusionLayers; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// TODO move MapTile part to BuildingLayer and make -// this class work on ExtrusionLayers - public class ExtrusionRenderer extends LayerRenderer { static final Logger log = LoggerFactory.getLogger(ExtrusionRenderer.class); + private final boolean debug = false; private final TileRenderer mTileLayer; private final int mZoomMin; @@ -43,6 +41,7 @@ public class ExtrusionRenderer extends LayerRenderer { private final boolean drawAlpha; protected float mAlpha = 1; + private final int mMode; public ExtrusionRenderer(TileRenderer tileRenderLayer, int zoomMin, int zoomMax, boolean mesh, boolean alpha) { @@ -54,15 +53,11 @@ public class ExtrusionRenderer extends LayerRenderer { drawAlpha = alpha; } - private boolean initialized = false; - private final TileSet mTileSet; - private MapTile[] mTiles; - private int mTileCnt; + private ExtrusionLayers[] mExtrusionLayerSet; + private int mExtrusionLayerCnt; - private final int mMode; - - static class Shader extends GLShader { + public static class Shader extends GLShader { int uMVP, uColor, uAlpha, uMode, aPos, aLight; public Shader(String shader) { @@ -78,23 +73,20 @@ public class ExtrusionRenderer extends LayerRenderer { } } - private Shader mShader[] = { null, null }; - - private boolean initShader() { - initialized = true; - - mShader[0] = new Shader("extrusion_layer_ext"); - mShader[1] = new Shader("extrusion_layer_mesh"); + protected Shader mShader; + @Override + protected boolean setup() { + if (mMode == 0) + mShader = new Shader("extrusion_layer_ext"); + else + mShader = new Shader("extrusion_layer_mesh"); return true; } @Override public void update(GLViewport v) { - if (!initialized && !initShader()) - return; - if (mAlpha == 0 || v.pos.zoomLevel < (mZoomMin - 1)) { setReady(false); return; @@ -111,8 +103,8 @@ public class ExtrusionRenderer extends LayerRenderer { } /* keep a list of tiles available for rendering */ - if (mTiles == null || mTiles.length < mTileSet.cnt * 4) - mTiles = new MapTile[mTileSet.cnt * 4]; + if (mExtrusionLayerSet == null || mExtrusionLayerSet.length < mTileSet.cnt * 4) + mExtrusionLayerSet = new ExtrusionLayers[mTileSet.cnt * 4]; int zoom = tiles[0].zoomLevel; @@ -120,41 +112,41 @@ public class ExtrusionRenderer extends LayerRenderer { boolean compiled = false; if (zoom >= mZoomMin && zoom <= mZoomMax) { - // TODO - if tile is not available try parent or children + /* TODO - if tile is not available try parent or children */ for (int i = 0; i < mTileSet.cnt; i++) { - ExtrusionLayer el = getLayer(tiles[i]); - if (el == null) + ExtrusionLayers els = getLayer(tiles[i]); + if (els == null) continue; - if (el.compiled) - mTiles[activeTiles++] = tiles[i]; - else if (!compiled && compileLayers(el)) { - mTiles[activeTiles++] = tiles[i]; + if (els.compiled) + mExtrusionLayerSet[activeTiles++] = els; + else if (!compiled && els.compileLayers()) { + mExtrusionLayerSet[activeTiles++] = els; compiled = true; } } } else if (zoom == mZoomMax + 1) { /* special case for s3db: render from parent tiles */ - O: for (int i = 0; i < mTileSet.cnt; i++) { + for (int i = 0; i < mTileSet.cnt; i++) { MapTile t = tiles[i].node.parent(); if (t == null) continue; - for (MapTile c : mTiles) - if (c == t) - continue O; + // for (MapTile c : mTiles) + // if (c == t) + // continue O; - ExtrusionLayer el = getLayer(t); - if (el == null) + ExtrusionLayers els = getLayer(t); + if (els == null) continue; - if (el.compiled) - mTiles[activeTiles++] = tiles[i]; + if (els.compiled) + mExtrusionLayerSet[activeTiles++] = els; - else if (!compiled && compileLayers(el)) { - mTiles[activeTiles++] = t; + else if (!compiled && els.compileLayers()) { + mExtrusionLayerSet[activeTiles++] = els; compiled = true; } } @@ -167,12 +159,12 @@ public class ExtrusionRenderer extends LayerRenderer { continue; MapTile c = t.node.child(j); - ExtrusionLayer el = getLayer(c); + ExtrusionLayers el = getLayer(c); if (el == null || !el.compiled) continue; - mTiles[activeTiles++] = c; + mExtrusionLayerSet[activeTiles++] = el; } } } @@ -181,7 +173,9 @@ public class ExtrusionRenderer extends LayerRenderer { if (compiled) MapRenderer.animate(); - mTileCnt = activeTiles; + mExtrusionLayerCnt = activeTiles; + + //log.debug("active tiles: {}", mExtrusionLayerCnt); if (activeTiles > 0) setReady(true); @@ -189,71 +183,22 @@ public class ExtrusionRenderer extends LayerRenderer { mTileLayer.releaseTiles(mTileSet); } - private boolean compileLayers(ExtrusionLayer el) { - if (el == null) - return false; - - if (el.compiled) - return true; - - int sumIndices = 0; - int sumVertices = 0; - for (ExtrusionLayer l = el; l != null; l = l.next()) { - sumIndices += l.sumIndices; - sumVertices += l.sumVertices; - } - if (sumIndices == 0) { - return false; - } - ShortBuffer vbuf = MapRenderer.getShortBuffer(sumVertices * 4); - ShortBuffer ibuf = MapRenderer.getShortBuffer(sumIndices); - - for (ExtrusionLayer l = el; l != null; l = l.next()) - l.compile(vbuf, ibuf); - - int size = sumIndices * 2; - if (ibuf.position() != sumIndices) { - int pos = ibuf.position(); - log.error("invalid indice size: {} {}", sumIndices, pos); - size = pos * 2; - } - el.vboIndices = BufferObject.get(GL20.GL_ELEMENT_ARRAY_BUFFER, size); - el.vboIndices.loadBufferData(ibuf.flip(), size); - el.vboIndices.unbind(); - - size = sumVertices * 4 * 2; - if (vbuf.position() != sumVertices * 4) { - int pos = vbuf.position(); - log.error("invalid vertex size: {} {}", sumVertices, pos); - size = pos * 2; - } - - el.vboVertices = BufferObject.get(GL20.GL_ARRAY_BUFFER, size); - el.vboVertices.loadBufferData(vbuf.flip(), size); - el.vboVertices.unbind(); - - GLUtils.checkGlError("extrusion layer"); - return true; - } - - private static ExtrusionLayer getLayer(MapTile t) { + private static ExtrusionLayers getLayer(MapTile t) { ElementLayers layers = t.getLayers(); - if (layers == null || !t.state(READY | NEW_DATA)) + if (layers != null && !t.state(READY | NEW_DATA)) return null; - return layers.getExtrusionLayers(); + return BuildingLayer.get(t); } - private final boolean debug = false; + private void renderCombined(int vertexPointer, ExtrusionLayers els) { + if (els.vboIndices == null) + return; - private void renderCombined(int vertexPointer, ExtrusionLayer el) { - for (; el != null; el = el.next()) { + els.vboIndices.bind(); + els.vboVertices.bind(); - if (el.vboIndices == null) - continue; - - el.vboIndices.bind(); - el.vboVertices.bind(); + for (ExtrusionLayer el = els.layers; el != null; el = el.next()) { GL.glVertexAttribPointer(vertexPointer, 3, GL20.GL_SHORT, false, 8, 0); @@ -276,8 +221,8 @@ public class ExtrusionRenderer extends LayerRenderer { // TODO one could render in one pass to texture and then draw the texture // with alpha... might be faster and would allow postprocessing outlines. - MapTile[] tiles = mTiles; - Shader s = mShader[mMode]; + ExtrusionLayers[] els = mExtrusionLayerSet; + Shader s = mShader; //[mMode]; if (debug) { s.useProgram(); @@ -291,16 +236,16 @@ public class ExtrusionRenderer extends LayerRenderer { GLState.test(false, false); GLState.blend(true); - for (int i = 0; i < mTileCnt; i++) { - ExtrusionLayer el = tiles[i].getLayers().getExtrusionLayers(); + for (int i = 0; i < mExtrusionLayerCnt; i++) { + ExtrusionLayer el = els[i].getLayers(); - setMatrix(v, tiles[i], 0); + setMatrix(v, els[i], 0); v.mvp.setAsUniform(s.uMVP); - renderCombined(s.aPos, el); + renderCombined(s.aPos, els[i]); - // just a temporary reference! - tiles[i] = null; + /* just a temporary reference! */ + els[i] = null; } return; } @@ -311,7 +256,6 @@ public class ExtrusionRenderer extends LayerRenderer { GLState.test(true, false); s.useProgram(); - //GLState.useProgram(shaderProgram[mMode]); GLState.enableVertexArrays(s.aPos, -1); GLState.blend(false); @@ -326,18 +270,17 @@ public class ExtrusionRenderer extends LayerRenderer { //GLUtils.glUniform4fv(uExtColor, 4, mColor); /* draw to depth buffer */ - for (int i = 0; i < mTileCnt; i++) { - MapTile t = tiles[i]; - ExtrusionLayer el = t.getLayers().getExtrusionLayers(); + for (int i = 0; i < mExtrusionLayerCnt; i++) { + ExtrusionLayer el = els[i].getLayers(); if (el == null) continue; - int d = MapTile.depthOffset(t) * 10; + int d = 0; // FIXME MapTile.depthOffset(t) * 10; - setMatrix(v, t, d); + setMatrix(v, els[i], d); v.mvp.setAsUniform(s.uMVP); - renderCombined(s.aPos, el); + renderCombined(s.aPos, els[i]); } GL.glColorMask(true, true, true, true); @@ -350,28 +293,28 @@ public class ExtrusionRenderer extends LayerRenderer { float[] currentColor = null; - for (int i = 0; i < mTileCnt; i++) { - MapTile t = tiles[i]; - ExtrusionLayer el = t.getLayers().getExtrusionLayers(); + for (int i = 0; i < mExtrusionLayerCnt; i++) { + ExtrusionLayer el = els[i].getLayers(); if (el == null) continue; - if (el.vboIndices == null) + if (els[i].vboIndices == null) continue; - int d = 1; + els[i].vboIndices.bind(); + els[i].vboVertices.bind(); + + int d = 0; if (drawAlpha) { GL.glDepthFunc(GL20.GL_EQUAL); - d = MapTile.depthOffset(t) * 10; + + // FIXME d = MapTile.depthOffset(t) * 10; } - setMatrix(v, t, d); + setMatrix(v, els[i], d); v.mvp.setAsUniform(s.uMVP); - el.vboIndices.bind(); - el.vboVertices.bind(); - for (; el != null; el = el.next()) { if (el.colors != currentColor) { @@ -443,8 +386,9 @@ public class ExtrusionRenderer extends LayerRenderer { GL20.GL_UNSIGNED_SHORT, offset); } } - // just a temporary reference! - tiles[i] = null; + + /* just a temporary reference! */ + els[i] = null; } GL.glDepthMask(false); @@ -455,13 +399,13 @@ public class ExtrusionRenderer extends LayerRenderer { mTileLayer.releaseTiles(mTileSet); } - private static void setMatrix(GLViewport v, MapTile tile, int delta) { - int z = tile.zoomLevel; + private static void setMatrix(GLViewport v, ExtrusionLayers l, int delta) { + int z = l.zoomLevel; double curScale = Tile.SIZE * v.pos.scale; float scale = (float) (v.pos.scale / (1 << z)); - float x = (float) ((tile.x - v.pos.x) * curScale); - float y = (float) ((tile.y - v.pos.y) * curScale); + float x = (float) ((l.x - v.pos.x) * curScale); + float y = (float) ((l.y - v.pos.y) * curScale); v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE); // scale height ??? diff --git a/vtm/src/org/oscim/renderer/elements/ElementLayers.java b/vtm/src/org/oscim/renderer/elements/ElementLayers.java index 87667044..dc530e62 100644 --- a/vtm/src/org/oscim/renderer/elements/ElementLayers.java +++ b/vtm/src/org/oscim/renderer/elements/ElementLayers.java @@ -58,12 +58,6 @@ public class ElementLayers extends TileData { /** Text- and SymbolLayer */ private RenderElement textureLayers; - /** - * FIXME this is somewhat out-of-place, as it is not - * compiled with the other layers - */ - private RenderElement extrusionLayers; - /** * VBO holds all vertex data to draw lines and polygons after compilation. * Layout: @@ -184,20 +178,6 @@ public class ElementLayers extends TileData { return textureLayers; } - /** - * Set new ExtrusionLayers and clear previous. - */ - public void setExtrusionLayers(ExtrusionLayer el) { - for (RenderElement l = extrusionLayers; l != null; l = l.next) - l.clear(); - - extrusionLayers = el; - } - - public ExtrusionLayer getExtrusionLayers() { - return (ExtrusionLayer) extrusionLayers; - } - private RenderElement getLayer(int level, int type) { RenderElement layer = null; @@ -364,14 +344,11 @@ public class ElementLayers extends TileData { public void setFrom(ElementLayers layers) { setBaseLayers(layers.baseLayers); setTextureLayers((TextureLayer) layers.textureLayers); - setExtrusionLayers((ExtrusionLayer) layers.extrusionLayers); mCurLayer = null; layers.baseLayers = null; layers.textureLayers = null; - layers.extrusionLayers = null; layers.mCurLayer = null; - } /** cleanup only when layers are not used by tile or layer anymore! */ @@ -379,7 +356,6 @@ public class ElementLayers extends TileData { /* NB: set null calls clear() on each layer! */ setBaseLayers(null); setTextureLayers(null); - setExtrusionLayers(null); mCurLayer = null; if (vbo != null) diff --git a/vtm/src/org/oscim/renderer/elements/ExtrusionLayer.java b/vtm/src/org/oscim/renderer/elements/ExtrusionLayer.java index 668945b2..27ce090e 100644 --- a/vtm/src/org/oscim/renderer/elements/ExtrusionLayer.java +++ b/vtm/src/org/oscim/renderer/elements/ExtrusionLayer.java @@ -23,7 +23,6 @@ import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer.GeometryType; import org.oscim.core.MapElement; import org.oscim.core.Tile; -import org.oscim.renderer.BufferObject; import org.oscim.renderer.MapRenderer; import org.oscim.utils.FastMath; import org.oscim.utils.KeyMap; @@ -54,9 +53,6 @@ public class ExtrusionLayer extends RenderElement { public int sumVertices = 0; public int sumIndices = 0; - public BufferObject vboIndices; - public BufferObject vboVertices; - //private final static int IND_EVEN_SIDE = 0; //private final static int IND_ODD_SIDE = 1; private final static int IND_ROOF = 2; @@ -65,7 +61,6 @@ public class ExtrusionLayer extends RenderElement { private final static int IND_OUTLINE = 3; private final static int IND_MESH = 4; - public boolean compiled = false; private final float mGroundResolution; private KeyMap mVertexMap; @@ -654,10 +649,6 @@ public class ExtrusionLayer extends RenderElement { public void compile(ShortBuffer vertexBuffer, ShortBuffer indexBuffer) { mClipper = null; - if (compiled) { - throw new IllegalStateException(); - } - if (mVertexMap != null) { vertexPool.releaseAll(mVertexMap.releaseItems()); mVertexMap = vertexMapPool.release(mVertexMap); @@ -665,7 +656,6 @@ public class ExtrusionLayer extends RenderElement { } if (sumVertices == 0) { - compiled = true; return; } @@ -686,7 +676,6 @@ public class ExtrusionLayer extends RenderElement { vertexBuffer.put(vi.vertices, 0, vi.used); clear(); - compiled = true; } @Override @@ -699,10 +688,7 @@ public class ExtrusionLayer extends RenderElement { mVertexMap = null; } - if (compiled) { - vboIndices = BufferObject.release(vboIndices); - vboVertices = BufferObject.release(vboVertices); - } else { + if (mIndices != null) { for (int i = 0; i <= IND_MESH; i++) mIndices[i] = VertexItem.pool.releaseAll(mIndices[i]); mIndices = null; diff --git a/vtm/src/org/oscim/renderer/elements/ExtrusionLayers.java b/vtm/src/org/oscim/renderer/elements/ExtrusionLayers.java new file mode 100644 index 00000000..1405389a --- /dev/null +++ b/vtm/src/org/oscim/renderer/elements/ExtrusionLayers.java @@ -0,0 +1,111 @@ +package org.oscim.renderer.elements; + +import java.nio.ShortBuffer; + +import org.oscim.backend.GL20; +import org.oscim.layers.tile.MapTile; +import org.oscim.layers.tile.MapTile.TileData; +import org.oscim.renderer.BufferObject; +import org.oscim.renderer.GLUtils; +import org.oscim.renderer.MapRenderer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ExtrusionLayers extends TileData { + static final Logger log = LoggerFactory.getLogger(ExtrusionLayers.class); + + public ExtrusionLayer layers; + + public boolean compiled; + + public final int zoomLevel; + + public final double x; + public final double y; + + public BufferObject vboIndices; + public BufferObject vboVertices; + + public ExtrusionLayers(MapTile tile) { + zoomLevel = tile.zoomLevel; + x = tile.x; + y = tile.y; + } + + /** + * Set new ExtrusionLayers and clear previous. + */ + public void setLayers(ExtrusionLayer el) { + for (RenderElement l = layers; l != null; l = l.next) + l.clear(); + + layers = el; + } + + public ExtrusionLayer getLayers() { + return (ExtrusionLayer) layers; + } + + @Override + protected void dispose() { + setLayers(null); + + if (compiled) { + vboIndices = BufferObject.release(vboIndices); + vboVertices = BufferObject.release(vboVertices); + } + + } + + public boolean compileLayers() { + ExtrusionLayer el = layers; + + if (el == null) + return false; + + //if (el.compiled) + // return true; + + int sumIndices = 0; + int sumVertices = 0; + for (ExtrusionLayer l = el; l != null; l = l.next()) { + sumIndices += l.sumIndices; + sumVertices += l.sumVertices; + } + if (sumIndices == 0) { + return false; + } + ShortBuffer vbuf = MapRenderer.getShortBuffer(sumVertices * 4); + ShortBuffer ibuf = MapRenderer.getShortBuffer(sumIndices); + + for (ExtrusionLayer l = el; l != null; l = l.next()) + l.compile(vbuf, ibuf); + + int size = sumIndices * 2; + if (ibuf.position() != sumIndices) { + int pos = ibuf.position(); + log.error("invalid indice size: {} {}", sumIndices, pos); + size = pos * 2; + } + vboIndices = BufferObject.get(GL20.GL_ELEMENT_ARRAY_BUFFER, size); + vboIndices.loadBufferData(ibuf.flip(), size); + vboIndices.unbind(); + + size = sumVertices * 4 * 2; + if (vbuf.position() != sumVertices * 4) { + int pos = vbuf.position(); + log.error("invalid vertex size: {} {}", sumVertices, pos); + size = pos * 2; + } + + vboVertices = BufferObject.get(GL20.GL_ARRAY_BUFFER, size); + vboVertices.loadBufferData(vbuf.flip(), size); + vboVertices.unbind(); + + GLUtils.checkGlError("extrusion layer"); + + compiled = true; + return true; + } + +}