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