- pack line texture coordinates in least significant bits of extrusion vector
- saving 4 bytes per vertex :) - use premultiplied alpha,fixing issues on HTC and no reason no to use premul - fix issue on HTC desire, went out-of-memory when setting buffer data to zero ?! - delete buffer and rereate instead - use 565 color config for devices that prefer it (HTC...)
This commit is contained in:
parent
7f469a6316
commit
7c95930ba3
@ -78,6 +78,8 @@ public class MapView extends GLSurfaceView {
|
|||||||
private static final float DEFAULT_TEXT_SCALE = 1;
|
private static final float DEFAULT_TEXT_SCALE = 1;
|
||||||
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
|
||||||
|
|
||||||
|
public final static boolean debugFrameTime = false;
|
||||||
|
|
||||||
private final MapController mMapController;
|
private final MapController mMapController;
|
||||||
private final MapViewPosition mMapViewPosition;
|
private final MapViewPosition mMapViewPosition;
|
||||||
|
|
||||||
@ -186,6 +188,7 @@ public class MapView extends GLSurfaceView {
|
|||||||
|
|
||||||
setEGLConfigChooser(new GlConfigChooser());
|
setEGLConfigChooser(new GlConfigChooser());
|
||||||
setEGLContextClientVersion(2);
|
setEGLContextClientVersion(2);
|
||||||
|
// setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
|
||||||
|
|
||||||
setRenderer(mMapRenderer);
|
setRenderer(mMapRenderer);
|
||||||
|
|
||||||
@ -193,8 +196,6 @@ public class MapView extends GLSurfaceView {
|
|||||||
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static boolean debugFrameTime = false;
|
|
||||||
|
|
||||||
private void initMapStartPosition() {
|
private void initMapStartPosition() {
|
||||||
GeoPoint startPoint = getStartPoint();
|
GeoPoint startPoint = getStartPoint();
|
||||||
if (startPoint != null) {
|
if (startPoint != null) {
|
||||||
|
|||||||
@ -22,10 +22,16 @@ import android.util.FloatMath;
|
|||||||
|
|
||||||
class LineLayer {
|
class LineLayer {
|
||||||
|
|
||||||
private static final float S = MapRenderer.COORD_MULTIPLIER;
|
private static final float COORD_SCALE = MapRenderer.COORD_MULTIPLIER;
|
||||||
private static final float S1000 = 1000;
|
// scale factor mapping direction vector to short values
|
||||||
|
private static final float DIR_SCALE = 2048;
|
||||||
|
// mask for packing last two bits of direction vector with texture coordinates
|
||||||
|
private static final int DIR_MASK = 0xFFFFFFFC;
|
||||||
|
|
||||||
|
// next layer
|
||||||
LineLayer next;
|
LineLayer next;
|
||||||
|
|
||||||
|
// lines referenced by this outline layer
|
||||||
LineLayer outlines;
|
LineLayer outlines;
|
||||||
|
|
||||||
Line line;
|
Line line;
|
||||||
@ -58,12 +64,12 @@ class LineLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj -- need some way to know
|
* line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj
|
||||||
* how the road connects to set the ending angles
|
|
||||||
*/
|
*/
|
||||||
void addLine(float[] points, int pos, int length) {
|
void addLine(float[] points, int pos, int length) {
|
||||||
float x, y, nextX, nextY, prevX, prevY, ux, uy, vx, vy, wx, wy;
|
float x, y, nextX, nextY, prevX, prevY;
|
||||||
float a;
|
float a, ux, uy, vx, vy, wx, wy;
|
||||||
|
|
||||||
int ipos = pos;
|
int ipos = pos;
|
||||||
boolean rounded = false;
|
boolean rounded = false;
|
||||||
boolean squared = false;
|
boolean squared = false;
|
||||||
@ -94,7 +100,8 @@ class LineLayer {
|
|||||||
ux = -vy;
|
ux = -vy;
|
||||||
uy = vx;
|
uy = vx;
|
||||||
|
|
||||||
int tsize = Tile.TILE_SIZE;
|
int tmax = Tile.TILE_SIZE + 10;
|
||||||
|
int tmin = -10;
|
||||||
|
|
||||||
if (pool == null) {
|
if (pool == null) {
|
||||||
pool = curItem = ShortPool.get();
|
pool = curItem = ShortPool.get();
|
||||||
@ -112,27 +119,25 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean outside = (x <= 0 || x >= tsize || y <= 0 || y >= tsize)
|
|
||||||
&& (x - vx <= 0 || x - vx >= tsize || y - vy <= 0 || y - vy >= tsize);
|
|
||||||
|
|
||||||
short ox, oy, dx, dy;
|
short ox, oy, dx, dy;
|
||||||
|
int ddx, ddy;
|
||||||
|
|
||||||
ox = (short) (x * S);
|
ox = (short) (x * COORD_SCALE);
|
||||||
oy = (short) (y * S);
|
oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
|
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||||
|
|
||||||
if (rounded && !outside) {
|
if (rounded && !outside) {
|
||||||
|
// add first vertex twice
|
||||||
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (2 | ddy & DIR_MASK);
|
||||||
|
|
||||||
// For rounded line edges
|
v[opos++] = ox;
|
||||||
dx = (short) ((ux - vx) * S1000);
|
v[opos++] = oy;
|
||||||
dy = (short) ((uy - vy) * S1000);
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
v[opos + 0] = ox;
|
|
||||||
v[opos + 1] = oy;
|
|
||||||
v[opos + 2] = dx;
|
|
||||||
v[opos + 3] = dy;
|
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -142,13 +147,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -158,16 +160,13 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = (short) (-(ux + vx) * S1000);
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
dy = (short) (-(uy + vy) * S1000);
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
||||||
v[opos + 3] = dy;
|
v[opos++] = (short) (2 | ddy & DIR_MASK);
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -178,16 +177,13 @@ class LineLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start of line
|
// Start of line
|
||||||
dx = (short) (ux * S1000);
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
dy = (short) (uy * S1000);
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
v[opos + 3] = dy;
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -197,13 +193,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = (short) (-dx);
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
v[opos + 3] = (short) (-dy);
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// outside means line is probably clipped
|
// outside means line is probably clipped
|
||||||
@ -221,16 +214,16 @@ class LineLayer {
|
|||||||
if (rounded)
|
if (rounded)
|
||||||
verticesCnt -= 2;
|
verticesCnt -= 2;
|
||||||
|
|
||||||
dx = (short) ((ux - vx) * S1000);
|
// add first vertex twice
|
||||||
dy = (short) ((uy - vy) * S1000);
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -240,13 +233,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -256,16 +246,14 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = (short) (-(ux + vx) * S1000);
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
dy = (short) (-(uy + vy) * S1000);
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
|
||||||
v[opos + 1] = oy;
|
|
||||||
v[opos + 2] = dx;
|
|
||||||
v[opos + 3] = dy;
|
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prevX = x;
|
prevX = x;
|
||||||
@ -298,14 +286,16 @@ class LineLayer {
|
|||||||
a = -wy * ux + wx * uy;
|
a = -wy * ux + wx * uy;
|
||||||
|
|
||||||
// boolean split = false;
|
// boolean split = false;
|
||||||
if (a < 0.1f && a > -0.1f) {
|
if (a < 0.01f && a > -0.01f) {
|
||||||
// Almost straight or miter goes to infinity, use normal vector
|
// Almost straight
|
||||||
ux = -wy;
|
ux = -wy;
|
||||||
uy = wx;
|
uy = wx;
|
||||||
} else {
|
} else {
|
||||||
ux = (ux / a);
|
ux = (ux / a);
|
||||||
uy = (uy / a);
|
uy = (uy / a);
|
||||||
|
|
||||||
|
// hack to avoid miter going to infinity
|
||||||
|
// note to myself: find my mathbook and do this properly!
|
||||||
if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) {
|
if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) {
|
||||||
ux = -wy;
|
ux = -wy;
|
||||||
uy = wx;
|
uy = wx;
|
||||||
@ -320,19 +310,16 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox = (short) (x * S);
|
ox = (short) (x * COORD_SCALE);
|
||||||
oy = (short) (y * S);
|
oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
dx = (short) (ux * S1000);
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
dy = (short) (uy * S1000);
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
v[opos + 3] = dy;
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -342,13 +329,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = (short) -dx;
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
v[opos + 3] = (short) -dy;
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
prevX = x;
|
prevX = x;
|
||||||
prevY = y;
|
prevY = y;
|
||||||
@ -367,8 +351,7 @@ class LineLayer {
|
|||||||
ux = vy;
|
ux = vy;
|
||||||
uy = -vx;
|
uy = -vx;
|
||||||
|
|
||||||
outside = (x <= 0 || x >= tsize || y <= 0 || y >= tsize)
|
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||||
&& (x - vx <= 0 || x - vx >= tsize || y - vy <= 0 || y - vy >= tsize);
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -378,21 +361,17 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox = (short) (x * S);
|
ox = (short) (x * COORD_SCALE);
|
||||||
oy = (short) (y * S);
|
oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
if (rounded && !outside) {
|
if (rounded && !outside) {
|
||||||
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
dx = (short) (ux * S1000);
|
v[opos++] = ox;
|
||||||
dy = (short) (uy * S1000);
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
v[opos + 0] = ox;
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
v[opos + 1] = oy;
|
|
||||||
v[opos + 2] = dx;
|
|
||||||
v[opos + 3] = dy;
|
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -402,13 +381,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = (short) -dx;
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
v[opos + 3] = (short) -dy;
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -419,16 +395,15 @@ class LineLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For rounded line edges
|
// For rounded line edges
|
||||||
dx = (short) ((ux - vx) * S1000);
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
dy = (short) ((uy - vy) * S1000);
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (0 | ddy & DIR_MASK);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = -1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -438,16 +413,16 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = (short) (-(ux + vx) * S1000);
|
// add last vertex twice
|
||||||
dy = (short) (-(uy + vy) * S1000);
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (0 | ddy & DIR_MASK);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = -1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -457,13 +432,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = -1;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (squared) {
|
if (squared) {
|
||||||
@ -477,16 +449,13 @@ class LineLayer {
|
|||||||
if (rounded)
|
if (rounded)
|
||||||
verticesCnt -= 2;
|
verticesCnt -= 2;
|
||||||
|
|
||||||
dx = (short) ((ux - vx) * S1000);
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
dy = (short) ((uy - vy) * S1000);
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
v[opos + 3] = dy;
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
v[opos + 4] = -1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -496,16 +465,16 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
dx = (short) (-(ux + vx) * S1000);
|
// add last vertex twice
|
||||||
dy = (short) (-(uy + vy) * S1000);
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
|
|
||||||
if (opos == ShortItem.SIZE) {
|
if (opos == ShortItem.SIZE) {
|
||||||
si.used = ShortItem.SIZE;
|
si.used = ShortItem.SIZE;
|
||||||
@ -515,13 +484,10 @@ class LineLayer {
|
|||||||
v = si.vertices;
|
v = si.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
v[opos + 0] = ox;
|
v[opos++] = ox;
|
||||||
v[opos + 1] = oy;
|
v[opos++] = oy;
|
||||||
v[opos + 2] = dx;
|
v[opos++] = dx;
|
||||||
v[opos + 3] = dy;
|
v[opos++] = dy;
|
||||||
v[opos + 4] = 1;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
opos += 6;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
si.used = opos;
|
si.used = opos;
|
||||||
|
|||||||
@ -35,10 +35,10 @@ import android.opengl.GLES20;
|
|||||||
import android.util.FloatMath;
|
import android.util.FloatMath;
|
||||||
|
|
||||||
class LineLayers {
|
class LineLayers {
|
||||||
private static int NUM_VERTEX_SHORTS = 6;
|
private static int NUM_VERTEX_SHORTS = 4;
|
||||||
|
|
||||||
private static final int LINE_VERTICES_DATA_POS_OFFSET = 0;
|
private static final int LINE_VERTICES_DATA_POS_OFFSET = 0;
|
||||||
private static final int LINE_VERTICES_DATA_TEX_OFFSET = 8;
|
private static final int LINE_VERTICES_DATA_TEX_OFFSET = 4;
|
||||||
|
|
||||||
// shader handles
|
// shader handles
|
||||||
private static int lineProgram;
|
private static int lineProgram;
|
||||||
@ -82,11 +82,11 @@ class LineLayers {
|
|||||||
glEnableVertexAttribArray(hLineVertexPosition);
|
glEnableVertexAttribArray(hLineVertexPosition);
|
||||||
glEnableVertexAttribArray(hLineTexturePosition);
|
glEnableVertexAttribArray(hLineTexturePosition);
|
||||||
|
|
||||||
glVertexAttribPointer(hLineVertexPosition, 4, GLES20.GL_SHORT,
|
glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT,
|
||||||
false, 12, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
false, 8, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT,
|
glVertexAttribPointer(hLineTexturePosition, 2, GLES20.GL_SHORT,
|
||||||
false, 12, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET);
|
false, 8, tile.lineOffset + LINE_VERTICES_DATA_TEX_OFFSET);
|
||||||
|
|
||||||
glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0);
|
glUniformMatrix4fv(hLineMatrix, 1, false, matrix, 0);
|
||||||
|
|
||||||
@ -115,7 +115,10 @@ class LineLayers {
|
|||||||
if (alpha > 1.0f)
|
if (alpha > 1.0f)
|
||||||
alpha = 1.0f;
|
alpha = 1.0f;
|
||||||
glUniform4f(hLineColor,
|
glUniform4f(hLineColor,
|
||||||
line.color[0], line.color[1], line.color[2], alpha);
|
line.color[0] * alpha,
|
||||||
|
line.color[1] * alpha,
|
||||||
|
line.color[2] * alpha,
|
||||||
|
alpha);
|
||||||
} else {
|
} else {
|
||||||
glUniform4fv(hLineColor, 1, line.color, 0);
|
glUniform4fv(hLineColor, 1, line.color, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,11 +16,9 @@ package org.mapsforge.android.glrenderer;
|
|||||||
|
|
||||||
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
import static android.opengl.GLES20.GL_BLEND;
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
import static android.opengl.GLES20.GL_DITHER;
|
|
||||||
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
||||||
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
import static android.opengl.GLES20.GL_SCISSOR_TEST;
|
import static android.opengl.GLES20.GL_SCISSOR_TEST;
|
||||||
import static android.opengl.GLES20.GL_SRC_ALPHA;
|
|
||||||
import static android.opengl.GLES20.GL_STENCIL_BUFFER_BIT;
|
import static android.opengl.GLES20.GL_STENCIL_BUFFER_BIT;
|
||||||
import static android.opengl.GLES20.glBindBuffer;
|
import static android.opengl.GLES20.glBindBuffer;
|
||||||
import static android.opengl.GLES20.glBlendFunc;
|
import static android.opengl.GLES20.glBlendFunc;
|
||||||
@ -30,7 +28,6 @@ import static android.opengl.GLES20.glClearColor;
|
|||||||
import static android.opengl.GLES20.glClearStencil;
|
import static android.opengl.GLES20.glClearStencil;
|
||||||
import static android.opengl.GLES20.glDisable;
|
import static android.opengl.GLES20.glDisable;
|
||||||
import static android.opengl.GLES20.glEnable;
|
import static android.opengl.GLES20.glEnable;
|
||||||
import static android.opengl.GLES20.glFinish;
|
|
||||||
import static android.opengl.GLES20.glGenBuffers;
|
import static android.opengl.GLES20.glGenBuffers;
|
||||||
import static android.opengl.GLES20.glScissor;
|
import static android.opengl.GLES20.glScissor;
|
||||||
import static android.opengl.GLES20.glViewport;
|
import static android.opengl.GLES20.glViewport;
|
||||||
@ -68,7 +65,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
private static final int MAX_TILES_IN_QUEUE = 40;
|
private static final int MAX_TILES_IN_QUEUE = 40;
|
||||||
private static final int CACHE_TILES_MAX = 250;
|
private static final int CACHE_TILES_MAX = 250;
|
||||||
private static final int LIMIT_BUFFERS = 16 * MB;
|
private static final int LIMIT_BUFFERS = 12 * MB;
|
||||||
|
|
||||||
private static int CACHE_TILES = CACHE_TILES_MAX;
|
private static int CACHE_TILES = CACHE_TILES_MAX;
|
||||||
|
|
||||||
@ -109,7 +106,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
private static float[] mMVPMatrix = new float[16];
|
private static float[] mMVPMatrix = new float[16];
|
||||||
// private static float[] mRotateMatrix = new float[16];
|
// private static float[] mRotateMatrix = new float[16];
|
||||||
private static float[] mProjMatrix = new float[16];
|
// private static float[] mProjMatrix = new float[16];
|
||||||
|
|
||||||
// newTiles is set in updateVisibleList and swapped
|
// newTiles is set in updateVisibleList and swapped
|
||||||
// with curTiles on main thread. curTiles is swapped
|
// with curTiles on main thread. curTiles is swapped
|
||||||
@ -600,6 +597,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// depthRange: -1 to 1, bits: 2^24 => 2/2^24 one step
|
||||||
|
// maybe one could avoid clearing the depth buffer for a few
|
||||||
|
// iterations when modifying glDepthRange before clipper
|
||||||
|
// gl_less test so that it does not fail
|
||||||
|
// private static final float depthStep = 0.00000011920928955078125f;
|
||||||
|
|
||||||
private static void setMatrix(GLMapTile tile, float div, int offset) {
|
private static void setMatrix(GLMapTile tile, float div, int offset) {
|
||||||
float x, y, scale;
|
float x, y, scale;
|
||||||
|
|
||||||
@ -609,7 +612,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
mMVPMatrix[12] = x * scale * mAspect;
|
mMVPMatrix[12] = x * scale * mAspect;
|
||||||
mMVPMatrix[13] = -(y + Tile.TILE_SIZE) * scale;
|
mMVPMatrix[13] = -(y + Tile.TILE_SIZE) * scale;
|
||||||
mMVPMatrix[14] = offset * 0.01f;
|
// increase the 'distance' with each tile drawn.
|
||||||
|
mMVPMatrix[14] = -1 + offset * 0.01f; // depthStep; // 0.01f;
|
||||||
mMVPMatrix[0] = scale * mAspect / COORD_MULTIPLIER;
|
mMVPMatrix[0] = scale * mAspect / COORD_MULTIPLIER;
|
||||||
mMVPMatrix[5] = scale / COORD_MULTIPLIER;
|
mMVPMatrix[5] = scale / COORD_MULTIPLIER;
|
||||||
|
|
||||||
@ -763,6 +767,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
||||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
|
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
int buf[] = new int[1];
|
||||||
|
|
||||||
synchronized (mVBOs) {
|
synchronized (mVBOs) {
|
||||||
for (VertexBufferObject vbo : mVBOs) {
|
for (VertexBufferObject vbo : mVBOs) {
|
||||||
|
|
||||||
@ -770,8 +777,19 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
mBufferMemoryUsage -= vbo.size;
|
mBufferMemoryUsage -= vbo.size;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
|
GlUtils.checkGlError("before");
|
||||||
glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
|
// this should free allocated memory but it does not. at least on HTC.
|
||||||
|
// glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
|
||||||
|
// glBufferData(GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// recreate vbo
|
||||||
|
buf[0] = vbo.id;
|
||||||
|
GLES20.glDeleteBuffers(1, buf, 0);
|
||||||
|
GLES20.glGenBuffers(1, buf, 0);
|
||||||
|
vbo.id = buf[0];
|
||||||
|
|
||||||
|
GlUtils.checkGlError("after");
|
||||||
|
|
||||||
vbo.size = 0;
|
vbo.size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -801,7 +819,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
// Note: i have the impression it is faster to also clear the
|
||||||
|
// stencil buffer even when not needed. probaly otherwise it
|
||||||
|
// is masked out from the depth buffer as they share the same
|
||||||
|
// memory region afaik
|
||||||
|
glClear(GLES20.GL_COLOR_BUFFER_BIT
|
||||||
|
| GLES20.GL_DEPTH_BUFFER_BIT
|
||||||
|
| GLES20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
if (mInitial)
|
if (mInitial)
|
||||||
return;
|
return;
|
||||||
@ -862,7 +887,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
if (updateTextures > 0)
|
if (updateTextures > 0)
|
||||||
TextRenderer.compileTextures();
|
TextRenderer.compileTextures();
|
||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||||
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
// glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
@ -883,17 +907,15 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
// glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
// glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
glDisable(GLES20.GL_DEPTH_TEST);
|
glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
|
//
|
||||||
|
|
||||||
mDrawCount = 0;
|
mDrawCount = 0;
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
|
|
||||||
int z = mDrawPosition.zoomLevel;
|
int z = mDrawPosition.zoomLevel;
|
||||||
float s = mDrawPosition.scale;
|
float s = mDrawPosition.scale;
|
||||||
|
|
||||||
int zoomLevelDiff = Math
|
int zoomLevelDiff = Math.max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0);
|
||||||
.max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0);
|
|
||||||
float scale = (float) Math.pow(1.4, zoomLevelDiff);
|
float scale = (float) Math.pow(1.4, zoomLevelDiff);
|
||||||
if (scale < 1)
|
if (scale < 1)
|
||||||
scale = 1;
|
scale = 1;
|
||||||
@ -913,7 +935,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
TextRenderer.endDraw();
|
TextRenderer.endDraw();
|
||||||
|
|
||||||
if (MapView.debugFrameTime) {
|
if (MapView.debugFrameTime) {
|
||||||
glFinish();
|
GLES20.glFinish();
|
||||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start));
|
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -921,19 +943,20 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void drawTile(GLMapTile tile, float div) {
|
private static void drawTile(GLMapTile tile, float div) {
|
||||||
|
// draw parents only once
|
||||||
if (tile.lastDraw == mRedrawCnt)
|
if (tile.lastDraw == mRedrawCnt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
tile.lastDraw = mRedrawCnt;
|
||||||
|
|
||||||
int z = mDrawPosition.zoomLevel;
|
int z = mDrawPosition.zoomLevel;
|
||||||
float s = mDrawPosition.scale;
|
float s = mDrawPosition.scale;
|
||||||
|
|
||||||
tile.lastDraw = mRedrawCnt;
|
// mDrawCount is used to calculation z offset.
|
||||||
|
// (used for depth clipping)
|
||||||
setMatrix(tile, div, mDrawCount++);
|
setMatrix(tile, div, mDrawCount++);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
||||||
// GLES20.glPolygonOffset(0, mDrawCount);
|
|
||||||
|
|
||||||
LineLayer ll = tile.lineLayers;
|
LineLayer ll = tile.lineLayers;
|
||||||
PolygonLayer pl = tile.polygonLayers;
|
PolygonLayer pl = tile.polygonLayers;
|
||||||
@ -955,15 +978,15 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
|
|
||||||
pl = PolygonLayers.drawPolygons(pl, lnext, mMVPMatrix, z, s, !clipped);
|
pl = PolygonLayers.drawPolygons(pl, lnext, mMVPMatrix, z, s, !clipped);
|
||||||
|
|
||||||
if (!clipped) {
|
clipped = true;
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// XXX nastay
|
// XXX nasty
|
||||||
if (!clipped) {
|
if (!clipped) {
|
||||||
PolygonLayers.drawPolygons(null, 0, mMVPMatrix, z, s, true);
|
PolygonLayers.drawPolygons(null, 0, mMVPMatrix, z, s, true);
|
||||||
clipped = true;
|
clipped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
ll = LineLayers.drawLines(tile, ll, pnext, mMVPMatrix, div, z, s);
|
ll = LineLayers.drawLines(tile, ll, pnext, mMVPMatrix, div, z, s);
|
||||||
@ -1081,14 +1104,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
// Set up textures
|
// Set up textures
|
||||||
TextRenderer.init(numTiles);
|
TextRenderer.init(numTiles);
|
||||||
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
// glDisable(GL_DITHER);
|
||||||
|
|
||||||
// glDisable(GLES20.GL_DEPTH_TEST);
|
|
||||||
// glDepthMask(false);
|
|
||||||
// GLES20.glDepthRangef(1, 0);
|
|
||||||
// GLES20.glClearDepthf(0);
|
|
||||||
|
|
||||||
glDisable(GL_DITHER);
|
|
||||||
|
|
||||||
if (mClearColor != null) {
|
if (mClearColor != null) {
|
||||||
glClearColor(mClearColor[0], mClearColor[1],
|
glClearColor(mClearColor[0], mClearColor[1],
|
||||||
@ -1096,12 +1112,17 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
} else {
|
} else {
|
||||||
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
|
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
glClearStencil(0);
|
glClearStencil(0);
|
||||||
glClear(GL_STENCIL_BUFFER_BIT);
|
glClear(GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(0, 0, mWidth, mHeight);
|
glScissor(0, 0, mWidth, mHeight);
|
||||||
|
|
||||||
|
glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
GlUtils.checkGlError("onSurfaceChanged");
|
||||||
|
|
||||||
mMapView.redrawTiles();
|
mMapView.redrawTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,10 +1148,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
|
|||||||
mFillCoords[6] = max;
|
mFillCoords[6] = max;
|
||||||
mFillCoords[7] = min;
|
mFillCoords[7] = min;
|
||||||
|
|
||||||
int i[] = new int[1];
|
// int i[] = new int[1];
|
||||||
|
|
||||||
// GLES20.glGetIntegerv(GLES20.GL_, i, 0);
|
// GLES20.glGetIntegerv(GLES20.GL_, i, 0);
|
||||||
Log.d(TAG, " >>>> " + i[0]);
|
// Log.d(TAG, " >>>> " + i[0]);
|
||||||
|
|
||||||
LineLayers.init();
|
LineLayers.init();
|
||||||
PolygonLayers.init();
|
PolygonLayers.init();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,6 @@ import static android.opengl.GLES20.glColorMask;
|
|||||||
import static android.opengl.GLES20.glDisable;
|
import static android.opengl.GLES20.glDisable;
|
||||||
import static android.opengl.GLES20.glDrawArrays;
|
import static android.opengl.GLES20.glDrawArrays;
|
||||||
import static android.opengl.GLES20.glEnable;
|
import static android.opengl.GLES20.glEnable;
|
||||||
import static android.opengl.GLES20.glEnableVertexAttribArray;
|
|
||||||
import static android.opengl.GLES20.glGetAttribLocation;
|
import static android.opengl.GLES20.glGetAttribLocation;
|
||||||
import static android.opengl.GLES20.glGetUniformLocation;
|
import static android.opengl.GLES20.glGetUniformLocation;
|
||||||
import static android.opengl.GLES20.glStencilFunc;
|
import static android.opengl.GLES20.glStencilFunc;
|
||||||
@ -82,7 +81,7 @@ class PolygonLayers {
|
|||||||
// do not modify stencil buffer
|
// do not modify stencil buffer
|
||||||
glStencilMask(0);
|
glStencilMask(0);
|
||||||
|
|
||||||
// GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
glEnable(GLES20.GL_DEPTH_TEST);
|
||||||
|
|
||||||
for (int c = 0; c < count; c++) {
|
for (int c = 0; c < count; c++) {
|
||||||
PolygonLayer l = mFillPolys[c];
|
PolygonLayer l = mFillPolys[c];
|
||||||
@ -90,7 +89,7 @@ class PolygonLayers {
|
|||||||
float alpha = 1.0f;
|
float alpha = 1.0f;
|
||||||
|
|
||||||
if (l.area.fade >= zoom || l.area.color[3] != 1.0) {
|
if (l.area.fade >= zoom || l.area.color[3] != 1.0) {
|
||||||
|
// draw alpha blending, fade in/out
|
||||||
if (l.area.fade >= zoom) {
|
if (l.area.fade >= zoom) {
|
||||||
alpha = (scale > 1.3f ? scale : 1.3f) - alpha;
|
alpha = (scale > 1.3f ? scale : 1.3f) - alpha;
|
||||||
if (alpha > 1.0f)
|
if (alpha > 1.0f)
|
||||||
@ -104,9 +103,13 @@ class PolygonLayers {
|
|||||||
blend = true;
|
blend = true;
|
||||||
}
|
}
|
||||||
glUniform4f(hPolygonColor,
|
glUniform4f(hPolygonColor,
|
||||||
l.area.color[0], l.area.color[1], l.area.color[2], alpha);
|
l.area.color[0] * alpha,
|
||||||
|
l.area.color[1] * alpha,
|
||||||
|
l.area.color[2] * alpha,
|
||||||
|
alpha);
|
||||||
|
|
||||||
} else if (l.area.blend == zoom) {
|
} else if (l.area.blend == zoom) {
|
||||||
|
// fade in/out
|
||||||
alpha = scale - 1.0f;
|
alpha = scale - 1.0f;
|
||||||
if (alpha > 1.0f)
|
if (alpha > 1.0f)
|
||||||
alpha = 1.0f;
|
alpha = 1.0f;
|
||||||
@ -118,6 +121,7 @@ class PolygonLayers {
|
|||||||
l.area.color[1] * (1 - alpha) + l.area.blendColor[1] * alpha,
|
l.area.color[1] * (1 - alpha) + l.area.blendColor[1] * alpha,
|
||||||
l.area.color[2] * (1 - alpha) + l.area.blendColor[2] * alpha, 1);
|
l.area.color[2] * (1 - alpha) + l.area.blendColor[2] * alpha, 1);
|
||||||
} else {
|
} else {
|
||||||
|
// draw solid
|
||||||
if (blend) {
|
if (blend) {
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
blend = false;
|
blend = false;
|
||||||
@ -144,7 +148,7 @@ class PolygonLayers {
|
|||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
|
|
||||||
glUseProgram(polygonProgram);
|
glUseProgram(polygonProgram);
|
||||||
glEnableVertexAttribArray(hPolygonVertexPosition);
|
GLES20.glEnableVertexAttribArray(hPolygonVertexPosition);
|
||||||
|
|
||||||
glVertexAttribPointer(hPolygonVertexPosition, 2,
|
glVertexAttribPointer(hPolygonVertexPosition, 2,
|
||||||
GLES20.GL_SHORT, false, 0,
|
GLES20.GL_SHORT, false, 0,
|
||||||
@ -177,9 +181,12 @@ class PolygonLayers {
|
|||||||
// clear stencilbuffer (tile region)
|
// clear stencilbuffer (tile region)
|
||||||
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
|
|
||||||
// draw depth clipper
|
|
||||||
if (first) {
|
if (first) {
|
||||||
|
// draw clip-region into depth buffer
|
||||||
GLES20.glDepthMask(true);
|
GLES20.glDepthMask(true);
|
||||||
|
// to prevent overdraw gl_less restricts
|
||||||
|
// the clip to the area where no other
|
||||||
|
// tile was drawn
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,6 +200,7 @@ class PolygonLayers {
|
|||||||
|
|
||||||
// stencil op for stencil method polygon drawing
|
// stencil op for stencil method polygon drawing
|
||||||
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
|
||||||
|
glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
mFillPolys[cnt] = l;
|
mFillPolys[cnt] = l;
|
||||||
|
|
||||||
@ -218,7 +226,6 @@ class PolygonLayers {
|
|||||||
|
|
||||||
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
|
||||||
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
|
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
|
||||||
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,17 +20,35 @@ class Shaders {
|
|||||||
final static String lineVertexShader = ""
|
final static String lineVertexShader = ""
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform mat4 mvp;"
|
+ "uniform mat4 mvp;"
|
||||||
+ "attribute vec4 a_position;"
|
+ "attribute vec2 a_position;"
|
||||||
+ "attribute vec2 a_st;"
|
+ "attribute vec2 a_st;"
|
||||||
+ "varying vec2 v_st;"
|
+ "varying vec2 v_st;"
|
||||||
+ "uniform float u_width;"
|
+ "uniform float u_width;"
|
||||||
+ "const float dscale = 8.0/1000.0;"
|
+ "const float dscale = 8.0/2048.0;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " vec2 dir = dscale * u_width * a_position.zw;"
|
// scale extrusion to line u_width pixel
|
||||||
+ " gl_Position = mvp * vec4(a_position.xy + dir, 0.0,1.0);"
|
// just ignore the two most insignificant bits of a_st :)
|
||||||
+ " v_st = u_width * a_st;"
|
+ " vec2 dir = dscale * u_width * a_st;"
|
||||||
|
+ " gl_Position = mvp * vec4(a_position + dir, 0.0,1.0);"
|
||||||
|
// last two bits of a_st hold the texture coordinates
|
||||||
|
// TODO use bit operations when available!
|
||||||
|
+ " v_st = u_width * (abs(mod(a_st,4.0)) - 1.0);"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
|
// final static String lineVertexShader = ""
|
||||||
|
// + "precision mediump float;"
|
||||||
|
// + "uniform mat4 mvp;"
|
||||||
|
// + "attribute vec4 a_position;"
|
||||||
|
// + "attribute vec2 a_st;"
|
||||||
|
// + "varying vec2 v_st;"
|
||||||
|
// + "uniform float u_width;"
|
||||||
|
// + "const float dscale = 8.0/1000.0;"
|
||||||
|
// + "void main() {"
|
||||||
|
// + " vec2 dir = dscale * u_width * a_position.zw;"
|
||||||
|
// + " gl_Position = mvp * vec4(a_position.xy + dir, 0.0,1.0);"
|
||||||
|
// + " v_st = u_width * a_st;"
|
||||||
|
// + "}";
|
||||||
|
|
||||||
final static String lineFragmentShader = ""
|
final static String lineFragmentShader = ""
|
||||||
+ "precision mediump float;"
|
+ "precision mediump float;"
|
||||||
+ "uniform float u_wscale;"
|
+ "uniform float u_wscale;"
|
||||||
@ -45,7 +63,12 @@ class Shaders {
|
|||||||
+ " len = abs(v_st.s);"
|
+ " len = abs(v_st.s);"
|
||||||
+ " else "
|
+ " else "
|
||||||
+ " len = length(v_st);"
|
+ " len = length(v_st);"
|
||||||
+ " color.a *= smoothstep(zero, u_wscale, u_width - len);"
|
// fade to alpha. u_wscale is the width in pixel which should be faded,
|
||||||
|
// u_width - len the position of this fragment on the perpendicular to the line
|
||||||
|
+ "color *= smoothstep(zero, u_wscale, u_width - len);"
|
||||||
|
+ "if (color.a < 0.02)"
|
||||||
|
+ " discard;"
|
||||||
|
+ " else"
|
||||||
+ " gl_FragColor = color;"
|
+ " gl_FragColor = color;"
|
||||||
+ "}";
|
+ "}";
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@
|
|||||||
package org.mapsforge.android.glrenderer;
|
package org.mapsforge.android.glrenderer;
|
||||||
|
|
||||||
class VertexBufferObject {
|
class VertexBufferObject {
|
||||||
final int id;
|
int id;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
VertexBufferObject(int id) {
|
VertexBufferObject(int id) {
|
||||||
|
|||||||
@ -1,240 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.input;
|
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.android.utils.PausableThread;
|
|
||||||
|
|
||||||
import android.os.SystemClock;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A MapMover moves the map horizontally and vertically at a configurable speed. It runs in a separate thread to avoid
|
|
||||||
* blocking the UI thread.
|
|
||||||
*/
|
|
||||||
public class MapMover extends PausableThread implements KeyEvent.Callback {
|
|
||||||
|
|
||||||
private static final int DEFAULT_MOVE_SPEED_FACTOR = 10;
|
|
||||||
private static final int FRAME_LENGTH_IN_MS = 15;
|
|
||||||
private static final float MOVE_SPEED = 0.2f;
|
|
||||||
private static final String THREAD_NAME = "MapMover";
|
|
||||||
private static final float TRACKBALL_MOVE_SPEED_FACTOR = 40;
|
|
||||||
|
|
||||||
private final MapView mMapView;
|
|
||||||
private float mMoveSpeedFactor;
|
|
||||||
private float mMoveX;
|
|
||||||
private float mMoveY;
|
|
||||||
private long mTimePrevious;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mapView
|
|
||||||
* the MapView which should be moved by this MapMover.
|
|
||||||
*/
|
|
||||||
public MapMover(MapView mapView) {
|
|
||||||
super();
|
|
||||||
mMapView = mapView;
|
|
||||||
mMoveSpeedFactor = DEFAULT_MOVE_SPEED_FACTOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the move speed factor, used for trackball and keyboard events.
|
|
||||||
*/
|
|
||||||
public float getMoveSpeedFactor() {
|
|
||||||
return mMoveSpeedFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
|
|
||||||
if (!mMapView.isClickable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
|
|
||||||
moveLeft();
|
|
||||||
return true;
|
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
|
|
||||||
moveRight();
|
|
||||||
return true;
|
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
|
|
||||||
moveUp();
|
|
||||||
return true;
|
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
|
||||||
moveDown();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyLongPress(int keyCode, KeyEvent keyEvent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyMultiple(int keyCode, int count, KeyEvent keyEvent) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyUp(int keyCode, KeyEvent keyEvent) {
|
|
||||||
if (!mMapView.isClickable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
|
|
||||||
mMoveX = 0;
|
|
||||||
return true;
|
|
||||||
} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
|
|
||||||
mMoveY = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param motionEvent
|
|
||||||
* a trackball event which should be handled.
|
|
||||||
* @return true if the event was handled, false otherwise.
|
|
||||||
*/
|
|
||||||
public boolean onTrackballEvent(MotionEvent motionEvent) {
|
|
||||||
if (!mMapView.isClickable()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
|
|
||||||
float mapMoveX = motionEvent.getX() * TRACKBALL_MOVE_SPEED_FACTOR * getMoveSpeedFactor();
|
|
||||||
float mapMoveY = motionEvent.getY() * TRACKBALL_MOVE_SPEED_FACTOR * getMoveSpeedFactor();
|
|
||||||
|
|
||||||
// mapView.getFrameBuffer().matrixPostTranslate(mapMoveX,
|
|
||||||
// mapMoveY);
|
|
||||||
mMapView.getMapPosition().moveMap(mapMoveX, mapMoveY);
|
|
||||||
mMapView.redrawTiles();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the move speed factor of the map, used for trackball and keyboard events.
|
|
||||||
*
|
|
||||||
* @param moveSpeedFactor
|
|
||||||
* the factor by which the move speed of the map will be multiplied.
|
|
||||||
* @throws IllegalArgumentException
|
|
||||||
* if the new move speed factor is negative.
|
|
||||||
*/
|
|
||||||
public void setMoveSpeedFactor(float moveSpeedFactor) {
|
|
||||||
if (moveSpeedFactor < 0) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
mMoveSpeedFactor = moveSpeedFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops moving the map completely.
|
|
||||||
*/
|
|
||||||
public void stopMove() {
|
|
||||||
mMoveX = 0;
|
|
||||||
mMoveY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveDown() {
|
|
||||||
if (mMoveY > 0) {
|
|
||||||
// stop moving the map vertically
|
|
||||||
mMoveY = 0;
|
|
||||||
} else if (mMoveY == 0) {
|
|
||||||
// start moving the map
|
|
||||||
mMoveY = -MOVE_SPEED * mMoveSpeedFactor;
|
|
||||||
mTimePrevious = SystemClock.uptimeMillis();
|
|
||||||
synchronized (this) {
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveLeft() {
|
|
||||||
if (mMoveX < 0) {
|
|
||||||
// stop moving the map horizontally
|
|
||||||
mMoveX = 0;
|
|
||||||
} else if (mMoveX == 0) {
|
|
||||||
// start moving the map
|
|
||||||
mMoveX = MOVE_SPEED * mMoveSpeedFactor;
|
|
||||||
mTimePrevious = SystemClock.uptimeMillis();
|
|
||||||
synchronized (this) {
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveRight() {
|
|
||||||
if (mMoveX > 0) {
|
|
||||||
// stop moving the map horizontally
|
|
||||||
mMoveX = 0;
|
|
||||||
} else if (mMoveX == 0) {
|
|
||||||
// start moving the map
|
|
||||||
mMoveX = -MOVE_SPEED * mMoveSpeedFactor;
|
|
||||||
mTimePrevious = SystemClock.uptimeMillis();
|
|
||||||
synchronized (this) {
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void moveUp() {
|
|
||||||
if (mMoveY < 0) {
|
|
||||||
// stop moving the map vertically
|
|
||||||
mMoveY = 0;
|
|
||||||
} else if (mMoveY == 0) {
|
|
||||||
// start moving the map
|
|
||||||
mMoveY = MOVE_SPEED * mMoveSpeedFactor;
|
|
||||||
mTimePrevious = SystemClock.uptimeMillis();
|
|
||||||
synchronized (this) {
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void afterPause() {
|
|
||||||
mTimePrevious = SystemClock.uptimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doWork() throws InterruptedException {
|
|
||||||
// calculate the time difference to previous call
|
|
||||||
long timeCurrent = SystemClock.uptimeMillis();
|
|
||||||
long timeElapsed = timeCurrent - mTimePrevious;
|
|
||||||
mTimePrevious = timeCurrent;
|
|
||||||
|
|
||||||
// add the movement to the transformation matrices
|
|
||||||
// mapView.getFrameBuffer().matrixPostTranslate(timeElapsed *
|
|
||||||
// moveX, timeElapsed * moveY);
|
|
||||||
|
|
||||||
// move the map and the overlays
|
|
||||||
mMapView.getMapPosition().moveMap(timeElapsed * mMoveX, timeElapsed * mMoveY);
|
|
||||||
mMapView.redrawTiles();
|
|
||||||
sleep(FRAME_LENGTH_IN_MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getThreadName() {
|
|
||||||
return THREAD_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasWork() {
|
|
||||||
return mMoveX != 0 || mMoveY != 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.input;
|
|
||||||
|
|
||||||
import org.mapsforge.android.MapView;
|
|
||||||
import org.mapsforge.android.utils.PausableThread;
|
|
||||||
|
|
||||||
import android.os.SystemClock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A ZoomAnimator handles the zoom-in and zoom-out animations of the corresponding MapView. It runs in a separate thread
|
|
||||||
* to avoid blocking the UI thread.
|
|
||||||
*/
|
|
||||||
public class ZoomAnimator extends PausableThread {
|
|
||||||
private static final int DEFAULT_DURATION = 250;
|
|
||||||
private static final int FRAME_LENGTH_IN_MS = 15;
|
|
||||||
private static final String THREAD_NAME = "ZoomAnimator";
|
|
||||||
|
|
||||||
private boolean mExecuteAnimation;
|
|
||||||
private final MapView mMapView;
|
|
||||||
// private float mPivotX;
|
|
||||||
// private float mPivotY;
|
|
||||||
private float mScaleFactorApplied;
|
|
||||||
private long mTimeStart;
|
|
||||||
private float mZoomDifference;
|
|
||||||
private float mZoomEnd;
|
|
||||||
private float mZoomStart;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mapView
|
|
||||||
* the MapView whose zoom level changes should be animated.
|
|
||||||
*/
|
|
||||||
public ZoomAnimator(MapView mapView) {
|
|
||||||
super();
|
|
||||||
mMapView = mapView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return true if the ZoomAnimator is working, false otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isExecuting() {
|
|
||||||
return mExecuteAnimation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the parameters for the zoom animation.
|
|
||||||
*
|
|
||||||
* @param zoomStart
|
|
||||||
* the zoom factor at the begin of the animation.
|
|
||||||
* @param zoomEnd
|
|
||||||
* the zoom factor at the end of the animation.
|
|
||||||
* @param pivotX
|
|
||||||
* the x coordinate of the animation center.
|
|
||||||
* @param pivotY
|
|
||||||
* the y coordinate of the animation center.
|
|
||||||
*/
|
|
||||||
public void setParameters(float zoomStart, float zoomEnd, float pivotX, float pivotY) {
|
|
||||||
mZoomStart = zoomStart;
|
|
||||||
mZoomEnd = zoomEnd;
|
|
||||||
// mPivotX = pivotX;
|
|
||||||
// mPivotY = pivotY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts a zoom animation with the current parameters.
|
|
||||||
*/
|
|
||||||
public void startAnimation() {
|
|
||||||
mZoomDifference = mZoomEnd - mZoomStart;
|
|
||||||
mScaleFactorApplied = mZoomStart;
|
|
||||||
mExecuteAnimation = true;
|
|
||||||
mTimeStart = SystemClock.uptimeMillis();
|
|
||||||
synchronized (this) {
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doWork() throws InterruptedException {
|
|
||||||
// calculate the elapsed time
|
|
||||||
long timeElapsed = SystemClock.uptimeMillis() - mTimeStart;
|
|
||||||
float timeElapsedPercent = Math.min(1, timeElapsed / (float) DEFAULT_DURATION);
|
|
||||||
|
|
||||||
// calculate the zoom and scale values at the current moment
|
|
||||||
float currentZoom = mZoomStart + timeElapsedPercent * mZoomDifference;
|
|
||||||
float scaleFactor = currentZoom / mScaleFactorApplied;
|
|
||||||
mScaleFactorApplied *= scaleFactor;
|
|
||||||
// mapView.getFrameBuffer().matrixPostScale(scaleFactor, scaleFactor,
|
|
||||||
// pivotX, pivotY);
|
|
||||||
|
|
||||||
// check if the animation time is over
|
|
||||||
if (timeElapsed >= DEFAULT_DURATION) {
|
|
||||||
mExecuteAnimation = false;
|
|
||||||
mMapView.redrawTiles();
|
|
||||||
} else {
|
|
||||||
mMapView.postInvalidate();
|
|
||||||
sleep(FRAME_LENGTH_IN_MS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getThreadName() {
|
|
||||||
return THREAD_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean hasWork() {
|
|
||||||
return mExecuteAnimation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -114,17 +114,17 @@ public final class Area extends RenderInstruction {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
color = new float[4];
|
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;
|
color[3] = (fill >> 24 & 0xff) / 255.0f;
|
||||||
|
color[0] = (fill >> 16 & 0xff) / 255.0f * color[3];
|
||||||
|
color[1] = (fill >> 8 & 0xff) / 255.0f * color[3];
|
||||||
|
color[2] = (fill >> 0 & 0xff) / 255.0f * color[3];
|
||||||
|
|
||||||
if (blend > 0) {
|
if (blend > 0) {
|
||||||
blendColor = new float[4];
|
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;
|
blendColor[3] = (blendFill >> 24 & 0xff) / 255.0f;
|
||||||
|
blendColor[0] = (blendFill >> 16 & 0xff) / 255.0f * blendColor[3];
|
||||||
|
blendColor[1] = (blendFill >> 8 & 0xff) / 255.0f * blendColor[3];
|
||||||
|
blendColor[2] = (blendFill >> 0 & 0xff) / 255.0f * blendColor[3];
|
||||||
} else {
|
} else {
|
||||||
blendColor = null;
|
blendColor = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -188,10 +188,10 @@ public final class Line extends RenderInstruction {
|
|||||||
this.cap = strokeLinecap;
|
this.cap = strokeLinecap;
|
||||||
|
|
||||||
color = new float[4];
|
color = new float[4];
|
||||||
color[0] = (stroke >> 16 & 0xff) / 255.0f;
|
|
||||||
color[1] = (stroke >> 8 & 0xff) / 255.0f;
|
|
||||||
color[2] = (stroke >> 0 & 0xff) / 255.0f;
|
|
||||||
color[3] = (stroke >> 24 & 0xff) / 255.0f;
|
color[3] = (stroke >> 24 & 0xff) / 255.0f;
|
||||||
|
color[0] = (stroke >> 16 & 0xff) / 255.0f * color[3];
|
||||||
|
color[1] = (stroke >> 8 & 0xff) / 255.0f * color[3];
|
||||||
|
color[2] = (stroke >> 0 & 0xff) / 255.0f * color[3];
|
||||||
|
|
||||||
this.width = strokeWidth;
|
this.width = strokeWidth;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|||||||
@ -25,9 +25,9 @@ public class GlConfigChooser implements GLSurfaceView.EGLConfigChooser {
|
|||||||
|
|
||||||
// Try to find a normal multisample configuration first.
|
// Try to find a normal multisample configuration first.
|
||||||
int[] configSpec = {
|
int[] configSpec = {
|
||||||
EGL10.EGL_RED_SIZE, 8,
|
EGL10.EGL_RED_SIZE, 5,
|
||||||
EGL10.EGL_GREEN_SIZE, 8,
|
EGL10.EGL_GREEN_SIZE, 6,
|
||||||
EGL10.EGL_BLUE_SIZE, 8,
|
EGL10.EGL_BLUE_SIZE, 5,
|
||||||
EGL10.EGL_ALPHA_SIZE, 0,
|
EGL10.EGL_ALPHA_SIZE, 0,
|
||||||
EGL10.EGL_DEPTH_SIZE, 24,
|
EGL10.EGL_DEPTH_SIZE, 24,
|
||||||
// Requires that setEGLContextClientVersion(2) is called on the view.
|
// Requires that setEGLContextClientVersion(2) is called on the view.
|
||||||
@ -132,15 +132,16 @@ public class GlConfigChooser implements GLSurfaceView.EGLConfigChooser {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
return String.format("EGLConfig rgba=%d%d%d%d depth=%d stencil=%d",
|
return String.format("EGLConfig rgba=%d%d%d%d depth=%d stencil=%d",
|
||||||
new Integer(r), new Integer(g),
|
Integer.valueOf(r), Integer.valueOf(g),
|
||||||
new Integer(b), new Integer(a), new Integer(d), new Integer(s))
|
Integer.valueOf(b), Integer.valueOf(a), Integer.valueOf(d),
|
||||||
|
Integer.valueOf(s))
|
||||||
+ " native="
|
+ " native="
|
||||||
+ findConfigAttrib(egl, display, config, EGL10.EGL_NATIVE_RENDERABLE, 0)
|
+ findConfigAttrib(egl, display, config, EGL10.EGL_NATIVE_RENDERABLE, 0)
|
||||||
+ " buffer="
|
+ " buffer="
|
||||||
+ findConfigAttrib(egl, display, config, EGL10.EGL_BUFFER_SIZE, 0)
|
+ findConfigAttrib(egl, display, config, EGL10.EGL_BUFFER_SIZE, 0)
|
||||||
+ String.format(
|
+ String.format(
|
||||||
" caveat=0x%04x",
|
" caveat=0x%04x",
|
||||||
new Integer(findConfigAttrib(egl, display, config,
|
Integer.valueOf(findConfigAttrib(egl, display, config,
|
||||||
EGL10.EGL_CONFIG_CAVEAT, 0)));
|
EGL10.EGL_CONFIG_CAVEAT, 0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user