diff --git a/src/org/oscim/renderer/layers/BasicRenderLayer.java b/src/org/oscim/renderer/layers/BasicRenderLayer.java
index b8ee51c7..b541c955 100644
--- a/src/org/oscim/renderer/layers/BasicRenderLayer.java
+++ b/src/org/oscim/renderer/layers/BasicRenderLayer.java
@@ -89,6 +89,10 @@ public abstract class BasicRenderLayer extends RenderLayer {
l = BitmapRenderer.draw(l, 1, m);
break;
+// case Layer.SYMBOL:
+// l = BitmapRenderer.draw(l, 1, m);
+// break;
+
default:
l = TextureRenderer.draw(l, scale, m);
}
diff --git a/src/org/oscim/renderer/layers/test/SymbolRenderLayer.java b/src/org/oscim/renderer/layers/test/SymbolRenderLayer.java
new file mode 100644
index 00000000..68f4a8df
--- /dev/null
+++ b/src/org/oscim/renderer/layers/test/SymbolRenderLayer.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Hannes Janetzek
+ *
+ * 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 .
+ */
+package org.oscim.renderer.layers.test;
+
+import java.io.IOException;
+
+import org.oscim.core.MapPosition;
+import org.oscim.renderer.GLRenderer.Matrices;
+import org.oscim.renderer.layers.BasicRenderLayer;
+import org.oscim.renderer.sublayers.SymbolItem;
+import org.oscim.renderer.sublayers.SymbolLayer;
+import org.oscim.theme.renderinstruction.BitmapUtils;
+import org.oscim.view.MapView;
+
+public class SymbolRenderLayer extends BasicRenderLayer {
+ boolean initialize = true;
+
+ public SymbolRenderLayer(MapView mapView) {
+ super(mapView);
+ SymbolLayer l = new SymbolLayer();
+ layers.textureLayers = l;
+
+ SymbolItem it = SymbolItem.pool.get();
+ it.billboard = false;
+
+ try {
+ it.bitmap = BitmapUtils.createBitmap("jar:symbols/cafe.png");
+ } catch (IOException e) {
+ e.printStackTrace();
+
+ }
+ l.addSymbol(it);
+
+ // compile layer on next frame
+ newData = true;
+ }
+
+ @Override
+ public void update(MapPosition position, boolean changed, Matrices matrices) {
+ if (initialize){
+ initialize = false;
+ mMapPosition.copy(position);
+ }
+ }
+}
diff --git a/src/org/oscim/renderer/sublayers/SymbolLayer.java b/src/org/oscim/renderer/sublayers/SymbolLayer.java
index 06e842e3..f057825b 100644
--- a/src/org/oscim/renderer/sublayers/SymbolLayer.java
+++ b/src/org/oscim/renderer/sublayers/SymbolLayer.java
@@ -14,35 +14,32 @@
*/
package org.oscim.renderer.sublayers;
+import java.nio.ShortBuffer;
+
+import org.oscim.utils.pool.Inlist;
-import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.util.Log;
// TODO share one static texture for all poi map symabols
public final class SymbolLayer extends TextureLayer {
private final static String TAG = SymbolLayer.class.getSimpleName();
- private final static int TEXTURE_WIDTH = TextureItem.TEXTURE_WIDTH;
- private final static int TEXTURE_HEIGHT = TextureItem.TEXTURE_HEIGHT;
private final static float SCALE = 8.0f;
+ private final static int VERTICES_PER_SPRITE = 4;
- SymbolItem symbols;
-
- private final Canvas mCanvas;
- private final Rect mRect = new Rect();
+ private SymbolItem symbols;
public SymbolLayer() {
type = Layer.SYMBOL;
fixed = true;
- mCanvas = new Canvas();
}
+ // TODO move sorting items to 'prepare'
public void addSymbol(SymbolItem item) {
- verticesCnt += 4;
+ verticesCnt += VERTICES_PER_SPRITE;
for (SymbolItem it = symbols; it != null; it = it.next) {
if (it.bitmap == item.bitmap) {
@@ -59,7 +56,7 @@ public final class SymbolLayer extends TextureLayer {
public void addDrawable(Drawable drawable, int state, float x, float y) {
- verticesCnt += 4;
+ verticesCnt += VERTICES_PER_SPRITE;
SymbolItem item = SymbolItem.pool.get();
item.drawable = drawable;
@@ -83,31 +80,44 @@ public final class SymbolLayer extends TextureLayer {
private final static int LBIT_MASK = 0xfffffffe;
- // TODO reuse texture when only symbol position changed
@Override
public boolean prepare() {
+ return true;
+ }
+
+ @Override
+ protected void compile(ShortBuffer sbuf) {
+ // offset of layer data in vbo
+ this.offset = sbuf.position() * 2; //SHORT_BYTES;
+
short numIndices = 0;
- short offsetIndices = 0;
- short curIndices = 0;
+ //short offsetIndices = 0;
+ //short curIndices = 0;
- curItem = VertexItem.pool.get();
- vertexItems = curItem;
- VertexItem si = curItem;
+ //curItem =
+ //vertexItems = curItem;
+ VertexItem si = VertexItem.pool.get();
- int pos = si.used;
+ int pos = 0;
short buf[] = si.vertices;
- int advanceY = 0;
- float x = 0;
- float y = 0;
+ //int advanceY = 0;
+ final float x = 0;
+ final float y = 0;
- TextureItem to = TextureItem.get(true);
- textures = to;
- mCanvas.setBitmap(to.bitmap);
+ TextureItem prevTextures = textures;
+ //TextureItem prev = textures;
+
+ textures = null;
+ TextureItem to = null;
+
+ //TextureItem to = TextureItem.get(true);
+ //textures = to;
+ //mCanvas.setBitmap(to.bitmap);
for (SymbolItem it = symbols; it != null;) {
- float width, height;
+ int width, height;
if (it.bitmap != null) {
// add bitmap
@@ -118,61 +128,43 @@ public final class SymbolLayer extends TextureLayer {
height = it.drawable.getIntrinsicHeight();
}
- if (height > advanceY)
- advanceY = (int) height;
-
- if (x + width > TEXTURE_WIDTH) {
- x = 0;
- y += advanceY;
- advanceY = (int) (height + 0.5f);
-
+ for (to = prevTextures; to != null; to = to.next){
+ if (to.bitmap == it.bitmap){
+ prevTextures = Inlist.remove(prevTextures, to);
+ textures = Inlist.append(textures, to);
+ break;
+ }
}
- if (y + height > TEXTURE_HEIGHT) {
- Log.d(TAG, "reached max symbols: " + numIndices);
+ if (to == null){
+ to = TextureItem.get(false);
+ to.bitmap = it.bitmap;
+ to.width = width;
+ to.height= height;
+ textures = Inlist.append(textures, to);
- to.offset = offsetIndices;
- to.vertices = curIndices;
-
- numIndices += curIndices;
- offsetIndices = numIndices;
- curIndices = 0;
-
- to.next = TextureItem.get(true);
- to = to.next;
-
- mCanvas.setBitmap(to.bitmap);
-
- x = 0;
- y = 0;
- advanceY = (int) height;
+ TextureItem.uploadTexture(to);
}
- if (it.bitmap != null) {
- mCanvas.drawBitmap(it.bitmap, x, y, null);
- } else {
- it.drawable.copyBounds(mRect);
- it.drawable.setBounds((int) x, (int) y, (int) (x + width), (int) (y + height));
- it.drawable.draw(mCanvas);
- it.drawable.setBounds(mRect);
- }
+ to.offset = numIndices;
+ to.vertices = 0;
short x1, y1, x2, y2;
if (it.bitmap != null) {
- float hw = width / 2.0f;
- float hh = height / 2.0f;
+ float hw = width / 2f;
+ float hh = height / 2f;
x1 = (short) (SCALE * (-hw));
x2 = (short) (SCALE * (hw));
y1 = (short) (SCALE * (hh));
y2 = (short) (SCALE * (-hh));
} else {
// use drawable offsets (for marker hotspot)
+ Rect mRect = it.drawable.getBounds();
x2 = (short) (SCALE * (mRect.left));
y2 = (short) (SCALE * (mRect.top));
x1 = (short) (SCALE * (mRect.right));
y1 = (short) (SCALE * (mRect.bottom));
-
}
short u1 = (short) (SCALE * x);
@@ -195,9 +187,7 @@ public final class SymbolLayer extends TextureLayer {
short ty = (short) (SCALE * it2.y);
if (pos == VertexItem.SIZE) {
- si.used = VertexItem.SIZE;
- si = si.next = VertexItem.pool.get();
- buf = si.vertices;
+ sbuf.put(buf, 0, VertexItem.SIZE);
pos = 0;
}
@@ -231,26 +221,42 @@ public final class SymbolLayer extends TextureLayer {
buf[pos++] = v1;
// six elements used to draw the four vertices
- curIndices += TextureRenderer.INDICES_PER_SPRITE;
+ to.vertices += TextureRenderer.INDICES_PER_SPRITE;
}
- x += width;
+
+ numIndices += to.vertices;
+ //offsetIndices = numIndices;
+
+ //to.offset = offsetIndices;
+ //= curIndices;
+ //x += width;
+
}
+// if (to != null) {
+// to.offset = offsetIndices;
+// to.vertices = curIndices;
+// }
+ //si.used = pos;
+ //curItem = si;
- to.offset = offsetIndices;
- to.vertices = curIndices;
+ if (pos > 0)
+ sbuf.put(buf, 0, pos);
- si.used = pos;
- curItem = si;
+ VertexItem.pool.release(si);
- return true;
+ TextureItem.releaseAll(prevTextures);
+ prevTextures = null;
}
+
@Override
protected void clear() {
- TextureItem.releaseAll(textures);
+ TextureItem.releaseAll(textures);
SymbolItem.pool.releaseAll(symbols);
- VertexItem.pool.releaseAll(vertexItems);
+
+ //VertexItem.pool.releaseAll(vertexItems);
+
textures = null;
symbols = null;
vertexItems = null;
diff --git a/src/org/oscim/renderer/sublayers/TextureItem.java b/src/org/oscim/renderer/sublayers/TextureItem.java
index fe4fd75a..89688d5d 100644
--- a/src/org/oscim/renderer/sublayers/TextureItem.java
+++ b/src/org/oscim/renderer/sublayers/TextureItem.java
@@ -45,6 +45,7 @@ public class TextureItem extends Inlist {
// temporary Bitmap
public Bitmap bitmap;
+ // external bitmap (not from pool) use
boolean ownBitmap;
TextureItem(int id) {
@@ -56,14 +57,21 @@ public class TextureItem extends Inlist {
}
/**
- * Retrieve a TextureItem from pool with default Bitmap
- * with dimension TextureRenderer.TEXTURE_WIDTH/HEIGHT.
- * */
- public synchronized static TextureItem get(boolean initBitmap) {
+ * Retrieve a TextureItem from pool.
+ *
+ * @param poolBitmap
+ * initialize with pooled Bitmap with dimension
+ * TextureRenderer.TEXTURE_WIDTH/HEIGHT.
+ */
+ public synchronized static TextureItem get(boolean poolBitmap) {
TextureItem ti = pool.get();
- if (initBitmap) {
+
+ if (poolBitmap) {
ti.bitmap = getBitmap();
ti.bitmap.eraseColor(Color.TRANSPARENT);
+ ti.ownBitmap = false;
+ } else {
+ ti.ownBitmap = true;
}
return ti;
}
@@ -158,9 +166,9 @@ public class TextureItem extends Inlist {
if (!to.ownBitmap)
TextureItem.releaseBitmap(to);
- else{
+ else {
// FIXME when in doubt
- to.bitmap = null;
+ //to.bitmap = null;
}
}
diff --git a/src/org/oscim/renderer/sublayers/TextureRenderer.java b/src/org/oscim/renderer/sublayers/TextureRenderer.java
index 3df8441b..0514a4c4 100644
--- a/src/org/oscim/renderer/sublayers/TextureRenderer.java
+++ b/src/org/oscim/renderer/sublayers/TextureRenderer.java
@@ -16,8 +16,6 @@
package org.oscim.renderer.sublayers;
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
-import static org.oscim.renderer.sublayers.TextureItem.TEXTURE_HEIGHT;
-import static org.oscim.renderer.sublayers.TextureItem.TEXTURE_WIDTH;
import org.oscim.renderer.GLRenderer;
import org.oscim.renderer.GLRenderer.Matrices;
@@ -37,6 +35,7 @@ public final class TextureRenderer {
private static int hTextureScale;
private static int hTextureScreenScale;
private static int hTextureTexCoord;
+ private static int hTextureSize;
public final static int INDICES_PER_SPRITE = 6;
final static int VERTICES_PER_SPRITE = 4;
@@ -49,6 +48,7 @@ public final class TextureRenderer {
hTextureMVMatrix = GLES20.glGetUniformLocation(mTextureProgram, "u_mv");
hTextureProjMatrix = GLES20.glGetUniformLocation(mTextureProgram, "u_proj");
hTextureScale = GLES20.glGetUniformLocation(mTextureProgram, "u_scale");
+ hTextureSize = GLES20.glGetUniformLocation(mTextureProgram, "u_div");
hTextureScreenScale = GLES20.glGetUniformLocation(mTextureProgram, "u_swidth");
hTextureVertex = GLES20.glGetAttribLocation(mTextureProgram, "vertex");
hTextureTexCoord = GLES20.glGetAttribLocation(mTextureProgram, "tex_coord");
@@ -81,6 +81,10 @@ public final class TextureRenderer {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ti.id);
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
+ GLES20.glUniform2f(hTextureSize,
+ 1f / (ti.width * COORD_SCALE),
+ 1f / (ti.height * COORD_SCALE));
+
// draw up to maxVertices in each iteration
for (int i = 0; i < ti.vertices; i += maxVertices) {
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
@@ -106,8 +110,9 @@ public final class TextureRenderer {
return layer.next;
}
- private final static double TEX_COORD_DIV_X = 1.0 / (TEXTURE_WIDTH * COORD_SCALE);
- private final static double TEX_COORD_DIV_Y = 1.0 / (TEXTURE_HEIGHT * COORD_SCALE);
+ //private final static double TEX_COORD_DIV_X = 1.0 / (TEXTURE_WIDTH * COORD_SCALE);
+ //private final static double TEX_COORD_DIV_Y = 1.0 / (TEXTURE_HEIGHT * COORD_SCALE);
+
private final static double COORD_DIV = 1.0 / GLRenderer.COORD_SCALE;
private final static String textVertexShader = ""
@@ -118,8 +123,9 @@ public final class TextureRenderer {
+ "uniform mat4 u_proj;"
+ "uniform float u_scale;"
+ "uniform float u_swidth;"
+ + "uniform vec2 u_div;"
+ "varying vec2 tex_c;"
- + "const vec2 div = vec2(" + TEX_COORD_DIV_X + "," + TEX_COORD_DIV_Y + ");"
+ //+ "const vec2 div = vec2(" + TEX_COORD_DIV_X + "," + TEX_COORD_DIV_Y + ");"
+ "const float coord_scale = " + COORD_DIV + ";"
+ "void main() {"
+ " vec4 pos;"
@@ -131,7 +137,7 @@ public final class TextureRenderer {
+ " pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.0, 0.0));"
+ " }"
+ " gl_Position = pos;"
- + " tex_c = tex_coord * div;"
+ + " tex_c = tex_coord * u_div;"
+ "}";
private final static String textFragmentShader = ""