more work on building layer
This commit is contained in:
475
src/org/oscim/renderer/layer/ExtrusionLayer.java
Normal file
475
src/org/oscim/renderer/layer/ExtrusionLayer.java
Normal file
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
* Copyright 2012, 2013 OpenScienceMap
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the
|
||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.GLRenderer;
|
||||
import org.oscim.view.MapView;
|
||||
import org.quake.triangle.TriangleJNI;
|
||||
|
||||
import android.opengl.GLES20;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class ExtrusionLayer extends Layer {
|
||||
private final static String TAG = ExtrusionLayer.class.getName();
|
||||
private static final float S = GLRenderer.COORD_MULTIPLIER;
|
||||
public int mIndicesBufferID;
|
||||
public int mVertexBufferID;
|
||||
public int mNumIndices = 0;
|
||||
private int mNumVertices = 0;
|
||||
private VertexPoolItem mVertices, mCurVertices;
|
||||
private VertexPoolItem mIndices[], mCurIndices[];
|
||||
|
||||
public int mIndiceCnt[] = { 0, 0, 0 };
|
||||
|
||||
public ExtrusionLayer(int level) {
|
||||
this.type = Layer.EXTRUSION;
|
||||
this.layer = level;
|
||||
|
||||
mVertices = mCurVertices = VertexPool.get();
|
||||
mIndices = new VertexPoolItem[3];
|
||||
mCurIndices = new VertexPoolItem[3];
|
||||
mIndices[0] = mCurIndices[0] = VertexPool.get();
|
||||
mIndices[1] = mCurIndices[1] = VertexPool.get();
|
||||
mIndices[2] = mCurIndices[2] = VertexPool.get();
|
||||
}
|
||||
|
||||
public void addBuildings(float[] points, short[] index, int height) {
|
||||
int complex = 0;
|
||||
boolean simple = true;
|
||||
|
||||
if (height == 0)
|
||||
height = 400;
|
||||
else
|
||||
height *= 40;
|
||||
|
||||
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
||||
int length = index[i];
|
||||
|
||||
// end marker
|
||||
if (length < 0)
|
||||
break;
|
||||
|
||||
// start next polygon
|
||||
if (length == 0) {
|
||||
complex = i + 1;
|
||||
simple = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// need at least three points
|
||||
if (length < 6) {
|
||||
pos += length;
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if polygon contains inner rings
|
||||
//if (simple && ((i < n - 1) && (index[i + 1] > 0)))
|
||||
// simple = false;
|
||||
|
||||
addOutline(points, pos, length, height, simple);
|
||||
pos += length;
|
||||
}
|
||||
}
|
||||
|
||||
private void addOutline(float[] points, int pos, int len, float height, boolean simple) {
|
||||
if (!MapView.enableClosePolygons)
|
||||
len -= 2;
|
||||
|
||||
// add two vertices for last face to make zigzag indices work
|
||||
boolean addFace = (len % 4 != 0);
|
||||
|
||||
// Log.d(TAG, "add: " + addFace + " " + len + " (" + pos + ")");
|
||||
|
||||
int vertexCnt = len + (addFace ? 2 : 0);
|
||||
int indicesCnt = (len >> 1) * 6;
|
||||
|
||||
short h = (short) height;
|
||||
|
||||
float cx = points[pos + len - 2];
|
||||
float cy = points[pos + len - 1];
|
||||
float nx = points[pos + 0];
|
||||
float ny = points[pos + 1];
|
||||
|
||||
float vx = nx - cx;
|
||||
float vy = ny - cy;
|
||||
float ca = (float) Math.sqrt(vx * vx + vy * vy);
|
||||
float pa = ca;
|
||||
float ux = vx;
|
||||
float uy = vy;
|
||||
|
||||
float vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f;
|
||||
|
||||
short color1 = (short) (200 + (50 * vlight));
|
||||
short fcolor = color1;
|
||||
short color2 = 0;
|
||||
|
||||
boolean even = true;
|
||||
|
||||
short[] vertices = mCurVertices.vertices;
|
||||
int v = mCurVertices.used;
|
||||
|
||||
int convex = 0;
|
||||
|
||||
for (int i = 0; i < len; i += 2, v += 8) {
|
||||
cx = nx;
|
||||
cy = ny;
|
||||
|
||||
if (v == VertexPoolItem.SIZE) {
|
||||
mCurVertices.used = VertexPoolItem.SIZE;
|
||||
mCurVertices.next = VertexPool.get();
|
||||
mCurVertices = mCurVertices.next;
|
||||
vertices = mCurVertices.vertices;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
vertices[v + 0] = vertices[v + 4] = (short) (cx * S);
|
||||
vertices[v + 1] = vertices[v + 5] = (short) (cy * S);
|
||||
|
||||
vertices[v + 2] = 0;
|
||||
vertices[v + 6] = h;
|
||||
|
||||
if (i < len - 2) {
|
||||
nx = points[pos + i + 2];
|
||||
ny = points[pos + i + 3];
|
||||
|
||||
vx = nx - cx;
|
||||
vy = ny - cy;
|
||||
ca = (float) Math.sqrt(vx * vx + vy * vy);
|
||||
|
||||
if (convex > -1) {
|
||||
// TODO fix for straight line...
|
||||
double dir = (vx * ux + vy * uy) / (ca * pa);
|
||||
|
||||
if (convex == 0)
|
||||
convex = dir > 0 ? 1 : 2;
|
||||
else if (convex == 1)
|
||||
convex = dir > 0 ? 1 : -1;
|
||||
else
|
||||
convex = dir > 0 ? -1 : 2;
|
||||
}
|
||||
vlight = vx > 0 ? (vx / ca) : -(vx / ca) - 0.1f;
|
||||
color2 = (short) (200 + (50 * vlight));
|
||||
} else {
|
||||
color2 = fcolor;
|
||||
}
|
||||
|
||||
short c;
|
||||
if (even)
|
||||
c = (short) (color1 | color2 << 8);
|
||||
else
|
||||
c = (short) (color2 | color1 << 8);
|
||||
|
||||
vertices[v + 3] = vertices[v + 7] = c;
|
||||
|
||||
pa = ca;
|
||||
ux = vx;
|
||||
uy = vy;
|
||||
color1 = color2;
|
||||
even = !even;
|
||||
}
|
||||
|
||||
if (addFace) {
|
||||
if (v == VertexPoolItem.SIZE) {
|
||||
mCurVertices.used = VertexPoolItem.SIZE;
|
||||
mCurVertices.next = VertexPool.get();
|
||||
mCurVertices = mCurVertices.next;
|
||||
vertices = mCurVertices.vertices;
|
||||
v = 0;
|
||||
}
|
||||
|
||||
cx = points[pos + 0];
|
||||
cy = points[pos + 1];
|
||||
|
||||
vertices[v + 0] = vertices[v + 4] = (short) (cx * S);
|
||||
vertices[v + 1] = vertices[v + 5] = (short) (cy * S);
|
||||
|
||||
vertices[v + 2] = 0;
|
||||
vertices[v + 6] = h;
|
||||
|
||||
short c = (short) (color1 | fcolor << 8);
|
||||
vertices[v + 3] = vertices[v + 7] = c;
|
||||
|
||||
v += 8;
|
||||
}
|
||||
|
||||
mCurVertices.used = v;
|
||||
|
||||
// fill ZigZagQuadIndices(tm)
|
||||
for (int j = 0; j < 2; j++) {
|
||||
short[] indices = mCurIndices[j].vertices;
|
||||
|
||||
// index id relative to mCurIndices
|
||||
int i = mCurIndices[j].used;
|
||||
|
||||
// vertex id
|
||||
v = mNumVertices + (j * 2);
|
||||
|
||||
for (int k = j * 2; k < len; k += 4) {
|
||||
short s0 = (short) (v++);
|
||||
short s1 = (short) (v++);
|
||||
short s2 = (short) (v++);
|
||||
short s3 = (short) (v++);
|
||||
|
||||
if (i == VertexPoolItem.SIZE) {
|
||||
mCurIndices[j].used = VertexPoolItem.SIZE;
|
||||
mCurIndices[j].next = VertexPool.get();
|
||||
mCurIndices[j] = mCurIndices[j].next;
|
||||
indices = mCurIndices[j].vertices;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if (k + 2 == len) {
|
||||
// connect last to first (when number of faces is even)
|
||||
if (!addFace) {
|
||||
//Log.d(TAG, "connect last " + vertexCnt + " " + len);
|
||||
s2 -= len;
|
||||
s3 -= len;
|
||||
}
|
||||
}
|
||||
indices[i++] = s0;
|
||||
indices[i++] = s1;
|
||||
indices[i++] = s2;
|
||||
|
||||
indices[i++] = s1;
|
||||
indices[i++] = s3;
|
||||
indices[i++] = s2;
|
||||
//System.out.println(" i:" + (mNumIndices + (k * 6))
|
||||
// + "\t(" + s0 + "," + s1 + "," + s2
|
||||
// + ")\t(" + s1 + "," + s3 + "," + s2 + ")");
|
||||
}
|
||||
mCurIndices[j].used = i;
|
||||
}
|
||||
|
||||
if (simple && (len <= 8 || convex > 0)) {
|
||||
//Log.d(TAG, len + " is simple " + convex);
|
||||
|
||||
// roof indices for convex shapes
|
||||
int i = mCurIndices[2].used;
|
||||
short[] indices = mCurIndices[2].vertices;
|
||||
short first = (short) (mNumVertices + 1);
|
||||
|
||||
for (int k = 0; k < len - 4; k += 2) {
|
||||
if (i == VertexPoolItem.SIZE) {
|
||||
mCurIndices[2].used = VertexPoolItem.SIZE;
|
||||
mCurIndices[2].next = VertexPool.get();
|
||||
mCurIndices[2] = mCurIndices[2].next;
|
||||
indices = mCurIndices[2].vertices;
|
||||
i = 0;
|
||||
}
|
||||
indices[i++] = first;
|
||||
//if (convex != 2) {
|
||||
// cw ?
|
||||
indices[i++] = (short) (first + k + 4);
|
||||
indices[i++] = (short) (first + k + 2);
|
||||
// } else {
|
||||
// indices[i++] = (short) (first + k + 2);
|
||||
// indices[i++] = (short) (first + k + 4);
|
||||
// }
|
||||
|
||||
// System.out.println("indice:" + k + "\t" + indices[cnt - 3] + ","
|
||||
// + indices[cnt - 2]+ "," + indices[cnt - 1]);
|
||||
|
||||
indicesCnt += 3;
|
||||
}
|
||||
mCurIndices[2].used = i;
|
||||
} else if (len < 400) {
|
||||
// triangulate up to 200 points
|
||||
short first = (short) (mNumVertices + 1);
|
||||
int used = triangulate(points, pos, len, mCurIndices[2], first);
|
||||
if (used > 0) {
|
||||
indicesCnt += used;
|
||||
// find the last item added..
|
||||
VertexPoolItem it = mIndices[2];
|
||||
while (it.next != null)
|
||||
it = it.next;
|
||||
mCurIndices[2] = it;
|
||||
}
|
||||
|
||||
// mCurIndices[2].next = VertexPool.get();
|
||||
// mCurIndices[2] = mCurIndices[2].next;
|
||||
// short[] indices = mCurIndices[2].vertices;
|
||||
// int used = triangulate(points, pos, len, indices);
|
||||
// if (used > 0) {
|
||||
// short first = (short) (mNumVertices + 1);
|
||||
// for (int i = 0; i < used; i += 3) {
|
||||
// indices[i] = (short) (indices[i] * 2 + first);
|
||||
// short tmp = indices[i + 1];
|
||||
// indices[i + 1] = (short) (indices[i + 2] * 2 + first);
|
||||
// indices[i + 2] = (short) (tmp * 2 + first);
|
||||
// }
|
||||
// mCurIndices[2].used = used;
|
||||
// indicesCnt += used;
|
||||
// }
|
||||
} else
|
||||
Log.d(TAG, "skip >>>>>>>>>> : " + len + " <<<<<<<<<<<<<");
|
||||
|
||||
//Log.d(TAG, "add building: " + vertexCnt);
|
||||
mNumVertices += vertexCnt;
|
||||
mNumIndices += indicesCnt;
|
||||
}
|
||||
|
||||
public void compile(ShortBuffer sbuf) {
|
||||
|
||||
if (mNumVertices == 0 || compiled)
|
||||
return;
|
||||
|
||||
mVboIds = new int[2];
|
||||
GLES20.glGenBuffers(2, mVboIds, 0);
|
||||
mIndicesBufferID = mVboIds[0];
|
||||
mVertexBufferID = mVboIds[1];
|
||||
|
||||
// upload indices
|
||||
|
||||
sbuf.clear();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
for (VertexPoolItem vi = mIndices[i]; vi != null; vi = vi.next) {
|
||||
//System.out.println("put indices: " + vi.used + " " + mNumIndices);
|
||||
sbuf.put(vi.vertices, 0, vi.used);
|
||||
mIndiceCnt[i] += vi.used;
|
||||
}
|
||||
}
|
||||
|
||||
// Log.d(TAG,"put indices: " + mNumIndices + "=="
|
||||
// + (mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2])
|
||||
// + " " + mIndiceCnt[0] + " " + mIndiceCnt[1] + " " + mIndiceCnt[2]);
|
||||
|
||||
mNumIndices = mIndiceCnt[0] + mIndiceCnt[1] + mIndiceCnt[2];
|
||||
|
||||
sbuf.flip();
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
|
||||
mNumIndices * 2, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||
|
||||
sbuf.clear();
|
||||
|
||||
// upload vertices
|
||||
for (VertexPoolItem vi = mVertices; vi != null; vi = vi.next) {
|
||||
//System.out.println("put vertices: " + vi.used + " " + mNumVertices);
|
||||
sbuf.put(vi.vertices, 0, vi.used);
|
||||
}
|
||||
|
||||
sbuf.flip();
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
|
||||
mNumVertices * 4 * 2, sbuf, GLES20.GL_DYNAMIC_DRAW);
|
||||
|
||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
for (VertexPoolItem i : mIndices)
|
||||
VertexPool.release(i);
|
||||
|
||||
VertexPool.release(mVertices);
|
||||
|
||||
compiled = true;
|
||||
}
|
||||
|
||||
public boolean compiled = false;
|
||||
|
||||
int[] mVboIds;
|
||||
|
||||
public boolean ready;
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
if (compiled) {
|
||||
GLES20.glDeleteBuffers(2, mVboIds, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
|
||||
}
|
||||
|
||||
private static boolean initialized = false;
|
||||
private static ShortBuffer sBuf;
|
||||
private static FloatBuffer fBuf;
|
||||
|
||||
public static synchronized int triangulate(float[] points, int pos, int len,
|
||||
VertexPoolItem item, int first) {
|
||||
|
||||
int numRings = 1;
|
||||
|
||||
if (!initialized) {
|
||||
// FIXME also cleanup on shutdown!
|
||||
fBuf = ByteBuffer.allocateDirect(360 * 4).order(ByteOrder.nativeOrder())
|
||||
.asFloatBuffer();
|
||||
|
||||
sBuf = ByteBuffer.allocateDirect(720 * 2).order(ByteOrder.nativeOrder())
|
||||
.asShortBuffer();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
fBuf.clear();
|
||||
fBuf.put(points, pos, len);
|
||||
|
||||
sBuf.clear();
|
||||
sBuf.put((short) (len >> 1)); // all points
|
||||
sBuf.put((short) (len >> 1)); // outer ring
|
||||
//sBuf.put((short)4); // inner ring
|
||||
|
||||
int numTris = TriangleJNI.triangulate(fBuf, numRings, sBuf, first);
|
||||
|
||||
int numIndices = numTris * 3;
|
||||
sBuf.limit(numIndices);
|
||||
sBuf.position(0);
|
||||
|
||||
for (int k = 0, cnt = 0; k < numIndices; k += cnt) {
|
||||
cnt = VertexPoolItem.SIZE - item.used;
|
||||
|
||||
if (item.used == VertexPoolItem.SIZE) {
|
||||
item.next = VertexPool.get();
|
||||
item = item.next;
|
||||
}
|
||||
|
||||
if (k + cnt > numIndices)
|
||||
cnt = numIndices - k;
|
||||
|
||||
sBuf.get(item.vertices, item.used, cnt);
|
||||
item.used += cnt;
|
||||
}
|
||||
|
||||
// sBuf.get(sIndices, 0, numIndices);
|
||||
//
|
||||
// short[] indices = item.vertices;
|
||||
// int i = item.used;
|
||||
//
|
||||
// for (int k = 0; k < numIndices; k += 3) {
|
||||
// if (i == VertexPoolItem.SIZE) {
|
||||
// item.used = VertexPoolItem.SIZE;
|
||||
// item.next = VertexPool.get();
|
||||
// item = item.next;
|
||||
// indices = item.vertices;
|
||||
// i = 0;
|
||||
// }
|
||||
// indices[i++] = sIndices[k + 0];
|
||||
// indices[i++] = sIndices[k + 1];
|
||||
// indices[i++] = sIndices[k + 2];
|
||||
// }
|
||||
// item.used = i;
|
||||
|
||||
return numIndices;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
* Copyright 2012, 2013 OpenScienceMap
|
||||
*
|
||||
* 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
|
||||
@@ -14,6 +14,9 @@
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
/**
|
||||
* @authorHannes Janetzek
|
||||
*/
|
||||
public abstract class Layer {
|
||||
public final static byte LINE = 0;
|
||||
public final static byte POLYGON = 1;
|
||||
@@ -21,15 +24,21 @@ public abstract class Layer {
|
||||
public final static byte POITEXT = 3;
|
||||
public final static byte SYMBOL = 4;
|
||||
public final static byte BITMAP = 5;
|
||||
public final static byte TEXLINE = 6;
|
||||
public final static byte EXTRUSION = 7;
|
||||
|
||||
public byte type;
|
||||
public byte type = -1;
|
||||
|
||||
public Layer next;
|
||||
|
||||
int layer;
|
||||
// number of vertices this layer holds
|
||||
// number of vertices for this layer
|
||||
public int verticesCnt;
|
||||
// vertices offset of this layer in VBO
|
||||
|
||||
// in case of line and polygon layer:
|
||||
// - number of VERTICES offset for this layertype in VBO
|
||||
// otherwise:
|
||||
// - offset in byte in VBO
|
||||
public int offset;
|
||||
|
||||
VertexPoolItem pool;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 Hannes Janetzek
|
||||
* Copyright 2012, 2013 OpenScienceMap
|
||||
*
|
||||
* 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
|
||||
@@ -18,13 +18,22 @@ import java.nio.ShortBuffer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* @author Hannes Janetzek
|
||||
*/
|
||||
public class Layers {
|
||||
|
||||
// mixed Polygon and Line layers
|
||||
public Layer layers;
|
||||
public int lineOffset;
|
||||
|
||||
public Layer textureLayers;
|
||||
public int texOffset;
|
||||
public Layer extrusionLayers;
|
||||
|
||||
// To not need to switch VertexAttribPointer positions all the time:
|
||||
// 1. polygons are packed in VBO at offset 0
|
||||
// 2. lines afterwards at lineOffset
|
||||
// 3. other layers keep their byte offset in Layer.offset
|
||||
public int lineOffset;
|
||||
|
||||
private Layer mCurLayer;
|
||||
|
||||
@@ -78,10 +87,78 @@ public class Layers {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// public boolean uploadLayers(BufferObject vbo, boolean addFill, boolean limit) {
|
||||
//
|
||||
// int newSize = getSize();
|
||||
// if (newSize == 0) {
|
||||
// // Log.d(TAG, "empty");
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// GLES20.glBindBuffer(GL_ARRAY_BUFFER, vbo.id);
|
||||
//
|
||||
// // use multiple buffers to avoid overwriting buffer while current
|
||||
// // data is uploaded (or rather the blocking which is probably done to
|
||||
// // avoid overwriting)
|
||||
// int curBuffer = uploadCnt++ % rotateBuffers;
|
||||
//
|
||||
// ShortBuffer sbuf = shortBuffer[curBuffer];
|
||||
//
|
||||
// // add fill coordinates
|
||||
// if (addFill)
|
||||
// newSize += 8;
|
||||
//
|
||||
// if (sbuf.capacity() < newSize) {
|
||||
// sbuf = ByteBuffer
|
||||
// .allocateDirect(newSize * SHORT_BYTES)
|
||||
// .order(ByteOrder.nativeOrder())
|
||||
// .asShortBuffer();
|
||||
//
|
||||
// shortBuffer[curBuffer] = sbuf;
|
||||
// } else {
|
||||
// sbuf.clear();
|
||||
// // if (addFill)
|
||||
// // sbuf.position(8);
|
||||
// }
|
||||
//
|
||||
// if (addFill)
|
||||
// sbuf.put(mFillCoords, 0, 8);
|
||||
//
|
||||
// compile(sbuf, addFill);
|
||||
//
|
||||
// sbuf.flip();
|
||||
//
|
||||
// if (newSize != sbuf.remaining()) {
|
||||
// Log.d(TAG, "wrong size: "
|
||||
// + newSize + " "
|
||||
// + sbuf.position() + " "
|
||||
// + sbuf.limit() + " "
|
||||
// + sbuf.remaining());
|
||||
// return false;
|
||||
// }
|
||||
// newSize *= SHORT_BYTES;
|
||||
//
|
||||
// // reuse memory allocated for vbo when possible and allocated
|
||||
// // memory is less then four times the new data
|
||||
// if (vbo.size > newSize && vbo.size < newSize * 4
|
||||
// && !limit) {
|
||||
// GLES20.glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, sbuf);
|
||||
// } else {
|
||||
// //mBufferMemoryUsage += newSize - vbo.size;
|
||||
// vbo.size = newSize;
|
||||
// GLES20.glBufferData(GL_ARRAY_BUFFER, vbo.size, sbuf, GL_DYNAMIC_DRAW);
|
||||
// //mBufferMemoryUsage += vbo.size;
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
private static int LINE_VERTEX_SHORTS = 4;
|
||||
private static int POLY_VERTEX_SHORTS = 2;
|
||||
private static int TEXTURE_VERTEX_SHORTS = 6;
|
||||
|
||||
//private static int EXTRUSION_VERTEX_SHORTS = 4;
|
||||
|
||||
public int getSize() {
|
||||
|
||||
int size = 0;
|
||||
@@ -91,12 +168,13 @@ public class Layers {
|
||||
size += l.verticesCnt * LINE_VERTEX_SHORTS;
|
||||
else
|
||||
size += l.verticesCnt * POLY_VERTEX_SHORTS;
|
||||
|
||||
}
|
||||
|
||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
||||
for (Layer l = textureLayers; l != null; l = l.next)
|
||||
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
||||
}
|
||||
|
||||
//for (Layer l = extrusionLayers; l != null; l = l.next)
|
||||
// size += l.verticesCnt * EXTRUSION_VERTEX_SHORTS;
|
||||
|
||||
return size;
|
||||
}
|
||||
@@ -113,18 +191,18 @@ public class Layers {
|
||||
lineOffset = sbuf.position() * 2; // * short-bytes
|
||||
addLayerItems(sbuf, layers, Layer.LINE, 0);
|
||||
|
||||
texOffset = sbuf.position() * 2; // * short-bytes
|
||||
|
||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
||||
TextureLayer sl = (TextureLayer) l;
|
||||
sl.compile(sbuf);
|
||||
TextureLayer tl = (TextureLayer) l;
|
||||
tl.compile(sbuf);
|
||||
}
|
||||
|
||||
// FIXME
|
||||
addLayerItems(sbuf, textureLayers, Layer.SYMBOL, 0);
|
||||
|
||||
// for (Layer l = extrusionLayers; l != null; l = l.next) {
|
||||
// ExtrusionLayer tl = (ExtrusionLayer) l;
|
||||
// tl.compile(sbuf);
|
||||
// }
|
||||
}
|
||||
|
||||
// optimization for lines and polygon: collect all pool items and add back in one go
|
||||
private static void addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) {
|
||||
VertexPoolItem last = null, items = null;
|
||||
|
||||
@@ -136,7 +214,8 @@ public class Layers {
|
||||
if (it.next == null)
|
||||
sbuf.put(it.vertices, 0, it.used);
|
||||
else
|
||||
sbuf.put(it.vertices);
|
||||
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE);
|
||||
|
||||
last = it;
|
||||
}
|
||||
if (last == null)
|
||||
@@ -155,8 +234,22 @@ public class Layers {
|
||||
VertexPool.release(items);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
static void addPoolItems(Layer l, ShortBuffer sbuf) {
|
||||
l.offset = sbuf.position() * 2; // (* short-bytes)
|
||||
|
||||
for (VertexPoolItem it = l.pool; it != null; it = it.next) {
|
||||
if (it.next == null)
|
||||
sbuf.put(it.vertices, 0, it.used);
|
||||
else
|
||||
sbuf.put(it.vertices, 0, VertexPoolItem.SIZE);
|
||||
}
|
||||
|
||||
VertexPool.release(l.pool);
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
// cleanup only when layers are not used by tile or overlay anymore!
|
||||
public void clear() {
|
||||
while (layers != null) {
|
||||
Layer l = layers;
|
||||
if (l.pool != null) {
|
||||
@@ -181,5 +274,20 @@ public class Layers {
|
||||
l = l.next;
|
||||
}
|
||||
textureLayers = null;
|
||||
|
||||
l = extrusionLayers;
|
||||
while (l != null) {
|
||||
|
||||
l.clear();
|
||||
|
||||
if (l.pool != null) {
|
||||
VertexPool.release(l.pool);
|
||||
l.pool = null;
|
||||
l.curItem = null;
|
||||
}
|
||||
|
||||
l = l.next;
|
||||
}
|
||||
extrusionLayers = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
import org.oscim.renderer.TextureRenderer;
|
||||
|
||||
@@ -85,14 +83,16 @@ public final class SymbolLayer extends TextureLayer {
|
||||
symbols = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
void compile(ShortBuffer sbuf) {
|
||||
if (TextureRenderer.debug)
|
||||
Log.d("...", "compile");
|
||||
|
||||
for (TextureObject to = textures; to != null; to = to.next)
|
||||
TextureObject.uploadTexture(to);
|
||||
}
|
||||
// @Override
|
||||
// void compile(ShortBuffer sbuf) {
|
||||
// if (TextureRenderer.debug)
|
||||
// Log.d("...", "compile");
|
||||
//
|
||||
// for (TextureObject to = textures; to != null; to = to.next)
|
||||
// TextureObject.uploadTexture(to);
|
||||
//
|
||||
// Layers.addPoolItems(this, sbuf);
|
||||
// }
|
||||
|
||||
private final static int LBIT_MASK = 0xfffffffe;
|
||||
|
||||
|
||||
@@ -14,13 +14,10 @@
|
||||
*/
|
||||
package org.oscim.renderer.layer;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
import org.oscim.renderer.TextureRenderer;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
|
||||
public final class TextLayer extends TextureLayer {
|
||||
@@ -92,15 +89,6 @@ public final class TextLayer extends TextureLayer {
|
||||
labels = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
void compile(ShortBuffer sbuf) {
|
||||
if (TextureRenderer.debug)
|
||||
Log.d("...", "compile");
|
||||
|
||||
for (TextureObject to = textures; to != null; to = to.next)
|
||||
TextureObject.uploadTexture(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean prepare() {
|
||||
if (TextureRenderer.debug)
|
||||
@@ -189,7 +177,7 @@ public final class TextLayer extends TextureLayer {
|
||||
} else {
|
||||
float vx = it.x1 - it.x2;
|
||||
float vy = it.y1 - it.y2;
|
||||
float a = FloatMath.sqrt(vx * vx + vy * vy);
|
||||
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||
vx = vx / a;
|
||||
vy = vy / a;
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ package org.oscim.renderer.layer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.oscim.renderer.TextureObject;
|
||||
import org.oscim.renderer.TextureRenderer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public abstract class TextureLayer extends Layer {
|
||||
public TextureObject textures;
|
||||
@@ -26,7 +29,15 @@ public abstract class TextureLayer extends Layer {
|
||||
* @param sbuf
|
||||
* buffer to add vertices
|
||||
*/
|
||||
abstract void compile(ShortBuffer sbuf);
|
||||
void compile(ShortBuffer sbuf) {
|
||||
if (TextureRenderer.debug)
|
||||
Log.d("...", "compile");
|
||||
|
||||
for (TextureObject to = textures; to != null; to = to.next)
|
||||
TextureObject.uploadTexture(to);
|
||||
|
||||
Layers.addPoolItems(this, sbuf);
|
||||
}
|
||||
|
||||
abstract public boolean prepare();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,15 @@ public class VertexPool {
|
||||
pool = null;
|
||||
}
|
||||
|
||||
// public static VertexPoolItem get(VertexPoolItem prev) {
|
||||
// VertexPoolItem it = get();
|
||||
// if (prev != null) {
|
||||
// prev.next = it;
|
||||
// prev.used = VertexPoolItem.SIZE;
|
||||
// }
|
||||
// return it;
|
||||
// }
|
||||
|
||||
public static synchronized VertexPoolItem get() {
|
||||
|
||||
if (pool == null && count > 0) {
|
||||
|
||||
Reference in New Issue
Block a user