add 'min-size' option to line renderinstruction, when size is less no outline will be drawn

This commit is contained in:
Hannes Janetzek 2013-01-21 03:13:47 +01:00
parent 6a34e478f5
commit 235e001a82
3 changed files with 77 additions and 41 deletions

View File

@ -25,9 +25,6 @@ import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram; import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer; import static android.opengl.GLES20.glVertexAttribPointer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.generator.TileGenerator; import org.oscim.generator.TileGenerator;
import org.oscim.renderer.layer.Layer; import org.oscim.renderer.layer.Layer;
@ -84,6 +81,8 @@ public final class LineRenderer {
//hLineTexturePosition[i] = glGetAttribLocation(lineProgram[i], "a_st"); //hLineTexturePosition[i] = glGetAttribLocation(lineProgram[i], "a_st");
} }
// create lookup table as texture for 'length(0..1,0..1)'
// using mirrored wrap mode for 'length(-1..1,-1..1)'
byte[] pixel = new byte[128 * 128]; byte[] pixel = new byte[128 * 128];
for (int x = 0; x < 128; x++) { for (int x = 0; x < 128; x++) {
@ -94,32 +93,11 @@ public final class LineRenderer {
if (color > 255) if (color > 255)
color = 255; color = 255;
pixel[x + y * 128] = (byte) color; pixel[x + y * 128] = (byte) color;
//pixel[(127 - x) + (127 - y) * 128] = (byte) color;
} }
} }
int[] textureIds = new int[1]; mTexID = GlUtils.loadTexture(pixel, 128, 128, GLES20.GL_ALPHA,
GLES20.glGenTextures(1, textureIds, 0); GLES20.GL_MIRRORED_REPEAT, GLES20.GL_MIRRORED_REPEAT);
mTexID = textureIds[0];
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexID);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_MIRRORED_REPEAT); // Set U Wrapping
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_MIRRORED_REPEAT); // Set V Wrapping
ByteBuffer buf = ByteBuffer.allocateDirect(128 * 128).order(ByteOrder.nativeOrder());
buf.put(pixel);
buf.position(0);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_ALPHA, 128, 128, 0, GLES20.GL_ALPHA,
GLES20.GL_UNSIGNED_BYTE, buf);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
return true; return true;
} }
@ -158,9 +136,16 @@ public final class LineRenderer {
glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0); glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
// line scale factor for non fixed lines: within a zoom-
// level lines would be scaled by the factor 2 via projection.
// though lines should only scale by sqrt(2). this is achieved
// by inverting scaling of extrusion vector with: width/sqrt(s).
// within one zoom-level: 1 <= s <= 2
float s = scale / div;
float lineScale = (float) Math.sqrt(s * 2 / 2.2);
// scale factor to map one pixel on tile to one pixel on screen: // scale factor to map one pixel on tile to one pixel on screen:
// only works with orthographic projection // only works with orthographic projection
float s = scale / div;
float pixel = 0; float pixel = 0;
if (mode == 1) if (mode == 1)
@ -170,8 +155,6 @@ public final class LineRenderer {
int lineMode = 0; int lineMode = 0;
glUniform1i(uLineMode, lineMode); glUniform1i(uLineMode, lineMode);
// line scale factor (for non fixed lines)
float lineScale = (float) Math.sqrt(s);
float blurScale = pixel; float blurScale = pixel;
boolean blur = false; boolean blur = false;
// dont increase scale when max is reached // dont increase scale when max is reached
@ -199,13 +182,17 @@ public final class LineRenderer {
} }
if (line.outline) { if (line.outline) {
// draw outline for linelayers references by this outline // draw linelayers references by this outline
for (LineLayer o = ll.outlines; o != null; o = o.outlines) { for (LineLayer o = ll.outlines; o != null; o = o.outlines) {
if (o.line.fixed || strokeMaxZoom) { if (o.line.fixed || strokeMaxZoom) {
width = (ll.width + o.width) / s; width = (ll.width + o.width) / s;
} else { } else {
width = ll.width / s + o.width / lineScale; width = ll.width / s + o.width / lineScale;
// check min size for outline
if (o.line.min > 0 && o.width * lineScale < o.line.min * 2)
continue;
} }
glUniform1f(uLineWidth, width); glUniform1f(uLineWidth, width);
@ -228,7 +215,6 @@ public final class LineRenderer {
lineMode = 0; lineMode = 0;
glUniform1i(uLineMode, lineMode); glUniform1i(uLineMode, lineMode);
} }
glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt); glDrawArrays(GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
} }
} else { } else {
@ -239,6 +225,9 @@ public final class LineRenderer {
width = ll.width / s; width = ll.width / s;
} else { } else {
width = ll.width / lineScale; width = ll.width / lineScale;
if (ll.line.min > 0 && ll.width * lineScale < ll.line.min * 2)
width = (ll.width - 0.2f) / lineScale;
} }
glUniform1f(uLineWidth, width); glUniform1f(uLineWidth, width);

View File

@ -56,14 +56,15 @@ public final class Line extends RenderInstruction {
boolean fixed = false; boolean fixed = false;
String style = null; String style = null;
float blur = 0; float blur = 0;
float min = 0;
if (line != null) { if (line != null) {
fixed = line.fixed; fixed = line.fixed;
fade = line.fade; fade = line.fade;
strokeLinecap = line.cap; strokeLinecap = line.cap;
blur = line.blur; blur = line.blur;
min = line.min;
} }
for (int i = 0; i < attributes.getLength(); ++i) { for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
String value = attributes.getValue(i); String value = attributes.getValue(i);
@ -82,6 +83,8 @@ public final class Line extends RenderInstruction {
strokeLinecap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH)); strokeLinecap = Cap.valueOf(value.toUpperCase(Locale.ENGLISH));
} else if ("fade".equals(name)) { } else if ("fade".equals(name)) {
fade = Integer.parseInt(value); fade = Integer.parseInt(value);
} else if ("min".equals(name)) {
min = Float.parseFloat(value);
} else if ("fixed".equals(name)) { } else if ("fixed".equals(name)) {
fixed = Boolean.parseBoolean(value); fixed = Boolean.parseBoolean(value);
} else if ("blur".equals(name)) { } else if ("blur".equals(name)) {
@ -102,14 +105,14 @@ public final class Line extends RenderInstruction {
strokeWidth = 1; strokeWidth = 1;
return new Line(line, style, src, stroke, strokeWidth, stipple, return new Line(line, style, src, stroke, strokeWidth, stipple,
strokeLinecap, level, fixed, fade, blur, isOutline); strokeLinecap, level, fixed, fade, blur, isOutline, min);
} }
if (!isOutline) if (!isOutline)
validate(strokeWidth); validate(strokeWidth);
return new Line(style, src, stroke, strokeWidth, stipple, strokeLinecap, return new Line(style, src, stroke, strokeWidth, stipple, strokeLinecap,
level, fixed, fade, blur, isOutline); level, fixed, fade, blur, isOutline, min);
} }
public Line(int stroke, float width, Cap cap) { public Line(int stroke, float width, Cap cap) {
@ -122,6 +125,7 @@ public final class Line extends RenderInstruction {
this.fixed = true; this.fixed = true;
this.fade = -1; this.fade = -1;
this.stipple = 2; this.stipple = 2;
this.min = 0;
color = GlUtils.colorToFloatP(stroke); color = GlUtils.colorToFloatP(stroke);
} }
@ -163,6 +167,8 @@ public final class Line extends RenderInstruction {
public final int stipple; public final int stipple;
public final float min;
/** /**
* @param style * @param style
* ... * ...
@ -186,10 +192,11 @@ public final class Line extends RenderInstruction {
* ... * ...
* @param isOutline * @param isOutline
* ... * ...
* @param min ...
*/ */
private Line(String style, String src, int stroke, float strokeWidth, private Line(String style, String src, int stroke, float strokeWidth,
int stipple, Cap strokeLinecap, int level, boolean fixed, int stipple, Cap strokeLinecap, int level, boolean fixed,
int fade, float blur, boolean isOutline) { int fade, float blur, boolean isOutline, float min) {
super(); super();
this.style = style; this.style = style;
@ -221,6 +228,7 @@ public final class Line extends RenderInstruction {
this.blur = blur; this.blur = blur;
this.fade = fade; this.fade = fade;
this.stipple = stipple; this.stipple = stipple;
this.min = min;
} }
/** /**
@ -248,10 +256,11 @@ public final class Line extends RenderInstruction {
* ... * ...
* @param isOutline * @param isOutline
* ... * ...
* @param min ...
*/ */
private Line(Line line, String style, String src, int stroke, float strokeWidth, private Line(Line line, String style, String src, int stroke, float strokeWidth,
int stipple, Cap strokeLinecap, int level, boolean fixed, int stipple, Cap strokeLinecap, int level, boolean fixed,
int fade, float blur, boolean isOutline) { int fade, float blur, boolean isOutline, float min) {
super(); super();
this.style = style; this.style = style;
@ -268,6 +277,7 @@ public final class Line extends RenderInstruction {
this.cap = strokeLinecap; this.cap = strokeLinecap;
this.blur = blur; this.blur = blur;
this.stipple = stipple; this.stipple = stipple;
this.min = min;
} }
@Override @Override

View File

@ -14,6 +14,9 @@
*/ */
package org.oscim.utils; package org.oscim.utils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.oscim.renderer.GLRenderer; import org.oscim.renderer.GLRenderer;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -38,20 +41,23 @@ public class GlUtils {
GLES20.glGenTextures(1, textures, 0); GLES20.glGenTextures(1, textures, 0);
int textureID = textures[0]; int textureID = textures[0];
// Log.i(TAG, "new texture " + textureID + " " + textureCnt++);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR); GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR); GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE); GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE); GLES20.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
@ -59,6 +65,37 @@ public class GlUtils {
return textureID; return textureID;
} }
public static int loadTexture(byte[] pixel, int width, int height, int format,
int wrap_s, int wrap_t) {
int[] textureIds = new int[1];
GLES20.glGenTextures(1, textureIds, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureIds[0]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S,
wrap_s); // Set U Wrapping
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T,
wrap_t); // Set V Wrapping
ByteBuffer buf = ByteBuffer.allocateDirect(width * height).order(ByteOrder.nativeOrder());
buf.put(pixel);
buf.position(0);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, format, width, height, 0, format,
GLES20.GL_UNSIGNED_BYTE, buf);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
return textureIds[0];
}
/** /**
* @param shaderType * @param shaderType
* shader type * shader type