diff --git a/src/org/oscim/renderer/LineTexRenderer.java b/src/org/oscim/renderer/LineTexRenderer.java
index 74524bdd..01028c31 100644
--- a/src/org/oscim/renderer/LineTexRenderer.java
+++ b/src/org/oscim/renderer/LineTexRenderer.java
@@ -23,6 +23,7 @@ import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.Layers;
import org.oscim.renderer.layer.LineLayer;
import org.oscim.renderer.layer.LineTexLayer;
+import org.oscim.theme.renderinstruction.Line;
import org.oscim.utils.GlUtils;
import android.opengl.GLES20;
@@ -45,15 +46,16 @@ public class LineTexRenderer {
private static int hTexColor;
private static int hBgColor;
private static int hScale;
+ private static int hPatternScale;
private static int hWidth;
private static int mIndicesBufferID;
private static int mVertexFlipID;
- // draw up to 100 quads in one round
+ // batch up up to 100 quads in one draw call
private static int maxQuads = 100;
private static int maxIndices = maxQuads * 6;
- private static int mTexID;
+ private static int[] mTexID;
public static void init() {
shader = GlUtils.createProgram(vertexShader, fragmentShader);
@@ -66,6 +68,7 @@ public class LineTexRenderer {
hTexColor = GLES20.glGetUniformLocation(shader, "u_color");
hBgColor = GLES20.glGetUniformLocation(shader, "u_bgcolor");
hScale = GLES20.glGetUniformLocation(shader, "u_scale");
+ hPatternScale = GLES20.glGetUniformLocation(shader, "u_pscale");
hWidth = GLES20.glGetUniformLocation(shader, "u_width");
hVertexPosition0 = GLES20.glGetAttribLocation(shader, "a_pos0");
@@ -115,14 +118,13 @@ public class LineTexRenderer {
GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
+ mTexID = new int[10];
+
byte[] stipple = new byte[2];
- stipple[0] = 8;
- stipple[1] = 8;
- //stipple[2] = 16;
- //stipple[3] = 48;
-
- mTexID = GlUtils.loadStippleTexture(stipple);
+ stipple[0] = 32;
+ stipple[1] = 32;
+ mTexID[0] = GlUtils.loadStippleTexture(stipple);
}
private final static int STRIDE = 12;
@@ -144,12 +146,7 @@ public class LineTexRenderer {
GLES20.glUniformMatrix4fv(hMatrix, 1, false, matrix, 0);
- GLES20.glUniform4f(hTexColor, 1.0f, 1.0f, 1.0f, 1.0f);
- //aa9988
- GLES20.glUniform4f(hBgColor, 0x99 / 255f, 0x96 / 255f, 0x93 / 255f, 0.95f);
-
- GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID);
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,
mIndicesBufferID);
@@ -160,21 +157,37 @@ public class LineTexRenderer {
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, layers.vbo.id);
- int offset = layers.texLineOffset;
-
float s = pos.scale / div;
+ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID[0]);
+
Layer l = curLayer;
while (l != null && l.type == Layer.TEXLINE) {
LineTexLayer ll = (LineTexLayer) l;
- //Line line = ll.line;
+ Line line = ll.line;
+
+ if (line.stippleColor == null)
+ GLES20.glUniform4f(hTexColor, 1.0f, 1.0f, 1.0f, 1.0f);
+ else
+ GLES20.glUniform4fv(hTexColor, 1, line.stippleColor, 0);
+
+ GLES20.glUniform4fv(hBgColor, 1, line.color, 0);
+
+ //GLES20.glUniform4f(hBgColor, 0x99 / 255f, 0x96 / 255f, 0x93 / 255f, 0.95f);
// scale pattern to twice its size, then reset scale to 1.
// (coord scale * pattern size) / scale
- GLES20.glUniform1f(hScale, (8 * 16) / Math.max((int)(s+0.25f), 1));
+ GLES20.glUniform1f(hPatternScale, (8 * (64 / line.stipple)) / Math.max((int) s, 1));
+ //float f = Math.max((int)(s), 1);
+ //Log.d(TAG, s + " : " + f);
+ //GLES20.glUniform1f(hPatternScale, (8 * line.stipple) / 1);
+ GLES20.glUniform1f(hScale, pos.scale);
GLES20.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
+ // add offset vertex
+ int vOffset = -STRIDE;
+
// first pass
int allIndices = (ll.evenQuads * 6);
for (int i = 0; i < allIndices; i += maxIndices) {
@@ -183,7 +196,7 @@ public class LineTexRenderer {
numIndices = maxIndices;
// i / 6 * (24 shorts per block * 2 short bytes)
- int add = offset + i * 8;
+ int add = (l.offset + i * 8) + vOffset;;
GLES20.glVertexAttribPointer(hVertexPosition0,
4, GLES20.GL_SHORT, false, STRIDE,
@@ -212,7 +225,7 @@ public class LineTexRenderer {
if (numIndices > maxIndices)
numIndices = maxIndices;
// i / 6 * (24 shorts per block * 2 short bytes)
- int add = offset + i * 8;
+ int add = (l.offset + i * 8) + vOffset;
GLES20.glVertexAttribPointer(hVertexPosition0,
4, GLES20.GL_SHORT, false, STRIDE,
@@ -255,7 +268,7 @@ public class LineTexRenderer {
+ "precision mediump float;"
+ "uniform mat4 u_mvp;"
+ "uniform vec4 u_color;"
- + "uniform float u_scale;"
+ + "uniform float u_pscale;"
+ "uniform float u_width;"
+ "attribute vec4 a_pos0;"
+ "attribute vec4 a_pos1;"
@@ -264,20 +277,41 @@ public class LineTexRenderer {
+ "attribute float a_flip;"
+ "varying vec2 v_st;"
+ "void main() {"
- // coord scale 8 * pattern length 16
- //+ " float div = (8.0 * 16.0) / max(ceil(log(u_scale)),1.0);"
- + " float div = u_scale;"
+ + " vec4 pos;"
+ " if (a_flip == 0.0){"
+ " vec2 dir = u_width * a_pos0.zw;"
- + " gl_Position = u_mvp * vec4(a_pos0.xy + dir, 0.0, 1.0);"
- + " v_st = vec2(a_len0.x/div, 1.0);"
- + " }else {"
+ + " pos = vec4(a_pos0.xy + dir, 0.0, 1.0);"
+ + " v_st = vec2(a_len0.x / u_pscale, 1.0);"
+ + " } else {"
+ " vec2 dir = u_width * a_pos1.zw ;"
- + " gl_Position = u_mvp * vec4(a_pos1.xy - dir, 0.0, 1.0);"
- + " v_st = vec2(a_len1.x/div, -1.0);"
- + " }"
+ + " pos = vec4(a_pos1.xy - dir, 0.0, 1.0);"
+ + " v_st = vec2(a_len1.x / u_pscale, -1.0);"
+ + " }"
+ + " gl_Position = u_mvp * pos;"
+ "}";
+ /*
+ final static String fragmentShader = ""
+ + "#extension GL_OES_standard_derivatives : enable\n"
+ + " precision mediump float;"
+ + " uniform sampler2D tex;"
+ + " uniform float u_scale;"
+ + " uniform vec4 u_color;"
+ + " uniform vec4 u_bgcolor;"
+ + " varying vec2 v_st;"
+ + " void main() {"
+ + " float len = texture2D(tex, v_st).a;"
+ + " float tex_w = abs(v_st.t);"
+ + " vec2 st_width = fwidth(v_st);"
+ + " float fuzz = max(st_width.s, st_width.t);"
+ //+ " float fuzz = fwidth(v_st.t);"
+ //+ " float line_w = 1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w);"
+ //+ " float stipple_w = 1.0 - smoothstep(0.7 - fuzz, 0.7, tex_w);"
+ + " float stipple_p = 1.0 - smoothstep(1.0 - fuzz, 1.0, length(vec2(len*u_scale, v_st.t)));"
+ + " gl_FragColor = u_bgcolor * stipple_p;"
+ // + " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
+ + "}"; //*/
+ //*
final static String fragmentShader = ""
+ "#extension GL_OES_standard_derivatives : enable\n"
+ "precision mediump float;"
@@ -294,6 +328,6 @@ public class LineTexRenderer {
+ " float stipple_w = (1.0 - smoothstep(0.7 - fuzz, 0.7, tex_w));"
+ " float stipple_p = smoothstep(0.495, 0.505, len);"
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
- + "}";
+ + "}"; //*/
}
diff --git a/src/org/oscim/renderer/layer/Layers.java b/src/org/oscim/renderer/layer/Layers.java
index 4d2c1010..05499077 100644
--- a/src/org/oscim/renderer/layer/Layers.java
+++ b/src/org/oscim/renderer/layer/Layers.java
@@ -150,9 +150,17 @@ public class Layers {
lineOffset = size * SHORT_BYTES;
size += addLayerItems(sbuf, baseLayers, Layer.LINE, 0);
-
texLineOffset = size * SHORT_BYTES;
- size += addLayerItems(sbuf, baseLayers, Layer.TEXLINE, 0);
+ for (Layer l = baseLayers; l != null; l= l.next){
+ if (l.type == Layer.TEXLINE){
+ // HACK, see LineTexLayer
+ //sbuf.position(sbuf.position() + 6);
+ addPoolItems(l, sbuf);
+ //l.offset -= 12;
+ }
+ }
+
+ //size += addLayerItems(sbuf, baseLayers, Layer.TEXLINE, 0);
for (Layer l = textureLayers; l != null; l = l.next) {
TextureLayer tl = (TextureLayer) l;
@@ -172,18 +180,10 @@ public class Layers {
VertexPoolItem last = null, items = null;
int size = 0;
- // HACK, see LineTexLayer
- boolean addOffset = (type == Layer.TEXLINE);
-
for (; l != null; l = l.next) {
if (l.type != type)
continue;
- if (addOffset){
- sbuf.position(sbuf.position() + 6);
- addOffset = false;
- }
-
for (VertexPoolItem it = l.pool; it != null; it = it.next) {
if (it.next == null){
size += it.used;
@@ -199,6 +199,7 @@ public class Layers {
continue;
l.offset = pos;
+
pos += l.verticesCnt;
last.next = items;
diff --git a/src/org/oscim/renderer/layer/LineTexLayer.java b/src/org/oscim/renderer/layer/LineTexLayer.java
index 75cb50b9..4f2a2712 100644
--- a/src/org/oscim/renderer/layer/LineTexLayer.java
+++ b/src/org/oscim/renderer/layer/LineTexLayer.java
@@ -21,6 +21,8 @@ import org.oscim.theme.renderinstruction.Line;
/**
* Layer for textured or stippled lines
+ *
+ * this would be all so much simpler with geometry shaders...
*/
public final class LineTexLayer extends Layer {
// Interleave two segment quads in one block to be able to use
@@ -57,6 +59,11 @@ public final class LineTexLayer extends Layer {
// 2, 1, 3,
// 4, 5, 6,
// 6, 5, 7,
+ //
+ // BIG NOTE: renderer assumes to be able to offset vertex array position
+ // so that in the first pass 'pos1' offset will be < 0 if no data precedes
+ // - in our case there is always the polygon fill array at start
+ // - see addLine hack otherwise.
private static final float COORD_SCALE = GLRenderer.COORD_MULTIPLIER;
// scale factor mapping extrusion vector to short values
@@ -84,15 +91,11 @@ public final class LineTexLayer extends Layer {
if (pool == null) {
curItem = pool = VertexPool.get();
- // need to make sure there is one unused
- // vertex in front for interleaving.
- // HACK add this offset when compiling
- // otherwise one cant use the full
+ // HACK add one vertex offset when compiling
+ // buffer otherwise one cant use the full
// VertexItem
- //curItem.used = 6;
-
- verticesCnt = 1;
+ //verticesCnt = 1;
}
VertexPoolItem si = curItem;
@@ -207,14 +210,14 @@ public final class LineTexLayer extends Layer {
pos += length;
}
+ evenSegment = even;
+
// advance offset to last written position
if (!even)
opos += 12;
si.used = opos;
curItem = si;
-
- evenSegment = even;
}
@Override
diff --git a/src/org/oscim/renderer/overlays/TestOverlay.java b/src/org/oscim/renderer/overlays/TestOverlay.java
index 6eccd8de..a49c7cf8 100644
--- a/src/org/oscim/renderer/overlays/TestOverlay.java
+++ b/src/org/oscim/renderer/overlays/TestOverlay.java
@@ -18,8 +18,11 @@ import org.oscim.core.MapPosition;
import org.oscim.renderer.layer.Layer;
import org.oscim.renderer.layer.LineTexLayer;
import org.oscim.renderer.layer.TextItem;
+import org.oscim.theme.renderinstruction.Line;
import org.oscim.view.MapView;
+import android.graphics.Color;
+
public class TestOverlay extends BasicOverlay {
TextItem labels;
@@ -47,7 +50,8 @@ public class TestOverlay extends BasicOverlay {
LineTexLayer lt = (LineTexLayer) layers.getLayer(2, Layer.TEXLINE);
- lt.width = 4;
+ lt.line = new Line(Color.BLUE, 1.0f, 8);
+ lt.width = 8;
lt.addLine(points, null);
float[] points2 = {
@@ -57,7 +61,9 @@ public class TestOverlay extends BasicOverlay {
-200, 200,
-200, -200
};
-
+ lt = (LineTexLayer) layers.getLayer(3, Layer.TEXLINE);
+ lt.line = new Line(Color.BLUE, 1.0f, 16);
+ lt.width = 8;
lt.addLine(points2, null);
//
diff --git a/src/org/oscim/theme/renderinstruction/Line.java b/src/org/oscim/theme/renderinstruction/Line.java
index 255fa80f..e01ea060 100644
--- a/src/org/oscim/theme/renderinstruction/Line.java
+++ b/src/org/oscim/theme/renderinstruction/Line.java
@@ -47,24 +47,40 @@ public final class Line extends RenderInstruction {
*/
public static Line create(Line line, String elementName, Attributes attributes,
int level, boolean isOutline) {
- String src = null;
- int stroke = Color.BLACK;
- float strokeWidth = 0;
- int stipple = 0;
- Cap strokeLinecap = Cap.ROUND;
+
+ // Style name
+ String style = null;
+ // Bitmap
+ //String src = null;
+
+ float width = 0;
+ Cap cap = Cap.ROUND;
+
+ // Extras
int fade = -1;
boolean fixed = false;
- String style = null;
float blur = 0;
float min = 0;
+ // Stipple
+ int stipple = 0;
+ float stippleWidth = 0;
+
+ float[] color = null;
+ float[] stippleColor = null;
+
if (line != null) {
+ color = line.color;
fixed = line.fixed;
fade = line.fade;
- strokeLinecap = line.cap;
+ cap = line.cap;
blur = line.blur;
min = line.min;
+ stipple = line.stipple;
+ stippleColor = line.stippleColor;
+ stippleWidth = line.stippleWidth;
}
+
for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
@@ -72,21 +88,27 @@ public final class Line extends RenderInstruction {
if ("name".equals(name))
style = value;
else if ("src".equals(name)) {
- src = value;
+ //src = value;
} else if ("stroke".equals(name)) {
- stroke = Color.parseColor(value);
+ int stroke = Color.parseColor(value);
+ color = GlUtils.colorToFloatP(stroke);
} else if ("width".equals(name)) {
- strokeWidth = Float.parseFloat(value);
+ width = Float.parseFloat(value);
+ } else if ("cap".equals(name)) {
+ cap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH));
+ } else if ("fixed".equals(name)) {
+ fixed = Boolean.parseBoolean(value);
} else if ("stipple".equals(name)) {
stipple = Integer.parseInt(value);
- } else if ("cap".equals(name)) {
- strokeLinecap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH));
+ } else if ("stipple-stroke".equals(name)) {
+ int stroke = Color.parseColor(value);
+ stippleColor = GlUtils.colorToFloatP(stroke);
+ } else if ("stipple-width".equals(name)) {
+ stippleWidth = Float.parseFloat(value);
} else if ("fade".equals(name)) {
fade = Integer.parseInt(value);
} else if ("min".equals(name)) {
min = Float.parseFloat(value);
- } else if ("fixed".equals(name)) {
- fixed = Boolean.parseBoolean(value);
} else if ("blur".equals(name)) {
blur = Float.parseFloat(value);
} else if ("from".equals(name)) {
@@ -95,38 +117,27 @@ public final class Line extends RenderInstruction {
}
}
- if (stipple != 0)
- strokeLinecap = Cap.BUTT;
+ // hint that sth is missing
+ if (color == null)
+ color = GlUtils.colorToFloatP(Color.RED);
+ if (stipple != 0 && stippleColor == null)
+ stippleColor = GlUtils.colorToFloatP(Color.GREEN);
+
+ // inherit properties from 'line'
if (line != null) {
+ // use stroke width relative to 'line'
+ width = line.width + width;
+ if (width <= 0)
+ width = 1;
- strokeWidth = line.width + strokeWidth;
- if (strokeWidth <= 0)
- strokeWidth = 1;
-
- return new Line(line, style, src, stroke, strokeWidth, stipple,
- strokeLinecap, level, fixed, fade, blur, isOutline, min);
+ } else if (!isOutline) {
+ validate(width);
}
- if (!isOutline)
- validate(strokeWidth);
-
- return new Line(style, src, stroke, strokeWidth, stipple, strokeLinecap,
- level, fixed, fade, blur, isOutline, min);
- }
-
- public Line(int stroke, float width, Cap cap) {
- this.level = 0;
- this.blur = 0;
- this.cap = cap;
- this.outline = false;
- this.style = "";
- this.width = width;
- this.fixed = true;
- this.fade = -1;
- this.stipple = 2;
- this.min = 0;
- color = GlUtils.colorToFloatP(stroke);
+ return new Line(level, style, color, width, cap, fixed,
+ stipple, stippleColor, stippleWidth,
+ fade, blur, isOutline, min);
}
private static void validate(float strokeWidth) {
@@ -147,59 +158,28 @@ public final class Line extends RenderInstruction {
private final int level;
- public final float width;
-
- // public final boolean round;
-
- public final float color[];
-
- public final boolean outline;
-
- public final boolean fixed;
-
- public final int fade;
-
public final String style;
-
+ public final float width;
+ public final float[] color;
public final Cap cap;
-
+ public final boolean outline;
+ public final boolean fixed;
+ public final int fade;
public final float blur;
-
- public final int stipple;
-
public final float min;
- /**
- * @param style
- * ...
- * @param src
- * ...
- * @param stroke
- * ...
- * @param strokeWidth
- * ...
- * @param stipple
- * ...
- * @param strokeLinecap
- * ...
- * @param level
- * ...
- * @param fixed
- * ...
- * @param fade
- * ...
- * @param blur
- * ...
- * @param isOutline
- * ...
- * @param min ...
- */
- private Line(String style, String src, int stroke, float strokeWidth,
- int stipple, Cap strokeLinecap, int level, boolean fixed,
- int fade, float blur, boolean isOutline, float min) {
- super();
+ public final int stipple;
+ public final float[] stippleColor;
+ public final float stippleWidth;
+ private Line(int level, String style, float[] stroke, float width,
+ Cap cap, boolean fixed,
+ int stipple, float[] stippleColor, float stippleWidth,
+ int fade, float blur, boolean isOutline, float min) {
+
+ this.level = level;
this.style = style;
+ this.outline = isOutline;
// paint = new Paint(Paint.ANTI_ALIAS_FLAG);
//
@@ -213,51 +193,55 @@ public final class Line extends RenderInstruction {
// if (strokeDasharray != null) {
// paint.setPathEffect(new DashPathEffect(strokeDasharray, 0));
// }
- // paint.setStrokeCap(strokeLinecap);
- // round = (strokeLinecap == Cap.ROUND);
-
- this.cap = strokeLinecap;
-
- color = GlUtils.colorToFloatP(stroke);
-
- this.width = strokeWidth;
- this.level = level;
- this.outline = isOutline;
+ this.cap = cap;
+ this.color = stroke;
+ this.width = width;
this.fixed = fixed;
+
+ this.stipple = stipple;
+ this.stippleColor = stippleColor;
+ this.stippleWidth = stippleWidth;
+
this.blur = blur;
this.fade = fade;
- this.stipple = stipple;
this.min = min;
}
+ public Line(int stroke, float width, Cap cap) {
+ this.level = 0;
+ this.blur = 0;
+ this.cap = cap;
+ this.outline = false;
+ this.style = "";
+ this.width = width;
+ this.fixed = true;
+ this.fade = -1;
+ this.stipple = 0;
+ this.stippleColor = null;
+ this.stippleWidth = 0;
+ this.min = 0;
+ this.color = GlUtils.colorToFloatP(stroke);
+ }
- private Line(Line line, String style, String src, int stroke, float strokeWidth,
- int stipple, Cap strokeLinecap, int level, boolean fixed,
- int fade, float blur, boolean isOutline, float min) {
- super();
-
- this.style = style;
-
- // round = (strokeLinecap == Cap.ROUND);
-
- color = line.color;
-
- this.width = strokeWidth;
- this.level = level;
- this.outline = isOutline;
- this.fixed = fixed;
- this.fade = fade;
- this.cap = strokeLinecap;
- this.blur = blur;
+ public Line(int stroke, float width, int stipple) {
+ this.level = 0;
+ this.blur = 0;
+ this.cap = Cap.BUTT;
+ this.outline = false;
+ this.style = "";
+ this.width = width;
+ this.fixed = true;
+ this.fade = -1;
this.stipple = stipple;
- this.min = min;
+ this.stippleColor = null;
+ this.stippleWidth = 0;
+ this.min = 0;
+ color = GlUtils.colorToFloatP(stroke);
}
@Override
public void renderWay(IRenderCallback renderCallback, Tag[] tags) {
- // renderCallback.renderWay(mPaint, mLevel, mColor, mStrokeWidth,
- // mRound, mOutline);
renderCallback.renderWay(this, level);
}
@@ -266,7 +250,5 @@ public final class Line extends RenderInstruction {
// paint.setStrokeWidth(strokeWidth * scaleFactor);
// }
- public int getLevel() {
- return this.level;
- }
+
}
diff --git a/src/org/oscim/theme/styles/default.xml b/src/org/oscim/theme/styles/default.xml
index 0bf7e040..c0f0f45f 100644
--- a/src/org/oscim/theme/styles/default.xml
+++ b/src/org/oscim/theme/styles/default.xml
@@ -56,7 +56,12 @@
-
+
+
+
+
+
@@ -377,10 +382,22 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -604,10 +621,22 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -704,10 +733,18 @@
-
+
-
+
+
+
+
+
+
+
+
+
@@ -882,7 +919,8 @@
-
+