/*
* Copyright 2012 Hannes Janetzek
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
*
* You should have received a copy of the GNU Lesser General License along with
* this program. If not, see .
*/
package org.mapsforge.android.glrenderer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import org.mapsforge.android.utils.FastMath;
import org.mapsforge.core.Tile;
import android.util.SparseArray;
class PolygonLayers {
private static final int NUM_VERTEX_FLOATS = 2;
private static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
-2, Tile.TILE_SIZE + 1, -2 };
private static byte[] mByteFillCoords = null;
private SparseArray layers;
PolygonLayer[] array = null;
int size;
PolygonLayers() {
layers = new SparseArray(10);
size = 4;
}
PolygonLayer getLayer(int layer, int color, int fade) {
PolygonLayer l = layers.get(layer);
if (l != null) {
if (color == l.color)
return l;
return getLayer(layer + 1, color, fade);
}
l = new PolygonLayer(layer, color, fade);
layers.put(layer, l);
return l;
}
FloatBuffer compileLayerData(FloatBuffer buf) {
FloatBuffer fbuf = buf;
array = new PolygonLayer[layers.size()];
for (int i = 0, n = layers.size(); i < n; i++) {
PolygonLayer l = layers.valueAt(i);
array[i] = l;
size += l.verticesCnt;
}
size *= NUM_VERTEX_FLOATS;
if (buf == null || buf.capacity() < size) {
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder());
// Log.d("GLMap", "allocate buffer " + size);
fbuf = bbuf.asFloatBuffer();
} else {
fbuf.position(0);
}
fbuf.put(mFillCoords, 0, 8);
int pos = 4;
for (int i = 0, n = array.length; i < n; i++) {
PolygonLayer l = array[i];
for (PoolItem item : l.pool) {
fbuf.put(item.vertices, 0, item.used);
}
l.offset = pos;
pos += l.verticesCnt;
LayerPool.add(l.pool);
l.pool = null;
}
fbuf.position(0);
// not needed for drawing
layers = null;
return fbuf;
}
ByteBuffer compileLayerData(ByteBuffer buf) {
ByteBuffer bbuf = buf;
array = new PolygonLayer[layers.size()];
for (int i = 0, n = layers.size(); i < n; i++) {
PolygonLayer l = layers.valueAt(i);
array[i] = l;
size += l.verticesCnt;
}
size *= NUM_VERTEX_FLOATS;
if (buf == null || buf.capacity() < size * 2) {
bbuf = ByteBuffer.allocateDirect(size * 2).order(ByteOrder.nativeOrder());
} else {
bbuf.position(0);
}
byte[] data = new byte[PoolItem.SIZE * 2];
if (mByteFillCoords == null) {
mByteFillCoords = new byte[16];
FastMath.convertFloatToHalf(mFillCoords[0], mByteFillCoords, 0);
FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 2);
FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 4);
FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 6);
FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 8);
FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 10);
FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 12);
FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 14);
}
bbuf.put(mByteFillCoords, 0, 16);
int pos = 4;
for (int i = 0, n = array.length; i < n; i++) {
PolygonLayer l = array[i];
for (int k = 0, m = l.pool.size(); k < m; k++) {
PoolItem item = l.pool.get(k);
PoolItem.toHalfFloat(item, data);
bbuf.put(data, 0, item.used * 2);
}
l.offset = pos;
pos += l.verticesCnt;
LayerPool.add(l.pool);
l.pool = null;
}
bbuf.position(0);
// not needed for drawing
layers = null;
return bbuf;
}
}