refactor: add api for common VertexItem use
- rename VertexItem -> VertexData
This commit is contained in:
parent
ad0eff3fac
commit
3f49361e4a
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
|
||||
|
216
vtm/src/org/oscim/renderer/elements/VertexData.java
Normal file
216
vtm/src/org/oscim/renderer/elements/VertexData.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user