- switched to using shorts instead of float/half-float
- fixed flickering caused by stencil/scissor combination on nexus - added blending option for areas in rendertheme
This commit is contained in:
parent
7f573f0ac4
commit
1cf0c02dd2
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<TextItem>();
|
||||
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);
|
||||
|
||||
@ -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<MapGeneratorJob> mJobList;
|
||||
private final ArrayList<VertexBufferObject> mVBOs;
|
||||
private final TileCacheKey mTileCacheKey;
|
||||
private final HashMap<TileCacheKey, GLMapTile> mTiles;
|
||||
private final ArrayList<GLMapTile> mTileList;
|
||||
private final TileDistanceSort mTileDistanceSort;
|
||||
private static ArrayList<MapGeneratorJob> mJobList;
|
||||
private static ArrayList<VertexBufferObject> mVBOs;
|
||||
private static TileCacheKey mTileCacheKey;
|
||||
private static HashMap<TileCacheKey, GLMapTile> mTiles;
|
||||
private static ArrayList<GLMapTile> 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<VertexBufferObject>();
|
||||
@ -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) {
|
||||
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)));
|
||||
} 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;
|
||||
}
|
||||
|
||||
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));
|
||||
// prefer lower zoom level, it covers a larger area
|
||||
t.distance /= -diff;
|
||||
}
|
||||
} else {
|
||||
dx = (t.pixelX + h) - x;
|
||||
dy = (t.pixelY + h) - y;
|
||||
dy *= mAspect;
|
||||
t.distance = (1 + ((dx > 0 ? dx : -dx) + (dy > 0 ? dy : -dy)));// * 2;
|
||||
}
|
||||
// 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
glUniform4f(hPolygonColor,
|
||||
l.area.color[0], l.area.color[1], l.area.color[2], alpha);
|
||||
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,
|
||||
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,10 +683,10 @@ 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);
|
||||
@ -677,7 +695,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
||||
// 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,
|
||||
glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT,
|
||||
false, 8, LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
glVertexAttribPointer(hLineTexturePosition, 2, OES_HALF_FLOAT,
|
||||
glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT,
|
||||
false, 8, LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
||||
} else {
|
||||
glVertexAttribPointer(hLineVertexPosition, 2, GL_FLOAT,
|
||||
false, 16, LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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;
|
||||
// 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);
|
||||
// }
|
||||
// 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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 = ""
|
||||
|
||||
28
src/org/mapsforge/android/glrenderer/ShortItem.java
Normal file
28
src/org/mapsforge/android/glrenderer/ShortItem.java
Normal file
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
@ -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);"
|
||||
+ "}";
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -147,28 +147,15 @@
|
||||
</rule>
|
||||
|
||||
|
||||
<rule e="way" k="natural|" v="*">
|
||||
<rule e="way" k="*" v="wood">
|
||||
<rule e="way" k="*" v="*" zoom-max="12">
|
||||
<area fill="#ebefe5" fade="7" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
<area fill="#d3dec8" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
<rule e="way" k="natural" v="wood">
|
||||
<area fill="#ebefe5" fade="7" blend="11" blend-fill="#d3dec8"/>
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="landuse" v="*">
|
||||
<rule e="way" k="*" v="forest">
|
||||
<rule e="way" k="*" v="*" zoom-max="12">
|
||||
<area fill="#ebefe5" fade="7" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
<area fill="#d3dec8" fade="12" />
|
||||
</rule>
|
||||
</rule>
|
||||
<rule e="way" k="landuse" v="forest">
|
||||
<area fill="#ebefe5" fade="7" blend="11" blend-fill="#d3dec8"/>
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- keep grass above forest:wood and leisure:park! -->
|
||||
<rule e="way" k="landuse" v="grass">
|
||||
<area fill="#ebf2d2" fade="10" />
|
||||
@ -481,6 +468,19 @@
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
<!-- different colors :) -->
|
||||
<!-- <rule e="way" k="*" v="residential">
|
||||
<line stroke="#00ff00" stroke-width="1.2" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="road">
|
||||
<line stroke="#ff00ff" stroke-width="1.2" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="living_street">
|
||||
<line stroke="#ffff00" stroke-width="1.2" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="unclassified">
|
||||
<line stroke="#00ffff" stroke-width="1.2" outline="2" stroke-linecap="butt" />
|
||||
</rule> -->
|
||||
</rule>
|
||||
|
||||
|
||||
@ -683,11 +683,11 @@
|
||||
<rule e="way" k="debug" v="area">
|
||||
<line stroke="#ff0000" stroke-width="1.2" fixed="true" stroke-linecap="butt" />
|
||||
<area fill="#880000ff"/>
|
||||
<caption k="name" font-size="15" fill="#ffffff" stroke="#000000" stroke-width="2.0"/>
|
||||
<caption k="name" font-size="15" fill="#ff0000" stroke="#444444" stroke-width="2.0"/>
|
||||
</rule>
|
||||
<rule e="way" k="debug" v="way">
|
||||
<line stroke="#00ffff" stroke-width="1.5" fixed="true" stroke-linecap="butt" />
|
||||
<caption k="name" font-size="15" fill="#ffffff" stroke="#000000" stroke-width="2.0"/>
|
||||
<caption k="name" font-size="15" fill="#00ffff" stroke="#444444" stroke-width="2.0"/>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@ -723,7 +723,7 @@
|
||||
<!-- place -->
|
||||
<rule e="node" k="place" v="*">
|
||||
<rule e="node" k="*" v="suburb|town|village" zoom-max="14">
|
||||
<caption k="name" font-style="bold" font-size="15" fill="#000000"
|
||||
<caption k="name" font-size="14" fill="#000000"
|
||||
stroke="#ffffff" stroke-width="2.0" />
|
||||
</rule>
|
||||
<rule e="node" k="*" v="island" zoom-min="10">
|
||||
|
||||
@ -92,6 +92,10 @@
|
||||
use="optional" default="0" />
|
||||
<xs:attribute name="fade" type="xs:integer" use="optional"
|
||||
default="-1" />
|
||||
<xs:attribute name="blend" type="xs:integer" use="optional"
|
||||
default="-1" />
|
||||
<xs:attribute name="blend-fill" type="tns:color" use="optional"
|
||||
default="#000000" />
|
||||
</xs:complexType>
|
||||
|
||||
<xs:complexType name="caption">
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user