S3DB/Buildings:

- allow multiple building extrusion buckets per tile
  (differently colored buildings depending on tags)
- fixed ExtrusionBucket index offsets
- rename more layer -> bucket
This commit is contained in:
Hannes Janetzek 2014-09-11 13:29:41 +02:00
parent 84c094000b
commit e32f45b585
9 changed files with 184 additions and 208 deletions

View File

@ -50,6 +50,16 @@ public abstract class TileLayer extends Layer implements UpdateListener {
}
public TileLayer(Map map, TileManager tileManager) {
super(map);
mTileManager = tileManager;
}
protected void setRenderer(TileRenderer renderer) {
renderer.setTileManager(mTileManager);
mRenderer = renderer;
}
abstract protected TileLoader createLoader();
public TileRenderer tileRenderer() {

View File

@ -24,7 +24,6 @@ import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.VectorTileLayer.TileLoaderThemeHook;
import org.oscim.map.Map;
import org.oscim.renderer.ExtrusionRenderer;
import org.oscim.renderer.OffscreenRenderer;
import org.oscim.renderer.OffscreenRenderer.Mode;
import org.oscim.renderer.bucket.ExtrusionBucket;
@ -32,6 +31,7 @@ import org.oscim.renderer.bucket.ExtrusionBuckets;
import org.oscim.renderer.bucket.RenderBuckets;
import org.oscim.theme.styles.ExtrusionStyle;
import org.oscim.theme.styles.RenderStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -40,39 +40,27 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
private final static int MIN_ZOOM = 17;
private final static int MAX_ZOOM = 17;
private final static boolean POST_AA = false;
private final static boolean TRANSLUCENT = true;
private static final Object BUILDING_DATA = BuildingLayer.class.getName();
private ExtrusionRenderer mExtRenderer;
public BuildingLayer(Map map, VectorTileLayer tileLayer) {
this(map, tileLayer, MIN_ZOOM, MAX_ZOOM);
// super(map);
// tileLayer.addHook(this);
//
// mMinZoom = MIN_ZOOM;
//
// OffscreenRenderer or = new OffscreenRenderer();
// or.setRenderer(new ExtrusionRenderer(tileLayer.tileRenderer(), MIN_ZOOM));
// mRenderer = or;
}
public BuildingLayer(Map map, VectorTileLayer tileLayer, int zoomMin, int zoomMax) {
super(map);
tileLayer.addHook(this);
mExtRenderer = new BuildingRenderer(tileLayer.tileRenderer(),
zoomMin, zoomMax, false, true);
if (POST_AA) {
OffscreenRenderer or = new OffscreenRenderer(Mode.SSAO_FXAA);
or.setRenderer(mExtRenderer);
mRenderer = or;
} else {
mRenderer = mExtRenderer;
}
mRenderer = new BuildingRenderer(tileLayer.tileRenderer(),
zoomMin, zoomMax,
false, TRANSLUCENT);
if (POST_AA)
mRenderer = new OffscreenRenderer(Mode.SSAO_FXAA, mRenderer);
}
/** TileLoaderThemeHook */
@ -91,36 +79,44 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
String v = element.tags.getValue(Tag.KEY_HEIGHT);
if (v != null)
height = Integer.parseInt(v);
v = element.tags.getValue(Tag.KEY_MIN_HEIGHT);
if (v != null)
minHeight = Integer.parseInt(v);
ExtrusionBuckets el = get(tile);
if (el.layers == null) {
double lat = MercatorProjection.toLatitude(tile.y);
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << tile.zoomLevel);
el.layers = new ExtrusionBucket(0, groundScale, extrusion.colors);
}
/* 12m default */
if (height == 0)
height = 12 * 100;
el.layers.add(element, height, minHeight);
ExtrusionBuckets ebs = get(tile);
for (ExtrusionBucket b = ebs.buckets; b != null; b = b.next()) {
if (b.colors == extrusion.colors) {
b.add(element, height, minHeight);
return true;
}
}
double lat = MercatorProjection.toLatitude(tile.y);
float groundScale = (float) MercatorProjection
.groundResolution(lat, 1 << tile.zoomLevel);
ebs.buckets = Inlist.push(ebs.buckets,
new ExtrusionBucket(0, groundScale,
extrusion.colors));
ebs.buckets.add(element, height, minHeight);
return true;
}
public static ExtrusionBuckets get(MapTile tile) {
ExtrusionBuckets el = (ExtrusionBuckets) tile.getData(BUILDING_DATA);
if (el == null) {
el = new ExtrusionBuckets(tile);
tile.addData(BUILDING_DATA, el);
ExtrusionBuckets eb = (ExtrusionBuckets) tile.getData(BUILDING_DATA);
if (eb == null) {
eb = new ExtrusionBuckets(tile);
tile.addData(BUILDING_DATA, eb);
}
return el;
return eb;
}
@Override
@ -128,7 +124,7 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
if (success)
get(tile).prepare();
else
get(tile).setLayers(null);
get(tile).setBuckets(null);
}
// private int multi;

View File

@ -101,8 +101,9 @@ public class BuildingRenderer extends ExtrusionRenderer {
TileDistanceSort.sort(tiles, 0, mTileSet.cnt);
/* keep a list of tiles available for rendering */
if (mExtrusionLayerSet == null || mExtrusionLayerSet.length < mTileSet.cnt * 4)
mExtrusionLayerSet = new ExtrusionBuckets[mTileSet.cnt * 4];
int maxTiles = mTileSet.cnt * 4;
if (mExtrusionBucketSet.length < maxTiles)
mExtrusionBucketSet = new ExtrusionBuckets[maxTiles];
/* compile one tile max per frame */
boolean compiled = false;
@ -114,14 +115,14 @@ public class BuildingRenderer extends ExtrusionRenderer {
/* TODO - if tile is not available try parent or children */
for (int i = 0; i < mTileSet.cnt; i++) {
ExtrusionBuckets els = getLayer(tiles[i]);
if (els == null)
ExtrusionBuckets ebs = getBuckets(tiles[i]);
if (ebs == null)
continue;
if (els.compiled)
mExtrusionLayerSet[activeTiles++] = els;
else if (!compiled && els.compileLayers()) {
mExtrusionLayerSet[activeTiles++] = els;
if (ebs.compiled)
mExtrusionBucketSet[activeTiles++] = ebs;
else if (!compiled && ebs.compile()) {
mExtrusionBucketSet[activeTiles++] = ebs;
compiled = true;
}
}
@ -137,15 +138,15 @@ public class BuildingRenderer extends ExtrusionRenderer {
// if (c == t)
// continue O;
ExtrusionBuckets els = getLayer(t);
if (els == null)
ExtrusionBuckets ebs = getBuckets(t);
if (ebs == null)
continue;
if (els.compiled)
mExtrusionLayerSet[activeTiles++] = els;
if (ebs.compiled)
mExtrusionBucketSet[activeTiles++] = ebs;
else if (!compiled && els.compileLayers()) {
mExtrusionLayerSet[activeTiles++] = els;
else if (!compiled && ebs.compile()) {
mExtrusionBucketSet[activeTiles++] = ebs;
compiled = true;
}
}
@ -158,12 +159,12 @@ public class BuildingRenderer extends ExtrusionRenderer {
continue;
MapTile c = t.node.child(j);
ExtrusionBuckets el = getLayer(c);
ExtrusionBuckets eb = getBuckets(c);
if (el == null || !el.compiled)
if (eb == null || !eb.compiled)
continue;
mExtrusionLayerSet[activeTiles++] = el;
mExtrusionBucketSet[activeTiles++] = eb;
}
}
}
@ -172,7 +173,7 @@ public class BuildingRenderer extends ExtrusionRenderer {
if (compiled)
MapRenderer.animate();
mExtrusionLayerCnt = activeTiles;
mBucketsCnt = activeTiles;
//log.debug("active tiles: {}", mExtrusionLayerCnt);
@ -192,9 +193,9 @@ public class BuildingRenderer extends ExtrusionRenderer {
mTileRenderer.releaseTiles(mTileSet);
}
private static ExtrusionBuckets getLayer(MapTile t) {
RenderBuckets layers = t.getBuckets();
if (layers != null && !t.state(READY | NEW_DATA))
private static ExtrusionBuckets getBuckets(MapTile t) {
RenderBuckets buckets = t.getBuckets();
if (buckets != null && !t.state(READY | NEW_DATA))
return null;
return BuildingLayer.get(t);

View File

@ -6,6 +6,7 @@ import org.oscim.layers.tile.TileManager;
import org.oscim.layers.tile.TileRenderer;
import org.oscim.map.Map;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.OffscreenRenderer;
import org.oscim.renderer.OffscreenRenderer.Mode;
import org.oscim.tiling.TileSource;
@ -28,9 +29,8 @@ public class S3DBLayer extends TileLayer {
private final TileSource mTileSource;
public S3DBLayer(Map map, TileSource tileSource) {
super(map,
new TileManager(map, SRC_ZOOM, SRC_ZOOM, MAX_CACHE),
new S3DBRenderer());
super(map, new TileManager(map, SRC_ZOOM, SRC_ZOOM, MAX_CACHE));
setRenderer(new S3DBRenderer());
mTileSource = tileSource;
initLoader(2);
@ -42,48 +42,30 @@ public class S3DBLayer extends TileLayer {
}
public static class S3DBRenderer extends TileRenderer {
BuildingRenderer mExtRenderer;
OffscreenRenderer or;
LayerRenderer mRenderer;
public S3DBRenderer() {
mExtRenderer = new BuildingRenderer(this, SRC_ZOOM, SRC_ZOOM, true, false);
mRenderer = new BuildingRenderer(this, SRC_ZOOM, SRC_ZOOM, true, false);
if (POST_FXAA) {
//or = new OffscreenRenderer(Mode.FXAA);
or = new OffscreenRenderer(Mode.SSAO_FXAA);
or.setRenderer(mExtRenderer);
}
if (POST_FXAA)
mRenderer = new OffscreenRenderer(Mode.SSAO_FXAA, mRenderer);
}
@Override
protected synchronized void update(GLViewport v) {
public synchronized void update(GLViewport v) {
super.update(v);
if (POST_FXAA) {
or.update(v);
setReady(or.isReady());
} else {
mExtRenderer.update(v);
setReady(mExtRenderer.isReady());
}
mRenderer.update(v);
setReady(mRenderer.isReady());
}
@Override
protected synchronized void render(GLViewport v) {
if (POST_FXAA) {
or.render(v);
} else {
mExtRenderer.render(v);
}
public synchronized void render(GLViewport v) {
mRenderer.render(v);
}
@Override
protected boolean setup() {
if (POST_FXAA) {
or.setup();
} else {
mExtRenderer.setup();
}
public boolean setup() {
mRenderer.setup();
return super.setup();
}
}

View File

@ -12,7 +12,6 @@ import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.renderer.bucket.ExtrusionBucket;
import org.oscim.renderer.bucket.ExtrusionBuckets;
import org.oscim.tiling.ITileDataSource;
import org.oscim.tiling.TileSource;
import org.slf4j.Logger;
@ -24,7 +23,7 @@ class S3DBTileLoader extends TileLoader {
/** current TileDataSource used by this MapTileLoader */
private final ITileDataSource mTileDataSource;
private ExtrusionBucket mLayers;
private ExtrusionBucket mParts;
private ExtrusionBucket mRoofs;
private float mGroundScale;
@ -77,13 +76,11 @@ class S3DBTileLoader extends TileLoader {
mRoofs = new ExtrusionBucket(0, mGroundScale, Color.get(247, 249, 250));
mLayers = new ExtrusionBucket(0, mGroundScale, Color.get(255, 254, 252));
mParts = new ExtrusionBucket(0, mGroundScale, Color.get(255, 254, 252));
//mRoofs = new ExtrusionLayer(0, mGroundScale, Color.get(207, 209, 210));
mRoofs.next = mLayers;
mRoofs.next = mParts;
ExtrusionBuckets layers = BuildingLayer.get(tile);
layers.setLayers(mRoofs);
BuildingLayer.get(tile).setBuckets(mRoofs);
process(mTilePlane);
}
@ -101,7 +98,7 @@ class S3DBTileLoader extends TileLoader {
return;
}
if (mLayers == null)
if (mParts == null)
initTile(mTile);
boolean isRoof = element.tags.containsKey(ROOF_KEY);
@ -123,11 +120,11 @@ class S3DBTileLoader extends TileLoader {
if (isRoof && (roofShape == null || "flat".equals(roofShape)))
mRoofs.add(element);
else
mLayers.add(element);
mParts.add(element);
return;
}
for (ExtrusionBucket l = mLayers; l != null; l = l.next()) {
for (ExtrusionBucket l = mParts; l != null; l = l.next()) {
if (l.color == c) {
l.add(element);
return;
@ -135,8 +132,8 @@ class S3DBTileLoader extends TileLoader {
}
ExtrusionBucket l = new ExtrusionBucket(0, mGroundScale, c);
l.next = mLayers.next;
mLayers.next = l;
l.next = mParts.next;
mParts.next = l;
l.add(element);
}
@ -144,7 +141,7 @@ class S3DBTileLoader extends TileLoader {
@Override
public void completed(QueryResult result) {
mLayers = null;
mParts = null;
mRoofs = null;
super.completed(result);

View File

@ -16,6 +16,17 @@
*/
package org.oscim.renderer;
import static org.oscim.backend.GL20.GL_CULL_FACE;
import static org.oscim.backend.GL20.GL_DEPTH_BUFFER_BIT;
import static org.oscim.backend.GL20.GL_EQUAL;
import static org.oscim.backend.GL20.GL_LEQUAL;
import static org.oscim.backend.GL20.GL_LESS;
import static org.oscim.backend.GL20.GL_LINES;
import static org.oscim.backend.GL20.GL_SHORT;
import static org.oscim.backend.GL20.GL_TRIANGLES;
import static org.oscim.backend.GL20.GL_UNSIGNED_BYTE;
import static org.oscim.backend.GL20.GL_UNSIGNED_SHORT;
import org.oscim.backend.GL20;
import org.oscim.core.Tile;
import org.oscim.renderer.bucket.ExtrusionBucket;
@ -30,8 +41,8 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
private final int mMode;
private Shader mShader;
protected ExtrusionBuckets[] mExtrusionLayerSet;
protected int mExtrusionLayerCnt;
protected ExtrusionBuckets[] mExtrusionBucketSet = {};
protected int mBucketsCnt;
protected float mAlpha = 1;
public ExtrusionRenderer(boolean mesh, boolean alpha) {
@ -65,22 +76,25 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
return true;
}
private void renderCombined(int vertexPointer, ExtrusionBuckets els) {
private void renderCombined(int vertexPointer, ExtrusionBuckets ebs) {
for (ExtrusionBucket el = els.layers; el != null; el = el.next()) {
for (ExtrusionBucket eb = ebs.buckets(); eb != null; eb = eb.next()) {
GL.glVertexAttribPointer(vertexPointer, 3,
GL20.GL_SHORT, false, 8, 0);
GL_SHORT, false, 8,
eb.getVertexOffset());
int sumIndices = el.idx[0] + el.idx[1] + el.idx[2];
int sumIndices = eb.idx[0] + eb.idx[1] + eb.idx[2];
/* extrusion */
if (sumIndices > 0)
GL.glDrawElements(GL20.GL_TRIANGLES, sumIndices,
GL20.GL_UNSIGNED_SHORT, 0);
GL.glDrawElements(GL_TRIANGLES, sumIndices,
GL_UNSIGNED_SHORT, eb.off[0]);
if (el.idx[2] > 0) {
int offset = sumIndices * 2;
GL.glDrawElements(GL20.GL_TRIANGLES, el.idx[4],
GL20.GL_UNSIGNED_SHORT, offset);
/* mesh */
if (eb.idx[4] > 0) {
GL.glDrawElements(GL_TRIANGLES, eb.idx[4],
GL_UNSIGNED_SHORT, eb.off[4]);
}
}
}
@ -89,7 +103,7 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
public void render(GLViewport v) {
GL.glDepthMask(true);
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
GL.glClear(GL_DEPTH_BUFFER_BIT);
GLState.test(true, false);
@ -100,12 +114,12 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
/* only use face-culling when it's unlikely
* that one'moves through the building' */
if (v.pos.zoomLevel < 18)
GL.glEnable(GL20.GL_CULL_FACE);
GL.glEnable(GL_CULL_FACE);
GL.glDepthFunc(GL20.GL_LESS);
GL.glDepthFunc(GL_LESS);
GL.glUniform1f(s.uAlpha, mAlpha);
ExtrusionBuckets[] els = mExtrusionLayerSet;
ExtrusionBuckets[] ebs = mExtrusionBucketSet;
if (mTranslucent) {
/* only draw to depth buffer */
@ -113,24 +127,24 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
GL.glColorMask(false, false, false, false);
GL.glUniform1i(s.uMode, -1);
for (int i = 0; i < mExtrusionLayerCnt; i++) {
if (els[i].ibo == null)
for (int i = 0; i < mBucketsCnt; i++) {
if (ebs[i].ibo == null)
return;
els[i].ibo.bind();
els[i].vbo.bind();
ebs[i].ibo.bind();
ebs[i].vbo.bind();
setMatrix(v, els[i], true);
setMatrix(v, ebs[i], true);
v.mvp.setAsUniform(s.uMVP);
renderCombined(s.aPos, els[i]);
renderCombined(s.aPos, ebs[i]);
}
/* only draw to color buffer */
GL.glColorMask(true, true, true, true);
GL.glDepthMask(false);
GL.glDepthFunc(GL20.GL_EQUAL);
GL.glDepthFunc(GL_EQUAL);
}
GLState.blend(true);
@ -138,108 +152,83 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
GLState.enableVertexArrays(s.aPos, s.aLight);
float[] currentColor = null;
for (int i = 0; i < mExtrusionLayerCnt; i++) {
if (els[i].ibo == null)
for (int i = 0; i < mBucketsCnt; i++) {
if (ebs[i].ibo == null)
continue;
els[i].ibo.bind();
els[i].vbo.bind();
ebs[i].ibo.bind();
ebs[i].vbo.bind();
if (!mTranslucent) {
setMatrix(v, els[i], false);
setMatrix(v, ebs[i], false);
v.mvp.setAsUniform(s.uMVP);
}
ExtrusionBucket el = els[i].getLayers();
for (; el != null; el = el.next()) {
ExtrusionBucket eb = ebs[i].buckets();
if (el.colors != currentColor) {
currentColor = el.colors;
for (; eb != null; eb = eb.next()) {
if (eb.colors != currentColor) {
currentColor = eb.colors;
GLUtils.glUniform4fv(s.uColor,
mMode == 0 ? 4 : 1,
el.colors);
eb.colors);
}
GL.glVertexAttribPointer(s.aPos, 3, GL_SHORT,
false, 8, eb.getVertexOffset());
GL.glVertexAttribPointer(s.aPos, 3, GL20.GL_SHORT,
false, 8, el.getVertexOffset());
GL.glVertexAttribPointer(s.aLight, 2,
GL20.GL_UNSIGNED_BYTE,
false, 8, el.getVertexOffset() + 6);
GL.glVertexAttribPointer(s.aLight, 2, GL_UNSIGNED_BYTE,
false, 8, eb.getVertexOffset() + 6);
/* draw extruded outlines */
if (el.idx[0] > 0) {
if (eb.idx[0] > 0) {
if (mTranslucent) {
GL.glDepthFunc(GL20.GL_EQUAL);
setMatrix(v, els[i], true);
setMatrix(v, ebs[i], true);
v.mvp.setAsUniform(s.uMVP);
}
/* draw roof */
GL.glUniform1i(s.uMode, 0);
GL.glDrawElements(GL20.GL_TRIANGLES,
el.idx[2],
GL20.GL_UNSIGNED_SHORT,
(el.idx[0]
+ el.idx[1]) * 2);
GL.glDrawElements(GL_TRIANGLES, eb.idx[2], GL_UNSIGNED_SHORT, eb.off[2]);
/* draw sides 1 */
GL.glUniform1i(s.uMode, 1);
GL.glDrawElements(GL20.GL_TRIANGLES,
el.idx[0],
GL20.GL_UNSIGNED_SHORT, 0);
GL.glDrawElements(GL_TRIANGLES, eb.idx[0], GL_UNSIGNED_SHORT, eb.off[0]);
/* draw sides 2 */
GL.glUniform1i(s.uMode, 2);
GL.glDrawElements(GL20.GL_TRIANGLES,
el.idx[1],
GL20.GL_UNSIGNED_SHORT,
el.idx[0] * 2);
GL.glDrawElements(GL_TRIANGLES, eb.idx[1], GL_UNSIGNED_SHORT, eb.off[1]);
if (mTranslucent) {
/* drawing gl_lines with the same coordinates does not
* result in same depth values as polygons, so add
* offset and draw gl_lequal: */
GL.glDepthFunc(GL20.GL_LEQUAL);
GL.glDepthFunc(GL_LEQUAL);
v.mvp.addDepthOffset(100);
v.mvp.setAsUniform(s.uMVP);
}
GL.glUniform1i(s.uMode, 3);
int offset = 2 * (el.indexOffset
+ el.idx[0] + el.idx[1]
+ el.idx[2]);
GL.glDrawElements(GL20.GL_LINES,
el.idx[3],
GL20.GL_UNSIGNED_SHORT,
offset);
GL.glDrawElements(GL_LINES, eb.idx[3], GL_UNSIGNED_SHORT, eb.off[3]);
}
/* draw triangle meshes */
if (el.idx[4] > 0) {
int offset = 2 * (el.indexOffset
+ el.idx[0] + el.idx[1]
+ el.idx[2] + el.idx[3]);
GL.glDrawElements(GL20.GL_TRIANGLES,
el.idx[4],
GL20.GL_UNSIGNED_SHORT,
offset);
if (eb.idx[4] > 0) {
GL.glDrawElements(GL_TRIANGLES, eb.idx[4], GL_UNSIGNED_SHORT, eb.off[4]);
}
}
/* just a temporary reference! */
els[i] = null;
ebs[i] = null;
}
if (!mTranslucent)
GL.glDepthMask(false);
if (v.pos.zoomLevel < 18)
GL.glDisable(GL20.GL_CULL_FACE);
GL.glDisable(GL_CULL_FACE);
}
private static void setMatrix(GLViewport v, ExtrusionBuckets l, boolean offset) {

View File

@ -44,10 +44,11 @@ public class OffscreenRenderer extends LayerRenderer {
public final Mode mode;
public OffscreenRenderer(Mode mode) {
public OffscreenRenderer(Mode mode, LayerRenderer renderer) {
this.mode = mode;
if (mode == Mode.SSAO || mode == Mode.SSAO_FXAA)
useDepthTexture = true;
setRenderer(renderer);
}
protected boolean setupFBO(GLViewport viewport) {

View File

@ -47,6 +47,8 @@ public class ExtrusionBucket extends RenderBucket {
/** indices for: 0. even sides, 1. odd sides, 2. roof, 3. roof outline */
public int idx[] = { 0, 0, 0, 0, 0 };
/** indices offsets in bytes */
public int off[] = { 0, 0, 0, 0, 0 };
//private final static int IND_EVEN_SIDE = 0;
//private final static int IND_ODD_SIDE = 1;
@ -60,8 +62,6 @@ public class ExtrusionBucket extends RenderBucket {
private KeyMap<Vertex> mVertexMap;
public int indexOffset;
//private static final int NORMAL_DIR_MASK = 0xFFFFFFFE;
//private int numIndexHits = 0;
@ -573,22 +573,24 @@ public class ExtrusionBucket extends RenderBucket {
if (numVertices == 0)
return;
indexOffset = iboData.position();
indiceOffset = iboData.position();
int iOffset = indiceOffset;
for (int i = 0; i <= IND_MESH; i++) {
if (mIndices[i] == null)
continue;
idx[i] += mIndices[i].compile(iboData);
if (mIndices[i] != null) {
idx[i] = mIndices[i].compile(iboData);
off[i] = iOffset * 2;
iOffset += idx[i];
}
}
vertexOffset = vboData.position() * 2;
vertexItems.compile(vboData);
clear();
}
@Override
protected void clear() {
public void clear() {
mClipper = null;
releaseVertexPool();

View File

@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
public class ExtrusionBuckets extends TileData {
static final Logger log = LoggerFactory.getLogger(ExtrusionBuckets.class);
public ExtrusionBucket layers;
public ExtrusionBucket buckets;
public boolean compiled;
@ -34,20 +34,20 @@ public class ExtrusionBuckets extends TileData {
/**
* Set new ExtrusionLayers and clear previous.
*/
public void setLayers(ExtrusionBucket el) {
for (RenderBucket l = layers; l != null; l = l.next)
l.clear();
public void setBuckets(ExtrusionBucket el) {
for (RenderBucket b = buckets; b != null; b = b.next)
b.clear();
layers = el;
buckets = el;
}
public ExtrusionBucket getLayers() {
return layers;
public ExtrusionBucket buckets() {
return buckets;
}
@Override
protected void dispose() {
setLayers(null);
setBuckets(null);
if (compiled) {
ibo = BufferObject.release(ibo);
@ -57,21 +57,21 @@ public class ExtrusionBuckets extends TileData {
}
public void prepare() {
for (RenderBucket l = layers; l != null; l = l.next)
l.prepare();
for (RenderBucket b = buckets; b != null; b = b.next)
b.prepare();
}
public boolean compileLayers() {
public boolean compile() {
if (layers == null)
if (buckets == null)
return false;
int sumIndices = 0;
int sumVertices = 0;
for (ExtrusionBucket l = layers; l != null; l = l.next()) {
sumIndices += l.numIndices;
sumVertices += l.numVertices;
for (ExtrusionBucket b = buckets; b != null; b = b.next()) {
sumIndices += b.numIndices;
sumVertices += b.numVertices;
}
if (sumIndices == 0)
return false;
@ -79,9 +79,9 @@ public class ExtrusionBuckets extends TileData {
ShortBuffer vboData = MapRenderer.getShortBuffer(sumVertices * 4);
ShortBuffer iboData = MapRenderer.getShortBuffer(sumIndices);
for (ExtrusionBucket l = layers; l != null; l = l.next()) {
l.compile(vboData, iboData);
}
for (ExtrusionBucket b = buckets; b != null; b = b.next())
b.compile(vboData, iboData);
int size = sumIndices * 2;
if (iboData.position() != sumIndices) {
int pos = iboData.position();
@ -90,7 +90,6 @@ public class ExtrusionBuckets extends TileData {
}
ibo = BufferObject.get(GL20.GL_ELEMENT_ARRAY_BUFFER, size);
ibo.loadBufferData(iboData.flip(), size);
ibo.unbind();
size = sumVertices * 4 * 2;
if (vboData.position() != sumVertices * 4) {
@ -101,7 +100,6 @@ public class ExtrusionBuckets extends TileData {
vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, size);
vbo.loadBufferData(vboData.flip(), size);
vbo.unbind();
compiled = true;