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

View File

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

View File

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

View File

@ -16,9 +16,6 @@
*/ */
package org.oscim.renderer.elements; 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.GL20;
import org.oscim.backend.GLAdapter; import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap; 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.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.LineStyle; import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -124,11 +120,6 @@ public final class LineLayer extends RenderElement {
else if (line.cap == Cap.SQUARE) else if (line.cap == Cap.SQUARE)
squared = true; squared = true;
if (vertexItems == null)
vertexItems = pool.get();
VertexItem vertexItem = Inlist.last(vertexItems);
/* Note: just a hack to save some vertices, when there are /* Note: just a hack to save some vertices, when there are
* more than 200 lines per type. FIXME make optional! */ * more than 200 lines per type. FIXME make optional! */
if (rounded && index != null) { if (rounded && index != null) {
@ -185,19 +176,12 @@ public final class LineLayer extends RenderElement {
points[ipos + 1] == points[ipos + 5]) points[ipos + 1] == points[ipos + 5])
length -= 2; 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) { private void addVertex(VertexData vi,
v[pos + 0] = x;
v[pos + 1] = y;
v[pos + 2] = (short) dx;
v[pos + 3] = (short) dy;
}
private VertexItem addVertex(VertexItem vertexItem,
float x, float y, float x, float y,
float vNextX, float vNextY, float vNextX, float vNextY,
float vPrevX, float vPrevY) { float vPrevX, float vPrevY) {
@ -222,37 +206,16 @@ public final class LineLayer extends RenderElement {
int ddx = (int) (ux * DIR_SCALE); int ddx = (int) (ux * DIR_SCALE);
int ddy = (int) (uy * DIR_SCALE); int ddy = (int) (uy * DIR_SCALE);
int opos = vertexItem.used; vi.add(ox, oy,
short[] v = vertexItem.vertices; (short) (0 | ddx & DIR_MASK),
(short) (1 | ddy & DIR_MASK));
if (opos == SIZE) { vi.add(ox, oy,
vertexItem = pool.getNext(vertexItem); (short) (2 | -ddx & DIR_MASK),
v = vertexItem.vertices; (short) (1 | -ddy & DIR_MASK));
opos = 0;
} }
v[opos + 0] = ox; private void addLine(VertexData vertices, float[] points, int start, int length,
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,
boolean rounded, boolean squared, boolean closed) { boolean rounded, boolean squared, boolean closed) {
float ux, uy; float ux, uy;
@ -262,9 +225,6 @@ public final class LineLayer extends RenderElement {
float nextX, nextY; float nextX, nextY;
double a; double a;
short v[] = vertexItem.vertices;
int opos = vertexItem.used;
/* amount of vertices used /* amount of vertices used
* + 2 for drawing triangle-strip * + 2 for drawing triangle-strip
* + 4 for round caps * + 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. */ /* when the endpoint is outside the tile region omit round caps. */
boolean outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax); 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) { if (rounded && !outside) {
ddx = (int) ((ux - vPrevX) * DIR_SCALE); ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE); ddy = (int) ((uy - vPrevY) * DIR_SCALE);
dx = (short) (0 | ddx & DIR_MASK); dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (2 | ddy & DIR_MASK); dy = (short) (2 | ddy & DIR_MASK);
addVertex(v, opos, ox, oy, dx, dy); vertices.add(ox, oy, (short) dx, (short) dy);
vertices.add(ox, oy, (short) dx, (short) 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;
}
ddx = (int) (-(ux + vPrevX) * DIR_SCALE); ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
ddy = (int) (-(uy + vPrevY) * DIR_SCALE); ddy = (int) (-(uy + vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(2 | ddx & DIR_MASK), (short) (2 | ddx & DIR_MASK),
(2 | ddy & DIR_MASK)); (short) (2 | ddy & DIR_MASK));
if ((opos += 4) == SIZE) {
vertexItem = pool.getNext(vertexItem);
v = vertexItem.vertices;
opos = 0;
}
/* Start of line */ /* Start of line */
ddx = (int) (ux * DIR_SCALE); ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE); ddy = (int) (uy * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(0 | ddx & DIR_MASK), (short) (0 | ddx & DIR_MASK),
(1 | ddy & 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));
vertices.add(ox, oy,
(short) (2 | -ddx & DIR_MASK),
(short) (1 | -ddy & DIR_MASK));
} else { } else {
/* outside means line is probably clipped /* outside means line is probably clipped
* TODO should align ending with tile boundary * TODO should align ending with tile boundary
@ -385,28 +313,15 @@ public final class LineLayer extends RenderElement {
dx = (short) (0 | ddx & DIR_MASK); dx = (short) (0 | ddx & DIR_MASK);
dy = (short) (1 | ddy & DIR_MASK); dy = (short) (1 | ddy & DIR_MASK);
addVertex(v, opos, ox, oy, dx, dy); vertices.add(ox, oy, (short) dx, (short) dy);
vertices.add(ox, oy, (short) dx, (short) 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;
}
ddx = (int) (-(ux + tx) * DIR_SCALE); ddx = (int) (-(ux + tx) * DIR_SCALE);
ddy = (int) (-(uy + ty) * DIR_SCALE); ddy = (int) (-(uy + ty) * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(2 | ddx & DIR_MASK), (short) (2 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK)); (short) (1 | ddy & DIR_MASK));
} }
curX = nextX; curX = nextX;
@ -416,7 +331,7 @@ public final class LineLayer extends RenderElement {
vPrevX *= -1; vPrevX *= -1;
vPrevY *= -1; vPrevY *= -1;
vertexItem.used = opos + 4; // vertexItem.used = opos + 4;
for (int end = start + length;;) { for (int end = start + length;;) {
@ -491,7 +406,7 @@ public final class LineLayer extends RenderElement {
vNextX /= a; vNextX /= a;
vNextY /= 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 */ /* flip unit vector to point back */
vPrevX = -vNextX; vPrevX = -vNextX;
@ -505,7 +420,7 @@ public final class LineLayer extends RenderElement {
vNextY /= a; vNextY /= a;
} }
vertexItem = addVertex(vertexItem, curX, curY, vPrevX, vPrevY, vNextX, vNextY); addVertex(vertices, curX, curY, vPrevX, vPrevY, vNextX, vNextY);
curX = nextX; curX = nextX;
curY = nextY; curY = nextY;
@ -515,20 +430,11 @@ public final class LineLayer extends RenderElement {
vPrevY = -vNextY; vPrevY = -vNextY;
} }
opos = vertexItem.used;
v = vertexItem.vertices;
ux = vPrevY; ux = vPrevY;
uy = -vPrevX; uy = -vPrevX;
outside = (curX < tmin || curX > tmax || curY < tmin || curY > tmax); 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); ox = (short) (curX * COORD_SCALE);
oy = (short) (curY * COORD_SCALE); oy = (short) (curY * COORD_SCALE);
@ -536,33 +442,21 @@ public final class LineLayer extends RenderElement {
ddx = (int) (ux * DIR_SCALE); ddx = (int) (ux * DIR_SCALE);
ddy = (int) (uy * DIR_SCALE); ddy = (int) (uy * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(0 | ddx & DIR_MASK), (short) (0 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK)); (short) (1 | ddy & DIR_MASK));
if ((opos += 4) == SIZE) { vertices.add(ox, oy,
vertexItem = pool.getNext(vertexItem); (short) (2 | -ddx & DIR_MASK),
v = vertexItem.vertices; (short) (1 | -ddy & DIR_MASK));
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;
}
/* For rounded line edges */ /* For rounded line edges */
ddx = (int) ((ux - vPrevX) * DIR_SCALE); ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE); ddy = (int) ((uy - vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(0 | ddx & DIR_MASK), (short) (0 | ddx & DIR_MASK),
(0 | ddy & DIR_MASK)); (short) (0 | ddy & DIR_MASK));
/* last vertex */ /* last vertex */
ddx = (int) (-(ux + vPrevX) * DIR_SCALE); ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
@ -585,9 +479,9 @@ public final class LineLayer extends RenderElement {
ddx = (int) ((ux - vPrevX) * DIR_SCALE); ddx = (int) ((ux - vPrevX) * DIR_SCALE);
ddy = (int) ((uy - vPrevY) * DIR_SCALE); ddy = (int) ((uy - vPrevY) * DIR_SCALE);
addVertex(v, opos, ox, oy, vertices.add(ox, oy,
(0 | ddx & DIR_MASK), (short) (0 | ddx & DIR_MASK),
(1 | ddy & DIR_MASK)); (short) (1 | ddy & DIR_MASK));
/* last vertex */ /* last vertex */
ddx = (int) (-(ux + vPrevX) * DIR_SCALE); ddx = (int) (-(ux + vPrevX) * DIR_SCALE);
@ -597,24 +491,8 @@ public final class LineLayer extends RenderElement {
} }
/* add last vertex twice */ /* add last vertex twice */
if ((opos += 4) == SIZE) { vertices.add(ox, oy, (short) dx, (short) dy);
vertexItem = pool.getNext(vertexItem); vertices.add(ox, oy, (short) dx, (short) dy);
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;
} }
static class Shader extends GLShader { 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.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.theme.styles.LineStyle; import org.oscim.theme.styles.LineStyle;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -108,32 +107,24 @@ public final class LineTexLayer extends RenderElement {
public void addLine(float[] points, short[] index) { public void addLine(float[] points, short[] index) {
VertexItem si = Inlist.last(vertexItems); if (vertexItems.empty()) {
/* HACK add one vertex offset when compiling
if (si == null) { * buffer otherwise one cant use the full
si = VertexItem.pool.get(); * VertexItem (see Layers.compile)
vertexItems = si; * add the two 'x' at front and end */
//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
//numVertices = 2; //numVertices = 2;
// the additional end vertex to make sure /* the additional end vertex to make sure
// not to read outside allocated memory * not to read outside allocated memory */
numVertices = 1; numVertices = 1;
} }
VertexData vi = vertexItems;
short v[] = si.vertices;
int opos = si.used;
boolean even = evenSegment; boolean even = evenSegment;
/* reset offset to last written position */ /* reset offset to last written position */
if (!even) if (!even)
opos -= 12; vi.seek(-12);
int n; int n;
int length = 0; int length = 0;
@ -187,33 +178,27 @@ public final class LineTexLayer extends RenderElement {
short dx = (short) (ux * DIR_SCALE); short dx = (short) (ux * DIR_SCALE);
short dy = (short) (uy * DIR_SCALE); short dy = (short) (uy * DIR_SCALE);
if (opos == VertexItem.SIZE) { vi.add((short) x,
si = VertexItem.pool.getNext(si); (short) y,
v = si.vertices; dx, dy,
opos = 0; (short) lineLength,
} (short) 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;
lineLength += a; lineLength += a;
v[opos + 12] = (short) nx;
v[opos + 13] = (short) ny; vi.seek(6);
v[opos + 14] = dx; vi.add((short) nx,
v[opos + 15] = dy; (short) ny,
v[opos + 16] = (short) lineLength; dx, dy,
v[opos + 17] = 0; (short) lineLength,
(short) 0);
x = nx; x = nx;
y = ny; y = ny;
if (even) { if (even) {
/* go to second segment */ /* go to second segment */
opos += 6; vi.seek(-12);
even = false; even = false;
/* vertex 0 and 2 were added */ /* vertex 0 and 2 were added */
@ -222,7 +207,6 @@ public final class LineTexLayer extends RenderElement {
} else { } else {
/* go to next block */ /* go to next block */
even = true; even = true;
opos += 18;
/* vertex 1 and 3 were added */ /* vertex 1 and 3 were added */
numVertices += 1; numVertices += 1;
@ -235,9 +219,7 @@ public final class LineTexLayer extends RenderElement {
/* advance offset to last written position */ /* advance offset to last written position */
if (!even) if (!even)
opos += 12; vi.seek(12);
si.used = opos;
} }
@Override @Override

View File

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

View File

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

View File

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

View File

@ -55,9 +55,6 @@ public final class SymbolLayer extends TextureLayer {
} }
} }
mSymbols.push(item); mSymbols.push(item);
//item.next = mSymbols;
//mSymbols = item;
} }
public void pushSymbol(SymbolItem item) { public void pushSymbol(SymbolItem item) {
@ -73,11 +70,6 @@ public final class SymbolLayer extends TextureLayer {
short numIndices = 0; short numIndices = 0;
VertexItem si = VertexItem.pool.get();
int pos = 0;
short buf[] = si.vertices;
prevTextures = textures; prevTextures = textures;
textures = null; textures = null;
TextureItem t = null; TextureItem t = null;
@ -165,15 +157,10 @@ public final class SymbolLayer extends TextureLayer {
short ty = (short) (SCALE * it.y); short ty = (short) (SCALE * it.y);
if (pos == VertexItem.SIZE) { vertexItems.add(tx, ty, x1, y1, u1, v2);
sbuf.put(buf, 0, VertexItem.SIZE); vertexItems.add(tx, ty, x1, y2, u1, v1);
pos = 0; vertexItems.add(tx, ty, x2, y1, u2, v2);
} vertexItems.add(tx, ty, x2, y2, u2, v1);
TextureLayer.putSprite(buf, pos, tx, ty,
x1, y1, x2, y2, u1, v1, u2, v2);
pos += TextLayer.VERTICES_PER_SPRITE * 6;
/* six elements used to draw the four vertices */ /* six elements used to draw the four vertices */
t.indices += TextureLayer.INDICES_PER_SPRITE; t.indices += TextureLayer.INDICES_PER_SPRITE;
@ -181,10 +168,7 @@ public final class SymbolLayer extends TextureLayer {
numIndices += t.indices; numIndices += t.indices;
} }
if (pos > 0) vertexItems.compile(sbuf);
sbuf.put(buf, 0, pos);
si = VertexItem.pool.release(si);
for (t = prevTextures; t != null; t = t.dispose()); for (t = prevTextures; t != null; t = t.dispose());
prevTextures = null; 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.CanvasAdapter;
import org.oscim.backend.canvas.Canvas; 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); //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; //private static int mFontPadY = 1;
public TextItem labels; public TextItem labels;
private final Canvas mCanvas; protected final Canvas mCanvas;
public TextItem getLabels() { public TextItem getLabels() {
return labels; return labels;
} }
public void setLabels(TextItem labels) {
this.labels = labels;
}
public TextLayer() { public TextLayer() {
super(RenderElement.SYMBOL); super(RenderElement.SYMBOL);
mCanvas = CanvasAdapter.g.getCanvas(); mCanvas = CanvasAdapter.g.getCanvas();
@ -49,20 +53,21 @@ public final class TextLayer extends TextureLayer {
if (item.text == it.text) { if (item.text == it.text) {
while (it.next != null 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 && item.text == it.next.text
// check same string instance /* check same string instance */
&& item.string != it.string && item.string != it.string
// check same string /* check same string */
&& !item.string.equals(it.string)) && !item.string.equals(it.string))
it = it.next; it = it.next;
// unify duplicate string /* unify duplicate string
// Note: this is required for 'packing test' in prepare to work! * // Note: this is required for 'packing test' in prepare to
* work! */
if (item.string != it.string && item.string.equals(it.string)) if (item.string != it.string && item.string.equals(it.string))
item.string = 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; item.next = it.next;
it.next = item; it.next = item;
return; return;
@ -75,14 +80,8 @@ public final class TextLayer extends TextureLayer {
@Override @Override
public boolean prepare() { public boolean prepare() {
short numIndices = 0; short numIndices = 0;
short offsetIndices = 0; short offsetIndices = 0;
VertexItem vi = vertexItems = VertexItem.pool.get();
int pos = vi.used; // 0
short buf[] = vi.vertices;
numVertices = 0; numVertices = 0;
int advanceY = 0; int advanceY = 0;
@ -139,16 +138,9 @@ public final class TextLayer extends TextureLayer {
width = TEXTURE_WIDTH; width = TEXTURE_WIDTH;
while (it != null) { while (it != null) {
if (pos == VertexItem.SIZE) { addItem(it, width, height, x, y);
vi.used = VertexItem.SIZE;
vi = VertexItem.pool.getNext(vi);
buf = vi.vertices;
pos = 0;
}
addItem(buf, pos, it, width, height, x, y);
pos += 24;
// six indices to draw the four vertices /* six indices to draw the four vertices */
numIndices += TextureLayer.INDICES_PER_SPRITE; numIndices += TextureLayer.INDICES_PER_SPRITE;
numVertices += 4; numVertices += 4;
@ -164,16 +156,15 @@ public final class TextLayer extends TextureLayer {
x += width; x += width;
} }
vi.used = pos;
t.offset = offsetIndices; t.offset = offsetIndices;
t.indices = (short) (numIndices - offsetIndices); t.indices = (short) (numIndices - offsetIndices);
return true; return true;
} }
void addItem(short[] buf, int pos, TextItem it, float width, float height, float x, float y) { protected void addItem(TextItem it,
// texture coordinates float width, float height, float x, float y) {
/* texture coordinates */
short u1 = (short) (COORD_SCALE * x); short u1 = (short) (COORD_SCALE * x);
short v1 = (short) (COORD_SCALE * y); short v1 = (short) (COORD_SCALE * y);
short u2 = (short) (COORD_SCALE * (x + width)); short u2 = (short) (COORD_SCALE * (x + width));
@ -203,64 +194,35 @@ public final class TextLayer extends TextureLayer {
vx *= hw; vx *= hw;
vy *= hw; vy *= hw;
// top-left /* top-left */
x1 = (short) (COORD_SCALE * (vx - ux)); x1 = (short) (COORD_SCALE * (vx - ux));
y1 = (short) (COORD_SCALE * (vy - uy)); y1 = (short) (COORD_SCALE * (vy - uy));
// top-right /* top-right */
x2 = (short) (COORD_SCALE * (-vx - ux)); x2 = (short) (COORD_SCALE * (-vx - ux));
y2 = (short) (COORD_SCALE * (-vy - uy)); y2 = (short) (COORD_SCALE * (-vy - uy));
// bot-right /* bot-right */
x4 = (short) (COORD_SCALE * (-vx + ux2)); x4 = (short) (COORD_SCALE * (-vx + ux2));
y4 = (short) (COORD_SCALE * (-vy + uy2)); y4 = (short) (COORD_SCALE * (-vy + uy2));
// bot-left /* bot-left */
x3 = (short) (COORD_SCALE * (vx + ux2)); x3 = (short) (COORD_SCALE * (vx + ux2));
y3 = (short) (COORD_SCALE * (vy + uy2)); y3 = (short) (COORD_SCALE * (vy + uy2));
} }
// add vertices /* add vertices */
int tmp = (int) (COORD_SCALE * it.x) & LBIT_MASK; int tmp = (int) (COORD_SCALE * it.x) & LBIT_MASK;
short tx = (short) (tmp | (it.text.caption ? 1 : 0)); short tx = (short) (tmp | (it.text.caption ? 1 : 0));
short ty = (short) (COORD_SCALE * it.y); short ty = (short) (COORD_SCALE * it.y);
// top-left vertexItems.add(tx, ty, x1, y1, u1, v2);
buf[pos++] = tx; vertexItems.add(tx, ty, x3, y3, u1, v1);
buf[pos++] = ty; vertexItems.add(tx, ty, x2, y2, u2, v2);
buf[pos++] = x1; vertexItems.add(tx, ty, x4, y4, u2, v1);
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;
} }
@Override @Override
public void clear() { public void clear() {
// release textures
super.clear(); super.clear();
clearLabels(); clearLabels();
//labels = TextItem.pool.releaseAll(labels);
//vertexItems = VertexItem.pool.releaseAll(vertexItems);
//numVertices = 0;
} }
public void clearLabels() { public void clearLabels() {

View File

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