more work on building layer
This commit is contained in:
parent
74ca621de0
commit
eb278585fa
@ -53,9 +53,10 @@ public interface IMapDatabaseCallback {
|
|||||||
* length of way data in wayNodes
|
* length of way data in wayNodes
|
||||||
* @param closed
|
* @param closed
|
||||||
* way is closed (means need to add endpoint == startpoint)
|
* way is closed (means need to add endpoint == startpoint)
|
||||||
|
* @param prio TODO
|
||||||
*/
|
*/
|
||||||
void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLength,
|
void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLength,
|
||||||
boolean closed);
|
boolean closed, int prio);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TBD: check if way will be rendered before decoding
|
* TBD: check if way will be rendered before decoding
|
||||||
|
@ -961,7 +961,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
&& mWayNodes[1] == mWayNodes[l - 1];
|
&& mWayNodes[1] == mWayNodes[l - 1];
|
||||||
|
|
||||||
mapDatabaseCallback
|
mapDatabaseCallback
|
||||||
.renderWay(layer, tags, mWayNodes, wayLengths, closed);
|
.renderWay(layer, tags, mWayNodes, wayLengths, closed, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
private static final int TAG_ELEM_INDEX = 12;
|
private static final int TAG_ELEM_INDEX = 12;
|
||||||
private static final int TAG_ELEM_COORDS = 13;
|
private static final int TAG_ELEM_COORDS = 13;
|
||||||
private static final int TAG_ELEM_LAYER = 21;
|
private static final int TAG_ELEM_LAYER = 21;
|
||||||
// private static final int TAG_ELEM_PRIORITY = 31;
|
private static final int TAG_ELEM_PRIORITY = 31;
|
||||||
|
|
||||||
private short[] mTmpKeys = new short[100];
|
private short[] mTmpKeys = new short[100];
|
||||||
private short[] mIndices = new short[10];
|
private short[] mIndices = new short[10];
|
||||||
@ -376,6 +376,8 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
int indexCnt = 1;
|
int indexCnt = 1;
|
||||||
int coordCnt = 0;
|
int coordCnt = 0;
|
||||||
int layer = 5;
|
int layer = 5;
|
||||||
|
int prio = 0;
|
||||||
|
|
||||||
Tag[] tags = null;
|
Tag[] tags = null;
|
||||||
short[] index = null;
|
short[] index = null;
|
||||||
|
|
||||||
@ -441,6 +443,10 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
layer = decodeVarint32();
|
layer = decodeVarint32();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TAG_ELEM_PRIORITY:
|
||||||
|
prio = decodeVarint32();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log.d(TAG, "X invalid type for way: " + tag);
|
Log.d(TAG, "X invalid type for way: " + tag);
|
||||||
}
|
}
|
||||||
@ -457,9 +463,9 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
float[] coords = mTmpCoords;
|
float[] coords = mTmpCoords;
|
||||||
|
|
||||||
if (type == TAG_TILE_LINE)
|
if (type == TAG_TILE_LINE)
|
||||||
mMapGenerator.renderWay((byte) layer, tags, coords, index, false);
|
mMapGenerator.renderWay((byte) layer, tags, coords, index, false, prio);
|
||||||
else if (type == TAG_TILE_POLY)
|
else if (type == TAG_TILE_POLY)
|
||||||
mMapGenerator.renderWay((byte) layer, tags, coords, index, true);
|
mMapGenerator.renderWay((byte) layer, tags, coords, index, true, prio);
|
||||||
else {
|
else {
|
||||||
if (debug)
|
if (debug)
|
||||||
Log.d(TAG, "add poi " + coords[1] + " " + coords[0] + " " + tags[0]);
|
Log.d(TAG, "add poi " + coords[1] + " " + coords[0] + " " + tags[0]);
|
||||||
|
@ -556,7 +556,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
if (layer == 0)
|
if (layer == 0)
|
||||||
layer = 5;
|
layer = 5;
|
||||||
|
|
||||||
mMapGenerator.renderWay((byte) layer, tags, coords, index, polygon);
|
mMapGenerator.renderWay((byte) layer, tags, coords, index, polygon, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
|
|
||||||
short[] idx = new short[mIndexPos];
|
short[] idx = new short[mIndexPos];
|
||||||
System.arraycopy(mIndex, 0, idx, 0, mIndexPos);
|
System.arraycopy(mIndex, 0, idx, 0, mIndexPos);
|
||||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, idx, polygon);
|
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, idx, polygon, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
@ -100,7 +100,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
mIndex[2] = 10;
|
mIndex[2] = 10;
|
||||||
mIndex[3] = 0;
|
mIndex[3] = 0;
|
||||||
|
|
||||||
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true);
|
mapDatabaseCallback.renderWay((byte) 0, mTags, mCoords, mIndex, true, 0);
|
||||||
|
|
||||||
mIndex[0] = 4;
|
mIndex[0] = 4;
|
||||||
mIndex[1] = -1;
|
mIndex[1] = -1;
|
||||||
@ -113,7 +113,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
Tag[] tags = new Tag[2];
|
Tag[] tags = new Tag[2];
|
||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex, false);
|
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex, false, 0);
|
||||||
|
|
||||||
// center up
|
// center up
|
||||||
mCoords[0] = size / 2;
|
mCoords[0] = size / 2;
|
||||||
@ -124,7 +124,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex,
|
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex,
|
||||||
false);
|
false, 0);
|
||||||
|
|
||||||
// center down
|
// center down
|
||||||
mCoords[0] = size / 2;
|
mCoords[0] = size / 2;
|
||||||
@ -134,7 +134,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tags = new Tag[2];
|
tags = new Tag[2];
|
||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex, false);
|
mapDatabaseCallback.renderWay((byte) 0, tags, mCoords, mIndex, false, 0);
|
||||||
|
|
||||||
// left-top to center
|
// left-top to center
|
||||||
mCoords[0] = size / 2;
|
mCoords[0] = size / 2;
|
||||||
@ -144,7 +144,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tags = new Tag[2];
|
tags = new Tag[2];
|
||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false);
|
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false, 0);
|
||||||
|
|
||||||
// middle horizontal
|
// middle horizontal
|
||||||
mCoords[0] = 0;
|
mCoords[0] = 0;
|
||||||
@ -154,7 +154,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tags = new Tag[2];
|
tags = new Tag[2];
|
||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false);
|
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false, 0);
|
||||||
|
|
||||||
// middle horizontal
|
// middle horizontal
|
||||||
mCoords[0] = 10;
|
mCoords[0] = 10;
|
||||||
@ -164,7 +164,7 @@ public class MapDatabase implements IMapDatabase {
|
|||||||
tags = new Tag[2];
|
tags = new Tag[2];
|
||||||
tags[0] = mTagsWay[0];
|
tags[0] = mTagsWay[0];
|
||||||
tags[1] = mTagsWay[1];
|
tags[1] = mTagsWay[1];
|
||||||
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false);
|
mapDatabaseCallback.renderWay((byte) 1, tags, mCoords, mIndex, false, 0);
|
||||||
|
|
||||||
// lon1 = size / 2;
|
// lon1 = size / 2;
|
||||||
// lat1 = size / 2;
|
// lat1 = size / 2;
|
||||||
|
@ -24,6 +24,7 @@ import org.oscim.database.IMapDatabaseCallback;
|
|||||||
import org.oscim.database.QueryResult;
|
import org.oscim.database.QueryResult;
|
||||||
import org.oscim.renderer.MapTile;
|
import org.oscim.renderer.MapTile;
|
||||||
import org.oscim.renderer.WayDecorator;
|
import org.oscim.renderer.WayDecorator;
|
||||||
|
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||||
import org.oscim.renderer.layer.Layer;
|
import org.oscim.renderer.layer.Layer;
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.layer.LineLayer;
|
import org.oscim.renderer.layer.LineLayer;
|
||||||
@ -103,6 +104,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
private float mProjectionScaleFactor;
|
private float mProjectionScaleFactor;
|
||||||
|
|
||||||
private float mPoiX, mPoiY;
|
private float mPoiX, mPoiY;
|
||||||
|
private int mPriority;
|
||||||
|
|
||||||
private Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
private Tag mTagEmptyName = new Tag(Tag.TAG_KEY_NAME, null, false);
|
||||||
private Tag mTagName;
|
private Tag mTagName;
|
||||||
@ -159,6 +161,14 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
|
|
||||||
mLayers = new Layers();
|
mLayers = new Layers();
|
||||||
|
|
||||||
|
//Log.d(TAG, "loading: " + tile);
|
||||||
|
//if ((tile.zoomLevel != 17) || (tile.tileX == 68752 && tile.tileY == 42640))
|
||||||
|
//if ((tile.zoomLevel != 17) || (tile.tileX == 68743 && tile.tileY == 42681))
|
||||||
|
//if ((tile.zoomLevel != 17) || (tile.tileX == 68736 && tile.tileY == 42653))
|
||||||
|
// TODO: building with non simple holes (Berlin):
|
||||||
|
//if ((tile.zoomLevel != 17) || (tile.tileX == 70428 && tile.tileY == 43009)),
|
||||||
|
//if ((tile.zoomLevel != 17) || (tile.tileX == 70463 && tile.tileY == 42990))
|
||||||
|
|
||||||
if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
|
if (mMapDatabase.executeQuery(tile, this) != QueryResult.SUCCESS) {
|
||||||
//Log.d(TAG, "Failed loading: " + tile);
|
//Log.d(TAG, "Failed loading: " + tile);
|
||||||
mLayers.clear();
|
mLayers.clear();
|
||||||
@ -188,6 +198,9 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
mLayers = null;
|
mLayers = null;
|
||||||
mLabels = null;
|
mLabels = null;
|
||||||
|
|
||||||
|
if (tile.layers.extrusionLayers != null)
|
||||||
|
((ExtrusionLayer) tile.layers.extrusionLayers).ready = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,16 +239,19 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
return mMapDatabase;
|
return mMapDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean mRenderBuildingModel;
|
||||||
|
|
||||||
private boolean filterTags(Tag[] tags) {
|
private boolean filterTags(Tag[] tags) {
|
||||||
|
mRenderBuildingModel = false;
|
||||||
|
|
||||||
for (int i = 0; i < tags.length; i++) {
|
for (int i = 0; i < tags.length; i++) {
|
||||||
String key = tags[i].key;
|
String key = tags[i].key;
|
||||||
if (key == Tag.TAG_KEY_NAME) {
|
if (tags[i].key == Tag.TAG_KEY_NAME) {
|
||||||
mTagName = tags[i];
|
mTagName = tags[i];
|
||||||
tags[i] = mTagEmptyName;
|
tags[i] = mTagEmptyName;
|
||||||
} else if (mCurrentTile.zoomLevel >= 17 &&
|
} else if (mCurrentTile.zoomLevel >= 17 &&
|
||||||
key == TAG_BUILDING) {
|
key == TAG_BUILDING) {
|
||||||
|
mRenderBuildingModel = true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -292,20 +308,19 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderWay(byte layer, Tag[] tags, float[] coords, short[] indices,
|
public void renderWay(byte layer, Tag[] tags, float[] coords, short[] indices,
|
||||||
boolean closed) {
|
boolean closed, int prio) {
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
mTagName = null;
|
mTagName = null;
|
||||||
mCurLineLayer = null;
|
mCurLineLayer = null;
|
||||||
|
|
||||||
|
mPriority = prio;
|
||||||
mClosed = closed;
|
mClosed = closed;
|
||||||
|
|
||||||
// replace tags that should not be cached in Rendertheme (e.g. name)
|
// replace tags that should not be cached in Rendertheme (e.g. name)
|
||||||
if (!filterTags(tags))
|
if (!filterTags(tags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mDrawingLayer = getValidLayer(layer) * mLevels;
|
|
||||||
|
|
||||||
// mProjected = false;
|
// mProjected = false;
|
||||||
// mSimplify = 0.5f;
|
// mSimplify = 0.5f;
|
||||||
// if (closed) {
|
// if (closed) {
|
||||||
@ -317,6 +332,7 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
// mSimplify = 0;
|
// mSimplify = 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
mDrawingLayer = getValidLayer(layer) * mLevels;
|
||||||
mCoords = coords;
|
mCoords = coords;
|
||||||
mIndices = indices;
|
mIndices = indices;
|
||||||
|
|
||||||
@ -394,14 +410,24 @@ public class TileGenerator implements IRenderCallback, IMapDatabaseCallback {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderArea(Area area, int level) {
|
public void renderArea(Area area, int level) {
|
||||||
|
int numLayer = mDrawingLayer + level;
|
||||||
|
|
||||||
|
if (mRenderBuildingModel) {
|
||||||
|
//Log.d(TAG, "add buildings: " + mCurrentTile + " " + mPriority);
|
||||||
|
if (mLayers.extrusionLayers == null)
|
||||||
|
mLayers.extrusionLayers = new ExtrusionLayer(0);
|
||||||
|
|
||||||
|
((ExtrusionLayer) mLayers.extrusionLayers).addBuildings(mCoords, mIndices, mPriority);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mDebugDrawPolygons)
|
if (!mDebugDrawPolygons)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if (!mProjected && !projectToTile())
|
// if (!mProjected && !projectToTile())
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
int numLayer = mDrawingLayer + level;
|
|
||||||
|
|
||||||
PolygonLayer layer = (PolygonLayer) mLayers.getLayer(numLayer, Layer.POLYGON);
|
PolygonLayer layer = (PolygonLayer) mLayers.getLayer(numLayer, Layer.POLYGON);
|
||||||
if (layer == null)
|
if (layer == null)
|
||||||
return;
|
return;
|
||||||
|
@ -89,8 +89,7 @@ public final class TextureRenderer {
|
|||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Layer draw(Layer layer, float scale, float[] projection,
|
public static Layer draw(Layer layer, float scale, float[] projection, float matrix[]) {
|
||||||
float matrix[], int offset) {
|
|
||||||
|
|
||||||
// GlUtils.checkGlError("draw texture >");
|
// GlUtils.checkGlError("draw texture >");
|
||||||
GLES20.glUseProgram(mTextureProgram);
|
GLES20.glUseProgram(mTextureProgram);
|
||||||
@ -121,7 +120,7 @@ public final class TextureRenderer {
|
|||||||
// can only draw MAX_ITEMS in each iteration
|
// can only draw MAX_ITEMS in each iteration
|
||||||
for (int i = 0; i < to.vertices; i += maxVertices) {
|
for (int i = 0; i < to.vertices; i += maxVertices) {
|
||||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
int off = (to.offset + i) * 8 + offset;
|
int off = (to.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hTextureVertex, 4,
|
GLES20.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
GLES20.GL_SHORT, false, 12, off);
|
GLES20.GL_SHORT, false, 12, off);
|
||||||
|
@ -35,6 +35,9 @@ import android.util.Log;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
|
* @TODO
|
||||||
|
* - this class should probably not be in 'renderer' -> tilemap?
|
||||||
|
* - make it general for reuse in tile-overlays
|
||||||
*/
|
*/
|
||||||
public class TileManager {
|
public class TileManager {
|
||||||
static final String TAG = TileManager.class.getSimpleName();
|
static final String TAG = TileManager.class.getSimpleName();
|
||||||
|
475
src/org/oscim/renderer/layer/ExtrusionLayer.java
Normal file
475
src/org/oscim/renderer/layer/ExtrusionLayer.java
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, 2013 OpenScienceMap
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.layer;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
import org.quake.triangle.TriangleJNI;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public class ExtrusionLayer extends Layer {
|
||||||
|
private final static String TAG = ExtrusionLayer.class.getName();
|
||||||
|
private static final float S = GLRenderer.COORD_MULTIPLIER;
|
||||||
|
public int mIndicesBufferID;
|
||||||
|
public int mVertexBufferID;
|
||||||
|
public int mNumIndices = 0;
|
||||||
|
private int mNumVertices = 0;
|
||||||
|
private VertexPoolItem mVertices, mCurVertices;
|
||||||
|
private VertexPoolItem mIndices[], mCurIndices[];
|
||||||
|
|
||||||
|
public int mIndiceCnt[] = { 0, 0, 0 };
|
||||||
|
|
||||||
|
public ExtrusionLayer(int level) {
|
||||||
|
this.type = Layer.EXTRUSION;
|
||||||
|
this.layer = level;
|
||||||
|
|
||||||
|
mVertices = mCurVertices = VertexPool.get();
|
||||||
|
mIndices = new VertexPoolItem[3];
|
||||||
|
mCurIndices = new VertexPoolItem[3];
|
||||||
|
mIndices[0] = mCurIndices[0] = VertexPool.get();
|
||||||
|
mIndices[1] = mCurIndices[1] = VertexPool.get();
|
||||||
|
mIndices[2] = mCurIndices[2] = VertexPool.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBuildings(float[] points, short[] index, int height) {
|
||||||
|
int complex = 0;
|
||||||
|
boolean simple = true;
|
||||||
|
|
||||||
|
if (height == 0)
|
||||||
|
height = 400;
|
||||||
|
else
|
||||||
|
height *= 40;
|
||||||
|
|
||||||
|
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
||||||
|
int length = index[i];
|
||||||
|
|
||||||
|
// end marker
|
||||||
|
if (length < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// start next polygon
|
||||||
|
if (length == 0) {
|
||||||
|
complex = i + 1;
|
||||||
|
simple = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// need at least three points
|
||||||
|
if (length < 6) {
|
||||||
|
pos += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if polygon contains inner rings
|
||||||
|
//if (simple && ((i < n - 1) && (index[i + 1] > 0)))
|
||||||
|
// simple = false;
|
||||||
|
|
||||||
|
addOutline(points, pos, length, height, simple);
|
||||||
|
pos += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addOutline(float[] points, int pos, int len, float height, boolean simple) {
|
||||||
|
if (!MapView.enableClosePolygons)
|
||||||
|
len -= 2;
|
||||||
|
|
||||||
|
// add two vertices for last face to make zigzag indices work
|
||||||
|
boolean addFace = (len % 4 != 0);
|
||||||
|
|
||||||
|
// Log.d(TAG, "add: " + addFace + " " + len + " (" + pos + ")");
|
||||||
|
|
||||||
|
int vertexCnt = len + (addFace ? 2 : 0);
|
||||||
|
int indicesCnt = (len >> 1) * 6;
|
||||||
|
|
||||||
|
short h = (short) height;
|
||||||
|
|
||||||
|
float cx = points[pos + len - 2];
|
||||||
|
float cy = points[pos + len - 1];
|
||||||
|
float nx = points[pos + 0];
|
||||||
|
float ny = points[pos + 1];
|
||||||
|
|
||||||
|
float vx = nx - cx;
|
||||||
|
float vy = ny - cy;
|
||||||
|
float ca = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
float pa = ca;
|
||||||
|
float ux = vx;
|
||||||
|
float uy = vy;
|
||||||
|
|
||||||
|
float vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f;
|
||||||
|
|
||||||
|
short color1 = (short) (200 + (50 * vlight));
|
||||||
|
short fcolor = color1;
|
||||||
|
short color2 = 0;
|
||||||
|
|
||||||
|
boolean even = true;
|
||||||
|
|
||||||
|
short[] vertices = mCurVertices.vertices;
|
||||||
|
int v = mCurVertices.used;
|
||||||
|
|
||||||
|
int convex = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i += 2, v += 8) {
|
||||||
|
cx = nx;
|
||||||
|
cy = ny;
|
||||||
|
|
||||||
|
if (v == VertexPoolItem.SIZE) {
|
||||||
|
mCurVertices.used = VertexPoolItem.SIZE;
|
||||||
|
mCurVertices.next = VertexPool.get();
|
||||||
|
mCurVertices = mCurVertices.next;
|
||||||
|
vertices = mCurVertices.vertices;
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertices[v + 0] = vertices[v + 4] = (short) (cx * S);
|
||||||
|
vertices[v + 1] = vertices[v + 5] = (short) (cy * S);
|
||||||
|
|
||||||
|
vertices[v + 2] = 0;
|
||||||
|
vertices[v + 6] = h;
|
||||||
|
|
||||||
|
if (i < len - 2) {
|
||||||
|
nx = points[pos + i + 2];
|
||||||
|
ny = points[pos + i + 3];
|
||||||
|
|
||||||
|
vx = nx - cx;
|
||||||
|
vy = ny - cy;
|
||||||
|
ca = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
|
if (convex > -1) {
|
||||||
|
// TODO fix for straight line...
|
||||||
|
double dir = (vx * ux + vy * uy) / (ca * pa);
|
||||||
|
|
||||||
|
if (convex == 0)
|
||||||
|
convex = dir > 0 ? 1 : 2;
|
||||||
|
else if (convex == 1)
|
||||||
|
convex = dir > 0 ? 1 : -1;
|
||||||
|
else
|
||||||
|
convex = dir > 0 ? -1 : 2;
|
||||||
|
}
|
||||||
|
vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f;
|
||||||
|
color2 = (short) (200 + (50 * vlight));
|
||||||
|
} else {
|
||||||
|
color2 = fcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
short c;
|
||||||
|
if (even)
|
||||||
|
c = (short) (color1 | color2 << 8);
|
||||||
|
else
|
||||||
|
c = (short) (color2 | color1 << 8);
|
||||||
|
|
||||||
|
vertices[v + 3] = vertices[v + 7] = c;
|
||||||
|
|
||||||
|
pa = ca;
|
||||||
|
ux = vx;
|
||||||
|
uy = vy;
|
||||||
|
color1 = color2;
|
||||||
|
even = !even;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addFace) {
|
||||||
|
if (v == VertexPoolItem.SIZE) {
|
||||||
|
mCurVertices.used = VertexPoolItem.SIZE;
|
||||||
|
mCurVertices.next = VertexPool.get();
|
||||||
|
mCurVertices = mCurVertices.next;
|
||||||
|
vertices = mCurVertices.vertices;
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx = points[pos + 0];
|
||||||
|
cy = points[pos + 1];
|
||||||
|
|
||||||
|
vertices[v + 0] = vertices[v + 4] = (short) (cx * S);
|
||||||
|
vertices[v + 1] = vertices[v + 5] = (short) (cy * S);
|
||||||
|
|
||||||
|
vertices[v + 2] = 0;
|
||||||
|
vertices[v + 6] = h;
|
||||||
|
|
||||||
|
short c = (short) (color1 | fcolor << 8);
|
||||||
|
vertices[v + 3] = vertices[v + 7] = c;
|
||||||
|
|
||||||
|
v += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurVertices.used = v;
|
||||||
|
|
||||||
|
// fill ZigZagQuadIndices(tm)
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
short[] indices = mCurIndices[j].vertices;
|
||||||
|
|
||||||
|
// index id relative to mCurIndices
|
||||||
|
int i = mCurIndices[j].used;
|
||||||
|
|
||||||
|
// vertex id
|
||||||
|
v = mNumVertices + (j * 2);
|
||||||
|
|
||||||
|
for (int k = j * 2; k < len; k += 4) {
|
||||||
|
short s0 = (short) (v++);
|
||||||
|
short s1 = (short) (v++);
|
||||||
|
short s2 = (short) (v++);
|
||||||
|
short s3 = (short) (v++);
|
||||||
|
|
||||||
|
if (i == VertexPoolItem.SIZE) {
|
||||||
|
mCurIndices[j].used = VertexPoolItem.SIZE;
|
||||||
|
mCurIndices[j].next = VertexPool.get();
|
||||||
|
mCurIndices[j] = mCurIndices[j].next;
|
||||||
|
indices = mCurIndices[j].vertices;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k + 2 == len) {
|
||||||
|
// connect last to first (when number of faces is even)
|
||||||
|
if (!addFace) {
|
||||||
|
//Log.d(TAG, "connect last " + vertexCnt + " " + len);
|
||||||
|
s2 -= len;
|
||||||
|
s3 -= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
indices[i++] = s0;
|
||||||
|
indices[i++] = s1;
|
||||||
|
indices[i++] = s2;
|
||||||
|
|
||||||
|
indices[i++] = s1;
|
||||||
|
indices[i++] = s3;
|
||||||
|
indices[i++] = s2;
|
||||||
|
//System.out.println(" i:" + (mNumIndices + (k * 6))
|
||||||
|
// + "\t(" + s0 + "," + s1 + "," + s2
|
||||||
|
// + ")\t(" + s1 + "," + s3 + "," + s2 + ")");
|
||||||
|
}
|
||||||
|
mCurIndices[j].used = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simple && (len <= 8 || convex > 0)) {
|
||||||
|
//Log.d(TAG, len + " is simple " + convex);
|
||||||
|
|
||||||
|
// roof indices for convex shapes
|
||||||
|
int i = mCurIndices[2].used;
|
||||||
|
short[] indices = mCurIndices[2].vertices;
|
||||||
|
short first = (short) (mNumVertices + 1);
|
||||||
|
|
||||||
|
for (int k = 0; k < len - 4; k += 2) {
|
||||||
|
if (i == VertexPoolItem.SIZE) {
|
||||||
|
mCurIndices[2].used = VertexPoolItem.SIZE;
|
||||||
|
mCurIndices[2].next = VertexPool.get();
|
||||||
|
mCurIndices[2] = mCurIndices[2].next;
|
||||||
|
indices = mCurIndices[2].vertices;
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
indices[i++] = first;
|
||||||
|
//if (convex != 2) {
|
||||||
|
// cw ?
|
||||||
|
indices[i++] = (short) (first + k + 4);
|
||||||
|
indices[i++] = (short) (first + k + 2);
|
||||||
|
// } else {
|
||||||
|
// indices[i++] = (short) (first + k + 2);
|
||||||
|
// indices[i++] = (short) (first + k + 4);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// System.out.println("indice:" + k + "\t" + indices[cnt - 3] + ","
|
||||||
|
// + indices[cnt - 2]+ "," + indices[cnt - 1]);
|
||||||
|
|
||||||
|
indicesCnt += 3;
|
||||||
|
}
|
||||||
|
mCurIndices[2].used = i;
|
||||||
|
} else if (len < 400) {
|
||||||
|
// triangulate up to 200 points
|
||||||
|
short first = (short) (mNumVertices + 1);
|
||||||
|
int used = triangulate(points, pos, len, mCurIndices[2], first);
|
||||||
|
if (used > 0) {
|
||||||
|
indicesCnt += used;
|
||||||
|
// find the last item added..
|
||||||
|
VertexPoolItem it = mIndices[2];
|
||||||
|
while (it.next != null)
|
||||||
|
it = it.next;
|
||||||
|
mCurIndices[2] = it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mCurIndices[2].next = VertexPool.get();
|
||||||
|
// mCurIndices[2] = mCurIndices[2].next;
|
||||||
|
// short[] indices = mCurIndices[2].vertices;
|
||||||
|
// int used = triangulate(points, pos, len, indices);
|
||||||
|
// if (used > 0) {
|
||||||
|
// short first = (short) (mNumVertices + 1);
|
||||||
|
// for (int i = 0; i < used; i += 3) {
|
||||||
|
// indices[i] = (short) (indices[i] * 2 + first);
|
||||||
|
// short tmp = indices[i + 1];
|
||||||
|
// indices[i + 1] = (short) (indices[i + 2] * 2 + first);
|
||||||
|
// indices[i + 2] = (short) (tmp * 2 + first);
|
||||||
|
// }
|
||||||
|
// mCurIndices[2].used = used;
|
||||||
|
// indicesCnt += used;
|
||||||
|
// }
|
||||||
|
} else
|
||||||
|
Log.d(TAG, "skip >>>>>>>>>> : " + len + " <<<<<<<<<<<<<");
|
||||||
|
|
||||||
|
//Log.d(TAG, "add building: " + vertexCnt);
|
||||||
|
mNumVertices += vertexCnt;
|
||||||
|
mNumIndices += indicesCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void compile(ShortBuffer sbuf) {
|
||||||
|
|
||||||
|
if (mNumVertices == 0 || compiled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mVboIds = new int[2];
|
||||||
|
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||||
|
mIndicesBufferID = mVboIds[0];
|
||||||
|
mVertexBufferID = mVboIds[1];
|
||||||
|
|
||||||
|
// upload indices
|
||||||
|
|
||||||
|
sbuf.clear();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (VertexPoolItem vi = mIndices[i]; vi != null; vi = vi.next) {
|
||||||
|
//System.out.println("put indices: " + vi.used + " " + mNumIndices);
|
||||||
|
sbuf.put(vi.vertices, 0, vi.used);
|
||||||
|
mIndiceCnt[i] += vi.used;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log.d(TAG,"put indices: " + mNumIndices + "=="
|
||||||
|
// + (mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2])
|
||||||
|
// + " " + mIndiceCnt[0] + " " + mIndiceCnt[1] + " " + mIndiceCnt[2]);
|
||||||
|
|
||||||
|
mNumIndices = mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2];
|
||||||
|
|
||||||
|
sbuf.flip();
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||||
|
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
mNumIndices * 2, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
sbuf.clear();
|
||||||
|
|
||||||
|
// upload vertices
|
||||||
|
for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) {
|
||||||
|
//System.out.println("put vertices: " + vi.used + " " + mNumVertices);
|
||||||
|
sbuf.put(vi.vertices, 0, vi.used);
|
||||||
|
}
|
||||||
|
|
||||||
|
sbuf.flip();
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||||
|
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
|
||||||
|
mNumVertices * 4 * 2, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
for (VertexPoolItem i : mIndices)
|
||||||
|
VertexPool.release(i);
|
||||||
|
|
||||||
|
VertexPool.release(mVertices);
|
||||||
|
|
||||||
|
compiled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean compiled = false;
|
||||||
|
|
||||||
|
int[] mVboIds;
|
||||||
|
|
||||||
|
public boolean ready;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clear() {
|
||||||
|
if (compiled) {
|
||||||
|
GLES20.glDeleteBuffers(2, mVboIds, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean initialized = false;
|
||||||
|
private static ShortBuffer sBuf;
|
||||||
|
private static FloatBuffer fBuf;
|
||||||
|
|
||||||
|
public static synchronized int triangulate(float[] points, int pos, int len,
|
||||||
|
VertexPoolItem item, int first) {
|
||||||
|
|
||||||
|
int numRings = 1;
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
// FIXME also cleanup on shutdown!
|
||||||
|
fBuf = ByteBuffer.allocateDirect(360 * 4).order(ByteOrder.nativeOrder())
|
||||||
|
.asFloatBuffer();
|
||||||
|
|
||||||
|
sBuf = ByteBuffer.allocateDirect(720 * 2).order(ByteOrder.nativeOrder())
|
||||||
|
.asShortBuffer();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fBuf.clear();
|
||||||
|
fBuf.put(points, pos, len);
|
||||||
|
|
||||||
|
sBuf.clear();
|
||||||
|
sBuf.put((short) (len >> 1)); // all points
|
||||||
|
sBuf.put((short) (len >> 1)); // outer ring
|
||||||
|
//sBuf.put((short)4); // inner ring
|
||||||
|
|
||||||
|
int numTris = TriangleJNI.triangulate(fBuf, numRings, sBuf, first);
|
||||||
|
|
||||||
|
int numIndices = numTris * 3;
|
||||||
|
sBuf.limit(numIndices);
|
||||||
|
sBuf.position(0);
|
||||||
|
|
||||||
|
for (int k = 0, cnt = 0; k < numIndices; k += cnt) {
|
||||||
|
cnt = VertexPoolItem.SIZE - item.used;
|
||||||
|
|
||||||
|
if (item.used == VertexPoolItem.SIZE) {
|
||||||
|
item.next = VertexPool.get();
|
||||||
|
item = item.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k + cnt > numIndices)
|
||||||
|
cnt = numIndices - k;
|
||||||
|
|
||||||
|
sBuf.get(item.vertices, item.used, cnt);
|
||||||
|
item.used += cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sBuf.get(sIndices, 0, numIndices);
|
||||||
|
//
|
||||||
|
// short[] indices = item.vertices;
|
||||||
|
// int i = item.used;
|
||||||
|
//
|
||||||
|
// for (int k = 0; k < numIndices; k += 3) {
|
||||||
|
// if (i == VertexPoolItem.SIZE) {
|
||||||
|
// item.used = VertexPoolItem.SIZE;
|
||||||
|
// item.next = VertexPool.get();
|
||||||
|
// item = item.next;
|
||||||
|
// indices = item.vertices;
|
||||||
|
// i = 0;
|
||||||
|
// }
|
||||||
|
// indices[i++] = sIndices[k + 0];
|
||||||
|
// indices[i++] = sIndices[k + 1];
|
||||||
|
// indices[i++] = sIndices[k + 2];
|
||||||
|
// }
|
||||||
|
// item.used = i;
|
||||||
|
|
||||||
|
return numIndices;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Hannes Janetzek
|
* Copyright 2012, 2013 OpenScienceMap
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@ -14,6 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layer;
|
package org.oscim.renderer.layer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @authorHannes Janetzek
|
||||||
|
*/
|
||||||
public abstract class Layer {
|
public abstract class Layer {
|
||||||
public final static byte LINE = 0;
|
public final static byte LINE = 0;
|
||||||
public final static byte POLYGON = 1;
|
public final static byte POLYGON = 1;
|
||||||
@ -21,15 +24,21 @@ public abstract class Layer {
|
|||||||
public final static byte POITEXT = 3;
|
public final static byte POITEXT = 3;
|
||||||
public final static byte SYMBOL = 4;
|
public final static byte SYMBOL = 4;
|
||||||
public final static byte BITMAP = 5;
|
public final static byte BITMAP = 5;
|
||||||
|
public final static byte TEXLINE = 6;
|
||||||
|
public final static byte EXTRUSION = 7;
|
||||||
|
|
||||||
public byte type;
|
public byte type = -1;
|
||||||
|
|
||||||
public Layer next;
|
public Layer next;
|
||||||
|
|
||||||
int layer;
|
int layer;
|
||||||
// number of vertices this layer holds
|
// number of vertices for this layer
|
||||||
public int verticesCnt;
|
public int verticesCnt;
|
||||||
// vertices offset of this layer in VBO
|
|
||||||
|
// in case of line and polygon layer:
|
||||||
|
// - number of VERTICES offset for this layertype in VBO
|
||||||
|
// otherwise:
|
||||||
|
// - offset in byte in VBO
|
||||||
public int offset;
|
public int offset;
|
||||||
|
|
||||||
VertexPoolItem pool;
|
VertexPoolItem pool;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Hannes Janetzek
|
* Copyright 2012, 2013 OpenScienceMap
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
@ -18,13 +18,22 @@ import java.nio.ShortBuffer;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
public class Layers {
|
public class Layers {
|
||||||
|
|
||||||
|
// mixed Polygon and Line layers
|
||||||
public Layer layers;
|
public Layer layers;
|
||||||
public int lineOffset;
|
|
||||||
|
|
||||||
public Layer textureLayers;
|
public Layer textureLayers;
|
||||||
public int texOffset;
|
public Layer extrusionLayers;
|
||||||
|
|
||||||
|
// To not need to switch VertexAttribPointer positions all the time:
|
||||||
|
// 1. polygons are packed in VBO at offset 0
|
||||||
|
// 2. lines afterwards at lineOffset
|
||||||
|
// 3. other layers keep their byte offset in Layer.offset
|
||||||
|
public int lineOffset;
|
||||||
|
|
||||||
private Layer mCurLayer;
|
private Layer mCurLayer;
|
||||||
|
|
||||||
@ -78,10 +87,78 @@ public class Layers {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public boolean uploadLayers(BufferObject vbo, boolean addFill, boolean limit) {
|
||||||
|
//
|
||||||
|
// int newSize = getSize();
|
||||||
|
// if (newSize == 0) {
|
||||||
|
// // Log.d(TAG, "empty");
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// GLES20.glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
|
||||||
|
//
|
||||||
|
// // use multiple buffers to avoid overwriting buffer while current
|
||||||
|
// // data is uploaded (or rather the blocking which is probably done to
|
||||||
|
// // avoid overwriting)
|
||||||
|
// int curBuffer = uploadCnt++ % rotateBuffers;
|
||||||
|
//
|
||||||
|
// ShortBuffer sbuf = shortBuffer[curBuffer];
|
||||||
|
//
|
||||||
|
// // add fill coordinates
|
||||||
|
// if (addFill)
|
||||||
|
// newSize += 8;
|
||||||
|
//
|
||||||
|
// if (sbuf.capacity() < newSize) {
|
||||||
|
// sbuf = ByteBuffer
|
||||||
|
// .allocateDirect(newSize * SHORT_BYTES)
|
||||||
|
// .order(ByteOrder.nativeOrder())
|
||||||
|
// .asShortBuffer();
|
||||||
|
//
|
||||||
|
// shortBuffer[curBuffer] = sbuf;
|
||||||
|
// } else {
|
||||||
|
// sbuf.clear();
|
||||||
|
// // if (addFill)
|
||||||
|
// // sbuf.position(8);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (addFill)
|
||||||
|
// sbuf.put(mFillCoords, 0, 8);
|
||||||
|
//
|
||||||
|
// compile(sbuf, addFill);
|
||||||
|
//
|
||||||
|
// sbuf.flip();
|
||||||
|
//
|
||||||
|
// if (newSize != sbuf.remaining()) {
|
||||||
|
// Log.d(TAG, "wrong size: "
|
||||||
|
// + newSize + " "
|
||||||
|
// + sbuf.position() + " "
|
||||||
|
// + sbuf.limit() + " "
|
||||||
|
// + sbuf.remaining());
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// newSize *= SHORT_BYTES;
|
||||||
|
//
|
||||||
|
// // reuse memory allocated for vbo when possible and allocated
|
||||||
|
// // memory is less then four times the new data
|
||||||
|
// if (vbo.size > newSize && vbo.size < newSize * 4
|
||||||
|
// && !limit) {
|
||||||
|
// GLES20.glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, sbuf);
|
||||||
|
// } else {
|
||||||
|
// //mBufferMemoryUsage += newSize - vbo.size;
|
||||||
|
// vbo.size = newSize;
|
||||||
|
// GLES20.glBufferData(GL_ARRAY_BUFFER, vbo.size, sbuf, GL_DYNAMIC_DRAW);
|
||||||
|
// //mBufferMemoryUsage += vbo.size;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
private static int LINE_VERTEX_SHORTS = 4;
|
private static int LINE_VERTEX_SHORTS = 4;
|
||||||
private static int POLY_VERTEX_SHORTS = 2;
|
private static int POLY_VERTEX_SHORTS = 2;
|
||||||
private static int TEXTURE_VERTEX_SHORTS = 6;
|
private static int TEXTURE_VERTEX_SHORTS = 6;
|
||||||
|
|
||||||
|
//private static int EXTRUSION_VERTEX_SHORTS = 4;
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
@ -91,12 +168,13 @@ public class Layers {
|
|||||||
size += l.verticesCnt * LINE_VERTEX_SHORTS;
|
size += l.verticesCnt * LINE_VERTEX_SHORTS;
|
||||||
else
|
else
|
||||||
size += l.verticesCnt * POLY_VERTEX_SHORTS;
|
size += l.verticesCnt * POLY_VERTEX_SHORTS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
for (Layer l = textureLayers; l != null; l = l.next)
|
||||||
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
||||||
}
|
|
||||||
|
//for (Layer l = extrusionLayers; l != null; l = l.next)
|
||||||
|
// size += l.verticesCnt * EXTRUSION_VERTEX_SHORTS;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -113,18 +191,18 @@ public class Layers {
|
|||||||
lineOffset = sbuf.position() * 2; // * short-bytes
|
lineOffset = sbuf.position() * 2; // * short-bytes
|
||||||
addLayerItems(sbuf, layers, Layer.LINE, 0);
|
addLayerItems(sbuf, layers, Layer.LINE, 0);
|
||||||
|
|
||||||
texOffset = sbuf.position() * 2; // * short-bytes
|
|
||||||
|
|
||||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
for (Layer l = textureLayers; l != null; l = l.next) {
|
||||||
TextureLayer sl = (TextureLayer) l;
|
TextureLayer tl = (TextureLayer) l;
|
||||||
sl.compile(sbuf);
|
tl.compile(sbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME
|
// for (Layer l = extrusionLayers; l != null; l = l.next) {
|
||||||
addLayerItems(sbuf, textureLayers, Layer.SYMBOL, 0);
|
// ExtrusionLayer tl = (ExtrusionLayer) l;
|
||||||
|
// tl.compile(sbuf);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimization for lines and polygon: collect all pool items and add back in one go
|
||||||
private static void addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) {
|
private static void addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) {
|
||||||
VertexPoolItem last = null, items = null;
|
VertexPoolItem last = null, items = null;
|
||||||
|
|
||||||
@ -136,7 +214,8 @@ public class Layers {
|
|||||||
if (it.next == null)
|
if (it.next == null)
|
||||||
sbuf.put(it.vertices, 0, it.used);
|
sbuf.put(it.vertices, 0, it.used);
|
||||||
else
|
else
|
||||||
sbuf.put(it.vertices);
|
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE);
|
||||||
|
|
||||||
last = it;
|
last = it;
|
||||||
}
|
}
|
||||||
if (last == null)
|
if (last == null)
|
||||||
@ -155,8 +234,22 @@ public class Layers {
|
|||||||
VertexPool.release(items);
|
VertexPool.release(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
static void addPoolItems(Layer l, ShortBuffer sbuf) {
|
||||||
|
l.offset = sbuf.position() * 2; // (* short-bytes)
|
||||||
|
|
||||||
|
for (VertexPoolItem it = l.pool; it != null; it = it.next) {
|
||||||
|
if (it.next == null)
|
||||||
|
sbuf.put(it.vertices, 0, it.used);
|
||||||
|
else
|
||||||
|
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexPool.release(l.pool);
|
||||||
|
l.pool = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleanup only when layers are not used by tile or overlay anymore!
|
||||||
|
public void clear() {
|
||||||
while (layers != null) {
|
while (layers != null) {
|
||||||
Layer l = layers;
|
Layer l = layers;
|
||||||
if (l.pool != null) {
|
if (l.pool != null) {
|
||||||
@ -181,5 +274,20 @@ public class Layers {
|
|||||||
l = l.next;
|
l = l.next;
|
||||||
}
|
}
|
||||||
textureLayers = null;
|
textureLayers = null;
|
||||||
|
|
||||||
|
l = extrusionLayers;
|
||||||
|
while (l != null) {
|
||||||
|
|
||||||
|
l.clear();
|
||||||
|
|
||||||
|
if (l.pool != null) {
|
||||||
|
VertexPool.release(l.pool);
|
||||||
|
l.pool = null;
|
||||||
|
l.curItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = l.next;
|
||||||
|
}
|
||||||
|
extrusionLayers = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layer;
|
package org.oscim.renderer.layer;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.renderer.TextureObject;
|
import org.oscim.renderer.TextureObject;
|
||||||
import org.oscim.renderer.TextureRenderer;
|
import org.oscim.renderer.TextureRenderer;
|
||||||
|
|
||||||
@ -85,14 +83,16 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
symbols = item;
|
symbols = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
void compile(ShortBuffer sbuf) {
|
// void compile(ShortBuffer sbuf) {
|
||||||
if (TextureRenderer.debug)
|
// if (TextureRenderer.debug)
|
||||||
Log.d("...", "compile");
|
// Log.d("...", "compile");
|
||||||
|
//
|
||||||
for (TextureObject to = textures; to != null; to = to.next)
|
// for (TextureObject to = textures; to != null; to = to.next)
|
||||||
TextureObject.uploadTexture(to);
|
// TextureObject.uploadTexture(to);
|
||||||
}
|
//
|
||||||
|
// Layers.addPoolItems(this, sbuf);
|
||||||
|
// }
|
||||||
|
|
||||||
private final static int LBIT_MASK = 0xfffffffe;
|
private final static int LBIT_MASK = 0xfffffffe;
|
||||||
|
|
||||||
|
@ -14,13 +14,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layer;
|
package org.oscim.renderer.layer;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.renderer.TextureObject;
|
import org.oscim.renderer.TextureObject;
|
||||||
import org.oscim.renderer.TextureRenderer;
|
import org.oscim.renderer.TextureRenderer;
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.util.FloatMath;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
public final class TextLayer extends TextureLayer {
|
public final class TextLayer extends TextureLayer {
|
||||||
@ -92,15 +89,6 @@ public final class TextLayer extends TextureLayer {
|
|||||||
labels = item;
|
labels = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
void compile(ShortBuffer sbuf) {
|
|
||||||
if (TextureRenderer.debug)
|
|
||||||
Log.d("...", "compile");
|
|
||||||
|
|
||||||
for (TextureObject to = textures; to != null; to = to.next)
|
|
||||||
TextureObject.uploadTexture(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean prepare() {
|
public boolean prepare() {
|
||||||
if (TextureRenderer.debug)
|
if (TextureRenderer.debug)
|
||||||
@ -189,7 +177,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
} else {
|
} else {
|
||||||
float vx = it.x1 - it.x2;
|
float vx = it.x1 - it.x2;
|
||||||
float vy = it.y1 - it.y2;
|
float vy = it.y1 - it.y2;
|
||||||
float a = FloatMath.sqrt(vx * vx + vy * vy);
|
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
vx = vx / a;
|
vx = vx / a;
|
||||||
vy = vy / a;
|
vy = vy / a;
|
||||||
|
|
||||||
|
@ -17,6 +17,9 @@ package org.oscim.renderer.layer;
|
|||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
import org.oscim.renderer.TextureObject;
|
import org.oscim.renderer.TextureObject;
|
||||||
|
import org.oscim.renderer.TextureRenderer;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
public abstract class TextureLayer extends Layer {
|
public abstract class TextureLayer extends Layer {
|
||||||
public TextureObject textures;
|
public TextureObject textures;
|
||||||
@ -26,7 +29,15 @@ public abstract class TextureLayer extends Layer {
|
|||||||
* @param sbuf
|
* @param sbuf
|
||||||
* buffer to add vertices
|
* buffer to add vertices
|
||||||
*/
|
*/
|
||||||
abstract void compile(ShortBuffer sbuf);
|
void compile(ShortBuffer sbuf) {
|
||||||
|
if (TextureRenderer.debug)
|
||||||
|
Log.d("...", "compile");
|
||||||
|
|
||||||
|
for (TextureObject to = textures; to != null; to = to.next)
|
||||||
|
TextureObject.uploadTexture(to);
|
||||||
|
|
||||||
|
Layers.addPoolItems(this, sbuf);
|
||||||
|
}
|
||||||
|
|
||||||
abstract public boolean prepare();
|
abstract public boolean prepare();
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,15 @@ public class VertexPool {
|
|||||||
pool = null;
|
pool = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public static VertexPoolItem get(VertexPoolItem prev) {
|
||||||
|
// VertexPoolItem it = get();
|
||||||
|
// if (prev != null) {
|
||||||
|
// prev.next = it;
|
||||||
|
// prev.used = VertexPoolItem.SIZE;
|
||||||
|
// }
|
||||||
|
// return it;
|
||||||
|
// }
|
||||||
|
|
||||||
public static synchronized VertexPoolItem get() {
|
public static synchronized VertexPoolItem get() {
|
||||||
|
|
||||||
if (pool == null && count > 0) {
|
if (pool == null && count > 0) {
|
||||||
|
@ -40,9 +40,6 @@ public class BuildingOverlay extends RenderOverlay {
|
|||||||
super(mapView);
|
super(mapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int mNumIndices = 0;
|
|
||||||
private int mNumVertices = 0;
|
|
||||||
|
|
||||||
private static int buildingProgram;
|
private static int buildingProgram;
|
||||||
private static int hBuildingVertexPosition;
|
private static int hBuildingVertexPosition;
|
||||||
private static int hBuildingLightPosition;
|
private static int hBuildingLightPosition;
|
||||||
@ -55,8 +52,9 @@ public class BuildingOverlay extends RenderOverlay {
|
|||||||
private int mIndicesBufferID;
|
private int mIndicesBufferID;
|
||||||
private int mVertexBufferID;
|
private int mVertexBufferID;
|
||||||
|
|
||||||
|
private int mNumIndices = 0;
|
||||||
|
private int mNumVertices = 0;
|
||||||
private VertexPoolItem mVertices, mCurVertices;
|
private VertexPoolItem mVertices, mCurVertices;
|
||||||
|
|
||||||
private VertexPoolItem mIndices[], mCurIndices[];
|
private VertexPoolItem mIndices[], mCurIndices[];
|
||||||
|
|
||||||
private int mIndiceCnt[] = { 0, 0, 0 };
|
private int mIndiceCnt[] = { 0, 0, 0 };
|
||||||
|
328
src/org/oscim/renderer/overlays/BuildingOverlay2.java
Normal file
328
src/org/oscim/renderer/overlays/BuildingOverlay2.java
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 OpenScienceMap
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.overlays;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.MapTile;
|
||||||
|
import org.oscim.renderer.TileManager;
|
||||||
|
import org.oscim.renderer.TileSet;
|
||||||
|
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
import android.opengl.Matrix;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public class BuildingOverlay2 extends RenderOverlay {
|
||||||
|
private final static String TAG = BuildingOverlay2.class.getName();
|
||||||
|
|
||||||
|
public BuildingOverlay2(MapView mapView) {
|
||||||
|
super(mapView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int buildingProgram;
|
||||||
|
private static int hBuildingVertexPosition;
|
||||||
|
private static int hBuildingLightPosition;
|
||||||
|
private static int hBuildingMatrix;
|
||||||
|
private static int hBuildingColor;
|
||||||
|
private static int hBuildingMode;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
private int BUFFERSIZE = 65536 * 2;
|
||||||
|
private TileSet mTileSet;
|
||||||
|
private ShortBuffer mShortBuffer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||||
|
boolean tilesChanged) {
|
||||||
|
|
||||||
|
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
// Set up the program for rendering buildings
|
||||||
|
buildingProgram = GlUtils.createProgram(buildingVertexShader,
|
||||||
|
buildingFragmentShader);
|
||||||
|
if (buildingProgram == 0) {
|
||||||
|
Log.e("blah", "Could not create building program.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hBuildingMatrix = GLES20.glGetUniformLocation(buildingProgram, "u_mvp");
|
||||||
|
hBuildingColor = GLES20.glGetUniformLocation(buildingProgram, "u_color");
|
||||||
|
hBuildingMode = GLES20.glGetUniformLocation(buildingProgram, "u_mode");
|
||||||
|
hBuildingVertexPosition = GLES20.glGetAttribLocation(buildingProgram, "a_position");
|
||||||
|
hBuildingLightPosition = GLES20.glGetAttribLocation(buildingProgram, "a_light");
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocateDirect(BUFFERSIZE)
|
||||||
|
.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
mShortBuffer = buf.asShortBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ready = 0;
|
||||||
|
//if (curPos.zoomLevel < 17)
|
||||||
|
mTileSet = TileManager.getActiveTiles(mTileSet);
|
||||||
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible || tiles[i].layers == null
|
||||||
|
|| tiles[i].layers.extrusionLayers == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
|
||||||
|
if (el.ready && !el.compiled) {
|
||||||
|
el.compile(mShortBuffer);
|
||||||
|
GlUtils.checkGlError("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.compiled)
|
||||||
|
ready++;
|
||||||
|
}
|
||||||
|
|
||||||
|
isReady = ready > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// r: 0.815686275, 0.91372549
|
||||||
|
// g: 0.901960784
|
||||||
|
// b: 0.890196078
|
||||||
|
// sligthly differ adjacent faces to imrpove contrast
|
||||||
|
float mColor[] = { 0.71872549f, 0.701960784f, 0.690196078f, 0.7f };
|
||||||
|
float mColor2[] = { 0.71372549f, 0.701960784f, 0.695196078f, 0.7f };
|
||||||
|
float mRoofColor[] = { 0.81f, 0.80f, 0.79f, 0.7f };
|
||||||
|
boolean debug = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
||||||
|
|
||||||
|
boolean first = true;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible || tiles[i].layers == null
|
||||||
|
|| tiles[i].layers.extrusionLayers == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
if (!el.compiled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
GLES20.glUseProgram(buildingProgram);
|
||||||
|
GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
||||||
|
GLES20.glUniform1i(hBuildingMode, 0);
|
||||||
|
GLES20.glUniform4f(hBuildingColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], 1);
|
||||||
|
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hBuildingLightPosition, 2,
|
||||||
|
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mNumIndices,
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawCount = 20;
|
||||||
|
// draw to depth buffer
|
||||||
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible || tiles[i].layers == null
|
||||||
|
|| tiles[i].layers.extrusionLayers == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
if (!el.compiled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
GLES20.glUseProgram(buildingProgram);
|
||||||
|
GLRenderer.enableVertexArrays(hBuildingVertexPosition, -1);
|
||||||
|
|
||||||
|
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||||
|
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||||
|
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
//GLES20.glCullFace(GLES20.GL_CW);
|
||||||
|
GLES20.glDepthMask(true);
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
|
GLES20.glUniform1i(hBuildingMode, 0);
|
||||||
|
GLES20.glColorMask(false, false, false, false);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glPolygonOffset(0, drawCount--);
|
||||||
|
// seems there are not infinite offset units possible
|
||||||
|
// this should suffice for at least two rows, i.e.
|
||||||
|
// having not two neighbours with the same depth
|
||||||
|
if (drawCount == 0)
|
||||||
|
drawCount = 20;
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], 1);
|
||||||
|
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mNumIndices,
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first)
|
||||||
|
return;
|
||||||
|
// enable color buffer, use depth mask
|
||||||
|
GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
||||||
|
GLES20.glColorMask(true, true, true, true);
|
||||||
|
GLES20.glDepthMask(false);
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
|
|
||||||
|
drawCount = 20;
|
||||||
|
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible || tiles[i].layers == null
|
||||||
|
|| tiles[i].layers.extrusionLayers == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
if (!el.compiled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
GLES20.glPolygonOffset(0, drawCount--);
|
||||||
|
if (drawCount == 0)
|
||||||
|
drawCount = 20;
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], 1);
|
||||||
|
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hBuildingLightPosition, 2,
|
||||||
|
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
||||||
|
|
||||||
|
// draw roof
|
||||||
|
GLES20.glUniform1i(hBuildingMode, 0);
|
||||||
|
//GLES20.glUniform4f(hBuildingColor, 0.81f, 0.8f, 0.8f, 0.9f);
|
||||||
|
GLES20.glUniform4fv(hBuildingColor, 1, mRoofColor, 0);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[2],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, (el.mIndiceCnt[0] + el.mIndiceCnt[1]) * 2);
|
||||||
|
|
||||||
|
// draw sides 1
|
||||||
|
//GLES20.glUniform4f(hBuildingColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
//GLES20.glUniform4f(hBuildingColor, 0.9f, 0.905f, 0.9f, 1.0f);
|
||||||
|
GLES20.glUniform4fv(hBuildingColor, 1, mColor, 0);
|
||||||
|
GLES20.glUniform1i(hBuildingMode, 1);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[0],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
// draw sides 2
|
||||||
|
//GLES20.glUniform4f(hBuildingColor, 0.9f, 0.9f, 0.905f, 1.0f);
|
||||||
|
GLES20.glUniform4fv(hBuildingColor, 1, mColor2, 0);
|
||||||
|
GLES20.glUniform1i(hBuildingMode, 2);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
||||||
|
|
||||||
|
GlUtils.checkGlError("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first) {
|
||||||
|
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||||
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
|
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj,
|
||||||
|
MapTile tile, float div) {
|
||||||
|
|
||||||
|
float x = (float) (tile.pixelX - mapPosition.x * div);
|
||||||
|
float y = (float) (tile.pixelY - mapPosition.y * div);
|
||||||
|
float scale = mapPosition.scale / div;
|
||||||
|
|
||||||
|
Matrix.setIdentityM(matrix, 0);
|
||||||
|
|
||||||
|
// translate relative to map center
|
||||||
|
matrix[12] = x * scale;
|
||||||
|
matrix[13] = y * scale;
|
||||||
|
|
||||||
|
// scale to tile to world coordinates
|
||||||
|
scale /= GLRenderer.COORD_MULTIPLIER;
|
||||||
|
matrix[0] = scale;
|
||||||
|
matrix[5] = scale;
|
||||||
|
matrix[10] = scale / 1000f;
|
||||||
|
|
||||||
|
Matrix.multiplyMM(matrix, 0, mapPosition.viewMatrix, 0, matrix, 0);
|
||||||
|
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final static String buildingVertexShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "uniform int u_mode;"
|
||||||
|
+ "uniform float u_scale;"
|
||||||
|
+ "attribute vec4 a_position;"
|
||||||
|
+ "attribute vec2 a_light;"
|
||||||
|
+ "varying vec4 color;"
|
||||||
|
+ "const float ff = 255.0;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mvp * a_position;"
|
||||||
|
+ " if (u_mode == 0)"
|
||||||
|
// roof / depth pass
|
||||||
|
+ " color = u_color;"
|
||||||
|
+ " else if (u_mode == 1)"
|
||||||
|
// sides 1 - use 0xff00
|
||||||
|
+ " color = vec4(u_color.rgb * (a_light.y / ff), 0.8);"
|
||||||
|
+ " else"
|
||||||
|
// sides 2 - use 0x00ff
|
||||||
|
+ " color = vec4(u_color.rgb * (a_light.x / ff), 0.8);"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
final static String buildingFragmentShader = ""
|
||||||
|
+ "precision lowp float;"
|
||||||
|
+ "varying vec4 color;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_FragColor = color;"
|
||||||
|
+ "}";
|
||||||
|
}
|
@ -116,9 +116,7 @@ public abstract class RenderOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = layers.textureLayers; l != null;) {
|
for (Layer l = layers.textureLayers; l != null;) {
|
||||||
|
l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div, proj, mv);
|
||||||
l = TextureRenderer.draw(l, (mMapPosition.scale / pos.scale) * div, proj, mv,
|
|
||||||
layers.texOffset);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,6 +179,10 @@
|
|||||||
<line stroke="#9aabae" width="1.0" fixed="true" cap="butt"/>
|
<line stroke="#9aabae" width="1.0" fixed="true" cap="butt"/>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
<rule e="way" k="*" v="hospital" zoom-min="14">
|
||||||
|
<area fill="#f0f0d8" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
<rule e="way" k="*" v="parking" zoom-min="14">
|
<rule e="way" k="*" v="parking" zoom-min="14">
|
||||||
<area fill="#f4f4f4" stroke="#d4d4d4" stroke-width="0.2" />
|
<area fill="#f4f4f4" stroke="#d4d4d4" stroke-width="0.2" />
|
||||||
</rule>
|
</rule>
|
||||||
@ -472,7 +476,7 @@
|
|||||||
<!-- building -->
|
<!-- building -->
|
||||||
<rule e="way" k="building" v="*">
|
<rule e="way" k="building" v="*">
|
||||||
|
|
||||||
<rule e="way" k="*" v="*" zoom-min="15">
|
<rule e="way" k="*" v="*" zoom-min="15" zoom-max="16">
|
||||||
<use-area name="building" fade="15"/>
|
<use-area name="building" fade="15"/>
|
||||||
<use-line name="building" fade="15"/>
|
<use-line name="building" fade="15"/>
|
||||||
<!-- <line stroke="#c9c3c1" width="1.0" fixed="true" cap="butt" fade="15"/>
|
<!-- <line stroke="#c9c3c1" width="1.0" fixed="true" cap="butt" fade="15"/>
|
||||||
@ -926,6 +930,11 @@
|
|||||||
<rule e="way" k="debug" v="box">
|
<rule e="way" k="debug" v="box">
|
||||||
<line stroke="#000000" width="1.5" fixed="true" cap="butt" />
|
<line stroke="#000000" width="1.5" fixed="true" cap="butt" />
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
|
<!-- HACK!!! render building models last -->
|
||||||
|
<rule e="way" k="building" v="*" zoom-min="17">
|
||||||
|
<use-area name="building" fade="15"/>
|
||||||
|
</rule>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
<rule e="node" k="*" v="*">
|
<rule e="node" k="*" v="*">
|
||||||
|
@ -45,7 +45,7 @@ import org.oscim.overlay.OverlayManager;
|
|||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLView;
|
import org.oscim.renderer.GLView;
|
||||||
import org.oscim.renderer.TileManager;
|
import org.oscim.renderer.TileManager;
|
||||||
import org.oscim.renderer.overlays.BuildingOverlay;
|
import org.oscim.renderer.overlays.BuildingOverlay2;
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ExternalRenderTheme;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
import org.oscim.theme.RenderTheme;
|
import org.oscim.theme.RenderTheme;
|
||||||
@ -184,9 +184,9 @@ public class MapView extends RelativeLayout {
|
|||||||
mMapZoomControls.setShowMapZoomControls(true);
|
mMapZoomControls.setShowMapZoomControls(true);
|
||||||
enableRotation = true;
|
enableRotation = true;
|
||||||
|
|
||||||
mOverlayManager.add(new LabelingOverlay(this));
|
|
||||||
//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
||||||
mOverlayManager.add(new GenericOverlay(this, new BuildingOverlay(this)));
|
mOverlayManager.add(new GenericOverlay(this, new BuildingOverlay2(this)));
|
||||||
|
mOverlayManager.add(new LabelingOverlay(this));
|
||||||
|
|
||||||
// mOverlayManager.add(new GenericOverlay(this, new TestOverlay(this)));
|
// mOverlayManager.add(new GenericOverlay(this, new TestOverlay(this)));
|
||||||
|
|
||||||
|
58
src/org/quake/triangle/TriangleJNI.java
Normal file
58
src/org/quake/triangle/TriangleJNI.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package org.quake.triangle;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
public class TriangleJNI {
|
||||||
|
public TriangleJNI() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// private static boolean initialized = false;
|
||||||
|
//
|
||||||
|
// private static ShortBuffer sBuf;
|
||||||
|
// private static FloatBuffer fBuf;
|
||||||
|
//
|
||||||
|
// public static synchronized int triangulate(float[] points, int pos, int len, short[] indices) {
|
||||||
|
//
|
||||||
|
// int numRings = 1;
|
||||||
|
//
|
||||||
|
// if (!initialized) {
|
||||||
|
// fBuf = ByteBuffer.allocateDirect(360 * 4).order(ByteOrder.nativeOrder())
|
||||||
|
// .asFloatBuffer();
|
||||||
|
// sBuf = ByteBuffer.allocateDirect(360 * 2).order(ByteOrder.nativeOrder())
|
||||||
|
// .asShortBuffer();
|
||||||
|
// initialized = true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fBuf.clear();
|
||||||
|
// fBuf.put(points, pos, len);
|
||||||
|
//
|
||||||
|
// sBuf.clear();
|
||||||
|
// sBuf.put((short) (len >> 1)); // all points
|
||||||
|
// sBuf.put((short) (len >> 1)); // outer ring
|
||||||
|
// //sBuf.put((short)4); // inner ring
|
||||||
|
//
|
||||||
|
// int numTris = TriangleJNI.triangulate(fBuf, numRings, sBuf);
|
||||||
|
// if (numTris > 100)
|
||||||
|
// Log.d("triangle", "Triangles: " + numTris);
|
||||||
|
//
|
||||||
|
// sBuf.limit(numTris * 3);
|
||||||
|
// sBuf.position(0);
|
||||||
|
//
|
||||||
|
// // for(int i = 0; i < numTris * 3; i+=3){
|
||||||
|
// // Log.d("triangle", ">>" + sBuf.get()+ " "+ sBuf.get() + " "+ sBuf.get());
|
||||||
|
// // }
|
||||||
|
//
|
||||||
|
// sBuf.get(indices, 0, numTris * 3);
|
||||||
|
//
|
||||||
|
// return numTris * 3;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static native int triangulate(FloatBuffer points, int length, ShortBuffer result,
|
||||||
|
int ioffset);
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("triangle-jni");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user