- started overlays
- started symbol layer - move renderer and generator out of view package - hopefully the last big refactoring for a while... - improve perspective, plane should be more far away to decrease foreshortening
This commit is contained in:
37
src/org/oscim/renderer/layer/Layer.java
Normal file
37
src/org/oscim/renderer/layer/Layer.java
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
public class Layer {
|
||||
public final static byte LINE = 0;
|
||||
public final static byte POLYGON = 1;
|
||||
public final static byte WAYTEXT = 2;
|
||||
public final static byte POITEXT = 3;
|
||||
public final static byte SYMBOL = 4;
|
||||
public final static byte BITMAP = 5;
|
||||
|
||||
public byte type;
|
||||
|
||||
public Layer next;
|
||||
|
||||
int layer;
|
||||
// number of vertices this layer holds
|
||||
public int verticesCnt;
|
||||
// vertices offset of this layer in VBO
|
||||
public int offset;
|
||||
|
||||
VertexPoolItem pool;
|
||||
protected VertexPoolItem curItem;
|
||||
}
|
||||
166
src/org/oscim/renderer/layer/Layers.java
Normal file
166
src/org/oscim/renderer/layer/Layers.java
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class Layers {
|
||||
|
||||
public Layer layers;
|
||||
public int lineOffset;
|
||||
|
||||
public Layer symbolLayers;
|
||||
public int symbolOffset;
|
||||
|
||||
private Layer mCurLayer;
|
||||
|
||||
public Layer getLayer(int level, byte type) {
|
||||
Layer l = layers;
|
||||
Layer ret = null;
|
||||
|
||||
if (mCurLayer != null && mCurLayer.layer == level) {
|
||||
ret = mCurLayer;
|
||||
} else if (l == null || l.layer > level) {
|
||||
// insert new layer at start
|
||||
l = null;
|
||||
} else {
|
||||
while (true) {
|
||||
if (l.layer == level) {
|
||||
// found layer
|
||||
ret = l;
|
||||
break;
|
||||
}
|
||||
|
||||
if (l.next == null || l.next.layer > level) {
|
||||
// insert new layer between current and next layer
|
||||
break;
|
||||
}
|
||||
l = l.next;
|
||||
}
|
||||
}
|
||||
if (ret == null) {
|
||||
if (type == Layer.LINE)
|
||||
ret = new LineLayer(level);
|
||||
else
|
||||
ret = new PolygonLayer(level);
|
||||
|
||||
if (l == null) {
|
||||
ret.next = layers;
|
||||
layers = ret;
|
||||
} else {
|
||||
ret.next = l.next;
|
||||
l.next = ret;
|
||||
}
|
||||
} else if (ret.type != type) {
|
||||
Log.d("...", "wrong layer type " + ret.type + " " + type);
|
||||
// FIXME thorw exception
|
||||
return null;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static int LINE_VERTEX_SHORTS = 4;
|
||||
private static int POLY_VERTEX_SHORTS = 2;
|
||||
private static int TEXTURE_VERTEX_SHORTS = 6;
|
||||
|
||||
public int getSize() {
|
||||
int size = 0;
|
||||
for (Layer l = layers; l != null; l = l.next) {
|
||||
if (l.type == Layer.LINE)
|
||||
size += l.verticesCnt * LINE_VERTEX_SHORTS;
|
||||
else
|
||||
size += l.verticesCnt * POLY_VERTEX_SHORTS;
|
||||
|
||||
}
|
||||
|
||||
for (Layer l = symbolLayers; l != null; l = l.next) {
|
||||
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
public void compile(ShortBuffer sbuf, boolean addFill) {
|
||||
// offset from fill coordinates
|
||||
int pos = 0;
|
||||
if (addFill)
|
||||
pos = 4;
|
||||
|
||||
// add polygons first, needed to get the offsets right...
|
||||
addLayerItems(sbuf, layers, Layer.POLYGON, pos);
|
||||
|
||||
lineOffset = sbuf.position() * 2; // * short-bytes
|
||||
addLayerItems(sbuf, layers, Layer.LINE, 0);
|
||||
|
||||
symbolOffset = sbuf.position() * 2; // * short-bytes
|
||||
|
||||
for (Layer l = symbolLayers; l != null; l = l.next) {
|
||||
SymbolLayer sl = (SymbolLayer) l;
|
||||
sl.compile(sbuf);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) {
|
||||
VertexPoolItem last = null, items = null;
|
||||
|
||||
for (; l != null; l = l.next) {
|
||||
if (l.type != type)
|
||||
continue;
|
||||
|
||||
for (VertexPoolItem it = l.pool; it != null; it = it.next) {
|
||||
if (it.next == null)
|
||||
sbuf.put(it.vertices, 0, it.used);
|
||||
else
|
||||
sbuf.put(it.vertices);
|
||||
last = it;
|
||||
}
|
||||
if (last == null)
|
||||
continue;
|
||||
|
||||
l.offset = pos;
|
||||
pos += l.verticesCnt;
|
||||
|
||||
last.next = items;
|
||||
items = l.pool;
|
||||
last = null;
|
||||
|
||||
l.pool = null;
|
||||
l.curItem = null;
|
||||
}
|
||||
VertexPool.release(items);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
// FIXME collect pool and add as a whole
|
||||
for (Layer l = layers; l != null; l = l.next) {
|
||||
if (l.pool != null) {
|
||||
VertexPool.release(l.pool);
|
||||
l.pool = null;
|
||||
l.curItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
for (Layer l = symbolLayers; l != null; l = l.next) {
|
||||
SymbolLayer sl = (SymbolLayer) l;
|
||||
if (sl.textures != null)
|
||||
TextureObject.release(sl.textures);
|
||||
}
|
||||
}
|
||||
}
|
||||
500
src/org/oscim/renderer/layer/LineLayer.java
Normal file
500
src/org/oscim/renderer/layer/LineLayer.java
Normal file
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.theme.renderinstruction.Line;
|
||||
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.util.FloatMath;
|
||||
|
||||
public final class LineLayer extends Layer {
|
||||
|
||||
private static final float COORD_SCALE = GLRenderer.COORD_MULTIPLIER;
|
||||
// scale factor mapping extrusion vector to short values
|
||||
private static final float DIR_SCALE = 2048;
|
||||
// mask for packing last two bits of extrusion vector with texture
|
||||
// coordinates
|
||||
private static final int DIR_MASK = 0xFFFFFFFC;
|
||||
|
||||
// lines referenced by this outline layer
|
||||
public LineLayer outlines;
|
||||
public Line line;
|
||||
public float width;
|
||||
|
||||
// boolean isOutline;
|
||||
|
||||
LineLayer(int layer) {
|
||||
this.layer = layer;
|
||||
this.type = Layer.LINE;
|
||||
}
|
||||
|
||||
// LineLayer(int layer, Line line, float width, boolean outline) {
|
||||
// this.layer = layer;
|
||||
// this.width = width;
|
||||
// this.line = line;
|
||||
// // this.isOutline = outline;
|
||||
// }
|
||||
|
||||
public void addOutline(LineLayer link) {
|
||||
for (LineLayer l = outlines; l != null; l = l.outlines)
|
||||
if (link == l)
|
||||
return;
|
||||
|
||||
link.outlines = outlines;
|
||||
outlines = link;
|
||||
}
|
||||
|
||||
/*
|
||||
* line extrusion is based on code from GLMap
|
||||
* (https://github.com/olofsj/GLMap/) by olofsj
|
||||
*/
|
||||
|
||||
public void addLine(float[] points, short[] index, boolean closed) {
|
||||
float x, y, nextX, nextY, prevX, prevY;
|
||||
float a, ux, uy, vx, vy, wx, wy;
|
||||
|
||||
int tmax = Tile.TILE_SIZE + 10;
|
||||
int tmin = -10;
|
||||
|
||||
boolean rounded = false;
|
||||
boolean squared = false;
|
||||
|
||||
if (line.cap == Cap.ROUND)
|
||||
rounded = true;
|
||||
else if (line.cap == Cap.SQUARE)
|
||||
squared = true;
|
||||
|
||||
if (pool == null) {
|
||||
pool = curItem = VertexPool.get();
|
||||
}
|
||||
|
||||
VertexPoolItem si = curItem;
|
||||
short v[] = si.vertices;
|
||||
int opos = si.used;
|
||||
|
||||
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
||||
|
||||
int length = index[i];
|
||||
if (length < 0)
|
||||
break;
|
||||
|
||||
// save some vertices
|
||||
if (rounded && i > 200)
|
||||
rounded = false;
|
||||
|
||||
// need at least two points
|
||||
if (length < 4) {
|
||||
pos += length;
|
||||
continue;
|
||||
}
|
||||
|
||||
closed = false;
|
||||
|
||||
// amount of vertices used
|
||||
// + 2 for drawing triangle-strip
|
||||
// + 4 for round caps
|
||||
// + 2 for closing polygons
|
||||
verticesCnt += length + (rounded ? 6 : 2) + (closed ? 2 : 0);
|
||||
|
||||
int ipos = pos;
|
||||
|
||||
x = points[ipos++];
|
||||
y = points[ipos++];
|
||||
|
||||
nextX = points[ipos++];
|
||||
nextY = points[ipos++];
|
||||
|
||||
// Calculate triangle corners for the given width
|
||||
vx = nextX - x;
|
||||
vy = nextY - y;
|
||||
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
|
||||
vx = (vx / a);
|
||||
vy = (vy / a);
|
||||
|
||||
ux = -vy;
|
||||
uy = vx;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
short ox, oy, dx, dy;
|
||||
int ddx, ddy;
|
||||
|
||||
ox = (short) (x * COORD_SCALE);
|
||||
oy = (short) (y * COORD_SCALE);
|
||||
|
||||
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
if (rounded && !outside) {
|
||||
// add first vertex twice
|
||||
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||
// last two bit encode texture coord (-1)
|
||||
dx = (short) (0 | ddx & DIR_MASK);
|
||||
dy = (short) (2 | ddy & DIR_MASK);
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
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) (2 | ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
// Start of line
|
||||
ddx = (int) (ux * DIR_SCALE);
|
||||
ddy = (int) (uy * DIR_SCALE);
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
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
|
||||
// TODO should align ending with tile boundary
|
||||
// for now, just extend the line a little
|
||||
|
||||
if (squared) {
|
||||
vx = 0;
|
||||
vy = 0;
|
||||
} else if (!outside) {
|
||||
vx *= 0.5;
|
||||
vy *= 0.5;
|
||||
}
|
||||
|
||||
if (rounded)
|
||||
verticesCnt -= 2;
|
||||
|
||||
// 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++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
prevX = x;
|
||||
prevY = y;
|
||||
x = nextX;
|
||||
y = nextY;
|
||||
|
||||
for (;;) {
|
||||
if (ipos < pos + length) {
|
||||
nextX = points[ipos++];
|
||||
nextY = points[ipos++];
|
||||
} else if (closed && ipos < pos + length + 2) {
|
||||
// add startpoint == endpoint
|
||||
nextX = points[pos];
|
||||
nextY = points[pos + 1];
|
||||
ipos += 2;
|
||||
} else
|
||||
break;
|
||||
|
||||
// Unit vector pointing back to previous node
|
||||
vx = prevX - x;
|
||||
vy = prevY - y;
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
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 = (wx / a);
|
||||
wy = (wy / a);
|
||||
|
||||
// Sum of these two vectors points
|
||||
ux = vx + wx;
|
||||
uy = vy + wy;
|
||||
|
||||
a = -wy * ux + wx * uy;
|
||||
|
||||
// boolean split = false;
|
||||
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
|
||||
if (ux > 2.0f || ux < -2.0f || uy > 2.0f || uy < -2.0f) {
|
||||
ux = -wy;
|
||||
uy = wx;
|
||||
}
|
||||
}
|
||||
|
||||
ox = (short) (x * COORD_SCALE);
|
||||
oy = (short) (y * COORD_SCALE);
|
||||
|
||||
ddx = (int) (ux * DIR_SCALE);
|
||||
ddy = (int) (uy * DIR_SCALE);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||
|
||||
prevX = x;
|
||||
prevY = y;
|
||||
x = nextX;
|
||||
y = nextY;
|
||||
}
|
||||
|
||||
vx = prevX - x;
|
||||
vy = prevY - y;
|
||||
|
||||
a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
|
||||
vx = (vx / a);
|
||||
vy = (vy / a);
|
||||
|
||||
ux = vy;
|
||||
uy = -vx;
|
||||
|
||||
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si.next = VertexPool.get();
|
||||
si = si.next;
|
||||
opos = 0;
|
||||
v = si.vertices;
|
||||
}
|
||||
|
||||
ox = (short) (x * COORD_SCALE);
|
||||
oy = (short) (y * COORD_SCALE);
|
||||
|
||||
if (rounded && !outside) {
|
||||
ddx = (int) (ux * DIR_SCALE);
|
||||
ddy = (int) (uy * DIR_SCALE);
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
// For rounded line edges
|
||||
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++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
// 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++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
} else {
|
||||
if (squared) {
|
||||
vx = 0;
|
||||
vy = 0;
|
||||
} else if (!outside) {
|
||||
vx *= 0.5;
|
||||
vy *= 0.5;
|
||||
}
|
||||
|
||||
if (rounded)
|
||||
verticesCnt -= 2;
|
||||
|
||||
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
// 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++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
|
||||
if (opos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
opos = 0;
|
||||
}
|
||||
|
||||
v[opos++] = ox;
|
||||
v[opos++] = oy;
|
||||
v[opos++] = dx;
|
||||
v[opos++] = dy;
|
||||
}
|
||||
pos += length;
|
||||
}
|
||||
|
||||
si.used = opos;
|
||||
curItem = si;
|
||||
}
|
||||
}
|
||||
90
src/org/oscim/renderer/layer/PolygonLayer.java
Normal file
90
src/org/oscim/renderer/layer/PolygonLayer.java
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.theme.renderinstruction.Area;
|
||||
|
||||
public final class PolygonLayer extends Layer {
|
||||
private static final float S = GLRenderer.COORD_MULTIPLIER;
|
||||
|
||||
public Area area;
|
||||
|
||||
PolygonLayer(int layer) {
|
||||
this.layer = layer;
|
||||
this.type = Layer.POLYGON;
|
||||
curItem = VertexPool.get();
|
||||
pool = curItem;
|
||||
}
|
||||
|
||||
public void addPolygon(float[] points, short[] index) {
|
||||
short center = (short) ((Tile.TILE_SIZE >> 1) * S);
|
||||
|
||||
VertexPoolItem si = curItem;
|
||||
short[] v = si.vertices;
|
||||
int outPos = si.used;
|
||||
|
||||
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
||||
int length = index[i];
|
||||
if (length < 0)
|
||||
break;
|
||||
|
||||
// need at least three points
|
||||
if (length < 6) {
|
||||
pos += length;
|
||||
continue;
|
||||
}
|
||||
|
||||
verticesCnt += length / 2 + 2;
|
||||
|
||||
int inPos = pos;
|
||||
|
||||
if (outPos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
v[outPos++] = center;
|
||||
v[outPos++] = center;
|
||||
|
||||
for (int j = 0; j < length; j += 2) {
|
||||
if (outPos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
outPos = 0;
|
||||
}
|
||||
v[outPos++] = (short) (points[inPos++] * S);
|
||||
v[outPos++] = (short) (points[inPos++] * S);
|
||||
}
|
||||
|
||||
if (outPos == VertexPoolItem.SIZE) {
|
||||
si = si.next = VertexPool.get();
|
||||
v = si.vertices;
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
v[outPos++] = (short) (points[pos + 0] * S);
|
||||
v[outPos++] = (short) (points[pos + 1] * S);
|
||||
|
||||
pos += length;
|
||||
}
|
||||
|
||||
si.used = outPos;
|
||||
curItem = si;
|
||||
}
|
||||
|
||||
}
|
||||
29
src/org/oscim/renderer/layer/SymbolItem.java
Normal file
29
src/org/oscim/renderer/layer/SymbolItem.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
public class SymbolItem {
|
||||
SymbolItem next;
|
||||
|
||||
public Bitmap bitmap;
|
||||
public float x;
|
||||
public float y;
|
||||
public boolean billboard;
|
||||
|
||||
// center, top, bottom, left, right, top-left...
|
||||
byte placement;
|
||||
}
|
||||
200
src/org/oscim/renderer/layer/SymbolLayer.java
Normal file
200
src/org/oscim/renderer/layer/SymbolLayer.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLUtils;
|
||||
import android.util.Log;
|
||||
|
||||
// TODO share one static texture for all poi map symabols
|
||||
|
||||
public final class SymbolLayer extends TextureLayer {
|
||||
private static String TAG = SymbolLayer.class.getSimpleName();
|
||||
|
||||
private final static int TEXTURE_WIDTH = 256;
|
||||
private final static int TEXTURE_HEIGHT = 256;
|
||||
private final static float SCALE = 8.0f;
|
||||
|
||||
private static short[] mVertices;
|
||||
private static Bitmap mBitmap;
|
||||
private static Canvas mCanvas;
|
||||
private static int mBitmapFormat;
|
||||
private static int mBitmapType;
|
||||
|
||||
SymbolItem symbols;
|
||||
|
||||
public SymbolLayer() {
|
||||
if (mBitmap == null) {
|
||||
mBitmap = Bitmap.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
mCanvas = new Canvas(mBitmap);
|
||||
mBitmapFormat = GLUtils.getInternalFormat(mBitmap);
|
||||
mBitmapType = GLUtils.getType(mBitmap);
|
||||
//
|
||||
mVertices = new short[40 * 24];
|
||||
}
|
||||
}
|
||||
|
||||
public void addSymbol(SymbolItem item) {
|
||||
|
||||
verticesCnt += 4;
|
||||
|
||||
SymbolItem it = symbols;
|
||||
|
||||
for (; it != null; it = it.next) {
|
||||
if (it.bitmap == item.bitmap) {
|
||||
item.next = it.next;
|
||||
it.next = item;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
item.next = symbols;
|
||||
symbols = item;
|
||||
}
|
||||
|
||||
private final static int LBIT_MASK = 0xfffffffe;
|
||||
private final RectF mRect = new RectF();
|
||||
|
||||
// TODO ... reuse texture when only symbol position changed
|
||||
public void compile(ShortBuffer sbuf) {
|
||||
|
||||
int pos = 0;
|
||||
short buf[] = mVertices;
|
||||
|
||||
int advanceY = 0;
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
||||
mBitmap.eraseColor(Color.TRANSPARENT);
|
||||
|
||||
for (SymbolItem it = symbols; it != null;) {
|
||||
|
||||
// add bitmap
|
||||
float width = it.bitmap.getWidth();
|
||||
float height = it.bitmap.getHeight();
|
||||
|
||||
if (height > advanceY)
|
||||
advanceY = (int) height;
|
||||
|
||||
if (x + width > TEXTURE_WIDTH) {
|
||||
x = 0;
|
||||
y += advanceY;
|
||||
advanceY = (int) (height + 0.5f);
|
||||
|
||||
if (y + height > TEXTURE_HEIGHT) {
|
||||
Log.d(TAG, "reached max symbols");
|
||||
// need to sync bitmap upload somehow???
|
||||
TextureObject to = TextureObject.get();
|
||||
TextureObject.uploadTexture(to, mBitmap,
|
||||
mBitmapFormat, mBitmapType,
|
||||
TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
to.next = textures;
|
||||
textures = to;
|
||||
|
||||
sbuf.put(buf, 0, pos);
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
mRect.left = x;
|
||||
mRect.top = y;
|
||||
mRect.right = x + width;
|
||||
mRect.bottom = y + height;
|
||||
// Log.d("...", "draw " + x + " " + y + " " + width + " " + height);
|
||||
|
||||
mCanvas.drawBitmap(it.bitmap, null, mRect, null);
|
||||
// mCanvas.drawBitmap(it.bitmap, x, y, null);
|
||||
|
||||
float hw = width / 2.0f;
|
||||
float hh = height / 2.0f;
|
||||
short x1, x2, x3, x4, y1, y2, y3, y4;
|
||||
x1 = x3 = (short) (SCALE * (-hw));
|
||||
x2 = x4 = (short) (SCALE * (hw));
|
||||
|
||||
y1 = y3 = (short) (SCALE * (hh));
|
||||
y2 = y4 = (short) (SCALE * (-hh));
|
||||
|
||||
short u1 = (short) (SCALE * x);
|
||||
short v1 = (short) (SCALE * y);
|
||||
short u2 = (short) (SCALE * (x + width));
|
||||
short v2 = (short) (SCALE * (y + height));
|
||||
|
||||
// add symbol items referencing the same bitmap
|
||||
for (SymbolItem it2 = it;; it2 = it2.next) {
|
||||
|
||||
if (it2 == null || it2.bitmap != it.bitmap) {
|
||||
it = it2;
|
||||
break;
|
||||
}
|
||||
|
||||
// add vertices
|
||||
short tx = (short) ((int) (SCALE * it2.x) & LBIT_MASK | (it2.billboard ? 1 : 0));
|
||||
short ty = (short) (SCALE * it2.y);
|
||||
|
||||
// top-left
|
||||
buf[pos++] = tx;
|
||||
buf[pos++] = ty;
|
||||
buf[pos++] = x1;
|
||||
buf[pos++] = y1;
|
||||
buf[pos++] = u1;
|
||||
buf[pos++] = v2;
|
||||
|
||||
// top-right
|
||||
buf[pos++] = tx;
|
||||
buf[pos++] = ty;
|
||||
buf[pos++] = x2;
|
||||
buf[pos++] = y3;
|
||||
buf[pos++] = u2;
|
||||
buf[pos++] = v2;
|
||||
|
||||
// bot-right
|
||||
buf[pos++] = tx;
|
||||
buf[pos++] = ty;
|
||||
buf[pos++] = x4;
|
||||
buf[pos++] = y4;
|
||||
buf[pos++] = u2;
|
||||
buf[pos++] = v1;
|
||||
|
||||
// bot-left
|
||||
buf[pos++] = tx;
|
||||
buf[pos++] = ty;
|
||||
buf[pos++] = x3;
|
||||
buf[pos++] = y2;
|
||||
buf[pos++] = u1;
|
||||
buf[pos++] = v1;
|
||||
|
||||
x += width + 1;
|
||||
}
|
||||
}
|
||||
|
||||
TextureObject to = TextureObject.get();
|
||||
|
||||
TextureObject.uploadTexture(to, mBitmap,
|
||||
mBitmapFormat, mBitmapType,
|
||||
TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
|
||||
to.next = textures;
|
||||
textures = to;
|
||||
|
||||
sbuf.put(buf, 0, pos);
|
||||
}
|
||||
}
|
||||
22
src/org/oscim/renderer/layer/TextLayer.java
Normal file
22
src/org/oscim/renderer/layer/TextLayer.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import org.oscim.renderer.TextItem;
|
||||
|
||||
public final class TextLayer extends TextureLayer {
|
||||
TextItem labels;
|
||||
|
||||
}
|
||||
22
src/org/oscim/renderer/layer/TextureLayer.java
Normal file
22
src/org/oscim/renderer/layer/TextureLayer.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
|
||||
public abstract class TextureLayer extends Layer {
|
||||
public TextureObject textures;
|
||||
|
||||
}
|
||||
112
src/org/oscim/renderer/layer/VertexPool.java
Normal file
112
src/org/oscim/renderer/layer/VertexPool.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class VertexPool {
|
||||
private static final int POOL_LIMIT = 6000;
|
||||
|
||||
static private VertexPoolItem pool = null;
|
||||
static private int count = 0;
|
||||
static private int countAll = 0;
|
||||
|
||||
public static synchronized void init() {
|
||||
count = 0;
|
||||
countAll = 0;
|
||||
pool = null;
|
||||
}
|
||||
|
||||
static synchronized VertexPoolItem get() {
|
||||
|
||||
if (pool == null && count > 0) {
|
||||
Log.d("VertexPool", "XXX wrong count: " + count);
|
||||
}
|
||||
if (pool == null) {
|
||||
countAll++;
|
||||
return new VertexPoolItem();
|
||||
}
|
||||
|
||||
count--;
|
||||
|
||||
if (count < 0) {
|
||||
int c = 0;
|
||||
|
||||
for (VertexPoolItem tmp = pool; tmp != null; tmp = tmp.next)
|
||||
c++;
|
||||
|
||||
Log.d("VertexPool", "XXX wrong count: " + count + " left" + c);
|
||||
return new VertexPoolItem();
|
||||
}
|
||||
|
||||
VertexPoolItem it = pool;
|
||||
pool = pool.next;
|
||||
it.used = 0;
|
||||
it.next = null;
|
||||
return it;
|
||||
}
|
||||
|
||||
// private static float load = 1.0f;
|
||||
// private static int loadCount = 0;
|
||||
|
||||
static synchronized void release(VertexPoolItem items) {
|
||||
if (items == null)
|
||||
return;
|
||||
|
||||
// int pall = countAll;
|
||||
// int pcnt = count;
|
||||
|
||||
// limit pool items
|
||||
if (countAll < POOL_LIMIT) {
|
||||
|
||||
VertexPoolItem last = items;
|
||||
|
||||
while (true) {
|
||||
count++;
|
||||
// load += (float) last.used / VertexPoolItem.SIZE;
|
||||
// loadCount++;
|
||||
|
||||
if (last.next == null)
|
||||
break;
|
||||
|
||||
last = last.next;
|
||||
}
|
||||
|
||||
last.next = pool;
|
||||
pool = items;
|
||||
// Log.d("Pool", "added: " + (count - pcnt) + " " + count + " " +
|
||||
// countAll
|
||||
// + " load: " + (load / loadCount));
|
||||
|
||||
} else {
|
||||
// int cleared = 0;
|
||||
VertexPoolItem prev, tmp = items;
|
||||
while (tmp != null) {
|
||||
prev = tmp;
|
||||
tmp = tmp.next;
|
||||
|
||||
countAll--;
|
||||
|
||||
// load += (float) prev.used / VertexPoolItem.SIZE;
|
||||
// loadCount++;
|
||||
|
||||
prev.next = null;
|
||||
|
||||
}
|
||||
// Log.d("Pool", "dropped: " + (pall - countAll) + " " + count + " "
|
||||
// + countAll + " load: " + (load / loadCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/org/oscim/renderer/layer/VertexPoolItem.java
Normal file
29
src/org/oscim/renderer/layer/VertexPoolItem.java
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
public class VertexPoolItem {
|
||||
final short[] vertices;
|
||||
int used;
|
||||
VertexPoolItem next;
|
||||
|
||||
VertexPoolItem() {
|
||||
vertices = new short[SIZE];
|
||||
used = 0;
|
||||
}
|
||||
|
||||
// must be multiple of 4 (expected in LineLayer/PolygonLayer)
|
||||
static final int SIZE = 256;
|
||||
}
|
||||
Reference in New Issue
Block a user