add client-side triangulator, not enabled yet

This commit is contained in:
Hannes Janetzek 2012-07-23 17:07:32 +02:00
parent 99e361d8a0
commit f32aa5d431
9 changed files with 509 additions and 134 deletions

View File

@ -75,6 +75,7 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
private LineLayers mLineLayers;
private PolygonLayers mPolyLayers;
private MeshLayers mMeshLayers;
private int mDrawingLayer;
private int mLevels;
@ -316,6 +317,9 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
PolygonLayer l = mPolyLayers.getLayer(mDrawingLayer + area.level, area.color,
area.fade);
// MeshLayer l = mMeshLayers.getLayer(mDrawingLayer + area.level, area.color,
// area.fade);
for (int i = 0, pos = 0, n = mWays.length; i < n; i++) {
int length = mWays[i];
// need at least three points
@ -324,6 +328,7 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
pos += length;
}
}
@Override
@ -386,8 +391,10 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
mLineLayers = new LineLayers();
mPolyLayers = new PolygonLayers();
mMeshLayers = new MeshLayers();
mCurrentTile.lineLayers = mLineLayers;
mCurrentTile.polygonLayers = mPolyLayers;
mCurrentTile.meshLayers = mMeshLayers;
firstMatch = true;
mMapDatabase.executeQuery(mCurrentTile, this);

View File

@ -24,6 +24,7 @@ class GLMapTile extends MapTile {
LineLayers lineLayers;
PolygonLayers polygonLayers;
MeshLayers meshLayers;
boolean newData;
boolean loading;

View File

@ -39,7 +39,7 @@ class Layer {
colors[3] = (color >> 24 & 0xff) / 255.0f;
}
float[] getNextItem() {
float[] getNextPoolItem() {
curItem.used = PoolItem.SIZE;
curItem = LayerPool.get();
pool.add(curItem);

View File

@ -44,10 +44,9 @@ class LineLayer extends Layer {
outlines.add(link);
}
// private void addVertex(float x, float y, byte tex, byte[] c){
// //
// }
/*
* line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj
*/
void addLine(float[] pointArray, int pos, int length, float w, boolean capRound) {
float x, y, nextX, nextY, prevX, prevY, ux, uy, vx, vy, wx, wy;
double a;
@ -64,7 +63,7 @@ class LineLayer extends Layer {
int vertexPos = curItem.used;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -105,7 +104,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 1.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -115,7 +114,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 1.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -125,7 +124,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 1.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -136,7 +135,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -163,7 +162,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -173,7 +172,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -244,7 +243,7 @@ class LineLayer extends Layer {
uyw = uy * w;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -254,7 +253,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -304,7 +303,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -314,7 +313,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -325,7 +324,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = -1.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -336,7 +335,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = -1.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -360,7 +359,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}
@ -371,7 +370,7 @@ class LineLayer extends Layer {
curVertices[vertexPos++] = 0.0f;
if (vertexPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
vertexPos = 0;
}

View File

@ -164,9 +164,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
private void updateTileDistances() {
int h = (Tile.TILE_SIZE >> 1);
byte zoom = mMapPosition.zoomLevel;
long x = mTileX * (Tile.TILE_SIZE); // - (Tile.TILE_SIZE >> 1);
long y = mTileY * (Tile.TILE_SIZE); // - (Tile.TILE_SIZE >> 1);
long x = mTileX * (Tile.TILE_SIZE) + h;
long y = mTileY * (Tile.TILE_SIZE) + h;
int diff;
long dx, dy;
@ -178,26 +179,26 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
if (diff != 0) {
if (diff > 0) {
// tile zoom level is child of current
dx = (t.pixelX >> diff) - x;
dy = (t.pixelY >> diff) - y;
dx = ((t.pixelX + h) >> diff) - x;
dy = ((t.pixelY + h) >> diff) - y;
} else {
// tile zoom level is parent of current
dx = (t.pixelX << -diff) - x;
dy = (t.pixelY << -diff) - y;
dx = ((t.pixelX + h) << -diff) - x;
dy = ((t.pixelY + h) << -diff) - y;
}
if (diff == -1) {
// load parent before current layer (kind of progressive transmission :)
dy *= mAspect;
t.distance = 2 + ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy));
} else {
// load parent before current layer (kind of progressive transmission :)
t.distance = ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy));
// prefer lower zoom level, i.e. it covers a larger area
t.distance *= (1 + (diff > 0 ? diff * 4 : -diff * 2));
}
} else {
dx = t.pixelX - x;
dy = t.pixelY - y;
dx = (t.pixelX + h) - x;
dy = (t.pixelY + h) - y;
dy *= mAspect;
t.distance = (1 + ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)));// * 2;
}
@ -307,10 +308,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
long pixelLeft = (long) x - offsetX;
long pixelTop = (long) y - offsetY;
long tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel);
long tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel);
long tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel);
long tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel);
long tileLeft = MercatorProjection.pixelXToTileX(pixelLeft, zoomLevel) - 1;
long tileTop = MercatorProjection.pixelYToTileY(pixelTop, zoomLevel) - 1;
long tileRight = MercatorProjection.pixelXToTileX(pixelRight, zoomLevel) + 1;
long tileBottom = MercatorProjection.pixelYToTileY(pixelBottom, zoomLevel) + 1;
mJobList.clear();
mJobParameter = mMapView.getJobParameters();
@ -321,9 +322,19 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
return false;
int max = newTiles.tiles.length - 1;
long limit = (long) Math.pow(2, zoomLevel) - 1;
for (long tileY = tileTop - 1; tileY <= tileBottom + 1; tileY++) {
for (long tileX = tileLeft - 1; tileX <= tileRight + 1; tileX++) {
if (tileTop < 0)
tileTop = 0;
if (tileLeft < 0)
tileLeft = 0;
if (tileBottom >= limit)
tileBottom = limit;
if (tileRight >= limit)
tileRight = limit;
for (long tileY = tileTop; tileY <= tileBottom; tileY++) {
for (long tileX = tileLeft; tileX <= tileRight; tileX++) {
// FIXME
if (tiles == max)
break;
@ -553,7 +564,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
private boolean drawPolygons(GLMapTile tile, int diff) {
float scale, x, y, z = 1;
int cnt = 0;
if (tile.polygonLayers == null || tile.polygonLayers.array == null)
return true;
@ -574,24 +585,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
if (diff == 0) {
scale = (float) (mDrawScale * 2.0 / mHeight);
x = (float) (mDrawX - tile.x);
y = (float) (tile.y - mDrawY);
} else {
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
scale = (float) (mDrawScale * 2.0 / mHeight / z);
x = (float) (mDrawX * z - tile.x);
y = (float) (tile.y - mDrawY * z);
}
int cnt = 0;
mMVPMatrix[12] = -x * (scale * mAspect);
mMVPMatrix[13] = -y * (scale);
mMVPMatrix[0] = (scale * mAspect);
mMVPMatrix[5] = (scale);
setMatrix(tile, diff);
GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
boolean firstPass = true;
@ -611,11 +605,11 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
else {
// clear stencilbuffer
GLES20.glStencilMask(0xFF);
// GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
// clear stencilbuffer (tile region)
GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
// stencil op for stencil method polygon drawing
@ -646,8 +640,45 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
return true;
}
private boolean drawTriangles(GLMapTile tile, int diff) {
if (tile.meshLayers == null || tile.meshLayers.array == null)
return true;
GLES20.glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
if (useHalfFloat) {
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
OES_HALF_FLOAT, false, 0,
POLYGON_VERTICES_DATA_POS_OFFSET);
} else {
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
GLES20.GL_FLOAT, false, 0,
POLYGON_VERTICES_DATA_POS_OFFSET);
}
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
setMatrix(tile, diff);
GLES20.glUniformMatrix4fv(gPolygonMatrixHandle, 1, false, mMVPMatrix, 0);
MeshLayer[] layers = tile.meshLayers.array;
for (int i = 0, n = layers.length; i < n; i++) {
MeshLayer l = layers[i];
GLES20.glUniform4fv(gPolygonColorHandle, 1, l.colors, 0);
// GLES20.glUniform4f(gPolygonColorHandle, 1, 0, 0, 1);
// System.out.println("draw: " + l.offset + " " + l.verticesCnt);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, l.offset, l.verticesCnt);
}
return true;
}
private boolean drawLines(GLMapTile tile, int diff) {
float x, y, scale;
float z = 1;
if (tile.lineLayers == null || tile.lineLayers.array == null)
@ -672,22 +703,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
if (diff == 0) {
scale = (float) (mDrawScale * 2.0 / mHeight);
x = (float) (mDrawX - tile.x);
y = (float) (tile.y - mDrawY);
} else {
if (diff != 0)
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
scale = (float) (mDrawScale * 2.0 / mHeight / z);
x = (float) (mDrawX * z - tile.x);
y = (float) (tile.y - mDrawY * z);
}
mMVPMatrix[12] = -x * (scale * mAspect);
mMVPMatrix[13] = -y * (scale);
mMVPMatrix[0] = (scale * mAspect);
mMVPMatrix[5] = (scale);
setMatrix(tile, diff);
GLES20.glUniformMatrix4fv(gLineMatrixHandle, 1, false, mMVPMatrix, 0);
LineLayer[] layers = tile.lineLayers.array;
@ -750,6 +769,27 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
return true;
}
private void setMatrix(GLMapTile tile, int diff) {
float x, y, scale;
float z = 1;
if (diff == 0) {
scale = (float) (mDrawScale * 2.0 / mHeight);
x = (float) (mDrawX - tile.x);
y = (float) (tile.y - mDrawY);
} else {
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
scale = (float) (mDrawScale * 2.0 / mHeight / z);
x = (float) (mDrawX * z - tile.x);
y = (float) (tile.y - mDrawY * z);
}
mMVPMatrix[12] = -x * (scale * mAspect);
mMVPMatrix[13] = -y * (scale);
mMVPMatrix[0] = (scale * mAspect);
mMVPMatrix[5] = (scale);
}
private boolean setTileScissor(GLMapTile tile, float div) {
double dx, dy, scale;
@ -868,15 +908,49 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
// private int uploadCnt;
private void drawProxyTriangles(GLMapTile tile) {
if (tile.parent != null && tile.parent.isDrawn) {
tile.parent.sx = tile.sx;
tile.parent.sy = tile.sy;
tile.parent.sw = tile.sw;
tile.parent.sh = tile.sh;
drawTriangles(tile.parent, -1);
} else {
int drawn = 0;
for (int i = 0; i < 4; i++) {
GLMapTile c = tile.child[i];
if (c != null && c.isDrawn && setTileScissor(c, 2)) {
drawTriangles(c, 1);
drawn++;
}
}
if (drawn < 4 && tile.parent != null) {
GLMapTile p = tile.parent.parent;
if (p != null && p.isDrawn) {
p.sx = tile.sx;
p.sy = tile.sy;
p.sw = tile.sw;
p.sh = tile.sh;
drawTriangles(p, -2);
}
}
}
}
private boolean mTriangulate = false;
private int uploadCnt = 0;
private boolean uploadTileData(GLMapTile tile) {
// not sure about this, but seems it fixes some flickering when
// multiple tiles are uploaded in one go. but if this is really
// the issue tiles should stay corrupted..
// if (uploadCnt++ > 0)
// GLES20.glFinish();
if (uploadCnt++ > 0)
GLES20.glFinish();
if (tile.lineVBO == null) {
// Upload line data to vertex buffer object
@ -915,33 +989,64 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
tile.lineLayers = null;
}
if (useHalfFloat)
shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
else
floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
if (!mTriangulate) {
if (useHalfFloat)
shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
else
floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
// Upload polygon data to vertex buffer object
if (tile.polygonLayers.size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
// Upload polygon data to vertex buffer object
if (tile.polygonLayers.size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
GLES20.GL_STATIC_DRAW);
if (useHalfFloat) {
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
shortBuffer, GLES20.GL_STATIC_DRAW);
} else {
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
floatBuffer, GLES20.GL_STATIC_DRAW);
}
mBufferMemoryUsage += tile.polygonVBO.size;
if (useHalfFloat) {
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
shortBuffer, GLES20.GL_STATIC_DRAW);
} else {
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
floatBuffer, GLES20.GL_STATIC_DRAW);
tile.polygonLayers = null;
}
mBufferMemoryUsage += tile.polygonVBO.size;
} else {
tile.polygonLayers = null;
}
else {
if (useHalfFloat)
shortBuffer = tile.meshLayers.compileLayerData(shortBuffer);
else
floatBuffer = tile.meshLayers.compileLayerData(floatBuffer);
// Upload triangle data to vertex buffer object
if (tile.meshLayers.size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
GLES20.GL_STATIC_DRAW);
if (useHalfFloat) {
tile.polygonVBO.size = tile.meshLayers.size * SHORT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
shortBuffer, GLES20.GL_STATIC_DRAW);
} else {
tile.polygonVBO.size = tile.meshLayers.size * FLOAT_BYTES;
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
floatBuffer, GLES20.GL_STATIC_DRAW);
}
mBufferMemoryUsage += tile.polygonVBO.size;
} else {
tile.meshLayers = null;
}
}
tile.newData = false;
tile.isDrawn = true;
tile.isLoading = false;
@ -964,7 +1069,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
GLES20.glStencilMask(0xFF);
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
GLES20.glFlush();
// GLES20.glFlush();
// long endTime = SystemClock.uptimeMillis();
// long dt = endTime - startTime;
@ -1018,7 +1123,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
CACHE_TILES += 50;
}
// uploadCnt = 0;
uploadCnt = 0;
// check visible tiles, set tile clip scissors, upload new vertex data
for (int i = 0; i < tileCnt; i++) {
@ -1054,46 +1159,64 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
}
}
// GLES20.glFinish();
GlUtils.checkGlError("upload");
if (timing)
clear_time = (SystemClock.uptimeMillis() - start);
GLES20.glEnable(GLES20.GL_SCISSOR_TEST);
GLES20.glDisable(GLES20.GL_BLEND);
// Draw Polygons
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
GLES20.glUseProgram(gPolygonProgram);
GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
// GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
GLMapTile tile = tiles[i];
if (!mTriangulate) {
GLES20.glDisable(GLES20.GL_BLEND);
// Draw Polygons
GLES20.glEnable(GLES20.GL_STENCIL_TEST);
if (tile.isDrawn)
drawPolygons(tile, 0);
else
drawProxyPolygons(tile);
// GLES20.glEnableVertexAttribArray(gPolygonVertexPositionHandle);
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
GLMapTile tile = tiles[i];
if (tile.isDrawn)
drawPolygons(tile, 0);
else
drawProxyPolygons(tile);
}
}
}
GlUtils.checkGlError("polygons");
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
} else {
// Draw Triangles
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
GLMapTile tile = tiles[i];
GLES20.glDisable(GLES20.GL_STENCIL_TEST);
if (tile.isDrawn)
drawTriangles(tile, 0);
else
drawProxyTriangles(tile);
}
}
GlUtils.checkGlError("triangles");
}
// required on GalaxyII, Android 2.3.3
GLES20.glDisableVertexAttribArray(gPolygonVertexPositionHandle);
// GLES20.glDisableVertexAttribArray(gPolygonVertexPositionHandle);
if (timing) {
GLES20.glFinish();
poly_time = (SystemClock.uptimeMillis() - start);
}
// GLES20.glFlush();
GLES20.glFlush();
// Draw lines
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glUseProgram(gLineProgram);
GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
// GLES20.glEnableVertexAttribArray(gLineVertexPositionHandle);
// GLES20.glEnableVertexAttribArray(gLineTexturePositionHandle);
for (int i = 0; i < tileCnt; i++) {
if (tiles[i].isVisible) {
@ -1111,9 +1234,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
+ clear_time + " " + poly_time);
}
GLES20.glDisableVertexAttribArray(gLineVertexPositionHandle);
GLES20.glDisableVertexAttribArray(gLineTexturePositionHandle);
// GLES20.glDisableVertexAttribArray(gLineVertexPositionHandle);
// GLES20.glDisableVertexAttribArray(gLineTexturePositionHandle);
GlUtils.checkGlError("lines");
GLES20.glFinish();
}
private int[] mVboIds;
@ -1220,6 +1344,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
GLES20.glDisable(GLES20.GL_DITHER);
GLES20.glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
GLES20.glClearStencil(0);
// GLES20.glFrontFace(GLES20.GL_CCW);
}
@Override

View File

@ -0,0 +1,75 @@
/*
* Copyright 2010, 2011, 2012 Hannes Janetzek
*
* 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.mapsforge.android.glrenderer;
import java.util.LinkedList;
import org.poly2tri.Poly2Tri;
import org.poly2tri.geometry.polygon.Polygon;
import org.poly2tri.geometry.polygon.PolygonPoint;
import org.poly2tri.triangulation.delaunay.DelaunayTriangle;
public class MeshLayer extends Layer {
MeshLayer(int l, int color) {
super(l, color);
curItem = LayerPool.get();
pool = new LinkedList<PoolItem>();
pool.add(curItem);
}
void addPolygon(float[] points, int position, int length) {
float[] curVertices = curItem.vertices;
int outPos = curItem.used;
int len = length / 2 - 1;
int pos = position;
PolygonPoint[] pp = new PolygonPoint[len];
for (int i = 0; i < len; i++) {
pp[i] = new PolygonPoint(points[pos++], points[pos++]);
}
Polygon poly = new Polygon(pp);
Poly2Tri.triangulate(poly);
for (DelaunayTriangle tri : poly.getTriangles()) {
for (int i = 0; i < 3; i++) {
if (outPos == PoolItem.SIZE) {
curVertices = getNextPoolItem();
outPos = 0;
}
curVertices[outPos++] = (float) tri.points[i].getX();
curVertices[outPos++] = (float) tri.points[i].getY();
}
// System.out.println("" +
// (float) tri.points[0].getX() + "/" + (float) tri.points[0].getY()
// + ", " +
// (float) tri.points[1].getX() + "/" + (float) tri.points[1].getY()
// + ", " +
// (float) tri.points[2].getX() + "/" + (float) tri.points[2].getY());
}
// System.out.println("---");
curItem.used = outPos;
verticesCnt += poly.getTriangles().size() * 3;
}
}

View File

@ -0,0 +1,150 @@
/*
* Copyright 2010, 2011, 2012 Hannes Janetzek
*
* 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.mapsforge.android.glrenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.util.SparseArray;
public class MeshLayers {
private static final int NUM_VERTEX_FLOATS = 2;
private SparseArray<MeshLayer> layers;
MeshLayer[] array = null;
int size;
MeshLayers() {
layers = new SparseArray<MeshLayer>(10);
size = 0;
}
MeshLayer getLayer(int layer, int color, int fade) {
MeshLayer l = layers.get(layer);
if (l != null) {
return l;
}
l = new MeshLayer(layer, color);
layers.put(layer, l);
return l;
}
FloatBuffer compileLayerData(FloatBuffer buf) {
FloatBuffer fbuf = buf;
array = new MeshLayer[layers.size()];
for (int i = 0, n = layers.size(); i < n; i++) {
MeshLayer l = layers.valueAt(i);
array[i] = l;
size += l.verticesCnt;
}
size *= NUM_VERTEX_FLOATS;
if (buf == null || buf.capacity() < size) {
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
ByteOrder.nativeOrder());
// Log.d("GLMap", "allocate buffer " + size);
fbuf = bbuf.asFloatBuffer();
} else {
fbuf.position(0);
}
int pos = 0;
for (int i = 0, n = array.length; i < n; i++) {
MeshLayer l = array[i];
for (PoolItem item : l.pool) {
fbuf.put(item.vertices, 0, item.used);
// for (int j = 0; j < item.used; j++)
// System.out.println(">" + item.vertices[j]);
}
l.offset = pos;
pos += l.verticesCnt;
LayerPool.add(l.pool);
l.pool = null;
}
fbuf.position(0);
// for (int i = 0; i < size; i++)
// System.out.println("<" + fbuf.get());
// fbuf.position(0);
// System.out.println("....... mesh layer size: " + size + " " + array.length);
// not needed for drawing
layers = null;
return fbuf;
}
ShortBuffer compileLayerData(ShortBuffer buf) {
ShortBuffer sbuf = buf;
array = new MeshLayer[layers.size()];
for (int i = 0, n = layers.size(); i < n; i++) {
MeshLayer l = layers.valueAt(i);
array[i] = l;
size += l.verticesCnt;
}
size *= NUM_VERTEX_FLOATS;
if (buf == null || buf.capacity() < size) {
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
ByteOrder.nativeOrder());
sbuf = bbuf.asShortBuffer();
} else {
sbuf.position(0);
}
short[] data = new short[PoolItem.SIZE];
int pos = 0;
for (int i = 0, n = array.length; i < n; i++) {
MeshLayer l = array[i];
for (int k = 0, m = l.pool.size(); k < m; k++) {
PoolItem item = l.pool.get(k);
PoolItem.toHalfFloat(item, data);
sbuf.put(data, 0, item.used);
}
l.offset = pos;
pos += l.verticesCnt;
LayerPool.add(l.pool);
l.pool = null;
}
// System.out.println("....... mesh layer size: " + size + " " + array.length);
sbuf.position(0);
// not needed for drawing
layers = null;
return sbuf;
}
}

View File

@ -16,14 +16,12 @@ package org.mapsforge.android.glrenderer;
import java.util.LinkedList;
import org.mapsforge.core.Tile;
class PolygonLayer extends Layer {
int fadeLevel;
// private boolean first = true;
// private float originX;
// private float originY;
private boolean first = true;
private float originX;
private float originY;
PolygonLayer(int layer, int color, int fade) {
super(layer, color);
@ -37,29 +35,29 @@ class PolygonLayer extends Layer {
verticesCnt += length / 2 + 2;
// if (first) {
// first = false;
// originX = points[pos];
// originY = points[pos + 1];
// }
if (first) {
first = false;
originX = points[pos];
originY = points[pos + 1];
}
float[] curVertices = curItem.vertices;
int outPos = curItem.used;
if (outPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
outPos = 0;
}
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
curVertices[outPos++] = originX; // Tile.TILE_SIZE >> 1;
curVertices[outPos++] = originY; // Tile.TILE_SIZE >> 1;
int remaining = length;
int inPos = pos;
while (remaining > 0) {
if (outPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
outPos = 0;
}
@ -74,10 +72,10 @@ class PolygonLayer extends Layer {
}
if (outPos == PoolItem.SIZE) {
curVertices = getNextItem();
curVertices = getNextPoolItem();
outPos = 0;
}
// Float.intBitsToFloat(bits)
curVertices[outPos++] = points[pos + 0];
curVertices[outPos++] = points[pos + 1];

View File

@ -0,0 +1,19 @@
/*
* Copyright 2010, 2011, 2012 mapsforge.org
*
* 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.mapsforge.android.glrenderer;
public class SymbolLayer {
}