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:
parent
84c094000b
commit
e32f45b585
@ -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() {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user