refactor: add api for common VertexItem use

- rename VertexItem -> VertexData
This commit is contained in:
Hannes Janetzek 2014-06-10 21:33:53 +02:00
parent ad0eff3fac
commit 3f49361e4a
16 changed files with 533 additions and 781 deletions

View File

@ -1,7 +1,7 @@
package org.oscim.utils;
import org.oscim.core.GeometryBuffer;
import org.oscim.renderer.elements.VertexItem;
import org.oscim.renderer.elements.VertexData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -17,7 +17,7 @@ public class Tessellator {
static final Logger log = LoggerFactory.getLogger(Tessellator.class);
public static int tessellate(GeometryBuffer geom, float scale,
VertexItem outPoints, VertexItem outTris, int vertexOffset) {
VertexData outPoints, VertexData outTris, int vertexOffset) {
int numIndices = 0;
int indexPos = 0;
@ -64,22 +64,19 @@ public class Tessellator {
numIndices += resIndices;
for (int k = 0, cnt = 0; k < resIndices; k += cnt) {
VertexData.Chunk chunk = outTris.obtainChunk();
if (outTris.used == VertexItem.SIZE) {
outTris.next = VertexItem.pool.get();
outTris = outTris.next;
}
cnt = VertexItem.SIZE - outTris.used;
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > resIndices)
cnt = resIndices - k;
for (int i = 0; i < cnt; i++)
outTris.vertices[outTris.used + i] =
chunk.vertices[chunk.used + i] =
(short) (vertexOffset + io.get(k + i));
outTris.used += cnt;
chunk.used += cnt;
outTris.releaseChunk();
}
Float32Array po = res.getPoints(res);
@ -88,22 +85,19 @@ public class Tessellator {
vertexOffset += (resPoints >> 1);
for (int k = 0, cnt = 0; k < resPoints; k += cnt) {
VertexData.Chunk chunk = outPoints.obtainChunk();
if (outPoints.used == VertexItem.SIZE) {
outPoints.next = VertexItem.pool.get();
outPoints = outPoints.next;
}
cnt = VertexItem.SIZE - outPoints.used;
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > resPoints)
cnt = resPoints - k;
for (int i = 0; i < cnt; i++)
outPoints.vertices[outPoints.used + i] =
chunk.vertices[chunk.used + i] =
(short) (po.get(k + i) * scale);
outPoints.used += cnt;
chunk.used += cnt;
outPoints.releaseChunk();
}
if (idx >= indexEnd || geom.index[idx] < 0)
@ -114,7 +108,7 @@ public class Tessellator {
}
public static int tessellate(float[] points, int ppos, int plen, short[] index,
int ipos, int rings, int vertexOffset, VertexItem outTris) {
int ipos, int rings, int vertexOffset, VertexData outTris) {
Int32Array io;
try {
@ -145,22 +139,19 @@ public class Tessellator {
int numIndices = io.length();
for (int k = 0, cnt = 0; k < numIndices; k += cnt) {
VertexData.Chunk chunk = outTris.obtainChunk();
if (outTris.used == VertexItem.SIZE) {
outTris.next = VertexItem.pool.get();
outTris = outTris.next;
}
cnt = VertexItem.SIZE - outTris.used;
cnt = VertexData.SIZE - chunk.used;
if (k + cnt > numIndices)
cnt = numIndices - k;
for (int i = 0; i < cnt; i++) {
int idx = (vertexOffset + io.get(k + i));
outTris.vertices[outTris.used + i] = (short) idx;
chunk.vertices[chunk.used + i] = (short) idx;
}
outTris.used += cnt;
chunk.used += cnt;
outTris.releaseChunk();
}
return numIndices;

View File

@ -127,7 +127,7 @@ class S3DBTileLoader extends TileLoader {
return;
}
for (ExtrusionLayer l = mLayers; l != null; l = (ExtrusionLayer) l.next) {
for (ExtrusionLayer l = mLayers; l != null; l = l.next()) {
if (l.color == c) {
l.add(element);
return;

View File

@ -292,53 +292,25 @@ public class ElementLayers extends TileData {
private static int addLayerItems(ShortBuffer sbuf, RenderElement l,
int type, int pos) {
VertexItem last = null, items = null;
int size = 0;
for (; l != null; l = l.next) {
if (l.type != type)
continue;
for (VertexItem it = l.vertexItems; it != null; it = it.next) {
if (it.next == null) {
size += it.used;
sbuf.put(it.vertices, 0, it.used);
}
else {
size += VertexItem.SIZE;
sbuf.put(it.vertices, 0, VertexItem.SIZE);
}
last = it;
}
if (last == null)
continue;
size += l.vertexItems.compile(sbuf);
l.offset = pos;
pos += l.numVertices;
last.next = items;
items = l.vertexItems;
last = null;
l.vertexItems = null;
}
items = VertexItem.pool.releaseAll(items);
return size;
}
static void addPoolItems(RenderElement l, ShortBuffer sbuf) {
/* keep offset of layer data in vbo */
l.offset = sbuf.position() * SHORT_BYTES;
for (VertexItem it = l.vertexItems; it != null; it = it.next) {
if (it.next == null)
sbuf.put(it.vertices, 0, it.used);
else
sbuf.put(it.vertices, 0, VertexItem.SIZE);
}
l.vertexItems = VertexItem.pool.releaseAll(l.vertexItems);
l.vertexItems.compile(sbuf);
}
public void setFrom(ElementLayers layers) {

View File

@ -29,7 +29,6 @@ import org.oscim.utils.KeyMap;
import org.oscim.utils.KeyMap.HashItem;
import org.oscim.utils.Tessellator;
import org.oscim.utils.geom.LineClipper;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.Pool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,10 +37,8 @@ public class ExtrusionLayer extends RenderElement {
static final Logger log = LoggerFactory.getLogger(ExtrusionLayer.class);
private static final float S = MapRenderer.COORD_SCALE;
private VertexItem mVertices;
private VertexItem mCurVertices;
private VertexItem mIndices[];
private final VertexItem mCurIndices[];
private VertexData mVertices;
private VertexData mIndices[];
private LineClipper mClipper;
/** 16 floats rgba for top, even-side, odd-sides and outline */
@ -80,12 +77,12 @@ public class ExtrusionLayer extends RenderElement {
this.color = 0;
mGroundResolution = groundResolution;
mVertices = mCurVertices = VertexItem.pool.get();
mVertices = VertexData.get();
mIndices = new VertexData[5];
mIndices = new VertexItem[5];
mCurIndices = new VertexItem[5];
for (int i = 0; i <= IND_MESH; i++)
mIndices[i] = mCurIndices[i] = VertexItem.pool.get();
mIndices[i] = VertexData.get();
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE);
}
@ -97,20 +94,20 @@ public class ExtrusionLayer extends RenderElement {
super(RenderElement.EXTRUSION);
this.level = level;
this.color = color;
this.colors = new float[4];
float a = Color.aToFloat(color);
colors = new float[4];
colors[0] = a * Color.rToFloat(color);
colors[1] = a * Color.gToFloat(color);
colors[2] = a * Color.bToFloat(color);
colors[3] = a;
mGroundResolution = groundResolution;
mVertices = mCurVertices = VertexItem.pool.get();
mVertices = VertexData.get();
mIndices = new VertexItem[5];
mCurIndices = new VertexItem[5];
mIndices = new VertexData[5];
mIndices[4] = VertexData.get();
mIndices[4] = mCurIndices[4] = VertexItem.pool.get();
synchronized (vertexPool) {
mVertexMap = vertexMapPool.get();
}
@ -227,12 +224,11 @@ public class ExtrusionLayer extends RenderElement {
if (vertex == null) {
key.id = vertexCnt++;
addVertex(key);
addIndex(key);
addIndex(key, true);
key = vertexPool.get();
} else {
//numIndexHits++;
addIndex(vertex);
addIndex(vertex, false);
}
key.set((short) (vx2 * scale),
@ -244,12 +240,11 @@ public class ExtrusionLayer extends RenderElement {
if (vertex == null) {
key.id = vertexCnt++;
addVertex(key);
addIndex(key);
addIndex(key, true);
key = vertexPool.get();
} else {
//numIndexHits++;
addIndex(vertex);
addIndex(vertex, false);
}
key.set((short) (vx3 * scale),
@ -260,12 +255,11 @@ public class ExtrusionLayer extends RenderElement {
vertex = mVertexMap.put(key, false);
if (vertex == null) {
key.id = vertexCnt++;
addVertex(key);
addIndex(key);
addIndex(key, true);
key = vertexPool.get();
} else {
//numIndexHits++;
addIndex(vertex);
addIndex(vertex, false);
}
}
@ -274,31 +268,12 @@ public class ExtrusionLayer extends RenderElement {
sumVertices = vertexCnt;
}
private void addVertex(Vertex vertex) {
VertexItem vi = mCurVertices;
private void addIndex(Vertex v, boolean addVertex) {
if (addVertex)
mVertices.add(v.x, v.y, v.z, v.n);
if (vi.used == VertexItem.SIZE) {
mCurVertices.used = VertexItem.SIZE;
mCurVertices = VertexItem.pool.getNext(vi);
vi = mCurVertices;
}
vi.vertices[vi.used++] = vertex.x;
vi.vertices[vi.used++] = vertex.y;
vi.vertices[vi.used++] = vertex.z;
vi.vertices[vi.used++] = vertex.n;
}
private void addIndex(Vertex v) {
VertexItem vi = mCurIndices[IND_MESH];
if (vi.used == VertexItem.SIZE) {
mCurIndices[IND_MESH].used = VertexItem.SIZE;
mCurIndices[IND_MESH] = VertexItem.pool.getNext(vi);
vi = mCurIndices[IND_MESH];
}
mIndices[IND_MESH].add((short) v.id);
sumIndices++;
vi.vertices[vi.used++] = (short) v.id;
}
// private void encodeNormal(float v[], int offset) {
@ -309,62 +284,59 @@ public class ExtrusionLayer extends RenderElement {
// return result;
// }
//
public void addNoNormal(MapElement element) {
if (element.type != GeometryType.TRIS)
return;
short[] index = element.index;
float[] points = element.points;
/* current vertex id */
int startVertex = sumVertices;
/* roof indices for convex shapes */
int i = mCurIndices[IND_MESH].used;
short[] indices = mCurIndices[IND_MESH].vertices;
int first = startVertex;
for (int k = 0, n = index.length; k < n;) {
if (index[k] < 0)
break;
if (i == VertexItem.SIZE) {
mCurIndices[IND_MESH].used = VertexItem.SIZE;
mCurIndices[IND_MESH].next = VertexItem.pool.get();
mCurIndices[IND_MESH] = mCurIndices[IND_MESH].next;
indices = mCurIndices[IND_MESH].vertices;
i = 0;
}
indices[i++] = (short) (first + index[k++]);
indices[i++] = (short) (first + index[k++]);
indices[i++] = (short) (first + index[k++]);
}
mCurIndices[IND_MESH].used = i;
short[] vertices = mCurVertices.vertices;
int v = mCurVertices.used;
int vertexCnt = element.pointPos;
for (int j = 0; j < vertexCnt;) {
/* add bottom and top vertex for each point */
if (v == VertexItem.SIZE) {
mCurVertices.used = VertexItem.SIZE;
mCurVertices.next = VertexItem.pool.get();
mCurVertices = mCurVertices.next;
vertices = mCurVertices.vertices;
v = 0;
}
/* set coordinate */
vertices[v++] = (short) (points[j++] * S);
vertices[v++] = (short) (points[j++] * S);
vertices[v++] = (short) (points[j++] * S);
v++;
}
mCurVertices.used = v;
sumVertices += (vertexCnt / 3);
}
//public void addNoNormal(MapElement element) {
// if (element.type != GeometryType.TRIS)
// return;
//
// short[] index = element.index;
// float[] points = element.points;
//
// /* current vertex id */
// int startVertex = sumVertices;
//
// /* roof indices for convex shapes */
// int i = mCurIndices[IND_MESH].used;
// short[] indices = mCurIndices[IND_MESH].vertices;
//
// int first = startVertex;
//
// for (int k = 0, n = index.length; k < n;) {
// if (index[k] < 0)
// break;
//
// if (i == VertexItem.SIZE) {
// mCurIndices[IND_MESH] = VertexItem.getNext(mCurIndices[IND_MESH]);
// indices = mCurIndices[IND_MESH].vertices;
// i = 0;
// }
// indices[i++] = (short) (first + index[k++]);
// indices[i++] = (short) (first + index[k++]);
// indices[i++] = (short) (first + index[k++]);
// }
// mCurIndices[IND_MESH].used = i;
//
// short[] vertices = mCurVertices.vertices;
// int v = mCurVertices.used;
//
// int vertexCnt = element.pointPos;
//
// for (int j = 0; j < vertexCnt;) {
// /* add bottom and top vertex for each point */
// if (v == VertexItem.SIZE) {
// mCurVertices = VertexItem.getNext(mCurVertices);
// vertices = mCurVertices.vertices;
// v = 0;
// }
// /* set coordinate */
// vertices[v++] = (short) (points[j++] * S);
// vertices[v++] = (short) (points[j++] * S);
// vertices[v++] = (short) (points[j++] * S);
// v++;
// }
//
// mCurVertices.used = v;
// sumVertices += (vertexCnt / 3);
//}
public void add(MapElement element, float height, float minHeight) {
@ -418,7 +390,7 @@ public class ExtrusionLayer extends RenderElement {
if (simpleOutline && (ipos < n - 1) && (index[ipos + 1] > 0))
simpleOutline = false;
boolean convex = addOutline(points, ppos, len, minHeight,
boolean convex = extrudeOutline(points, ppos, len, minHeight,
height, simpleOutline);
if (simpleOutline && (convex || len <= 8)) {
@ -430,29 +402,20 @@ public class ExtrusionLayer extends RenderElement {
}
}
/** roof indices for convex shapes */
private void addRoofSimple(int startVertex, int len) {
/* roof indices for convex shapes */
int i = mCurIndices[IND_ROOF].used;
short[] indices = mCurIndices[IND_ROOF].vertices;
short first = (short) (startVertex + 1);
for (int k = 0; k < len - 4; k += 2) {
if (i == VertexItem.SIZE) {
mCurIndices[IND_ROOF].used = VertexItem.SIZE;
mCurIndices[IND_ROOF].next = VertexItem.pool.get();
mCurIndices[IND_ROOF] = mCurIndices[IND_ROOF].next;
indices = mCurIndices[IND_ROOF].vertices;
i = 0;
}
indices[i++] = first;
indices[i++] = (short) (first + k + 2);
indices[i++] = (short) (first + k + 4);
sumIndices += 3;
}
mCurIndices[IND_ROOF].used = i;
VertexData it = mIndices[IND_ROOF];
len -= 4;
for (int k = 0; k < len; k += 2) {
it.add(first,
(short) (first + k + 2),
(short) (first + k + 4));
}
sumIndices += (len / 2) * 3;
}
/** roof indices for concave shapes */
private void addRoof(int startVertex, GeometryBuffer geom, int ipos, int ppos) {
short[] index = geom.index;
float[] points = geom.points;
@ -466,22 +429,19 @@ public class ExtrusionLayer extends RenderElement {
rings++;
}
sumIndices += Tessellator.tessellate(points, ppos, len, index, ipos, rings,
startVertex + 1, mCurIndices[IND_ROOF]);
mCurIndices[IND_ROOF] = Inlist.last(mCurIndices[IND_ROOF]);
sumIndices += Tessellator.tessellate(points, ppos, len,
index, ipos, rings,
startVertex + 1,
mIndices[IND_ROOF]);
}
private boolean addOutline(float[] points, int pos, int len, float minHeight,
float height, boolean convex) {
private boolean extrudeOutline(float[] points, int pos, int len,
float minHeight, float height, boolean convex) {
/* add two vertices for last face to make zigzag indices work */
boolean addFace = (len % 4 != 0);
int vertexCnt = len + (addFace ? 2 : 0);
short h = (short) height;
short mh = (short) minHeight;
float cx = points[pos + len - 2];
float cy = points[pos + len - 1];
float nx = points[pos + 0];
@ -495,46 +455,26 @@ public class ExtrusionLayer extends RenderElement {
float a = (float) Math.sqrt(vx * vx + vy * vy);
short color1 = (short) ((1 + vx / a) * 127);
short fcolor = color1;
short color2 = 0;
short fcolor = color1, color2 = 0;
short h = (short) height, mh = (short) minHeight;
int even = 0;
int changeX = 0;
int changeY = 0;
int angleSign = 0;
int changeX = 0, changeY = 0, angleSign = 0;
/* vertex offset for all vertices in layer */
int vOffset = sumVertices;
short[] vertices = mCurVertices.vertices;
int v = mCurVertices.used;
mClipper.clipStart((int) nx, (int) ny);
for (int i = 2, n = vertexCnt + 2; i < n; i += 2, v += 8) {
for (int i = 2, n = vertexCnt + 2; i < n; i += 2 /* , v += 8 */) {
cx = nx;
cy = ny;
ux = vx;
uy = vy;
/* add bottom and top vertex for each point */
if (v == VertexItem.SIZE) {
mCurVertices.used = VertexItem.SIZE;
mCurVertices.next = VertexItem.pool.get();
mCurVertices = mCurVertices.next;
vertices = mCurVertices.vertices;
v = 0;
}
/* set coordinate */
vertices[v + 0] = vertices[v + 4] = (short) (cx * S);
vertices[v + 1] = vertices[v + 5] = (short) (cy * S);
/* set height */
vertices[v + 2] = mh;
vertices[v + 6] = h;
/* get direction to next point */
if (i < len) {
nx = points[pos + i + 0];
@ -544,8 +484,11 @@ public class ExtrusionLayer extends RenderElement {
ny = points[pos + 1];
} else { // if (addFace)
short c = (short) (color1 | fcolor << 8);
vertices[v + 3] = vertices[v + 7] = c;
v += 8;
/* add bottom and top vertex for each point */
mVertices.add((short) (cx * S), (short) (cy * S), mh, c);
mVertices.add((short) (cx * S), (short) (cy * S), h, c);
//v += 8;
break;
}
@ -562,7 +505,10 @@ public class ExtrusionLayer extends RenderElement {
else
c = (short) (color2 | color1 << 8);
vertices[v + 3] = vertices[v + 7] = c;
/* add bottom and top vertex for each point */
mVertices.add((short) (cx * S), (short) (cy * S), mh, c);
mVertices.add((short) (cx * S), (short) (cy * S), h, c);
color1 = color2;
/* check if polygon is convex */
@ -609,41 +555,18 @@ public class ExtrusionLayer extends RenderElement {
s3 -= len;
}
VertexItem it = mCurIndices[even];
if (it.used == VertexItem.SIZE) {
it = VertexItem.pool.getNext(it);
mCurIndices[even] = it;
}
int ind = it.used;
short[] indices = it.vertices;
indices[ind + 0] = s0;
indices[ind + 1] = s2;
indices[ind + 2] = s1;
indices[ind + 3] = s1;
indices[ind + 4] = s2;
indices[ind + 5] = s3;
it.used += 6;
mIndices[even].add(s0, s2, s1);
mIndices[even].add(s1, s2, s3);
sumIndices += 6;
/* flipp even-odd */
even = ++even % 2;
/* add roof outline indices */
it = mCurIndices[IND_OUTLINE];
if (it.used == VertexItem.SIZE) {
it = VertexItem.pool.getNext(it);
mCurIndices[IND_OUTLINE] = it;
}
ind = it.used;
indices = it.vertices;
indices[ind + 0] = s1;
indices[ind + 1] = s3;
it.used += 2;
mIndices[IND_OUTLINE].add(s1, s3);
sumIndices += 2;
}
mCurVertices.used = v;
sumVertices += vertexCnt;
return convex;
}
@ -651,28 +574,21 @@ public class ExtrusionLayer extends RenderElement {
@Override
public void compile(ShortBuffer vertexBuffer, ShortBuffer indexBuffer) {
mClipper = null;
releaseVertexPool();
if (sumVertices == 0) {
if (sumVertices == 0)
return;
}
indexOffset = indexBuffer.position();
for (int i = 0; i <= IND_MESH; i++) {
for (VertexItem vi = mIndices[i]; vi != null; vi = vi.next) {
indexBuffer.put(vi.vertices, 0, vi.used);
numIndices[i] += vi.used;
if (mIndices[i] == null)
continue;
numIndices[i] += mIndices[i].compile(indexBuffer);
}
}
//log.debug("INDEX HITS " + numIndexHits + " / " + sumVertices + " / " + sumIndices);
offset = vertexBuffer.position() * 2;
for (VertexItem vi = mVertices; vi != null; vi = vi.next)
vertexBuffer.put(vi.vertices, 0, vi.used);
mVertices.compile(vertexBuffer);
clear();
}
@ -680,14 +596,19 @@ public class ExtrusionLayer extends RenderElement {
@Override
protected void clear() {
mClipper = null;
releaseVertexPool();
if (mIndices != null) {
for (int i = 0; i <= IND_MESH; i++)
mIndices[i] = VertexItem.pool.releaseAll(mIndices[i]);
mIndices = null;
mVertices = VertexItem.pool.releaseAll(mVertices);
for (int i = 0; i <= IND_MESH; i++) {
if (mIndices[i] == null)
continue;
mIndices[i].dispose();
}
mIndices = null;
mVertices.dispose();
mVertices = null;
}
releaseVertexPool();
}
void releaseVertexPool() {

View File

@ -6,7 +6,6 @@ import org.oscim.backend.GL20;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.MapTile.TileData;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.MapRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -58,29 +57,26 @@ public class ExtrusionLayers extends TileData {
}
public boolean compileLayers() {
ExtrusionLayer el = layers;
if (el == null)
if (layers == null)
return false;
//if (el.compiled)
// return true;
int sumIndices = 0;
int sumVertices = 0;
for (ExtrusionLayer l = el; l != null; l = l.next()) {
for (ExtrusionLayer l = layers; l != null; l = l.next()) {
sumIndices += l.sumIndices;
sumVertices += l.sumVertices;
}
if (sumIndices == 0) {
if (sumIndices == 0)
return false;
}
ShortBuffer vbuf = MapRenderer.getShortBuffer(sumVertices * 4);
ShortBuffer ibuf = MapRenderer.getShortBuffer(sumIndices);
for (ExtrusionLayer l = el; l != null; l = l.next())
for (ExtrusionLayer l = layers; l != null; l = l.next()) {
l.compile(vbuf, ibuf);
}
int size = sumIndices * 2;
if (ibuf.position() != sumIndices) {
int pos = ibuf.position();
@ -102,9 +98,8 @@ public class ExtrusionLayers extends TileData {
vboVertices.loadBufferData(vbuf.flip(), size);
vboVertices.unbind();
GLUtils.checkGlError("extrusion layer");
compiled = true;
return true;
}

View File

@ -16,9 +16,6 @@
*/
package org.oscim.renderer.elements;
import static org.oscim.renderer.elements.VertexItem.SIZE;
import static org.oscim.renderer.elements.VertexItem.pool;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap;
@ -30,7 +27,6 @@ import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -124,11 +120,6 @@ public final class LineLayer extends RenderElement {
else if (line.cap == Cap.SQUARE)
squared = true;
if (vertexItems == null)
vertexItems = pool.get();
VertexItem vertexItem = Inlist.last(vertexItems);
/* Note: just a hack to save some vertices, when there are
* more than 200 lines per type. FIXME make optional! */
if (rounded && index != null) {
@ -185,19 +176,12 @@ public final class LineLayer extends RenderElement {
points[ipos + 1] == points[ipos + 5])
length -= 2;
vertexItem = addLine(vertexItem, points, ipos, length, rounded, squared, closed);
addLine(vertexItems, points, ipos, length, rounded, squared, closed);
}
}
private void addVertex(short[] v, int pos, short x, short y, int dx, int dy) {
v[pos + 0] = x;
v[pos + 1] = y;
v[pos + 2] = (short) dx;
v[pos + 3] = (short) dy;
}
private VertexItem addVertex(VertexItem vertexItem,
private void addVertex(VertexData vi,
float x, float y,
float vNextX, float vNextY,
float vPrevX, float vPrevY) {
@ -222,37 +206,16 @@ public final class LineLayer extends RenderElement {
int ddx = (int) (ux * DIR_SCALE);
int ddy = (int) (uy * DIR_SCALE);
int opos = vertexItem.used;
short[] v = vertexItem.vertices;
vi.add(ox, oy,
(short) (0 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
if (opos == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
vi.add(ox, oy,
(short) (2 | -ddx & DIR_MASK),
(short) (1 | -ddy & DIR_MASK));
}
v[opos + 0] = ox;
v[opos + 1] = oy;
v[opos + 2] = (short) (0 | ddx & DIR_MASK);
v[opos + 3] = (short) (1 | ddy & DIR_MASK);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
v[opos + 0] = ox;
v[opos + 1] = oy;
v[opos + 2] = (short) (2 | -ddx & DIR_MASK);
v[opos + 3] = (short) (1 | -ddy & DIR_MASK);
vertexItem.used = opos + 4;
return vertexItem;
}
private VertexItem addLine(VertexItem vertexItem, float[] points, int start, int length,
private void addLine(VertexData vertices, float[] points, int start, int length,
boolean rounded, boolean squared, boolean closed) {
float ux, uy;
@ -262,9 +225,6 @@ public final class LineLayer extends RenderElement {
float nextX, nextY;
double a;
short v[] = vertexItem.vertices;
int opos = vertexItem.used;
/* amount of vertices used
* + 2 for drawing triangle-strip
* + 4 for round caps
@ -302,65 +262,33 @@ public final class LineLayer extends RenderElement {
/* when the endpoint is outside the tile region omit round caps. */
boolean outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax);
if (opos == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
if (rounded && !outside) {
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (2 | ddy & DIR_MASK);
addVertex(v, opos, ox, oy, dx, dy);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy, dx, dy);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
vertices.add(ox, oy, (short) dx, (short) dy);
vertices.add(ox, oy, (short) dx, (short) dy);
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
ddy = (int) (-(uy + vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy,
(2 | ddx & DIR_MASK),
(2 | ddy & DIR_MASK));
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
vertices.add(ox, oy,
(short) (2 | ddx & DIR_MASK),
(short) (2 | ddy & DIR_MASK));
/* Start of line */
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
addVertex(v, opos, ox, oy,
(0 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK));
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy,
(2 | -ddx & DIR_MASK),
(1 | -ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (0 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (2 | -ddx & DIR_MASK),
(short) (1 | -ddy & DIR_MASK));
} else {
/* outside means line is probably clipped
* TODO should align ending with tile boundary
@ -385,28 +313,15 @@ public final class LineLayer extends RenderElement {
dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK);
addVertex(v, opos, ox, oy, dx, dy);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy, dx, dy);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
vertices.add(ox, oy, (short) dx, (short) dy);
vertices.add(ox, oy, (short) dx, (short) dy);
ddx = (int) (-(ux + tx) * DIR_SCALE);
ddy = (int) (-(uy + ty) * DIR_SCALE);
addVertex(v, opos, ox, oy,
(2 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (2 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
}
curX = nextX;
@ -416,7 +331,7 @@ public final class LineLayer extends RenderElement {
vPrevX *= -1;
vPrevY *= -1;
vertexItem.used = opos + 4;
// vertexItem.used = opos + 4;
for (int end = start + length;;) {
@ -491,7 +406,7 @@ public final class LineLayer extends RenderElement {
vNextX /= a;
vNextY /= a;
vertexItem = addVertex(vertexItem, px, py, vPrevX, vPrevY, vNextX, vNextY);
addVertex(vertices, px, py, vPrevX, vPrevY, vNextX, vNextY);
/* flip unit vector to point back */
vPrevX = -vNextX;
@ -505,7 +420,7 @@ public final class LineLayer extends RenderElement {
vNextY /= a;
}
vertexItem = addVertex(vertexItem, curX, curY, vPrevX, vPrevY, vNextX, vNextY);
addVertex(vertices, curX, curY, vPrevX, vPrevY, vNextX, vNextY);
curX = nextX;
curY = nextY;
@ -515,20 +430,11 @@ public final class LineLayer extends RenderElement {
vPrevY = -vNextY;
}
opos = vertexItem.used;
v = vertexItem.vertices;
ux = vPrevY;
uy = -vPrevX;
outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax);
if (opos == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
ox = (short) (curX * COORD_SCALE);
oy = (short) (curY * COORD_SCALE);
@ -536,33 +442,21 @@ public final class LineLayer extends RenderElement {
ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE);
addVertex(v, opos, ox, oy,
(0 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (0 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy,
(2 | -ddx & DIR_MASK),
(1 | -ddy & DIR_MASK));
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
vertices.add(ox, oy,
(short) (2 | -ddx & DIR_MASK),
(short) (1 | -ddy & DIR_MASK));
/* For rounded line edges */
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy,
(0 | ddx & DIR_MASK),
(0 | ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (0 | ddx & DIR_MASK),
(short) (0 | ddy & DIR_MASK));
/* last vertex */
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
@ -585,9 +479,9 @@ public final class LineLayer extends RenderElement {
ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy,
(0 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK));
vertices.add(ox, oy,
(short) (0 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
/* last vertex */
ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
@ -597,24 +491,8 @@ public final class LineLayer extends RenderElement {
}
/* add last vertex twice */
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy, dx, dy);
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
addVertex(v, opos, ox, oy, dx, dy);
vertexItem.used = opos + 4;
return vertexItem;
vertices.add(ox, oy, (short) dx, (short) dy);
vertices.add(ox, oy, (short) dx, (short) dy);
}
static class Shader extends GLShader {

View File

@ -28,7 +28,6 @@ import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -108,32 +107,24 @@ public final class LineTexLayer extends RenderElement {
public void addLine(float[] points, short[] index) {
VertexItem si = Inlist.last(vertexItems);
if (si == null) {
si = VertexItem.pool.get();
vertexItems = si;
//curItem = vertexItems;
// HACK add one vertex offset when compiling
// buffer otherwise one cant use the full
// VertexItem (see Layers.compile)
// add the two 'x' at front and end
if (vertexItems.empty()) {
/* HACK add one vertex offset when compiling
* buffer otherwise one cant use the full
* VertexItem (see Layers.compile)
* add the two 'x' at front and end */
//numVertices = 2;
// the additional end vertex to make sure
// not to read outside allocated memory
/* the additional end vertex to make sure
* not to read outside allocated memory */
numVertices = 1;
}
short v[] = si.vertices;
int opos = si.used;
VertexData vi = vertexItems;
boolean even = evenSegment;
/* reset offset to last written position */
if (!even)
opos -= 12;
vi.seek(-12);
int n;
int length = 0;
@ -187,33 +178,27 @@ public final class LineTexLayer extends RenderElement {
short dx = (short) (ux * DIR_SCALE);
short dy = (short) (uy * DIR_SCALE);
if (opos == VertexItem.SIZE) {
si = VertexItem.pool.getNext(si);
v = si.vertices;
opos = 0;
}
v[opos + 0] = (short) x;
v[opos + 1] = (short) y;
v[opos + 2] = dx;
v[opos + 3] = dy;
v[opos + 4] = (short) lineLength;
v[opos + 5] = 0;
vi.add((short) x,
(short) y,
dx, dy,
(short) lineLength,
(short) 0);
lineLength += a;
v[opos + 12] = (short) nx;
v[opos + 13] = (short) ny;
v[opos + 14] = dx;
v[opos + 15] = dy;
v[opos + 16] = (short) lineLength;
v[opos + 17] = 0;
vi.seek(6);
vi.add((short) nx,
(short) ny,
dx, dy,
(short) lineLength,
(short) 0);
x = nx;
y = ny;
if (even) {
/* go to second segment */
opos += 6;
vi.seek(-12);
even = false;
/* vertex 0 and 2 were added */
@ -222,7 +207,6 @@ public final class LineTexLayer extends RenderElement {
} else {
/* go to next block */
even = true;
opos += 18;
/* vertex 1 and 3 were added */
numVertices += 1;
@ -235,9 +219,7 @@ public final class LineTexLayer extends RenderElement {
/* advance offset to last written position */
if (!even)
opos += 12;
si.used = opos;
vi.seek(12);
}
@Override

View File

@ -31,7 +31,6 @@ import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.AreaStyle;
import org.oscim.utils.ColorUtil;
import org.oscim.utils.Tessellator;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -42,7 +41,7 @@ public class MeshLayer extends RenderElement {
BufferObject indicesVbo;
int numIndices;
VertexItem indiceItems;
VertexData indiceItems = new VertexData();
public AreaStyle area;
public float heightOffset;
@ -55,42 +54,30 @@ public class MeshLayer extends RenderElement {
if (geom.index[0] < 6)
return;
if (vertexItems == null) {
vertexItems = VertexItem.pool.get();
indiceItems = VertexItem.pool.get();
}
numIndices += Tessellator.tessellate(geom, MapRenderer.COORD_SCALE,
Inlist.last(vertexItems),
Inlist.last(indiceItems),
vertexItems,
indiceItems,
numVertices);
numVertices = vertexItems.getSize() / 2;
numVertices = vertexItems.countSize() / 2;
if (numIndices <= 0) {
if (numIndices <= 0)
log.debug("empty " + geom.index);
vertexItems = VertexItem.pool.releaseAll(vertexItems);
indiceItems = VertexItem.pool.releaseAll(indiceItems);
}
}
@Override
protected void compile(ShortBuffer sbuf) {
if (indiceItems == null) {
if (numIndices <= 0) {
indicesVbo = BufferObject.release(indicesVbo);
return;
}
// add vertices to shared VBO
/* add vertices to shared VBO */
ElementLayers.addPoolItems(this, sbuf);
// add indices to indicesVbo
/* add indices to indicesVbo */
sbuf = MapRenderer.getShortBuffer(numIndices);
for (VertexItem it = indiceItems; it != null; it = it.next)
sbuf.put(it.vertices, 0, it.used);
indiceItems = VertexItem.pool.releaseAll(indiceItems);
indiceItems.compile(sbuf);
if (indicesVbo == null)
indicesVbo = BufferObject.get(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
@ -101,8 +88,10 @@ public class MeshLayer extends RenderElement {
@Override
protected void clear() {
indicesVbo = BufferObject.release(indicesVbo);
indiceItems = VertexItem.pool.releaseAll(indiceItems);
vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems.dispose();
indiceItems.dispose();
numIndices = 0;
numVertices = 0;
}
public static class Renderer {

View File

@ -27,7 +27,6 @@ import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.AreaStyle;
import org.oscim.utils.FastMath;
import org.oscim.utils.math.Interpolation;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,7 +49,6 @@ public final class PolygonLayer extends RenderElement {
super(RenderElement.POLYGON);
level = layer;
vertexItems = VertexItem.pool.get();
}
public void addPolygon(GeometryBuffer geom) {
@ -60,57 +58,32 @@ public final class PolygonLayer extends RenderElement {
public void addPolygon(float[] points, short[] index) {
short center = (short) ((Tile.SIZE >> 1) * S);
VertexItem si = Inlist.last(vertexItems);
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
/* need at least three points */
if (length < 6) {
pos += length;
continue;
}
numVertices += length / 2 + 2;
vertexItems.add(center, center);
int inPos = pos;
if (outPos == VertexItem.SIZE) {
si = VertexItem.pool.getNext(si);
v = si.vertices;
outPos = 0;
}
v[outPos++] = center;
v[outPos++] = center;
for (int j = 0; j < length; j += 2) {
if (outPos == VertexItem.SIZE) {
si = VertexItem.pool.getNext(si);
v = si.vertices;
outPos = 0;
}
v[outPos++] = (short) (points[inPos++] * S);
v[outPos++] = (short) (points[inPos++] * S);
vertexItems.add((short) (points[inPos++] * S),
(short) (points[inPos++] * S));
}
if (outPos == VertexItem.SIZE) {
si = VertexItem.pool.getNext(si);
v = si.vertices;
outPos = 0;
}
v[outPos++] = (short) (points[pos + 0] * S);
v[outPos++] = (short) (points[pos + 1] * S);
vertexItems.add((short) (points[pos + 0] * S),
(short) (points[pos + 1] * S));
pos += length;
}
si.used = outPos;
}
static class Shader extends GLShader {

View File

@ -41,7 +41,7 @@ public abstract class RenderElement extends Inlist<RenderElement> {
protected int numVertices;
/** temporary list of vertex data. */
protected VertexItem vertexItems;
protected final VertexData vertexItems = new VertexData();
protected RenderElement(int type) {
this.type = type;
@ -49,8 +49,7 @@ public abstract class RenderElement extends Inlist<RenderElement> {
/** clear all resources. */
protected void clear() {
if (vertexItems != null)
vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems.dispose();
numVertices = 0;
}

View File

@ -55,9 +55,6 @@ public final class SymbolLayer extends TextureLayer {
}
}
mSymbols.push(item);
//item.next = mSymbols;
//mSymbols = item;
}
public void pushSymbol(SymbolItem item) {
@ -73,11 +70,6 @@ public final class SymbolLayer extends TextureLayer {
short numIndices = 0;
VertexItem si = VertexItem.pool.get();
int pos = 0;
short buf[] = si.vertices;
prevTextures = textures;
textures = null;
TextureItem t = null;
@ -165,15 +157,10 @@ public final class SymbolLayer extends TextureLayer {
short ty = (short) (SCALE * it.y);
if (pos == VertexItem.SIZE) {
sbuf.put(buf, 0, VertexItem.SIZE);
pos = 0;
}
TextureLayer.putSprite(buf, pos, tx, ty,
x1, y1, x2, y2, u1, v1, u2, v2);
pos += TextLayer.VERTICES_PER_SPRITE * 6;
vertexItems.add(tx, ty, x1, y1, u1, v2);
vertexItems.add(tx, ty, x1, y2, u1, v1);
vertexItems.add(tx, ty, x2, y1, u2, v2);
vertexItems.add(tx, ty, x2, y2, u2, v1);
/* six elements used to draw the four vertices */
t.indices += TextureLayer.INDICES_PER_SPRITE;
@ -181,10 +168,7 @@ public final class SymbolLayer extends TextureLayer {
numIndices += t.indices;
}
if (pos > 0)
sbuf.put(buf, 0, pos);
si = VertexItem.pool.release(si);
vertexItems.compile(sbuf);
for (t = prevTextures; t != null; t = t.dispose());
prevTextures = null;

View File

@ -21,21 +21,25 @@ import static org.oscim.renderer.MapRenderer.COORD_SCALE;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Canvas;
public final class TextLayer extends TextureLayer {
public class TextLayer extends TextureLayer {
//static final Logger log = LoggerFactory.getLogger(TextureLayer.class);
private final static int LBIT_MASK = 0xfffffffe;
protected final static int LBIT_MASK = 0xfffffffe;
private static int mFontPadX = 1;
protected static int mFontPadX = 1;
//private static int mFontPadY = 1;
public TextItem labels;
private final Canvas mCanvas;
protected final Canvas mCanvas;
public TextItem getLabels() {
return labels;
}
public void setLabels(TextItem labels) {
this.labels = labels;
}
public TextLayer() {
super(RenderElement.SYMBOL);
mCanvas = CanvasAdapter.g.getCanvas();
@ -49,20 +53,21 @@ public final class TextLayer extends TextureLayer {
if (item.text == it.text) {
while (it.next != null
// break if next item uses different text style
/* break if next item uses different text style */
&& item.text == it.next.text
// check same string instance
/* check same string instance */
&& item.string != it.string
// check same string
/* check same string */
&& !item.string.equals(it.string))
it = it.next;
// unify duplicate string
// Note: this is required for 'packing test' in prepare to work!
/* unify duplicate string
* // Note: this is required for 'packing test' in prepare to
* work! */
if (item.string != it.string && item.string.equals(it.string))
item.string = it.string;
// insert after text of same type and/or before same string
/* insert after text of same type and/or before same string */
item.next = it.next;
it.next = item;
return;
@ -75,14 +80,8 @@ public final class TextLayer extends TextureLayer {
@Override
public boolean prepare() {
short numIndices = 0;
short offsetIndices = 0;
VertexItem vi = vertexItems = VertexItem.pool.get();
int pos = vi.used; // 0
short buf[] = vi.vertices;
numVertices = 0;
int advanceY = 0;
@ -139,16 +138,9 @@ public final class TextLayer extends TextureLayer {
width = TEXTURE_WIDTH;
while (it != null) {
if (pos == VertexItem.SIZE) {
vi.used = VertexItem.SIZE;
vi = VertexItem.pool.getNext(vi);
buf = vi.vertices;
pos = 0;
}
addItem(buf, pos, it, width, height, x, y);
pos += 24;
addItem(it, width, height, x, y);
// six indices to draw the four vertices
/* six indices to draw the four vertices */
numIndices += TextureLayer.INDICES_PER_SPRITE;
numVertices += 4;
@ -164,16 +156,15 @@ public final class TextLayer extends TextureLayer {
x += width;
}
vi.used = pos;
t.offset = offsetIndices;
t.indices = (short) (numIndices - offsetIndices);
return true;
}
void addItem(short[] buf, int pos, TextItem it, float width, float height, float x, float y) {
// texture coordinates
protected void addItem(TextItem it,
float width, float height, float x, float y) {
/* texture coordinates */
short u1 = (short) (COORD_SCALE * x);
short v1 = (short) (COORD_SCALE * y);
short u2 = (short) (COORD_SCALE * (x + width));
@ -203,64 +194,35 @@ public final class TextLayer extends TextureLayer {
vx *= hw;
vy *= hw;
// top-left
/* top-left */
x1 = (short) (COORD_SCALE * (vx - ux));
y1 = (short) (COORD_SCALE * (vy - uy));
// top-right
/* top-right */
x2 = (short) (COORD_SCALE * (-vx - ux));
y2 = (short) (COORD_SCALE * (-vy - uy));
// bot-right
/* bot-right */
x4 = (short) (COORD_SCALE * (-vx + ux2));
y4 = (short) (COORD_SCALE * (-vy + uy2));
// bot-left
/* bot-left */
x3 = (short) (COORD_SCALE * (vx + ux2));
y3 = (short) (COORD_SCALE * (vy + uy2));
}
// add vertices
/* add vertices */
int tmp = (int) (COORD_SCALE * it.x) & LBIT_MASK;
short tx = (short) (tmp | (it.text.caption ? 1 : 0));
short ty = (short) (COORD_SCALE * it.y);
// top-left
buf[pos++] = tx;
buf[pos++] = ty;
buf[pos++] = x1;
buf[pos++] = y1;
buf[pos++] = u1;
buf[pos++] = v2;
// bot-left
buf[pos++] = tx;
buf[pos++] = ty;
buf[pos++] = x3;
buf[pos++] = y3;
buf[pos++] = u1;
buf[pos++] = v1;
// top-right
buf[pos++] = tx;
buf[pos++] = ty;
buf[pos++] = x2;
buf[pos++] = y2;
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;
vertexItems.add(tx, ty, x1, y1, u1, v2);
vertexItems.add(tx, ty, x3, y3, u1, v1);
vertexItems.add(tx, ty, x2, y2, u2, v2);
vertexItems.add(tx, ty, x4, y4, u2, v1);
}
@Override
public void clear() {
// release textures
super.clear();
clearLabels();
//labels = TextItem.pool.releaseAll(labels);
//vertexItems = VertexItem.pool.releaseAll(vertexItems);
//numVertices = 0;
}
public void clearLabels() {

View File

@ -72,47 +72,11 @@ public abstract class TextureLayer extends RenderElement {
while (textures != null)
textures = textures.dispose();
vertexItems = VertexItem.pool.releaseAll(vertexItems);
vertexItems.dispose();
numVertices = 0;
}
static void putSprite(short buf[], int pos,
short tx, short ty,
short x1, short y1,
short x2, short y2,
short u1, short v1,
short u2, short v2) {
/* top-left */
buf[pos + 0] = tx;
buf[pos + 1] = ty;
buf[pos + 2] = x1;
buf[pos + 3] = y1;
buf[pos + 4] = u1;
buf[pos + 5] = v2;
/* bot-left */
buf[pos + 6] = tx;
buf[pos + 7] = ty;
buf[pos + 8] = x1;
buf[pos + 9] = y2;
buf[pos + 10] = u1;
buf[pos + 11] = v1;
/* top-right */
buf[pos + 12] = tx;
buf[pos + 13] = ty;
buf[pos + 14] = x2;
buf[pos + 15] = y1;
buf[pos + 16] = u2;
buf[pos + 17] = v2;
/* bot-right */
buf[pos + 18] = tx;
buf[pos + 19] = ty;
buf[pos + 20] = x2;
buf[pos + 21] = y2;
buf[pos + 22] = u2;
buf[pos + 23] = v1;
}
static class Shader extends GLShader {
int uMV, uProj, uScale, uTexSize, aPos, aTexCoord;

View File

@ -0,0 +1,216 @@
/*
* Copyright 2012 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.renderer.elements;
import java.nio.ShortBuffer;
import org.oscim.renderer.elements.VertexData.Chunk;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.SyncPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* TODO override append() etc to update internal (cur) state.
*/
public class VertexData extends Inlist.List<Chunk> {
static final Logger log = LoggerFactory.getLogger(VertexData.class);
public static class Chunk extends Inlist<Chunk> {
public final short[] vertices = new short[SIZE];
public int used;
};
private static class Pool extends SyncPool<Chunk> {
public Pool() {
super(MAX_POOL);
}
@Override
protected Chunk createItem() {
return new Chunk();
}
@Override
protected boolean clearItem(Chunk it) {
it.used = 0;
return true;
}
}
public int countSize() {
if (cur == null)
return 0;
cur.used = used;
int size = 0;
for (Chunk it = head(); it != null; it = it.next)
size += it.used;
return size;
}
@Override
public Chunk clear() {
if (cur == null)
return null;
cur.used = used;
used = SIZE; /* set SIZE to get new item on add */
cur = null;
vertices = null;
return super.clear();
}
private static final int MAX_POOL = 500;
private final static Pool pool = new Pool();
/* Must be multiple of
* 4 (LineLayer/PolygonLayer),
* 24 (TexLineLayer - one block, i.e. two segments)
* 24 (TextureLayer) */
public static final int SIZE = 360;
public void dispose() {
pool.releaseAll(super.clear());
used = SIZE; /* set SIZE to get new item on add */
cur = null;
vertices = null;
}
public int compile(ShortBuffer sbuf) {
if (cur == null)
return 0;
cur.used = used;
int size = 0;
for (Chunk it = head(); it != null; it = it.next) {
size += it.used;
sbuf.put(it.vertices, 0, it.used);
}
dispose();
//log.debug("compiled {}", size);
return size;
}
private Chunk cur;
/* set SIZE to get new item on add */
private int used = SIZE;
private short[] vertices;
private void getNext() {
if (cur == null) {
cur = pool.get();
push(cur);
} else {
if (cur.next != null)
throw new IllegalStateException("seeeked...");
cur.used = SIZE;
cur.next = pool.get();
cur = cur.next;
}
vertices = cur.vertices;
used = 0;
}
public void add(short a) {
if (used == SIZE)
getNext();
vertices[used++] = a;
}
public void add(short a, short b) {
if (used == SIZE)
getNext();
vertices[used + 0] = a;
vertices[used + 1] = b;
used += 2;
}
public void add(short a, short b, short c) {
if (used == SIZE)
getNext();
vertices[used + 0] = a;
vertices[used + 1] = b;
vertices[used + 2] = c;
used += 3;
}
public void add(short a, short b, short c, short d) {
if (used == SIZE)
getNext();
vertices[used + 0] = a;
vertices[used + 1] = b;
vertices[used + 2] = c;
vertices[used + 3] = d;
used += 4;
}
public void add(short a, short b, short c, short d, short e, short f) {
if (used == SIZE)
getNext();
vertices[used + 0] = a;
vertices[used + 1] = b;
vertices[used + 2] = c;
vertices[used + 3] = d;
vertices[used + 4] = e;
vertices[used + 5] = f;
used += 6;
}
public static VertexData get() {
return new VertexData();
}
/** When changing the position releaseChunk to update internal state */
public Chunk obtainChunk() {
if (used == SIZE)
getNext();
cur.used = used;
return cur;
}
public void releaseChunk() {
used = cur.used;
}
public void seek(int offset) {
used += offset;
cur.used = used;
if (used > SIZE || used < 0)
throw new IllegalStateException("seekkeed: " + offset + ":" + used);
}
public boolean empty() {
return cur == null;
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright 2012 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.oscim.renderer.elements;
import org.oscim.utils.pool.Inlist;
import org.oscim.utils.pool.SyncPool;
public class VertexItem extends Inlist<VertexItem> {
private static final int MAX_POOL = 500;
public final static class Pool extends SyncPool<VertexItem> {
public Pool() {
super(MAX_POOL);
}
@Override
protected VertexItem createItem() {
return new VertexItem();
}
@Override
protected boolean clearItem(VertexItem it) {
it.used = 0;
return true;
}
public VertexItem getNext(VertexItem it) {
it.next = get();
return it.next;
}
}
public final static Pool pool = new Pool();
public int getSize() {
int size = used;
for (VertexItem it = next; it != null; it = it.next)
size += it.used;
return size;
}
public final short[] vertices = new short[SIZE];
public int used;
// must be multiple of
// 4 (LineLayer/PolygonLayer),
// 24 (TexLineLayer - one block, i.e. two segments)
// 24 (TextureLayer)
public static final int SIZE = 360;
}

View File

@ -19,7 +19,7 @@ package org.oscim.utils;
import java.util.Arrays;
import org.oscim.core.GeometryBuffer;
import org.oscim.renderer.elements.VertexItem;
import org.oscim.renderer.elements.VertexData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,7 +34,7 @@ public class Tessellator {
* positions.
*/
public static int tessellate(float[] points, int ppos, int plen, short[] index,
int ipos, int rings, int vertexOffset, VertexItem outTris) {
int ipos, int rings, int vertexOffset, VertexData outTris) {
int[] result = new int[2];
@ -50,29 +50,26 @@ public class Tessellator {
}
int cnt;
int numIndices = 0;
int sumIndices = 0;
if (outTris.used == VertexItem.SIZE)
outTris = VertexItem.pool.getNext(outTris);
VertexData.Chunk vd = outTris.obtainChunk();
while ((cnt = Tessellator.tessGetIndicesWO(ctx,
outTris.vertices,
outTris.used)) > 0) {
int start = outTris.used;
while ((cnt = Tessellator.tessGetIndicesWO(ctx, vd.vertices, vd.used)) > 0) {
int start = vd.used;
int end = start + cnt;
short[] v = outTris.vertices;
short[] v = vd.vertices;
for (int i = start; i < end; i++)
v[i] *= 2;
// when a ring has an odd number of points one (or rather two)
// additional vertices will be added. so the following rings
// needs extra offset
/* when a ring has an odd number of points one (or rather two)
* additional vertices will be added. so the following rings
* needs extra offset */
int shift = 0;
for (int i = 0, m = rings - 1; i < m; i++) {
shift += (index[ipos + i]);
// even number of points?
/* even number of points? */
if (((index[ipos + i] >> 1) & 1) == 0)
continue;
@ -83,25 +80,27 @@ public class Tessellator {
shift += 2;
}
// shift by vertexOffset
/* shift by vertexOffset */
for (int i = start; i < end; i++)
v[i] += vertexOffset;
outTris.used += cnt;
numIndices += cnt;
sumIndices += cnt;
if (outTris.used == VertexItem.SIZE) {
outTris = VertexItem.pool.getNext(outTris);
vd.used += cnt;
outTris.releaseChunk();
if (vd.used == VertexData.SIZE) {
/* gets next item since this one is full */
vd = outTris.obtainChunk();
continue;
}
// no more indices to get.
/* no more indices to get. */
break;
}
Tessellator.tessFinish(ctx);
return numIndices;
return sumIndices;
}
/**
@ -133,7 +132,7 @@ public class Tessellator {
}
if (out == null) {
// overwrite geom contents
/* overwrite geom contents */
out = geom;
if (verticesAdded) {
out.ensurePointSize(result[RESULT_VERTICES], false);
@ -158,7 +157,7 @@ public class Tessellator {
}
public static int tessellate(GeometryBuffer geom, float scale,
VertexItem outPoints, VertexItem outTris, int vertexOffset) {
VertexData outPoints, VertexData outTris, int vertexOffset) {
int numIndices = 0;
int indexPos = 0;
@ -198,47 +197,40 @@ public class Tessellator {
pointPos += numPoints;
if (outTris.used == VertexItem.SIZE)
outTris = VertexItem.pool.getNext(outTris);
while (true) {
int cnt = Tessellator.tessGetIndicesWO(ctx,
outTris.vertices,
outTris.used);
VertexData.Chunk vd = outTris.obtainChunk();
int cnt = Tessellator.tessGetIndicesWO(ctx, vd.vertices, vd.used);
if (cnt <= 0)
break;
// shift by vertexOffset
for (int pos = outTris.used, end = pos + cnt; pos < end; pos++)
outTris.vertices[pos] += vertexOffset;
/* shift by vertexOffset */
for (int pos = vd.used, end = pos + cnt; pos < end; pos++)
vd.vertices[pos] += vertexOffset;
outTris.used += cnt;
numIndices += cnt;
if (outTris.used < VertexItem.SIZE)
break;
vd.used += cnt;
outTris.releaseChunk();
outTris = VertexItem.pool.getNext(outTris);
if (vd.used < VertexData.SIZE)
break;
}
if (outPoints.used == VertexItem.SIZE)
outPoints = VertexItem.pool.getNext(outPoints);
while (true) {
int cnt = Tessellator.tessGetVerticesWO(ctx,
outPoints.vertices,
outPoints.used,
scale);
VertexData.Chunk vd = outPoints.obtainChunk();
int cnt = Tessellator.tessGetVerticesWO(ctx, vd.vertices, vd.used, scale);
if (cnt <= 0)
break;
outPoints.used += cnt;
vertexOffset += cnt >> 1;
if (outPoints.used < VertexItem.SIZE)
break;
vd.used += cnt;
outPoints.releaseChunk();
outPoints = VertexItem.pool.getNext(outPoints);
if (vd.used < VertexData.SIZE)
break;
}
Tessellator.tessFinish(ctx);
@ -249,6 +241,7 @@ public class Tessellator {
if (vertexOffset > Short.MAX_VALUE) {
log.debug("too much !!!" + Arrays.toString(geom.index));
return 0;
}
return numIndices;