diff --git a/src/org/mapsforge/android/MapView.java b/src/org/mapsforge/android/MapView.java
index 6ec03d73..03148c51 100644
--- a/src/org/mapsforge/android/MapView.java
+++ b/src/org/mapsforge/android/MapView.java
@@ -78,6 +78,8 @@ public class MapView extends GLSurfaceView {
private static final float DEFAULT_TEXT_SCALE = 1;
private static final Byte DEFAULT_START_ZOOM_LEVEL = Byte.valueOf((byte) 16);
+ public final static boolean debugFrameTime = false;
+
private final MapController mMapController;
private final MapViewPosition mMapViewPosition;
@@ -186,6 +188,7 @@ public class MapView extends GLSurfaceView {
setEGLConfigChooser(new GlConfigChooser());
setEGLContextClientVersion(2);
+ // setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
setRenderer(mMapRenderer);
@@ -193,8 +196,6 @@ public class MapView extends GLSurfaceView {
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
- public final static boolean debugFrameTime = false;
-
private void initMapStartPosition() {
GeoPoint startPoint = getStartPoint();
if (startPoint != null) {
diff --git a/src/org/mapsforge/android/glrenderer/LineLayer.java b/src/org/mapsforge/android/glrenderer/LineLayer.java
index 4b64bee7..a8e95633 100644
--- a/src/org/mapsforge/android/glrenderer/LineLayer.java
+++ b/src/org/mapsforge/android/glrenderer/LineLayer.java
@@ -22,10 +22,16 @@ import android.util.FloatMath;
class LineLayer {
- private static final float S = MapRenderer.COORD_MULTIPLIER;
- private static final float S1000 = 1000;
+ private static final float COORD_SCALE = MapRenderer.COORD_MULTIPLIER;
+ // 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;
+
+ // lines referenced by this outline layer
LineLayer outlines;
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
- * how the road connects to set the ending angles
+ * line extrusion is based on code from GLMap (https://github.com/olofsj/GLMap/) by olofsj
*/
void addLine(float[] points, int pos, int length) {
- float x, y, nextX, nextY, prevX, prevY, ux, uy, vx, vy, wx, wy;
- float a;
+ float x, y, nextX, nextY, prevX, prevY;
+ float a, ux, uy, vx, vy, wx, wy;
+
int ipos = pos;
boolean rounded = false;
boolean squared = false;
@@ -94,7 +100,8 @@ class LineLayer {
ux = -vy;
uy = vx;
- int tsize = Tile.TILE_SIZE;
+ int tmax = Tile.TILE_SIZE + 10;
+ int tmin = -10;
if (pool == null) {
pool = curItem = ShortPool.get();
@@ -112,27 +119,25 @@ class LineLayer {
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;
+ int ddx, ddy;
- ox = (short) (x * S);
- oy = (short) (y * S);
+ ox = (short) (x * COORD_SCALE);
+ oy = (short) (y * COORD_SCALE);
+
+ boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
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
- dx = (short) ((ux - vx) * S1000);
- dy = (short) ((uy - vy) * S1000);
-
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -142,13 +147,10 @@ class LineLayer {
v = si.vertices;
}
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -158,16 +160,13 @@ class LineLayer {
v = si.vertices;
}
- dx = (short) (-(ux + vx) * S1000);
- dy = (short) (-(uy + vy) * S1000);
+ ddx = (int) (-(ux + vx) * DIR_SCALE);
+ ddy = (int) (-(uy + vy) * DIR_SCALE);
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (2 | ddx & DIR_MASK);
+ v[opos++] = (short) (2 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -178,16 +177,13 @@ class LineLayer {
}
// Start of line
- dx = (short) (ux * S1000);
- dy = (short) (uy * S1000);
+ ddx = (int) (ux * DIR_SCALE);
+ ddy = (int) (uy * DIR_SCALE);
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (0 | ddx & DIR_MASK);
+ v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -197,13 +193,10 @@ class LineLayer {
v = si.vertices;
}
- v[opos + 0] = ox;
- v[opos + 1] = oy;
- v[opos + 2] = (short) (-dx);
- v[opos + 3] = (short) (-dy);
- v[opos + 4] = 1;
- v[opos + 5] = 0;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (2 | -ddx & DIR_MASK);
+ v[opos++] = (short) (1 | -ddy & DIR_MASK);
} else {
// outside means line is probably clipped
@@ -221,16 +214,16 @@ class LineLayer {
if (rounded)
verticesCnt -= 2;
- dx = (short) ((ux - vx) * S1000);
- dy = (short) ((uy - vy) * S1000);
+ // add first vertex twice
+ 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 + 1] = oy;
- v[opos + 2] = dx;
- v[opos + 3] = dy;
- v[opos + 4] = -1;
- v[opos + 5] = 0;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -240,13 +233,10 @@ class LineLayer {
v = si.vertices;
}
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -256,16 +246,14 @@ class LineLayer {
v = si.vertices;
}
- dx = (short) (-(ux + vx) * S1000);
- dy = (short) (-(uy + vy) * S1000);
+ ddx = (int) (-(ux + vx) * DIR_SCALE);
+ 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;
@@ -298,14 +286,16 @@ class LineLayer {
a = -wy * ux + wx * uy;
// boolean split = false;
- if (a < 0.1f && a > -0.1f) {
- // Almost straight or miter goes to infinity, use normal vector
+ if (a < 0.01f && a > -0.01f) {
+ // Almost straight
ux = -wy;
uy = wx;
} else {
ux = (ux / 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) {
ux = -wy;
uy = wx;
@@ -320,19 +310,16 @@ class LineLayer {
v = si.vertices;
}
- ox = (short) (x * S);
- oy = (short) (y * S);
+ ox = (short) (x * COORD_SCALE);
+ oy = (short) (y * COORD_SCALE);
- dx = (short) (ux * S1000);
- dy = (short) (uy * S1000);
+ ddx = (int) (ux * DIR_SCALE);
+ ddy = (int) (uy * DIR_SCALE);
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (0 | ddx & DIR_MASK);
+ v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -342,13 +329,10 @@ class LineLayer {
v = si.vertices;
}
- v[opos + 0] = ox;
- v[opos + 1] = oy;
- v[opos + 2] = (short) -dx;
- v[opos + 3] = (short) -dy;
- v[opos + 4] = 1;
- v[opos + 5] = 0;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (2 | -ddx & DIR_MASK);
+ v[opos++] = (short) (1 | -ddy & DIR_MASK);
prevX = x;
prevY = y;
@@ -367,8 +351,7 @@ class LineLayer {
ux = vy;
uy = -vx;
- outside = (x <= 0 || x >= tsize || y <= 0 || y >= tsize)
- && (x - vx <= 0 || x - vx >= tsize || y - vy <= 0 || y - vy >= tsize);
+ outside = (x < tmin || x > tmax || y < tmin || y > tmax);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -378,21 +361,17 @@ class LineLayer {
v = si.vertices;
}
- ox = (short) (x * S);
- oy = (short) (y * S);
+ ox = (short) (x * COORD_SCALE);
+ oy = (short) (y * COORD_SCALE);
if (rounded && !outside) {
+ ddx = (int) (ux * DIR_SCALE);
+ ddy = (int) (uy * DIR_SCALE);
- dx = (short) (ux * S1000);
- dy = (short) (uy * S1000);
-
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (0 | ddx & DIR_MASK);
+ v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -402,13 +381,10 @@ class LineLayer {
v = si.vertices;
}
- v[opos + 0] = ox;
- v[opos + 1] = oy;
- v[opos + 2] = (short) -dx;
- v[opos + 3] = (short) -dy;
- v[opos + 4] = 1;
- v[opos + 5] = 0;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (2 | -ddx & DIR_MASK);
+ v[opos++] = (short) (1 | -ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -419,16 +395,15 @@ class LineLayer {
}
// For rounded line edges
- dx = (short) ((ux - vx) * S1000);
- 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) (0 | 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] = -1;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -438,16 +413,16 @@ class LineLayer {
v = si.vertices;
}
- dx = (short) (-(ux + vx) * S1000);
- dy = (short) (-(uy + vy) * S1000);
+ // add last vertex twice
+ 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 + 1] = oy;
- v[opos + 2] = dx;
- v[opos + 3] = dy;
- v[opos + 4] = 1;
- v[opos + 5] = -1;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -457,13 +432,10 @@ class LineLayer {
v = si.vertices;
}
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
} else {
if (squared) {
@@ -477,16 +449,13 @@ class LineLayer {
if (rounded)
verticesCnt -= 2;
- dx = (short) ((ux - vx) * S1000);
- dy = (short) ((uy - vy) * S1000);
+ ddx = (int) ((ux - vx) * DIR_SCALE);
+ ddy = (int) ((uy - vy) * DIR_SCALE);
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = (short) (0 | ddx & DIR_MASK);
+ v[opos++] = (short) (1 | ddy & DIR_MASK);
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -496,16 +465,16 @@ class LineLayer {
v = si.vertices;
}
- dx = (short) (-(ux + vx) * S1000);
- dy = (short) (-(uy + vy) * S1000);
+ // add last vertex twice
+ 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 + 1] = oy;
- v[opos + 2] = dx;
- v[opos + 3] = dy;
- v[opos + 4] = 1;
- v[opos + 5] = 0;
- opos += 6;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
if (opos == ShortItem.SIZE) {
si.used = ShortItem.SIZE;
@@ -515,13 +484,10 @@ class LineLayer {
v = si.vertices;
}
- 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;
+ v[opos++] = ox;
+ v[opos++] = oy;
+ v[opos++] = dx;
+ v[opos++] = dy;
}
si.used = opos;
diff --git a/src/org/mapsforge/android/glrenderer/LineLayers.java b/src/org/mapsforge/android/glrenderer/LineLayers.java
index ed895206..9241dea0 100644
--- a/src/org/mapsforge/android/glrenderer/LineLayers.java
+++ b/src/org/mapsforge/android/glrenderer/LineLayers.java
@@ -35,10 +35,10 @@ import android.opengl.GLES20;
import android.util.FloatMath;
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_TEX_OFFSET = 8;
+ private static final int LINE_VERTICES_DATA_TEX_OFFSET = 4;
// shader handles
private static int lineProgram;
@@ -82,11 +82,11 @@ class LineLayers {
glEnableVertexAttribArray(hLineVertexPosition);
glEnableVertexAttribArray(hLineTexturePosition);
- glVertexAttribPointer(hLineVertexPosition, 4, GLES20.GL_SHORT,
- false, 12, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
+ glVertexAttribPointer(hLineVertexPosition, 2, GLES20.GL_SHORT,
+ false, 8, tile.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
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);
@@ -115,7 +115,10 @@ class LineLayers {
if (alpha > 1.0f)
alpha = 1.0f;
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 {
glUniform4fv(hLineColor, 1, line.color, 0);
}
diff --git a/src/org/mapsforge/android/glrenderer/MapRenderer.java b/src/org/mapsforge/android/glrenderer/MapRenderer.java
index 3e603867..673257e1 100644
--- a/src/org/mapsforge/android/glrenderer/MapRenderer.java
+++ b/src/org/mapsforge/android/glrenderer/MapRenderer.java
@@ -16,11 +16,9 @@ package org.mapsforge.android.glrenderer;
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
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_ONE_MINUS_SRC_ALPHA;
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.glBindBuffer;
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.glDisable;
import static android.opengl.GLES20.glEnable;
-import static android.opengl.GLES20.glFinish;
import static android.opengl.GLES20.glGenBuffers;
import static android.opengl.GLES20.glScissor;
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 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;
@@ -109,7 +106,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
private static float[] mMVPMatrix = 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
// with curTiles on main thread. curTiles is swapped
@@ -600,6 +597,12 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
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) {
float x, y, scale;
@@ -609,7 +612,8 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
mMVPMatrix[12] = x * scale * mAspect;
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[5] = scale / COORD_MULTIPLIER;
@@ -763,6 +767,9 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / MB + "MB");
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ int buf[] = new int[1];
+
synchronized (mVBOs) {
for (VertexBufferObject vbo : mVBOs) {
@@ -770,8 +777,19 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
continue;
mBufferMemoryUsage -= vbo.size;
- glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
- glBufferData(GL_ARRAY_BUFFER, 0, null, GL_DYNAMIC_DRAW);
+ GlUtils.checkGlError("before");
+ // 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;
}
}
@@ -801,7 +819,14 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
}
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)
return;
@@ -862,7 +887,6 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
if (updateTextures > 0)
TextRenderer.compileTextures();
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
// 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_DEPTH_TEST);
+ //
mDrawCount = 0;
glEnable(GL_BLEND);
- glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-
int z = mDrawPosition.zoomLevel;
float s = mDrawPosition.scale;
- int zoomLevelDiff = Math
- .max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0);
+ int zoomLevelDiff = Math.max(z - MapGenerator.STROKE_MAX_ZOOM_LEVEL, 0);
float scale = (float) Math.pow(1.4, zoomLevelDiff);
if (scale < 1)
scale = 1;
@@ -913,7 +935,7 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
TextRenderer.endDraw();
if (MapView.debugFrameTime) {
- glFinish();
+ GLES20.glFinish();
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) {
-
+ // draw parents only once
if (tile.lastDraw == mRedrawCnt)
return;
+ tile.lastDraw = mRedrawCnt;
+
int z = mDrawPosition.zoomLevel;
float s = mDrawPosition.scale;
- tile.lastDraw = mRedrawCnt;
-
+ // mDrawCount is used to calculation z offset.
+ // (used for depth clipping)
setMatrix(tile, div, mDrawCount++);
glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
- // GLES20.glPolygonOffset(0, mDrawCount);
LineLayer ll = tile.lineLayers;
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);
- if (!clipped) {
- clipped = true;
- }
+ clipped = true;
+
} else {
- // XXX nastay
+ // XXX nasty
if (!clipped) {
PolygonLayers.drawPolygons(null, 0, mMVPMatrix, z, s, true);
clipped = true;
}
+
glEnable(GL_BLEND);
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
TextRenderer.init(numTiles);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- // glDisable(GLES20.GL_DEPTH_TEST);
- // glDepthMask(false);
- // GLES20.glDepthRangef(1, 0);
- // GLES20.glClearDepthf(0);
-
- glDisable(GL_DITHER);
+ // glDisable(GL_DITHER);
if (mClearColor != null) {
glClearColor(mClearColor[0], mClearColor[1],
@@ -1096,12 +1112,17 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
} else {
glClearColor(0.98f, 0.98f, 0.97f, 1.0f);
}
+
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
glScissor(0, 0, mWidth, mHeight);
+ glBlendFunc(GLES20.GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ GlUtils.checkGlError("onSurfaceChanged");
+
mMapView.redrawTiles();
}
@@ -1127,10 +1148,10 @@ public class MapRenderer implements org.mapsforge.android.IMapRenderer {
mFillCoords[6] = max;
mFillCoords[7] = min;
- int i[] = new int[1];
-
+ // int i[] = new int[1];
// GLES20.glGetIntegerv(GLES20.GL_, i, 0);
- Log.d(TAG, " >>>> " + i[0]);
+ // Log.d(TAG, " >>>> " + i[0]);
+
LineLayers.init();
PolygonLayers.init();
}
diff --git a/src/org/mapsforge/android/glrenderer/PolygonLayers.java b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
index 6809ffb7..049130f1 100644
--- a/src/org/mapsforge/android/glrenderer/PolygonLayers.java
+++ b/src/org/mapsforge/android/glrenderer/PolygonLayers.java
@@ -25,7 +25,6 @@ import static android.opengl.GLES20.glColorMask;
import static android.opengl.GLES20.glDisable;
import static android.opengl.GLES20.glDrawArrays;
import static android.opengl.GLES20.glEnable;
-import static android.opengl.GLES20.glEnableVertexAttribArray;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glStencilFunc;
@@ -82,7 +81,7 @@ class PolygonLayers {
// do not modify stencil buffer
glStencilMask(0);
- // GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
+ glEnable(GLES20.GL_DEPTH_TEST);
for (int c = 0; c < count; c++) {
PolygonLayer l = mFillPolys[c];
@@ -90,7 +89,7 @@ class PolygonLayers {
float alpha = 1.0f;
if (l.area.fade >= zoom || l.area.color[3] != 1.0) {
-
+ // draw alpha blending, fade in/out
if (l.area.fade >= zoom) {
alpha = (scale > 1.3f ? scale : 1.3f) - alpha;
if (alpha > 1.0f)
@@ -104,9 +103,13 @@ class PolygonLayers {
blend = true;
}
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) {
+ // fade in/out
alpha = scale - 1.0f;
if (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[2] * (1 - alpha) + l.area.blendColor[2] * alpha, 1);
} else {
+ // draw solid
if (blend) {
glDisable(GL_BLEND);
blend = false;
@@ -144,7 +148,7 @@ class PolygonLayers {
int cnt = 0;
glUseProgram(polygonProgram);
- glEnableVertexAttribArray(hPolygonVertexPosition);
+ GLES20.glEnableVertexAttribArray(hPolygonVertexPosition);
glVertexAttribPointer(hPolygonVertexPosition, 2,
GLES20.GL_SHORT, false, 0,
@@ -177,9 +181,12 @@ class PolygonLayers {
// clear stencilbuffer (tile region)
glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
- // draw depth clipper
if (first) {
+ // draw clip-region into depth buffer
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);
}
@@ -193,6 +200,7 @@ class PolygonLayers {
// stencil op for stencil method polygon drawing
glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
+ glDisable(GLES20.GL_DEPTH_TEST);
}
mFillPolys[cnt] = l;
@@ -218,7 +226,6 @@ class PolygonLayers {
// required on GalaxyII, Android 2.3.3 (cant just VAA enable once...)
GLES20.glDisableVertexAttribArray(hPolygonVertexPosition);
-
return l;
}
diff --git a/src/org/mapsforge/android/glrenderer/Shaders.java b/src/org/mapsforge/android/glrenderer/Shaders.java
index c88e62e9..c3bd5eb6 100644
--- a/src/org/mapsforge/android/glrenderer/Shaders.java
+++ b/src/org/mapsforge/android/glrenderer/Shaders.java
@@ -20,17 +20,35 @@ class Shaders {
final static String lineVertexShader = ""
+ "precision mediump float;"
+ "uniform mat4 mvp;"
- + "attribute vec4 a_position;"
+ + "attribute vec2 a_position;"
+ "attribute vec2 a_st;"
+ "varying vec2 v_st;"
+ "uniform float u_width;"
- + "const float dscale = 8.0/1000.0;"
+ + "const float dscale = 8.0/2048.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;"
+ // scale extrusion to line u_width pixel
+ // just ignore the two most insignificant bits of 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 = ""
+ "precision mediump float;"
+ "uniform float u_wscale;"
@@ -45,7 +63,12 @@ class Shaders {
+ " len = abs(v_st.s);"
+ " else "
+ " 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;"
+ "}";
diff --git a/src/org/mapsforge/android/glrenderer/VertexBufferObject.java b/src/org/mapsforge/android/glrenderer/VertexBufferObject.java
index 40c5d6e2..b1a6a50f 100644
--- a/src/org/mapsforge/android/glrenderer/VertexBufferObject.java
+++ b/src/org/mapsforge/android/glrenderer/VertexBufferObject.java
@@ -16,11 +16,11 @@
package org.mapsforge.android.glrenderer;
class VertexBufferObject {
- final int id;
+ int id;
int size;
VertexBufferObject(int id) {
this.id = id;
size = 0;
}
-}
\ No newline at end of file
+}
diff --git a/src/org/mapsforge/android/input/MapMover.java b/src/org/mapsforge/android/input/MapMover.java
deleted file mode 100644
index fc2e2b5f..00000000
--- a/src/org/mapsforge/android/input/MapMover.java
+++ /dev/null
@@ -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 .
- */
-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;
- }
-}
diff --git a/src/org/mapsforge/android/input/ZoomAnimator.java b/src/org/mapsforge/android/input/ZoomAnimator.java
deleted file mode 100644
index b45860f5..00000000
--- a/src/org/mapsforge/android/input/ZoomAnimator.java
+++ /dev/null
@@ -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 .
- */
-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;
- }
-}
diff --git a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
index 442ddeb4..15bfd5de 100644
--- a/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
+++ b/src/org/mapsforge/android/rendertheme/renderinstruction/Area.java
@@ -114,17 +114,17 @@ public final class Area extends RenderInstruction {
// }
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[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) {
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[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 {
blendColor = null;
}
diff --git a/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java b/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java
index 1df42522..b63d0740 100644
--- a/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java
+++ b/src/org/mapsforge/android/rendertheme/renderinstruction/Line.java
@@ -188,10 +188,10 @@ public final class Line extends RenderInstruction {
this.cap = strokeLinecap;
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[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.level = level;
diff --git a/src/org/mapsforge/android/utils/GlConfigChooser.java b/src/org/mapsforge/android/utils/GlConfigChooser.java
index c26373c3..16e015ea 100644
--- a/src/org/mapsforge/android/utils/GlConfigChooser.java
+++ b/src/org/mapsforge/android/utils/GlConfigChooser.java
@@ -25,9 +25,9 @@ public class GlConfigChooser implements GLSurfaceView.EGLConfigChooser {
// Try to find a normal multisample configuration first.
int[] configSpec = {
- EGL10.EGL_RED_SIZE, 8,
- EGL10.EGL_GREEN_SIZE, 8,
- EGL10.EGL_BLUE_SIZE, 8,
+ EGL10.EGL_RED_SIZE, 5,
+ EGL10.EGL_GREEN_SIZE, 6,
+ EGL10.EGL_BLUE_SIZE, 5,
EGL10.EGL_ALPHA_SIZE, 0,
EGL10.EGL_DEPTH_SIZE, 24,
// 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",
- new Integer(r), new Integer(g),
- new Integer(b), new Integer(a), new Integer(d), new Integer(s))
+ Integer.valueOf(r), Integer.valueOf(g),
+ Integer.valueOf(b), Integer.valueOf(a), Integer.valueOf(d),
+ Integer.valueOf(s))
+ " native="
+ findConfigAttrib(egl, display, config, EGL10.EGL_NATIVE_RENDERABLE, 0)
+ " buffer="
+ findConfigAttrib(egl, display, config, EGL10.EGL_BUFFER_SIZE, 0)
+ String.format(
" caveat=0x%04x",
- new Integer(findConfigAttrib(egl, display, config,
+ Integer.valueOf(findConfigAttrib(egl, display, config,
EGL10.EGL_CONFIG_CAVEAT, 0)));
}