diff --git a/src/org/mapsforge/android/MapView.java b/src/org/mapsforge/android/MapView.java
index ef5b1b62..c04e7c32 100644
--- a/src/org/mapsforge/android/MapView.java
+++ b/src/org/mapsforge/android/MapView.java
@@ -188,7 +188,10 @@ public class MapView extends GLSurfaceView {
mMapWorkers[i].start();
}
- setRenderTheme(InternalRenderTheme.OSMARENDER);
+ if (!setRenderTheme(InternalRenderTheme.OSMARENDER)) {
+ Log.d(TAG, "EEEK could parse theme");
+ // FIXME show init error dialog
+ }
setEGLConfigChooser(new GlConfigChooser());
setEGLContextClientVersion(2);
@@ -496,14 +499,15 @@ public class MapView extends GLSurfaceView {
* @throws IllegalArgumentException
* if the supplied internalRenderTheme is null.
*/
- public void setRenderTheme(InternalRenderTheme internalRenderTheme) {
+ public boolean setRenderTheme(InternalRenderTheme internalRenderTheme) {
if (internalRenderTheme == null) {
throw new IllegalArgumentException("render theme must not be null");
}
- setRenderTheme((Theme) internalRenderTheme);
+ boolean ret = setRenderTheme((Theme) internalRenderTheme);
clearAndRedrawMapView();
+ return ret;
}
/**
diff --git a/src/org/mapsforge/android/glrenderer/Layer.java b/src/org/mapsforge/android/glrenderer/Layer.java
deleted file mode 100644
index ca93b35e..00000000
--- a/src/org/mapsforge/android/glrenderer/Layer.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2012 Hannes Janetzek
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General 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 License for more details.
- *
- * You should have received a copy of the GNU Lesser General License along with
- * this program. If not, see .
- */
-package org.mapsforge.android.glrenderer;
-
-class Layer {
- PoolItem pool;
-
- protected PoolItem curItem;
-
- int verticesCnt;
- int offset;
-
- final int layer;
-
- Layer(int l) {
- layer = l;
- verticesCnt = 0;
- }
-
- float[] getNextPoolItem() {
- curItem.used = PoolItem.SIZE;
-
- curItem.next = VertexPool.get();
- curItem = curItem.next;
-
- return curItem.vertices;
- }
-}
diff --git a/src/org/mapsforge/android/glrenderer/LineLayer.java b/src/org/mapsforge/android/glrenderer/LineLayer.java
index f8524ddc..3e7264d0 100644
--- a/src/org/mapsforge/android/glrenderer/LineLayer.java
+++ b/src/org/mapsforge/android/glrenderer/LineLayer.java
@@ -15,11 +15,13 @@
package org.mapsforge.android.glrenderer;
import org.mapsforge.android.rendertheme.renderinstruction.Line;
-import org.mapsforge.core.Tile;
import android.util.FloatMath;
-class LineLayer extends Layer {
+class LineLayer {
+
+ private static final float SCALE_FACTOR = 16;
+
Line line;
LineLayer next;
@@ -28,14 +30,21 @@ class LineLayer extends Layer {
float width;
boolean isOutline;
+ ShortItem pool;
+ protected ShortItem curItem;
+ int verticesCnt;
+ int offset;
+
+ final int layer;
+
LineLayer(int layer, Line line, boolean outline) {
- super(layer);
+ this.layer = layer;
this.line = line;
this.isOutline = outline;
if (!outline) {
- curItem = VertexPool.get();
+ curItem = ShortPool.get();
pool = curItem;
}
}
@@ -49,6 +58,15 @@ class LineLayer extends Layer {
outlines = link;
}
+ short[] getNextItem() {
+ curItem.used = ShortItem.SIZE;
+
+ curItem.next = ShortPool.get();
+ curItem = curItem.next;
+
+ return curItem.vertices;
+ }
+
/*
* line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj
*/
@@ -57,7 +75,7 @@ class LineLayer extends Layer {
float a;
int pointPos = pos;
boolean rounded = capRound;
- width = w;
+ width = w;// * SCALE_FACTOR;
if (w < 0.5)
rounded = false;
@@ -66,19 +84,19 @@ class LineLayer extends Layer {
int MAX = PoolItem.SIZE;
- float[] curVertices = curItem.vertices;
+ short[] curVertices = curItem.vertices;
int vertexPos = curItem.used;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- x = pointArray[pointPos++];
- y = pointArray[pointPos++];
+ x = pointArray[pointPos++];// * SCALE_FACTOR;
+ y = pointArray[pointPos++];// * SCALE_FACTOR;
- nextX = pointArray[pointPos++];
- nextY = pointArray[pointPos++];
+ nextX = pointArray[pointPos++];// * SCALE_FACTOR;
+ nextY = pointArray[pointPos++];// * SCALE_FACTOR;
// Calculate triangle corners for the given width
vx = nextX - x;
@@ -86,8 +104,8 @@ class LineLayer extends Layer {
a = FloatMath.sqrt(vx * vx + vy * vy);
- vx = (float) (vx / a);
- vy = (float) (vy / a);
+ vx = (vx / a);
+ vy = (vy / a);
ux = -vy;
uy = vx;
@@ -98,58 +116,59 @@ class LineLayer extends Layer {
float vxw = vx * w;
float vyw = vy * w;
- boolean outside = (x <= 0 || x >= Tile.TILE_SIZE || y <= 0 || y >= Tile.TILE_SIZE)
- && (x - vxw <= 0 || x - vxw >= Tile.TILE_SIZE || y - vyw <= 0 || y - vyw >= Tile.TILE_SIZE);
+ // boolean outside = (x <= 0 || x >= Tile.TILE_SIZE || y <= 0 || y >= Tile.TILE_SIZE)
+ // && (x - vxw <= 0 || x - vxw >= Tile.TILE_SIZE || y - vyw <= 0 || y - vyw >= Tile.TILE_SIZE);
+ boolean outside = false;
if (rounded && !outside) {
// Add the first point twice to be able to draw with GL_TRIANGLE_STRIP
- curVertices[vertexPos++] = x + uxw - vxw;
- curVertices[vertexPos++] = y + uyw - vyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 1.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 1;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x + uxw - vxw;
- curVertices[vertexPos++] = y + uyw - vyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 1.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 1;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 1.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 1;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
// Start of line
- curVertices[vertexPos++] = x + uxw;
- curVertices[vertexPos++] = y + uyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw;
- curVertices[vertexPos++] = y - uyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
} else {
// outside means line is probably clipped
@@ -163,30 +182,30 @@ class LineLayer extends Layer {
verticesCnt -= 2;
}
// Add the first point twice to be able to draw with GL_TRIANGLE_STRIP
- curVertices[vertexPos++] = x + uxw - vxw;
- curVertices[vertexPos++] = y + uyw - vyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x + uxw - vxw;
- curVertices[vertexPos++] = y + uyw - vyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
}
prevX = x;
@@ -203,15 +222,15 @@ class LineLayer extends Layer {
vx = prevX - x;
vy = prevY - y;
a = FloatMath.sqrt(vx * vx + vy * vy);
- vx = (float) (vx / a);
- vy = (float) (vy / a);
+ vx = (vx / a);
+ vy = (vy / a);
// Unit vector pointing forward to next node
wx = nextX - x;
wy = nextY - y;
a = FloatMath.sqrt(wx * wx + wy * wy);
- wx = (float) (wx / a);
- wy = (float) (wy / a);
+ wx = (wx / a);
+ wy = (wy / a);
// Sum of these two vectors points
ux = vx + wx;
@@ -223,8 +242,8 @@ class LineLayer extends Layer {
ux = -wy;
uy = wx;
} else {
- ux = (float) (ux / a);
- uy = (float) (uy / a);
+ ux = (ux / a);
+ uy = (uy / a);
if (ux > 2 || uy > 2 || ux < -2 || uy < -2) {
ux = -wy;
@@ -250,24 +269,24 @@ class LineLayer extends Layer {
uyw = uy * w;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x + uxw;
- curVertices[vertexPos++] = y + uyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw;
- curVertices[vertexPos++] = y - uyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
prevX = x;
prevY = y;
@@ -280,8 +299,8 @@ class LineLayer extends Layer {
a = FloatMath.sqrt(vx * vx + vy * vy);
- vx = (float) (vx / a);
- vy = (float) (vy / a);
+ vx = (vx / a);
+ vy = (vy / a);
ux = vy;
uy = -vx;
@@ -292,69 +311,61 @@ class LineLayer extends Layer {
vxw = vx * w;
vyw = vy * w;
- outside = (x <= 0 || x >= Tile.TILE_SIZE || y <= 0 || y >= Tile.TILE_SIZE)
- && (x - vxw <= 0 || x - vxw >= Tile.TILE_SIZE || y - vyw <= 0 || y - vyw >= Tile.TILE_SIZE);
-
- // if (vertexPos == MAX) {
- // curItem.used = vertexPos;
- // curItem = LayerPool.get();
- // pool.add(curItem);
- // curVertices = curItem.vertices;
- // vertexPos = 0;
- // }
+ // outside = (x <= 0 || x >= Tile.TILE_SIZE || y <= 0 || y >= Tile.TILE_SIZE)
+ // && (x - vxw <= 0 || x - vxw >= Tile.TILE_SIZE || y - vyw <= 0 || y - vyw >= Tile.TILE_SIZE);
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
if (rounded && !outside) {
- curVertices[vertexPos++] = x + uxw;
- curVertices[vertexPos++] = y + uyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw;
- curVertices[vertexPos++] = y - uyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
// For rounded line edges
- curVertices[vertexPos++] = x + uxw - vxw;
- curVertices[vertexPos++] = y + uyw - vyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = -1.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = -1;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
// Add the last vertex twice to be able to draw with GL_TRIANGLE_STRIP
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = -1.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = -1;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = -1.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = -1;
} else {
if (!outside) {
@@ -365,31 +376,31 @@ class LineLayer extends Layer {
verticesCnt -= 2;
}
- curVertices[vertexPos++] = x + uxw;
- curVertices[vertexPos++] = y + uyw;
- curVertices[vertexPos++] = -1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x + uxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y + uyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = -1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
// Add the last vertex twice to be able to draw with GL_TRIANGLE_STRIP
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
if (vertexPos == MAX) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
vertexPos = 0;
}
- curVertices[vertexPos++] = x - uxw - vxw;
- curVertices[vertexPos++] = y - uyw - vyw;
- curVertices[vertexPos++] = 1.0f;
- curVertices[vertexPos++] = 0.0f;
+ curVertices[vertexPos++] = (short) ((x - uxw - vxw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = (short) ((y - uyw - vyw) * SCALE_FACTOR);
+ curVertices[vertexPos++] = 1;
+ curVertices[vertexPos++] = 0;
}
diff --git a/src/org/mapsforge/android/glrenderer/LineLayers.java b/src/org/mapsforge/android/glrenderer/LineLayers.java
index 97ebd51a..6c1bd674 100644
--- a/src/org/mapsforge/android/glrenderer/LineLayers.java
+++ b/src/org/mapsforge/android/glrenderer/LineLayers.java
@@ -16,57 +16,113 @@ package org.mapsforge.android.glrenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
class LineLayers {
private static int NUM_VERTEX_FLOATS = 4;
- static FloatBuffer compileLayerData(LineLayer layers, FloatBuffer buf) {
- FloatBuffer fbuf = buf;
- int size = 0;
-
- for (LineLayer l = layers; l != null; l = l.next)
- size += l.verticesCnt;
-
- size *= NUM_VERTEX_FLOATS;
-
- if (buf == null || buf.capacity() < size) {
- ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
- ByteOrder.nativeOrder());
- fbuf = bbuf.asFloatBuffer();
- } else {
- fbuf.clear();
- }
- int pos = 0;
-
- PoolItem last = null, items = null;
-
- for (LineLayer l = layers; l != null; l = l.next) {
- if (l.isOutline)
- continue;
-
- for (PoolItem item = l.pool; item != null; item = item.next) {
- fbuf.put(item.vertices, 0, item.used);
- last = item;
- }
- l.offset = pos;
- pos += l.verticesCnt;
-
- if (last != null) {
- last.next = items;
- items = l.pool;
- }
-
- l.pool = null;
- }
-
- VertexPool.add(items);
-
- fbuf.flip();
-
- return fbuf;
- }
+ // static FloatBuffer compileLayerData(LineLayer layers, FloatBuffer buf) {
+ // FloatBuffer fbuf = buf;
+ // int size = 0;
+ //
+ // for (LineLayer l = layers; l != null; l = l.next)
+ // size += l.verticesCnt;
+ //
+ // size *= NUM_VERTEX_FLOATS;
+ //
+ // if (buf == null || buf.capacity() < size) {
+ // ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
+ // ByteOrder.nativeOrder());
+ // fbuf = bbuf.asFloatBuffer();
+ // } else {
+ // fbuf.clear();
+ // }
+ // int pos = 0;
+ //
+ // PoolItem last = null, items = null;
+ //
+ // for (LineLayer l = layers; l != null; l = l.next) {
+ // if (l.isOutline)
+ // continue;
+ //
+ // for (PoolItem item = l.pool; item != null; item = item.next) {
+ // fbuf.put(item.vertices, 0, item.used);
+ // last = item;
+ // }
+ // l.offset = pos;
+ // pos += l.verticesCnt;
+ //
+ // if (last != null) {
+ // last.next = items;
+ // items = l.pool;
+ // }
+ //
+ // l.pool = null;
+ // }
+ //
+ // VertexPool.add(items);
+ //
+ // fbuf.flip();
+ //
+ // return fbuf;
+ // }
+ //
+ // static ShortBuffer compileLayerData(LineLayer layers, ShortBuffer buf) {
+ // int size = 0;
+ // ShortBuffer sbuf = buf;
+ //
+ // for (LineLayer l = layers; l != null; l = l.next)
+ // 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.clear();
+ // }
+ // int pos = 0;
+ //
+ // short[] data = new short[PoolItem.SIZE];
+ //
+ // PoolItem last = null, items = null;
+ //
+ // for (LineLayer l = layers; l != null; l = l.next) {
+ // if (l.isOutline)
+ // continue;
+ //
+ // for (PoolItem item = l.pool; item != null; item = item.next) {
+ // PoolItem.toHalfFloat(item, data);
+ // sbuf.put(data, 0, item.used);
+ // last = item;
+ // }
+ //
+ // l.offset = pos;
+ // pos += l.verticesCnt;
+ //
+ // if (last != null) {
+ // last.next = items;
+ // items = l.pool;
+ // }
+ //
+ // l.pool = null;
+ // }
+ //
+ // VertexPool.add(items);
+ //
+ // sbuf.flip();
+ //
+ // return sbuf;
+ // }
+ //
+ // static void clear(LineLayer layer) {
+ // for (LineLayer l = layer; l != null; l = l.next) {
+ // if (l.pool != null)
+ // VertexPool.add(l.pool);
+ // }
+ // }
static ShortBuffer compileLayerData(LineLayer layers, ShortBuffer buf) {
int size = 0;
@@ -86,17 +142,18 @@ class LineLayers {
}
int pos = 0;
- short[] data = new short[PoolItem.SIZE];
+ // short[] data = new short[PoolItem.SIZE];
- PoolItem last = null, items = null;
+ ShortItem last = null, items = null;
for (LineLayer l = layers; l != null; l = l.next) {
if (l.isOutline)
continue;
- for (PoolItem item = l.pool; item != null; item = item.next) {
- PoolItem.toHalfFloat(item, data);
- sbuf.put(data, 0, item.used);
+ for (ShortItem item = l.pool; item != null; item = item.next) {
+ // PoolItem.toHalfFloat(item, data);
+ // sbuf.put(data, 0, item.used);
+ sbuf.put(item.vertices, 0, item.used);
last = item;
}
@@ -111,7 +168,7 @@ class LineLayers {
l.pool = null;
}
- VertexPool.add(items);
+ ShortPool.add(items);
sbuf.flip();
@@ -121,7 +178,7 @@ class LineLayers {
static void clear(LineLayer layer) {
for (LineLayer l = layer; l != null; l = l.next) {
if (l.pool != null)
- VertexPool.add(l.pool);
+ ShortPool.add(l.pool);
}
}
}
diff --git a/src/org/mapsforge/android/glrenderer/MapGenerator.java b/src/org/mapsforge/android/glrenderer/MapGenerator.java
index 35e756e6..952dd687 100644
--- a/src/org/mapsforge/android/glrenderer/MapGenerator.java
+++ b/src/org/mapsforge/android/glrenderer/MapGenerator.java
@@ -49,6 +49,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
private static final byte STROKE_MIN_ZOOM_LEVEL = 12;
private static final byte LAYERS = 11;
private static final double f900913 = 20037508.342789244;
+ // 134217728
+ // 2147483648.000
private static RenderTheme renderTheme;
@@ -77,7 +79,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
*/
public MapGenerator() {
Log.d(TAG, "init DatabaseRenderer");
- VertexPool.init();
}
private float mPoiX = 256;
@@ -143,12 +144,10 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
private boolean mProjectedResult;
private float mSimplify;
- private boolean projectToTile(boolean area) {
+ private boolean projectToTile() {
if (mProjected)
return mProjectedResult;
- // float minx = Float.MAX_VALUE, miny = Float.MAX_VALUE, maxx = Float.MIN_VALUE, maxy = Float.MIN_VALUE;
-
float[] coords = mWayNodes;
long x = mCurrentTile.x;
@@ -186,17 +185,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
lat = (float) (Math.log((1.0 + sinLat) / (1.0 - sinLat)) * divy + dy);
}
- // if (area && i == 0) {
- // if (lon < minx)
- // minx = lon;
- // if (lon > maxx)
- // maxx = lon;
- // if (lat < miny)
- // miny = lat;
- // if (lat > maxy)
- // maxy = lat;
- // }
-
if (cnt != 0) {
// drop small distance intermediate nodes
@@ -214,15 +202,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
cnt += 2;
}
- // if (area) {
- // // Log.d(TAG, "area:" + (maxx - minx) * (maxy - miny));
- // if ((maxx - minx) * (maxy - miny) < 2000 / mCurrentTile.zoomLevel) {
- // mProjected = true;
- // mProjectedResult = false;
- // return false;
- // }
- // }
-
mWays[i] = (short) cnt;
}
mProjected = true;
@@ -239,19 +218,12 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
@Override
public void renderWay(byte layer, Tag[] tags, float[] wayNodes, short[] wayLength,
- boolean changed) {
+ boolean closed) {
- // Log.d(TAG, "render way: " + layer);
mTagName = null;
-
mProjected = false;
+
mDrawingLayer = getValidLayer(layer) * mLevels;
-
- // int len = wayLength[0];
- // boolean closed = (wayNodes[0] == wayNodes[len - 2] &&
- // wayNodes[1] == wayNodes[len - 1]);
-
- boolean closed = changed;
mSimplify = 0.5f;
if (closed) {
@@ -272,15 +244,12 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
// mRenderInstructions[i].renderWay(this, tags);
// }
- // prevClosed = closed;
mRenderInstructions = MapGenerator.renderTheme.matchWay(this, tags,
(byte) (mCurrentTile.zoomLevel + 0),
closed, true);
if (mRenderInstructions == null && mDebugDrawUnmatched)
debugUnmatched(closed, tags);
-
- // firstMatch = false;
}
private void debugUnmatched(boolean closed, Tag[] tags) {
@@ -312,9 +281,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
mLabels = new ArrayList();
mLabels.add(new TextItem(mWayNodes[0], mWayNodes[1], mTagName.value, caption));
}
-
- // if (caption.textKey == mTagEmptyName.key)
- // mLabels.add(new TextItem(mPoiX, mPoiY, mTagName.value, caption));
}
@Override
@@ -350,55 +316,41 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
}
+ private int countLines;
+ private int countNodes;
+
@Override
public void renderWay(Line line) {
- projectToTile(false);
+ projectToTile();
LineLayer outlineLayer = null;
LineLayer lineLayer = null;
int numLayer = mDrawingLayer + line.level;
- // LineLayer l = mLineLayers;
- //
- // for (; l != null; l = l.next)
- // if (l.next == null || l.next.layer > numLayer)
- // break;
- //
- // if (l == null || l == mLineLayers) {
- // // insert at start
- // lineLayer = new LineLayer(numLayer, line, false);
- // lineLayer.next = mLineLayers;
- // mLineLayers = lineLayer;
- // } else if (l.layer == numLayer) {
- // lineLayer = l;
- // } else {
- // // insert between current and next layer
- // lineLayer = new LineLayer(numLayer, line, false);
- // lineLayer.next = l.next;
- // l.next = lineLayer;
- // }
+ LineLayer l = mLineLayers;
- // FIXME simplify this...
if (mCurLineLayer != null && mCurLineLayer.layer == numLayer) {
lineLayer = mCurLineLayer;
- } else if (mLineLayers == null || mLineLayers.layer > numLayer) {
+ } else if (l == null || l.layer > numLayer) {
// insert new layer at start
lineLayer = new LineLayer(numLayer, line, false);
- lineLayer.next = mLineLayers;
+ lineLayer.next = l;
mLineLayers = lineLayer;
} else {
- for (LineLayer l = mLineLayers; l != null; l = l.next) {
+ while (l != null) {
+ // found layer
if (l.layer == numLayer) {
lineLayer = l;
break;
}
+ // insert new layer between current and next layer
if (l.next == null || l.next.layer > numLayer) {
lineLayer = new LineLayer(numLayer, line, false);
- // insert new layer between current and next layer
lineLayer.next = l.next;
l.next = lineLayer;
}
+ l = l.next;
}
}
@@ -421,9 +373,11 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
int length = mWays[i];
// need at least two points
- if (length >= 4)
+ if (length >= 4) {
lineLayer.addLine(mWayNodes, pos, length, w, line.round);
-
+ countLines++;
+ countNodes += length;
+ }
pos += length;
}
@@ -437,23 +391,26 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
numLayer = mDrawingLayer + outline.level;
- if (mLineLayers == null || mLineLayers.layer > numLayer) {
+ l = mLineLayers;
+
+ if (l == null || l.layer > numLayer) {
// insert new layer at start
outlineLayer = new LineLayer(numLayer, outline, true);
- outlineLayer.next = mLineLayers;
+ outlineLayer.next = l;
mLineLayers = outlineLayer;
} else {
- for (LineLayer l = mLineLayers; l != null; l = l.next) {
+ while (l != null) {
if (l.layer == numLayer) {
outlineLayer = l;
break;
}
+ // insert new layer between current and next layer
if (l.next == null || l.next.layer > numLayer) {
outlineLayer = new LineLayer(numLayer, outline, true);
- // insert new layer between current and next layer
outlineLayer.next = l.next;
l.next = outlineLayer;
}
+ l = l.next;
}
}
@@ -467,33 +424,36 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
if (!mDebugDrawPolygons)
return;
- // if (!projectToTile(mCurrentTile.zoomLevel < 14))
- if (!projectToTile(false))
+ if (!projectToTile())
return;
int numLayer = mDrawingLayer + area.level;
+
PolygonLayer layer = null;
+ PolygonLayer l = mPolyLayers;
if (mCurPolyLayer != null && mCurPolyLayer.layer == numLayer) {
layer = mCurPolyLayer;
- } else if (mPolyLayers == null || mPolyLayers.layer > numLayer) {
+ } else if (l == null || l.layer > numLayer) {
// insert new layer at start
layer = new PolygonLayer(numLayer, area);
- layer.next = mPolyLayers;
+ layer.next = l;
mPolyLayers = layer;
} else {
- for (PolygonLayer l = mPolyLayers; l != null; l = l.next) {
- if (l.layer >= numLayer) {
+ while (l != null) {
+
+ if (l.layer == numLayer) {
layer = l;
break;
}
+ // insert new layer between current and next layer
if (l.next == null || l.next.layer > numLayer) {
layer = new PolygonLayer(numLayer, area);
- // insert new layer between current and next layer
layer.next = l.next;
l.next = layer;
}
+ l = l.next;
}
}
if (layer == null)
@@ -536,9 +496,6 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
@Override
public boolean executeJob(MapGeneratorJob mapGeneratorJob) {
- if (!(mapGeneratorJob.tile instanceof GLMapTile))
- return false;
-
if (mMapDatabase == null)
return false;
@@ -547,7 +504,7 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
mCurrentTile = (GLMapTile) mapGeneratorJob.tile;
mDebugDrawPolygons = !mapGeneratorJob.debugSettings.mDisablePolygons;
mDebugDrawUnmatched = mapGeneratorJob.debugSettings.mDrawUnmatchted;
- if (mCurrentTile.isLoading || mCurrentTile.isDrawn)
+ if (mCurrentTile.isLoading || mCurrentTile.isReady)
return false;
mCurrentTile.isLoading = true;
@@ -561,7 +518,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
mLabels = null;
// firstMatch = true;
-
+ countLines = 0;
+ countNodes = 0;
mProjectionScaleFactor = (float) (1.0 / Math.cos(MercatorProjection
.pixelYToLatitude(mCurrentTile.pixelY, mCurrentTile.zoomLevel)
* (Math.PI / 180))); // / 1.5f;
@@ -576,7 +534,8 @@ public class MapGenerator implements IMapGenerator, IRenderCallback, IMapDatabas
}
if (mapGeneratorJob.debugSettings.mDrawTileFrames) {
- mTagName = new Tag("name", mCurrentTile.toString(), false);
+ mTagName = new Tag("name", countLines + " " + countNodes + " "
+ + mCurrentTile.toString(), false);
mPoiX = 10;
mPoiY = 10;
MapGenerator.renderTheme.matchNode(this, debugTagWay, (byte) 0);
diff --git a/src/org/mapsforge/android/glrenderer/MapRenderer.java b/src/org/mapsforge/android/glrenderer/MapRenderer.java
index da15fb87..e11b9c07 100644
--- a/src/org/mapsforge/android/glrenderer/MapRenderer.java
+++ b/src/org/mapsforge/android/glrenderer/MapRenderer.java
@@ -21,8 +21,6 @@ import static android.opengl.GLES20.GL_DEPTH_TEST;
import static android.opengl.GLES20.GL_DITHER;
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
import static android.opengl.GLES20.GL_EQUAL;
-import static android.opengl.GLES20.GL_EXTENSIONS;
-import static android.opengl.GLES20.GL_FLOAT;
import static android.opengl.GLES20.GL_INVERT;
import static android.opengl.GLES20.GL_NEVER;
import static android.opengl.GLES20.GL_ONE;
@@ -50,7 +48,6 @@ import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glFinish;
import static android.opengl.GLES20.glGenBuffers;
import static android.opengl.GLES20.glGetAttribLocation;
-import static android.opengl.GLES20.glGetString;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glScissor;
import static android.opengl.GLES20.glStencilFunc;
@@ -65,7 +62,6 @@ import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;
-import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Collections;
@@ -102,14 +98,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private static final String TAG = "MapRenderer";
private static final int MB = 1024 * 1024;
- // private boolean mTriangulate = false;
-
private static int CACHE_TILES_MAX = 250;
private static int CACHE_TILES = CACHE_TILES_MAX;
private static int LIMIT_BUFFERS = 20 * MB;
- private static final int OES_HALF_FLOAT = 0x8D61;
- private static final int FLOAT_BYTES = 4;
+ // private static final int OES_HALF_FLOAT = 0x8D61;
+ // private static final int FLOAT_BYTES = 4;
private static final int SHORT_BYTES = 2;
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
private static final int LINE_VERTICES_DATA_POS_OFFSET = 0;
@@ -118,16 +112,16 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private static int STENCIL_BITS = 8;
private final MapView mMapView;
- private final ArrayList mJobList;
- private final ArrayList mVBOs;
- private final TileCacheKey mTileCacheKey;
- private final HashMap mTiles;
- private final ArrayList mTileList;
- private final TileDistanceSort mTileDistanceSort;
+ private static ArrayList mJobList;
+ private static ArrayList mVBOs;
+ private static TileCacheKey mTileCacheKey;
+ private static HashMap mTiles;
+ private static ArrayList mTileList;
+ private static TileDistanceSort mTileDistanceSort;
- private DebugSettings mDebugSettings;
- private JobParameters mJobParameter;
- private MapPosition mMapPosition, mPrevMapPosition;
+ private static DebugSettings mDebugSettings;
+ private static JobParameters mJobParameter;
+ private static MapPosition mMapPosition, mPrevMapPosition;
private static int mWidth, mHeight;
private static float mAspect;
@@ -141,7 +135,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private static long mTileX, mTileY;
private static int rotateBuffers = 2;
- private static FloatBuffer floatBuffer[];
private static ShortBuffer shortBuffer[];
static boolean useHalfFloat = false;
@@ -171,7 +164,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
// nextTiles is swapped with curTiles in onDrawFrame in GL thread.
private static TilesData newTiles, nextTiles, curTiles;
- private boolean mInitial;
+ private static boolean mInitial;
// shader handles
private static int lineProgram;
@@ -198,7 +191,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
*/
public MapRenderer(MapView mapView) {
Log.d(TAG, "init MapRenderer");
+
mMapView = mapView;
+
+ if (mInitial)
+ return;
+
mDebugSettings = mapView.getDebugSettings();
mVBOs = new ArrayList();
@@ -214,7 +212,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
mUpdateTiles = false;
}
- private void updateTileDistances() {
+ private static void updateTileDistances() {
int h = (Tile.TILE_SIZE >> 1);
byte zoom = mMapPosition.zoomLevel;
long x = mTileX * (Tile.TILE_SIZE) + h;
@@ -222,57 +220,57 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
int diff;
long dx, dy;
- // TODO this could be optimized to consider move/zoom direction
+ // TODO this could need some fixing..
+ // and be optimized to consider move/zoom direction
for (int i = 0, n = mTileList.size(); i < n; i++) {
GLMapTile t = mTileList.get(i);
diff = (t.zoomLevel - zoom);
- if (diff != 0) {
- if (diff > 0) {
- // tile zoom level is child of current
- dx = ((t.pixelX + h) >> diff) - x;
- dy = ((t.pixelY + h) >> diff) - y;
- } else {
- // tile zoom level is parent of current
- dx = ((t.pixelX + h) << -diff) - x;
- dy = ((t.pixelY + h) << -diff) - y;
- }
-
- if (diff == -1) {
- 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 {
+ if (diff == 0) {
dx = (t.pixelX + h) - x;
dy = (t.pixelY + h) - y;
dy *= mAspect;
- t.distance = (1 + ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)));// * 2;
+ t.distance = (1 + ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)));
+ } else if (diff > 0) {
+ // tile zoom level is child of current
+ dx = ((t.pixelX + h) >> diff) - x;
+ dy = ((t.pixelY + h) >> diff) - y;
+
+ dy *= mAspect;
+ t.distance = 2 * ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy));
+
+ } else {
+ // tile zoom level is parent of current
+ dx = ((t.pixelX + h) << -diff) - x;
+ dy = ((t.pixelY + h) << -diff) - y;
+ dy *= mAspect;
+
+ t.distance = ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy));
+ // prefer lower zoom level, it covers a larger area
+ t.distance /= -diff;
}
- // Log.d(TAG, t + " " + t.distance);
+
+ // Log.d(TAG, diff + " " + (float) t.distance / Tile.TILE_SIZE + " " + t);
}
}
- private void limitCache(int remove) {
+ private static void limitCache(int remove) {
byte z = mMapPosition.zoomLevel;
for (int j = mTileList.size() - 1, cnt = 0; cnt < remove && j > 0; j--, cnt++) {
GLMapTile t = mTileList.remove(j);
if (t.isActive) {
- Log.d(TAG, "EEEK removing active tile");
+ // Log.d(TAG, "EEEK removing active tile");
mTileList.add(t);
continue;
}
// check if this tile is used as proxy for not yet drawn active tile
- if (t.isDrawn || t.newData || t.isLoading) {
+ // TODO to be simplified...
+ if (t.isReady || t.newData || t.isLoading) {
if (t.zoomLevel == z + 1) {
if (t.parent != null && t.parent.isActive
- && !(t.parent.isDrawn || t.parent.newData)) {
+ && !(t.parent.isReady || t.parent.newData)) {
mTileList.add(t);
Log.d(TAG, "EEEK removing active proxy child");
continue;
@@ -281,7 +279,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
GLMapTile c = null;
for (int i = 0; i < 4; i++) {
c = t.child[i];
- if (c != null && c.isActive && !(c.isDrawn || c.newData))
+ if (c != null && c.isActive && !(c.isReady || c.newData))
break;
c = null;
}
@@ -299,7 +297,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
for (int k = 0; k < 4; k++) {
c2 = c.child[k];
if (c2 != null && c2.isActive
- && !(c2.isDrawn || c2.newData))
+ && !(c2.isReady || c2.newData))
break;
c2 = null;
@@ -344,6 +342,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
t.polygonVBO = null;
}
}
+ if (t.newData) {
+ // Log.d(TAG, ">>>> clear unsused data ! " + t + "<<<<");
+ LineLayers.clear(t.lineLayers);
+ PolygonLayers.clear(t.polygonLayers);
+ }
}
}
@@ -425,14 +428,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
newTiles.tiles[tiles++] = tile;
- if (!tile.isDrawn && !tile.newData && !tile.isLoading) {
+ if (!tile.isReady && !tile.newData && !tile.isLoading) {
MapGeneratorJob job = new MapGeneratorJob(tile, mJobParameter,
mDebugSettings);
mJobList.add(job);
}
// prefetch parent
- // if (tile.parent != null && !tile.parent.isDrawn && !tile.parent.newData
+ // if (tile.parent != null && !tile.parent.isReady && !tile.parent.newData
// && !tile.parent.isLoading) {
// MapGeneratorJob job = new MapGeneratorJob(tile.parent, mJobParameter,
// mDebugSettings);
@@ -484,7 +487,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
return true;
}
- private void setChildren(GLMapTile tile) {
+ private static void setChildren(GLMapTile tile) {
long xx = tile.tileX << 1;
long yy = tile.tileY << 1;
@@ -597,23 +600,42 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
float alpha = 1.0f;
- if (l.area.fade >= mDrawZ) {
+ if (l.area.fade >= mDrawZ || l.area.color[3] != 1.0) {
alpha = (mDrawScale > 1.3f ? mDrawScale : 1.3f) - alpha;
if (alpha > 1.0f)
alpha = 1.0f;
+ alpha *= l.area.color[3];
+
if (!blend) {
glEnable(GL_BLEND);
blend = true;
}
- } else if (blend) {
- glDisable(GL_BLEND);
- blend = false;
- }
+ glUniform4f(hPolygonColor,
+ l.area.color[0], l.area.color[1], l.area.color[2], alpha);
- glUniform4f(hPolygonColor,
- l.area.color[0], l.area.color[1], l.area.color[2], alpha);
+ } else if (l.area.blend == mDrawZ) {
+ alpha = mDrawScale - 1.0f;
+ if (alpha > 1.0f)
+ alpha = 1.0f;
+ else if (alpha < 0)
+ alpha = 0;
+
+ glUniform4f(hPolygonColor,
+ l.area.color[0] * (1 - alpha) + l.area.blendColor[0] * alpha,
+ l.area.color[1] * (1 - alpha) + l.area.blendColor[1] * alpha,
+ l.area.color[2] * (1 - alpha) + l.area.blendColor[2] * alpha, 1);
+ } else {
+ if (blend) {
+ glDisable(GL_BLEND);
+ blend = false;
+ }
+ if (l.area.blend <= mDrawZ && l.area.blend > 0)
+ glUniform4fv(hPolygonColor, 1, l.area.blendColor, 0);
+ else
+ glUniform4fv(hPolygonColor, 1, l.area.color, 0);
+ }
// set stencil buffer mask used to draw this layer
glStencilFunc(GL_EQUAL, 0xff, 1 << c);
@@ -632,26 +654,22 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (tile.polygonLayers == null)
return true;
- glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
+ // Nexus doesnt like using changing scissor in combination with stencil...
+ // glScissor(tile.sx, tile.sy, tile.sw, tile.sh);
if (mLastBoundVBO != tile.polygonVBO.id) {
mLastBoundVBO = tile.polygonVBO.id;
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
- if (useHalfFloat) {
- glVertexAttribPointer(hPolygonVertexPosition, 2,
- OES_HALF_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
- } else {
- glVertexAttribPointer(hPolygonVertexPosition, 2,
- GL_FLOAT, false, 0,
- POLYGON_VERTICES_DATA_POS_OFFSET);
- }
+ glVertexAttribPointer(hPolygonVertexPosition, 2,
+ GLES20.GL_SHORT, false, 0,
+ POLYGON_VERTICES_DATA_POS_OFFSET);
}
+
setMatrix(tile, diff);
glUniformMatrix4fv(hPolygonMatrix, 1, false, mMVPMatrix, 0);
- boolean firstPass = true;
+ // boolean firstPass = true;
for (PolygonLayer l = tile.polygonLayers; l != null; l = l.next) {
// fade out polygon layers (set in RederTheme)
@@ -665,19 +683,19 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
// never pass the test, i.e. always apply first stencil op (sfail)
glStencilFunc(GL_NEVER, 0, 0xff);
- if (firstPass)
- firstPass = false;
- else {
- GLES20.glFlush();
+ // if (firstPass)
+ // firstPass = false;
+ // else {
+ // GLES20.glFlush();
- // clear stencilbuffer
- glStencilMask(0xFF);
- // glClear(GL_STENCIL_BUFFER_BIT);
+ // clear stencilbuffer
+ glStencilMask(0xFF);
+ // glClear(GL_STENCIL_BUFFER_BIT);
- // clear stencilbuffer (tile region)
- glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- }
+ // clear stencilbuffer (tile region)
+ glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ // }
// stencil op for stencil method polygon drawing
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
@@ -720,19 +738,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
mLastBoundVBO = tile.lineVBO.id;
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
- if (useHalfFloat) {
- glVertexAttribPointer(hLineVertexPosition, 2, OES_HALF_FLOAT,
- false, 8, LINE_VERTICES_DATA_POS_OFFSET);
+ glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT,
+ false, 8, LINE_VERTICES_DATA_POS_OFFSET);
- glVertexAttribPointer(hLineTexturePosition, 2, OES_HALF_FLOAT,
- false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
- } else {
- glVertexAttribPointer(hLineVertexPosition, 2, GL_FLOAT,
- false, 16, LINE_VERTICES_DATA_POS_OFFSET);
+ glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT,
+ false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
- glVertexAttribPointer(hLineTexturePosition, 2, GL_FLOAT,
- false, 16, LINE_VERTICES_DATA_TEX_OFFSET);
- }
}
if (diff != 0)
z = (diff > 0) ? (1 << diff) : 1.0f / (1 << -diff);
@@ -888,7 +899,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private boolean uploadTileData(GLMapTile tile) {
ShortBuffer sbuf = null;
- FloatBuffer fbuf = null;
// double start = SystemClock.uptimeMillis();
@@ -914,68 +924,42 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
int size = 0;
- if (useHalfFloat) {
- sbuf = LineLayers.compileLayerData(tile.lineLayers,
- shortBuffer[uploadCnt * 2]);
- size = sbuf.remaining();
- shortBuffer[uploadCnt * 2] = sbuf;
- } else {
- fbuf = LineLayers.compileLayerData(tile.lineLayers,
- floatBuffer[uploadCnt * 2]);
- size = fbuf.remaining();
- floatBuffer[uploadCnt * 2] = fbuf;
- }
+ sbuf = LineLayers.compileLayerData(tile.lineLayers,
+ shortBuffer[uploadCnt * 2]);
+ size = sbuf.remaining();
+ shortBuffer[uploadCnt * 2] = sbuf;
if (size > 0) {
mBufferMemoryUsage -= tile.lineVBO.size;
glBindBuffer(GL_ARRAY_BUFFER, tile.lineVBO.id);
+ // Nexus doesnt like this either
// glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
- if (useHalfFloat) {
- tile.lineVBO.size = size * SHORT_BYTES;
- glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
- sbuf, GL_DYNAMIC_DRAW);
- } else {
- tile.lineVBO.size = size * FLOAT_BYTES;
- glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
- fbuf, GL_DYNAMIC_DRAW);
- }
-
+ tile.lineVBO.size = size * SHORT_BYTES;
+ glBufferData(GL_ARRAY_BUFFER, tile.lineVBO.size,
+ sbuf, GL_DYNAMIC_DRAW);
mBufferMemoryUsage += tile.lineVBO.size;
} else {
tile.lineLayers = null;
}
- if (useHalfFloat) {
- sbuf = PolygonLayers.compileLayerData(tile.polygonLayers,
- shortBuffer[uploadCnt * 2 + 1]);
- size = sbuf.remaining();
- shortBuffer[uploadCnt * 2 + 1] = sbuf;
- } else {
- fbuf = PolygonLayers.compileLayerData(tile.polygonLayers,
- floatBuffer[uploadCnt * 2 + 1]);
- size = fbuf.remaining();
- floatBuffer[uploadCnt * 2 + 1] = fbuf;
- }
+ sbuf = PolygonLayers.compileLayerData(tile.polygonLayers,
+ shortBuffer[uploadCnt * 2 + 1]);
+ size = sbuf.remaining();
+ shortBuffer[uploadCnt * 2 + 1] = sbuf;
+
// Upload polygon data to vertex buffer object
if (size > 0) {
mBufferMemoryUsage -= tile.polygonVBO.size;
glBindBuffer(GL_ARRAY_BUFFER, tile.polygonVBO.id);
- // glBufferData(GL_ARRAY_BUFFER, 0, null,
- // GL_DYNAMIC_DRAW);
- if (useHalfFloat) {
- tile.polygonVBO.size = size * SHORT_BYTES;
- glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
- sbuf, GL_DYNAMIC_DRAW);
- } else {
- tile.polygonVBO.size = size * FLOAT_BYTES;
- glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
- fbuf, GL_DYNAMIC_DRAW);
- }
+ tile.polygonVBO.size = size * SHORT_BYTES;
+ glBufferData(GL_ARRAY_BUFFER, tile.polygonVBO.size,
+ sbuf, GL_DYNAMIC_DRAW);
+
mBufferMemoryUsage += tile.polygonVBO.size;
} else {
@@ -983,7 +967,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
tile.newData = false;
- tile.isDrawn = true;
+ tile.isReady = true;
tile.isLoading = false;
// double compile = SystemClock.uptimeMillis();
@@ -1007,8 +991,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (timing)
start = SystemClock.uptimeMillis();
- glStencilMask(0xFF);
- glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ // glStencilMask(0xFF);
+ // glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT);
synchronized (this) {
mDrawX = mCurX;
@@ -1072,7 +1057,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
continue;
}
- if (!tile.isDrawn) {
+ if (!tile.isReady) {
if (tile.parent != null) {
if (tile.parent.newData)
uploadTileData(tile.parent);
@@ -1099,8 +1084,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (timing)
clear_time = (SystemClock.uptimeMillis() - start);
- glEnable(GL_SCISSOR_TEST);
-
+ // glEnable(GL_SCISSOR_TEST);
+ glScissor(0, 0, mWidth, mHeight);
glUseProgram(polygonProgram);
glEnableVertexAttribArray(hPolygonVertexPosition);
@@ -1112,7 +1097,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (tiles[i].isVisible) {
GLMapTile tile = tiles[i];
- if (tile.isDrawn)
+ if (tile.isReady)
drawPolygons(tile, 0);
else
drawProxyPolygons(tile);
@@ -1129,6 +1114,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
poly_time = (SystemClock.uptimeMillis() - start);
}
+ // glEnable(GL_SCISSOR_TEST);
+
// Draw lines
glEnable(GL_BLEND);
glUseProgram(lineProgram);
@@ -1140,7 +1127,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (tiles[i].isVisible) {
GLMapTile tile = tiles[i];
- if (tile.isDrawn)
+ if (tile.isReady)
drawLines(tile, 0);
else
drawProxyLines(tile);
@@ -1150,10 +1137,11 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
glDisableVertexAttribArray(hLineVertexPosition);
glDisableVertexAttribArray(hLineTexturePosition);
- glDisable(GL_SCISSOR_TEST);
+ glScissor(0, 0, mWidth, mHeight);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- mTextRenderer.beginDraw();
+
+ mTextRenderer.beginDraw(mDrawScale);
for (int i = 0; i < tileCnt; i++) {
if (!tiles[i].isVisible || tiles[i].texture == null)
continue;
@@ -1243,16 +1231,16 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
}
- String ext = glGetString(GL_EXTENSIONS);
+ // String ext = glGetString(GL_EXTENSIONS);
- if (ext.indexOf("GL_OES_vertex_half_float") >= 0) {
- useHalfFloat = true;
- shortBuffer = new ShortBuffer[rotateBuffers * 2];
- }
- else {
- floatBuffer = new FloatBuffer[rotateBuffers * 2];
- }
- Log.d(TAG, "Extensions: " + ext);
+ // if (ext.indexOf("GL_OES_vertex_half_float") >= 0) {
+ // useHalfFloat = true;
+ shortBuffer = new ShortBuffer[rotateBuffers * 2];
+ // }
+ // else {
+ // floatBuffer = new FloatBuffer[rotateBuffers * 2];
+ // }
+ // Log.d(TAG, "Extensions: " + ext);
hLineMatrix = glGetUniformLocation(lineProgram, "u_center");
hLineMode = glGetUniformLocation(lineProgram, "u_mode");
@@ -1289,13 +1277,15 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
glDisable(GL_DITHER);
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ glEnable(GL_SCISSOR_TEST);
GlUtils.checkGlError("onSurfaceCreated");
}
private void drawProxyLines(GLMapTile tile) {
- if (tile.parent != null && tile.parent.isDrawn) {
+ if (tile.parent != null && tile.parent.isReady) {
tile.parent.sx = tile.sx;
tile.parent.sy = tile.sy;
tile.parent.sw = tile.sw;
@@ -1306,7 +1296,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
// scissor coordinates already set for polygons
for (int i = 0; i < 4; i++) {
GLMapTile c = tile.child[i];
- if (c != null && c.isDrawn && c.isVisible) {
+ if (c != null && c.isReady && c.isVisible) {
drawLines(c, 1);
drawn++;
}
@@ -1314,7 +1304,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
if (drawn < 4 && tile.parent != null) {
GLMapTile p = tile.parent.parent;
- if (p != null && p.isDrawn) {
+ if (p != null && p.isReady) {
p.sx = tile.sx;
p.sy = tile.sy;
p.sw = tile.sw;
@@ -1326,7 +1316,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
private void drawProxyPolygons(GLMapTile tile) {
- if (tile.parent != null && tile.parent.isDrawn) {
+ if (tile.parent != null && tile.parent.isReady) {
tile.parent.sx = tile.sx;
tile.parent.sy = tile.sy;
tile.parent.sw = tile.sw;
@@ -1338,7 +1328,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
for (int i = 0; i < 4; i++) {
GLMapTile c = tile.child[i];
- if (c != null && c.isDrawn && setTileScissor(c, 2)) {
+ if (c != null && c.isReady && setTileScissor(c, 2)) {
drawPolygons(c, 1);
drawn++;
}
@@ -1346,7 +1336,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (drawn < 4 && tile.parent != null) {
GLMapTile p = tile.parent.parent;
- if (p != null && p.isDrawn) {
+ if (p != null && p.isReady) {
p.sx = tile.sx;
p.sy = tile.sy;
p.sw = tile.sw;
diff --git a/src/org/mapsforge/android/glrenderer/PolygonLayer.java b/src/org/mapsforge/android/glrenderer/PolygonLayer.java
index bb8025d8..77056d53 100644
--- a/src/org/mapsforge/android/glrenderer/PolygonLayer.java
+++ b/src/org/mapsforge/android/glrenderer/PolygonLayer.java
@@ -16,21 +16,37 @@ package org.mapsforge.android.glrenderer;
import org.mapsforge.android.rendertheme.renderinstruction.Area;
-class PolygonLayer extends Layer {
+class PolygonLayer {
PolygonLayer next;
Area area;
-
+ private static final float SCALE_FACTOR = 16.0f;
private boolean first = true;
private float originX;
private float originY;
+ ShortItem pool;
+ protected ShortItem curItem;
+ int verticesCnt;
+ int offset;
+
+ final int layer;
+
PolygonLayer(int layer, Area area) {
- super(layer);
+ this.layer = layer;
this.area = area;
- curItem = VertexPool.get();
+ curItem = ShortPool.get();
pool = curItem;
}
+ short[] getNextItem() {
+ curItem.used = ShortItem.SIZE;
+
+ curItem.next = ShortPool.get();
+ curItem = curItem.next;
+
+ return curItem.vertices;
+ }
+
void addPolygon(float[] points, int pos, int length) {
verticesCnt += length / 2 + 2;
@@ -41,43 +57,48 @@ class PolygonLayer extends Layer {
originY = points[pos + 1];
}
- float[] curVertices = curItem.vertices;
+ short[] curVertices = curItem.vertices;
int outPos = curItem.used;
- if (outPos == PoolItem.SIZE) {
- curVertices = getNextPoolItem();
+ if (outPos == ShortItem.SIZE) {
+ curVertices = getNextItem();
outPos = 0;
}
- curVertices[outPos++] = originX; // Tile.TILE_SIZE >> 1;
- curVertices[outPos++] = originY; // Tile.TILE_SIZE >> 1;
+ curVertices[outPos++] = (short) (originX * SCALE_FACTOR);
+ curVertices[outPos++] = (short) (originY * SCALE_FACTOR);
int remaining = length;
int inPos = pos;
while (remaining > 0) {
- if (outPos == PoolItem.SIZE) {
- curVertices = getNextPoolItem();
+ if (outPos == ShortItem.SIZE) {
+ curVertices = getNextItem();
outPos = 0;
}
int len = remaining;
- if (len > (PoolItem.SIZE) - outPos)
- len = (PoolItem.SIZE) - outPos;
+ if (len > (ShortItem.SIZE) - outPos)
+ len = (ShortItem.SIZE) - outPos;
+
+ for (int i = 0; i < len; i++)
+ curVertices[outPos++] = (short) (points[inPos++] * SCALE_FACTOR);
+
+ // System.arraycopy(points, inPos, curVertices, outPos, len);
+
+ // outPos += len;
+ // inPos += len;
- System.arraycopy(points, inPos, curVertices, outPos, len);
- outPos += len;
- inPos += len;
remaining -= len;
}
if (outPos == PoolItem.SIZE) {
- curVertices = getNextPoolItem();
+ curVertices = getNextItem();
outPos = 0;
}
- curVertices[outPos++] = points[pos + 0];
- curVertices[outPos++] = points[pos + 1];
+ curVertices[outPos++] = (short) (points[pos + 0] * SCALE_FACTOR);
+ curVertices[outPos++] = (short) (points[pos + 1] * SCALE_FACTOR);
curItem.used = outPos;
}
diff --git a/src/org/mapsforge/android/glrenderer/PolygonLayers.java b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
index 98de333c..8bf625ee 100644
--- a/src/org/mapsforge/android/glrenderer/PolygonLayers.java
+++ b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
@@ -16,68 +16,137 @@ package org.mapsforge.android.glrenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
-import org.mapsforge.android.utils.FastMath;
import org.mapsforge.core.Tile;
class PolygonLayers {
private static final int NUM_VERTEX_FLOATS = 2;
- static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1,
- Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
- -2, Tile.TILE_SIZE + 1, -2 };
+ // static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1,
+ // Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
+ // -2, Tile.TILE_SIZE + 1, -2 };
- private static short[] mByteFillCoords = null;
+ // private static short[] mByteFillCoords = null;
- static FloatBuffer compileLayerData(PolygonLayer layers, FloatBuffer buf) {
- FloatBuffer fbuf = buf;
- int size = 4;
+ // static FloatBuffer compileLayerData(PolygonLayer layers, FloatBuffer buf) {
+ // FloatBuffer fbuf = buf;
+ // int size = 4;
+ //
+ // for (PolygonLayer l = layers; l != null; l = l.next)
+ // 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.clear();
+ // }
+ //
+ // fbuf.put(mFillCoords, 0, 8);
+ // int pos = 4;
+ //
+ // PoolItem last = null, items = null;
+ //
+ // for (PolygonLayer l = layers; l != null; l = l.next) {
+ //
+ // for (PoolItem item = l.pool; item != null; item = item.next) {
+ // fbuf.put(item.vertices, 0, item.used);
+ // last = item;
+ // }
+ // l.offset = pos;
+ // pos += l.verticesCnt;
+ //
+ // if (last != null) {
+ // last.next = items;
+ // items = l.pool;
+ // }
+ //
+ // l.pool = null;
+ // }
+ //
+ // VertexPool.add(items);
+ //
+ // fbuf.flip();
+ //
+ // return fbuf;
+ // }
+ //
+ // static final short[] tmpItem = new short[PoolItem.SIZE];
- for (PolygonLayer l = layers; l != null; l = l.next)
- size += l.verticesCnt;
+ // static ShortBuffer compileLayerData(PolygonLayer layers, ShortBuffer buf) {
+ // ShortBuffer sbuf = buf;
+ // int size = 4;
+ //
+ // for (PolygonLayer l = layers; l != null; l = l.next)
+ // 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.clear();
+ // }
+ //
+ // short[] data = tmpItem;
+ //
+ // if (mByteFillCoords == null) {
+ // mByteFillCoords = new short[8];
+ // FastMath.convertFloatToHalf(mFillCoords[0], mByteFillCoords, 0);
+ // FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 1);
+ // FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 2);
+ // FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 3);
+ // FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 4);
+ // FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 5);
+ // FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 6);
+ // FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 7);
+ // }
+ //
+ // sbuf.put(mByteFillCoords, 0, 8);
+ // int pos = 4;
+ //
+ // PoolItem last = null, items = null;
+ //
+ // for (PolygonLayer l = layers; l != null; l = l.next) {
+ //
+ // for (PoolItem item = l.pool; item != null; item = item.next) {
+ // PoolItem.toHalfFloat(item, data);
+ // sbuf.put(data, 0, item.used);
+ // last = item;
+ // }
+ //
+ // l.offset = pos;
+ // pos += l.verticesCnt;
+ //
+ // if (last != null) {
+ // last.next = items;
+ // items = l.pool;
+ // }
+ //
+ // l.pool = null;
+ // }
+ //
+ // VertexPool.add(items);
+ //
+ // sbuf.flip();
+ //
+ // return sbuf;
+ // }
+ //
+ // static void clear(PolygonLayer layers) {
+ // for (PolygonLayer l = layers; l != null; l = l.next) {
+ // if (l.pool != null)
+ // VertexPool.add(l.pool);
+ // }
+ // }
- 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.clear();
- }
-
- fbuf.put(mFillCoords, 0, 8);
- int pos = 4;
-
- PoolItem last = null, items = null;
-
- for (PolygonLayer l = layers; l != null; l = l.next) {
-
- for (PoolItem item = l.pool; item != null; item = item.next) {
- fbuf.put(item.vertices, 0, item.used);
- last = item;
- }
- l.offset = pos;
- pos += l.verticesCnt;
-
- if (last != null) {
- last.next = items;
- items = l.pool;
- }
-
- l.pool = null;
- }
-
- VertexPool.add(items);
-
- fbuf.flip();
-
- return fbuf;
- }
-
- static final short[] tmpItem = new short[PoolItem.SIZE];
+ private static short[] mFillCoords;
static ShortBuffer compileLayerData(PolygonLayer layers, ShortBuffer buf) {
ShortBuffer sbuf = buf;
@@ -96,30 +165,29 @@ class PolygonLayers {
sbuf.clear();
}
- short[] data = tmpItem;
-
- if (mByteFillCoords == null) {
- mByteFillCoords = new short[8];
- FastMath.convertFloatToHalf(mFillCoords[0], mByteFillCoords, 0);
- FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 1);
- FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 2);
- FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 3);
- FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 4);
- FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 5);
- FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 6);
- FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 7);
+ if (mFillCoords == null) {
+ short min = (-2) << 4;
+ short max = (short) ((Tile.TILE_SIZE + 1) << 4);
+ mFillCoords = new short[8];
+ mFillCoords[0] = min;
+ mFillCoords[1] = max;
+ mFillCoords[2] = max;
+ mFillCoords[3] = max;
+ mFillCoords[4] = min;
+ mFillCoords[5] = min;
+ mFillCoords[6] = max;
+ mFillCoords[7] = min;
}
- sbuf.put(mByteFillCoords, 0, 8);
+ sbuf.put(mFillCoords, 0, 8);
int pos = 4;
- PoolItem last = null, items = null;
+ ShortItem last = null, items = null;
for (PolygonLayer l = layers; l != null; l = l.next) {
- for (PoolItem item = l.pool; item != null; item = item.next) {
- PoolItem.toHalfFloat(item, data);
- sbuf.put(data, 0, item.used);
+ for (ShortItem item = l.pool; item != null; item = item.next) {
+ sbuf.put(item.vertices, 0, item.used);
last = item;
}
@@ -134,7 +202,7 @@ class PolygonLayers {
l.pool = null;
}
- VertexPool.add(items);
+ ShortPool.add(items);
sbuf.flip();
@@ -144,7 +212,7 @@ class PolygonLayers {
static void clear(PolygonLayer layers) {
for (PolygonLayer l = layers; l != null; l = l.next) {
if (l.pool != null)
- VertexPool.add(l.pool);
+ ShortPool.add(l.pool);
}
}
}
diff --git a/src/org/mapsforge/android/glrenderer/PoolItem.java b/src/org/mapsforge/android/glrenderer/PoolItem.java
deleted file mode 100644
index 1be769c1..00000000
--- a/src/org/mapsforge/android/glrenderer/PoolItem.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2012 Hannes Janetzek
- *
- * This program is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General 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 License for more details.
- *
- * You should have received a copy of the GNU Lesser General License along with
- * this program. If not, see .
- */
-
-package org.mapsforge.android.glrenderer;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-
-// TODO use byte[] for half-float, not converting on compilation (in glThread)
-
-class PoolItem {
- final float[] vertices;
- int used;
- PoolItem next;
-
- PoolItem() {
- vertices = new float[SIZE];
- used = 0;
- }
-
- static int SIZE = 128;
-
- private static final float FLOAT_HALF_PREC = 5.96046E-8f;
- private static final float FLOAT_HALF_MAX = 65504f;
-
- private static ByteBuffer byteBuffer = ByteBuffer.allocate(SIZE * 4);
- private static IntBuffer intBuffer = byteBuffer.asIntBuffer();
- private static FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
- private static int[] intArray = new int[SIZE];
-
- static void toHalfFloat(PoolItem item, short[] data) {
- floatBuffer.position(0);
- floatBuffer.put(item.vertices, 0, item.used);
- intBuffer.position(0);
- intBuffer.get(intArray, 0, item.used);
-
- int out = 0;
- for (int j = 0; j < item.used; j++) {
- float flt = item.vertices[j];
- int f = intArray[j];
-
- if (f == 0x0000000) {
- // == 0
- data[out++] = (short) 0x0000;
- } else if (f == 0x80000000) {
- // == -0
- data[out++] = (short) 0x8000;
- } else if (f == 0x3f800000) {
- // == 1
- data[out++] = (short) 0x3c00;
- } else if (f == 0xbf800000) {
- // == -1
- data[out++] = (short) 0xbc00;
- } else if (flt > FLOAT_HALF_MAX) {
- if (flt == Float.POSITIVE_INFINITY) {
- data[out++] = (short) 0x7c00;
- } else {
- data[out++] = (short) 0x7bff;
- }
- } else if (flt < -FLOAT_HALF_MAX) {
- if (flt == Float.NEGATIVE_INFINITY) {
- data[out++] = (short) 0xfc00;
- } else {
- data[out++] = (short) 0xfbff;
- }
- } else if (flt > 0f && flt < FLOAT_HALF_PREC) {
- data[out++] = (short) 0x0001;
- } else if (flt < 0f && flt > -FLOAT_HALF_PREC) {
- data[out++] = (short) 0x8001;
- } else {
- // maybe just ignore and set 0? -- we'll see. when this happens
- if (f == 0x7fc00000)
- throw new UnsupportedOperationException(
- "NaN to half conversion not supported!");
-
- data[out++] = (short) (((f >> 16) & 0x8000)
- | ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
- | ((f >> 13) & 0x03ff));
- }
- }
- }
-}
diff --git a/src/org/mapsforge/android/glrenderer/Shaders.java b/src/org/mapsforge/android/glrenderer/Shaders.java
index f4e30903..e632b20d 100644
--- a/src/org/mapsforge/android/glrenderer/Shaders.java
+++ b/src/org/mapsforge/android/glrenderer/Shaders.java
@@ -22,10 +22,12 @@ class Shaders {
+ "attribute vec4 a_position;"
+ "attribute vec2 a_st;"
+ "varying vec2 v_st;"
+ + "const vec4 scale = vec4(1.0/16.0, 1.0/16.0, 0.0, 1.0);"
+ "void main() {"
// + " gl_Position = u_center * vec4(a_position.x, a_position.y, 0.0, 1.0);"
// + " v_st = a_position.zw;"
- + " gl_Position = u_center * a_position;"
+ + " gl_Position = u_center * (scale * a_position);"
+ // + " gl_Position = u_center * a_position;"
+ " v_st = a_st;"
+ "}";
@@ -165,8 +167,9 @@ class Shaders {
+ "precision mediump float; \n"
+ "uniform mat4 u_center;\n"
+ "attribute vec4 a_position;"
+ + "const vec4 scale = vec4(1.0/16.0, 1.0/16.0, 0.0, 1.0);"
+ "void main() {"
- + " gl_Position = u_center * a_position;"
+ + " gl_Position = u_center * (scale * a_position);"
+ "}";
final static String gPolygonFragmentShader = ""
diff --git a/src/org/mapsforge/android/glrenderer/ShortItem.java b/src/org/mapsforge/android/glrenderer/ShortItem.java
new file mode 100644
index 00000000..f880dba1
--- /dev/null
+++ b/src/org/mapsforge/android/glrenderer/ShortItem.java
@@ -0,0 +1,28 @@
+/*
+ * 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 .
+ */
+package org.mapsforge.android.glrenderer;
+
+public class ShortItem {
+ final short[] vertices;
+ int used;
+ ShortItem next;
+
+ ShortItem() {
+ vertices = new short[SIZE];
+ used = 0;
+ }
+
+ static int SIZE = 128;
+}
diff --git a/src/org/mapsforge/android/glrenderer/VertexPool.java b/src/org/mapsforge/android/glrenderer/ShortPool.java
similarity index 68%
rename from src/org/mapsforge/android/glrenderer/VertexPool.java
rename to src/org/mapsforge/android/glrenderer/ShortPool.java
index 63200b8f..91dc670c 100644
--- a/src/org/mapsforge/android/glrenderer/VertexPool.java
+++ b/src/org/mapsforge/android/glrenderer/ShortPool.java
@@ -1,43 +1,39 @@
/*
- * Copyright 2012 Hannes Janetzek
+ * 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 License as published by the Free Software
+ * 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 License for more details.
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Lesser General License along with
+ * You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see .
*/
-
package org.mapsforge.android.glrenderer;
import android.annotation.SuppressLint;
-class VertexPool {
+public class ShortPool {
private static final int POOL_LIMIT = 8192;
@SuppressLint("UseValueOf")
private static final Boolean lock = new Boolean(true);
- static private PoolItem pool = null;
+ static private ShortItem pool = null;
static private int count = 0;
- static void init() {
- }
-
- static PoolItem get() {
+ static ShortItem get() {
synchronized (lock) {
if (count == 0)
- return new PoolItem();
+ return new ShortItem();
count--;
- PoolItem it = pool;
+ ShortItem it = pool;
pool = pool.next;
it.used = 0;
it.next = null;
@@ -45,12 +41,12 @@ class VertexPool {
}
}
- static void add(PoolItem items) {
+ static void add(ShortItem items) {
if (items == null)
return;
synchronized (lock) {
- PoolItem last = items;
+ ShortItem last = items;
// limit pool items
while (count < POOL_LIMIT) {
@@ -62,7 +58,7 @@ class VertexPool {
}
// clear references
- PoolItem tmp2, tmp = last.next;
+ ShortItem tmp2, tmp = last.next;
while (tmp != null) {
tmp2 = tmp;
tmp = tmp.next;
diff --git a/src/org/mapsforge/android/glrenderer/TextRenderer.java b/src/org/mapsforge/android/glrenderer/TextRenderer.java
index e339cf7a..b4f2c9dd 100644
--- a/src/org/mapsforge/android/glrenderer/TextRenderer.java
+++ b/src/org/mapsforge/android/glrenderer/TextRenderer.java
@@ -16,7 +16,6 @@ package org.mapsforge.android.glrenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import org.mapsforge.android.utils.GlUtils;
@@ -42,7 +41,7 @@ public class TextRenderer {
private int mBitmapFormat;
private int mBitmapType;
private ByteBuffer mByteBuffer;
- private FloatBuffer mFloatBuffer;
+ private ShortBuffer mShortBuffer;
private TextTexture[] mTextures;
private int mIndicesVBO;
@@ -50,30 +49,31 @@ public class TextRenderer {
final static int INDICES_PER_SPRITE = 6; // Indices Per Sprite
final static int VERTICES_PER_SPRITE = 4; // Vertices Per Sprite
- final static int FLOATS_PER_VERTICE = 4;
+ final static int SHORTS_PER_VERTICE = 6;
private static int mTextProgram;
- static int mTextUVPMatrixLocation;
- static int mTextVertexLocation;
- static int mTextTextureCoordLocation;
- static int mTextUColorLocation;
+ static int hTextUVPMatrix;
+ static int hTextVertex;
+ static int hTextScale;
+ static int hTextTextureCoord;
+ static int hTextUColor;
static Paint mPaint = new Paint(Color.BLACK);
boolean debug = false;
- float[] debugVertices = {
+ short[] debugVertices = {
0, 0,
- 0, 1,
+ 0, TEXTURE_HEIGHT,
0, TEXTURE_HEIGHT - 1,
0, 0,
TEXTURE_WIDTH - 1, 0,
- 1, 1,
+ TEXTURE_WIDTH, TEXTURE_HEIGHT,
TEXTURE_WIDTH - 1, TEXTURE_HEIGHT - 1,
- 1, 0,
+ TEXTURE_WIDTH, 0,
};
@@ -87,20 +87,21 @@ public class TextRenderer {
mTextProgram = GlUtils.createProgram(textVertexShader, textFragmentShader);
- mTextUVPMatrixLocation = GLES20.glGetUniformLocation(mTextProgram, "mvp");
- mTextUColorLocation = GLES20.glGetUniformLocation(mTextProgram, "col");
- mTextVertexLocation = GLES20.glGetAttribLocation(mTextProgram, "vertex");
- mTextTextureCoordLocation = GLES20.glGetAttribLocation(mTextProgram, "tex_coord");
+ hTextUVPMatrix = GLES20.glGetUniformLocation(mTextProgram, "mvp");
+ hTextUColor = GLES20.glGetUniformLocation(mTextProgram, "col");
+ hTextVertex = GLES20.glGetAttribLocation(mTextProgram, "vertex");
+ hTextScale = GLES20.glGetUniformLocation(mTextProgram, "scale");
+ hTextTextureCoord = GLES20.glGetAttribLocation(mTextProgram, "tex_coord");
// mVertexBuffer = new float[];
int bufferSize = numTextures
* MAX_LABELS * VERTICES_PER_SPRITE
- * FLOATS_PER_VERTICE * (Float.SIZE / 8);
+ * SHORTS_PER_VERTICE * (Short.SIZE / 8);
mByteBuffer = ByteBuffer.allocateDirect(bufferSize)
.order(ByteOrder.nativeOrder());
- mFloatBuffer = mByteBuffer.asFloatBuffer();
+ mShortBuffer = mByteBuffer.asShortBuffer();
int[] textureIds = new int[numTextures];
TextTexture[] textures = new TextTexture[numTextures];
@@ -184,20 +185,14 @@ public class TextRenderer {
if (tex.tile != null)
tex.tile.texture = null;
- // if (debug)
- // mBitmap.eraseColor(0xaa0000aa);
- // else
mBitmap.eraseColor(Color.TRANSPARENT);
int pos = 0;
- float[] buf = tex.vertices;
-
- float xx = mFontPadX;
- float yy = 0;
- float width, height;
+ short[] buf = tex.vertices;
float y = 0;
- float x = 0;
+ float x = mFontPadX;
+ float width, height;
int max = tile.labels.size();
if (max > MAX_LABELS)
@@ -214,8 +209,9 @@ public class TextRenderer {
mCanvas.drawLine(debugVertices[12], debugVertices[13], debugVertices[8],
debugVertices[9], mPaint);
}
+
int advanceY = 0;
- // int advanceX = 0;
+
for (int i = 0; i < max; i++) {
TextItem t = tile.labels.get(i);
@@ -225,18 +221,23 @@ public class TextRenderer {
if (height > advanceY)
advanceY = (int) height;
- if (xx + width > TEXTURE_WIDTH) {
- xx = mFontPadX;
+ if (x + width > TEXTURE_WIDTH) {
+ x = mFontPadX;
y += advanceY;
advanceY = (int) height;
}
- yy = y + (height - 1) - t.caption.fontDescent - mFontPadY;
+ float yy = y + (height - 1) - t.caption.fontDescent - mFontPadY;
+
+ if (yy > TEXTURE_HEIGHT) {
+ Log.d(TAG, "reached max labels");
+ continue;
+ }
if (t.caption.stroke != null)
- mCanvas.drawText(t.text, xx + t.width / 2, yy, t.caption.stroke);
+ mCanvas.drawText(t.text, x + t.width / 2, yy, t.caption.stroke);
- mCanvas.drawText(t.text, xx + t.width / 2, yy, t.caption.paint);
+ mCanvas.drawText(t.text, x + t.width / 2, yy, t.caption.paint);
// Log.d(TAG, "draw: " + t.text + " at:" + (xx + t.width / 2) + " " + yy + " w:"
// + t.width + " " + cellHeight);
@@ -246,44 +247,57 @@ public class TextRenderer {
float halfWidth = width / 2.0f;
float halfHeight = height / 2.0f;
- float x1 = t.x - halfWidth;
- float y1 = t.y - halfHeight;
- float x2 = t.x + halfWidth;
- float y2 = t.y + halfHeight;
- float u1 = xx / TEXTURE_WIDTH;
- float v1 = y / TEXTURE_HEIGHT;
- float u2 = u1 + (width / TEXTURE_WIDTH);
- float v2 = v1 + (height / TEXTURE_HEIGHT);
+ // short x1 = (short) (2.0f * (t.x - halfWidth));
+ // short y1 = (short) (2.0f * (t.y - halfHeight));
+ // short x2 = (short) (2.0f * (t.x + halfWidth));
+ // short y2 = (short) (2.0f * (t.y + halfHeight));
+ short x1 = (short) (2.0f * (-halfWidth));
+ short y1 = (short) (2.0f * (-halfHeight));
+ short x2 = (short) (2.0f * (halfWidth));
+ short y2 = (short) (2.0f * (halfHeight));
+
+ short u1 = (short) (2.0f * x);
+ short v1 = (short) (2.0f * y);
+ short u2 = (short) (2.0f * (x + width));
+ short v2 = (short) (2.0f * (y + height));
+
+ short tx = (short) (2.0f * t.x);
+ short ty = (short) (2.0f * t.y);
+
+ buf[pos++] = tx;
+ buf[pos++] = ty;
buf[pos++] = x1;
buf[pos++] = y1;
buf[pos++] = u1;
buf[pos++] = v2;
+ buf[pos++] = tx;
+ buf[pos++] = ty;
buf[pos++] = x2;
buf[pos++] = y1;
buf[pos++] = u2;
buf[pos++] = v2;
+ buf[pos++] = tx;
+ buf[pos++] = ty;
buf[pos++] = x2;
buf[pos++] = y2;
buf[pos++] = u2;
buf[pos++] = v1;
+ buf[pos++] = tx;
+ buf[pos++] = ty;
buf[pos++] = x1;
buf[pos++] = y2;
buf[pos++] = u1;
buf[pos++] = v1;
- // yy += cellHeight;
- // x += width;
+ x += width;
- xx += width;
-
- // y += cellHeight;
if (y > TEXTURE_HEIGHT) {
- Log.d(TAG, "reached max labels");
+ Log.d(TAG, "reached max labels: texture is full");
break;
}
}
@@ -309,42 +323,42 @@ public class TextRenderer {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
- mFloatBuffer.clear();
+ mShortBuffer.clear();
for (int i = 0; i < mTextures.length; i++) {
tex = mTextures[i];
if (tex.tile == null || !tex.tile.isActive)
continue;
- mFloatBuffer.put(tex.vertices, 0, tex.length);
+ mShortBuffer.put(tex.vertices, 0, tex.length);
tex.offset = offset;
offset += tex.length;
}
- mFloatBuffer.flip();
+ mShortBuffer.flip();
// Log.d(TAG, "compileTextures" + mFloatBuffer.remaining() + " " + offset);
// TODO use sub-bufferdata function
- GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, offset * (Float.SIZE / 8),
- mFloatBuffer, GLES20.GL_DYNAMIC_DRAW);
+ GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, offset * (Short.SIZE / 8),
+ mShortBuffer, GLES20.GL_DYNAMIC_DRAW);
}
- void beginDraw() {
+ void beginDraw(float scale) {
GLES20.glUseProgram(mTextProgram);
- GLES20.glEnableVertexAttribArray(mTextTextureCoordLocation);
- GLES20.glEnableVertexAttribArray(mTextVertexLocation);
-
+ GLES20.glEnableVertexAttribArray(hTextTextureCoord);
+ GLES20.glEnableVertexAttribArray(hTextVertex);
+ GLES20.glUniform1f(hTextScale, scale);
if (debug) {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
- mFloatBuffer.clear();
- mFloatBuffer.put(debugVertices, 0, 16);
- mFloatBuffer.flip();
- GLES20.glVertexAttribPointer(mTextVertexLocation, 2,
- GLES20.GL_FLOAT, false, 16, mFloatBuffer);
- mFloatBuffer.position(2);
- GLES20.glVertexAttribPointer(mTextTextureCoordLocation, 2,
- GLES20.GL_FLOAT, false, 16, mFloatBuffer);
+ mShortBuffer.clear();
+ mShortBuffer.put(debugVertices, 0, 16);
+ mShortBuffer.flip();
+ GLES20.glVertexAttribPointer(hTextVertex, 2,
+ GLES20.GL_SHORT, false, 8, mShortBuffer);
+ mShortBuffer.position(2);
+ GLES20.glVertexAttribPointer(hTextTextureCoord, 2,
+ GLES20.GL_SHORT, false, 8, mShortBuffer);
} else {
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesVBO);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVerticesVBO);
@@ -353,31 +367,32 @@ public class TextRenderer {
void endDraw() {
- GLES20.glDisableVertexAttribArray(mTextTextureCoordLocation);
- GLES20.glDisableVertexAttribArray(mTextVertexLocation);
+ GLES20.glDisableVertexAttribArray(hTextTextureCoord);
+ GLES20.glDisableVertexAttribArray(hTextVertex);
}
void drawTile(GLMapTile tile, float[] matrix) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tile.texture.id);
- GlUtils.checkGlError("bind");
- GLES20.glUniformMatrix4fv(mTextUVPMatrixLocation, 1, false, matrix, 0);
- GlUtils.checkGlError("matrix");
+ GLES20.glUniformMatrix4fv(hTextUVPMatrix, 1, false, matrix, 0);
if (debug) {
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
} else {
- GLES20.glVertexAttribPointer(mTextVertexLocation, 2,
- GLES20.GL_FLOAT, false, 16, tile.texture.offset * 4);
+ GLES20.glVertexAttribPointer(hTextVertex, 4,
+ GLES20.GL_SHORT, false, 12, tile.texture.offset * (Short.SIZE / 8));
- GLES20.glVertexAttribPointer(mTextTextureCoordLocation, 2,
- GLES20.GL_FLOAT, false, 16, tile.texture.offset * 4 + 8);
+ // GLES20.glVertexAttribPointer(hTextVertexOffset, 2,
+ // GLES20.GL_SHORT, false, 8, tile.texture.offset * (Short.SIZE / 8) + 4);
+ //
+ GLES20.glVertexAttribPointer(hTextTextureCoord, 2,
+ GLES20.GL_SHORT, false, 12, tile.texture.offset * (Short.SIZE / 8)
+ + 8);
- GLES20.glDrawElements(GLES20.GL_TRIANGLES, (tile.texture.length / 16) *
+ GLES20.glDrawElements(GLES20.GL_TRIANGLES, (tile.texture.length / 24) *
INDICES_PER_SPRITE, GLES20.GL_UNSIGNED_SHORT, 0);
-
}
}
@@ -385,12 +400,18 @@ public class TextRenderer {
private static String textVertexShader = ""
+ "precision highp float; "
+ "attribute vec4 vertex;"
+ // + "attribute vec4 offset;"
+ "attribute vec2 tex_coord;"
+ "uniform mat4 mvp;"
+ + "uniform float scale;"
+ "varying vec2 tex_c;"
+ + "const vec2 div = vec2(1.0/1024.0,1.0/512.0);"
+ + "const vec4 dp = vec4(0.5,0.5,0.5,0.5);"
+ "void main() {"
- + " gl_Position = mvp * vertex;"
- + " tex_c = tex_coord;"
+ + " vec4 s = dp * vertex;"
+ + " gl_Position = mvp * vec4(s.x + (s.z / scale), s.y + (s.w / scale), 0.0, 1.0);"
+ // + " gl_Position = vec4(pos.x + s.z, pos.y + s.w, 0.0, 1.0);"
+ + " tex_c = tex_coord * div;"
+ "}";
private static String textFragmentShader = ""
@@ -399,7 +420,7 @@ public class TextRenderer {
+ "uniform vec4 col;"
+ "varying vec2 tex_c;"
+ "void main() {"
- + " gl_FragColor = texture2D(tex, tex_c);"
+ + " gl_FragColor = texture2D(tex, tex_c.xy);"
+ "}";
}
diff --git a/src/org/mapsforge/android/glrenderer/TextTexture.java b/src/org/mapsforge/android/glrenderer/TextTexture.java
index 2ef358e3..eefe4fa3 100644
--- a/src/org/mapsforge/android/glrenderer/TextTexture.java
+++ b/src/org/mapsforge/android/glrenderer/TextTexture.java
@@ -16,7 +16,7 @@ package org.mapsforge.android.glrenderer;
public class TextTexture {
- final float[] vertices;
+ final short[] vertices;
final int id;
int length;
int offset;
@@ -25,7 +25,9 @@ public class TextTexture {
String[] text;
TextTexture(int textureID) {
- vertices = new float[TextRenderer.MAX_LABELS * 16];
+ vertices = new short[TextRenderer.MAX_LABELS *
+ TextRenderer.VERTICES_PER_SPRITE *
+ TextRenderer.SHORTS_PER_VERTICE];
id = textureID;
}
diff --git a/src/org/mapsforge/android/mapgenerator/MapTile.java b/src/org/mapsforge/android/mapgenerator/MapTile.java
index ebf608b3..dcae8202 100644
--- a/src/org/mapsforge/android/mapgenerator/MapTile.java
+++ b/src/org/mapsforge/android/mapgenerator/MapTile.java
@@ -21,9 +21,9 @@ import org.mapsforge.core.Tile;
*/
public class MapTile extends Tile {
/**
- * tile is loaded and ready for drawing. (set and used by render thread).
+ * tile is loaded and ready for drawing. (set and used by render thread after uploading data to gl).
*/
- public boolean isDrawn;
+ public boolean isReady;
/**
* tile is removed from JobQueue and loading in DatabaseRenderer. set by MapWorker.
diff --git a/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml b/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
index 8f837911..1d4cc5d1 100644
--- a/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
+++ b/src/org/mapsforge/android/rendertheme/osmarender/osmarender.xml
@@ -147,27 +147,14 @@
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
@@ -472,15 +459,28 @@
-
+
-
+
+
+
@@ -683,11 +683,11 @@
-
+
-
+
@@ -723,7 +723,7 @@
-
diff --git a/src/org/mapsforge/android/rendertheme/renderTheme.xsd b/src/org/mapsforge/android/rendertheme/renderTheme.xsd
index 03feede9..2513efb0 100644
--- a/src/org/mapsforge/android/rendertheme/renderTheme.xsd
+++ b/src/org/mapsforge/android/rendertheme/renderTheme.xsd
@@ -86,12 +86,16 @@
-
+
+
diff --git a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
index e6ae75c8..1f9a6125 100644
--- a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
+++ b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
@@ -49,6 +49,9 @@ public final class Area implements RenderInstruction {
int stroke = Color.TRANSPARENT;
float strokeWidth = 0;
int fade = -1;
+ int blend = -1;
+ int blendFill = Color.BLACK;
+
for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
@@ -63,13 +66,17 @@ public final class Area implements RenderInstruction {
strokeWidth = Float.parseFloat(value);
} else if ("fade".equals(name)) {
fade = Integer.parseInt(value);
+ } else if ("blend".equals(name)) {
+ blend = Integer.parseInt(value);
+ } else if ("blend-fill".equals(name)) {
+ blendFill = Color.parseColor(value);
} else {
RenderThemeHandler.logUnknownAttribute(elementName, name, value, i);
}
}
validate(strokeWidth);
- return new Area(src, fill, stroke, strokeWidth, fade, level);
+ return new Area(src, fill, stroke, strokeWidth, fade, level, blend, blendFill);
}
private static void validate(float strokeWidth) {
@@ -79,32 +86,8 @@ public final class Area implements RenderInstruction {
}
}
- /**
- *
- */
- public final int level;
- /**
- *
- */
- public final Paint paintFill;
- /**
- *
- */
- public final Paint paintOutline;
- /**
- *
- */
- public final float strokeWidth;
- /**
- *
- */
- public final float color[];
- /**
- *
- */
- public final int fade;
-
- private Area(String src, int fill, int stroke, float strokeWidth, int fade, int level)
+ private Area(String src, int fill, int stroke, float strokeWidth, int fade,
+ int level, int blend, int blendFill)
throws IOException {
super();
@@ -129,12 +112,24 @@ public final class Area implements RenderInstruction {
paintOutline.setColor(stroke);
paintOutline.setStrokeCap(Cap.ROUND);
}
+
color = new float[4];
color[0] = (fill >> 16 & 0xff) / 255.0f;
color[1] = (fill >> 8 & 0xff) / 255.0f;
color[2] = (fill >> 0 & 0xff) / 255.0f;
color[3] = (fill >> 24 & 0xff) / 255.0f;
+ if (blend > 0) {
+ blendColor = new float[4];
+ blendColor[0] = (blendFill >> 16 & 0xff) / 255.0f;
+ blendColor[1] = (blendFill >> 8 & 0xff) / 255.0f;
+ blendColor[2] = (blendFill >> 0 & 0xff) / 255.0f;
+ blendColor[3] = (blendFill >> 24 & 0xff) / 255.0f;
+ } else {
+ blendColor = null;
+ }
+
+ this.blend = blend;
this.strokeWidth = strokeWidth;
this.fade = fade;
this.level = level;
@@ -168,4 +163,33 @@ public final class Area implements RenderInstruction {
public void scaleTextSize(float scaleFactor) {
// do nothing
}
+
+ /**
+ *
+ */
+ public final int level;
+ /**
+ *
+ */
+ public final Paint paintFill;
+ /**
+ *
+ */
+ public final Paint paintOutline;
+ /**
+ *
+ */
+ public final float strokeWidth;
+ /**
+ *
+ */
+ public final float color[];
+ /**
+ *
+ */
+ public final int fade;
+
+ public final float blendColor[];
+
+ public final int blend;
}
diff --git a/src/org/mapsforge/android/swrenderer/GLMapTile.java b/src/org/mapsforge/android/swrenderer/GLMapTile.java
index 26486a1b..5f53b0a6 100644
--- a/src/org/mapsforge/android/swrenderer/GLMapTile.java
+++ b/src/org/mapsforge/android/swrenderer/GLMapTile.java
@@ -39,7 +39,6 @@ public class GLMapTile extends MapTile {
public GLMapTile(long tileX, long tileY, byte zoomLevel) {
super(tileX, tileY, zoomLevel);
mScale = 1;
- isDrawn = false;
mTextureID = -1;
}
diff --git a/src/org/mapsforge/android/swrenderer/MapRenderer.java b/src/org/mapsforge/android/swrenderer/MapRenderer.java
index 0a9e4890..8380d8a0 100644
--- a/src/org/mapsforge/android/swrenderer/MapRenderer.java
+++ b/src/org/mapsforge/android/swrenderer/MapRenderer.java
@@ -212,7 +212,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
newTiles[tiles++] = tile;
- if (!tile.isDrawn || (tile.getScale() != scale)) {
+ if (!tile.isReady || (tile.getScale() != scale)) {
tile.isLoading = true;
// approximation for TileScheduler
if (tileY < tileTop || tileY > tileBottom || tileX < tileLeft
@@ -455,7 +455,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
tile.setScale(mMapGeneratorJob.getScale());
- tile.isDrawn = true;
+ tile.isReady = true;
tile.isLoading = false;
mMapGeneratorJob = null;
diff --git a/src/org/mapsforge/database/pbmap/MapDatabase.java b/src/org/mapsforge/database/pbmap/MapDatabase.java
index 06460a50..2b3e79d8 100644
--- a/src/org/mapsforge/database/pbmap/MapDatabase.java
+++ b/src/org/mapsforge/database/pbmap/MapDatabase.java
@@ -59,7 +59,7 @@ public class MapDatabase implements IMapDatabase {
private static final MapFileInfo mMapInfo =
new MapFileInfo(new BoundingBox(-180, -90, 180, 90),
- new Byte((byte) 14), new GeoPoint(53.11, 8.85),
+ new Byte((byte) 4), new GeoPoint(53.11, 8.85),
WebMercator.NAME, 0, 0, 0, "de", "comment", "author");
private boolean mOpenFile = false;
@@ -343,7 +343,8 @@ public class MapDatabase implements IMapDatabase {
}
if (fail || index == null || tags == null || indexCnt == 0 || tagCnt == 0) {
- Log.d(TAG, "..." + index + " " + tags + " " + indexCnt + " " + coordCnt + " "
+ Log.d(TAG, "..." + index + " " + (tags != null ? tags[0] : "...") + " "
+ + indexCnt + " " + coordCnt + " "
+ tagCnt);
return false;
}