LineTexBucket: fix out of short range (#532)

This commit is contained in:
Gustl22 2018-04-26 16:01:59 +02:00 committed by Emux
parent ccfbb359a4
commit 77cfad50e0
No known key found for this signature in database
GPG Key ID: 64ED9980896038C3
2 changed files with 63 additions and 36 deletions

View File

@ -5,11 +5,11 @@ uniform mat4 u_mvp;
uniform vec4 u_color; uniform vec4 u_color;
uniform float u_pscale; uniform float u_pscale;
uniform float u_width; uniform float u_width;
attribute vec4 a_pos0; attribute vec4 a_pos0; // x:posX, y:posY, z:extrusX, w:extrusY
attribute vec4 a_pos1; attribute vec4 a_pos1;
attribute vec2 a_len0; attribute vec2 a_len0; // x:lineLength, y:unused
attribute vec2 a_len1; attribute vec2 a_len1;
attribute float a_flip; attribute float a_flip; // flip state
varying vec2 v_st; varying vec2 v_st;
void void
main(){ main(){
@ -44,15 +44,20 @@ uniform float u_mode;
void void
main(){ main(){
if (u_mode >= 1.0) { if (u_mode >= 1.0) {
/* Dash array or texture */
float step = 2.0; float step = 2.0;
if (u_mode == 2.0) { // dashed texture if (u_mode == 2.0) { // dashed texture
step = 1.0; step = 1.0;
} }
vec4 c = texture2D(tex, vec2(abs(mod(v_st.s + 1.0, step)), (v_st.t + 1.0) * 0.5)); // use lineLength mod texture step (mod is always positive)
// add 1.0 to avoid static line textures while zooming
vec4 c = texture2D(tex, vec2(mod(v_st.s + 1.0, step), (v_st.t + 1.0) * 0.5));
float fuzz = fwidth(c.a); float fuzz = fwidth(c.a);
gl_FragColor = (c * u_color) * smoothstep(0.5 - fuzz, 0.5 + fuzz, c.a); gl_FragColor = (c * u_color) * smoothstep(0.5 - fuzz, 0.5 + fuzz, c.a);
} }
else { else {
/* No dash array or texture */
/* distance on perpendicular to the line */ /* distance on perpendicular to the line */
float dist = abs(v_st.t); float dist = abs(v_st.t);
float fuzz = fwidth(v_st.t); float fuzz = fwidth(v_st.t);

View File

@ -2,6 +2,7 @@
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2016-2018 devemux86 * Copyright 2016-2018 devemux86
* Copyright 2017 Longri * Copyright 2017 Longri
* Copyright 2018 Gustl22
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@ -146,7 +147,7 @@ public final class LineTexBucket extends LineBucket {
float x = points[pos++] * COORD_SCALE; float x = points[pos++] * COORD_SCALE;
float y = points[pos++] * COORD_SCALE; float y = points[pos++] * COORD_SCALE;
/* randomize a bit */ /* randomize a bit (must be within range of +/- Short.MAX_VALUE) */
float lineLength = line.randomOffset ? (x * x + y * y) % 80 : 0; float lineLength = line.randomOffset ? (x * x + y * y) % 80 : 0;
while (pos < end) { while (pos < end) {
@ -158,40 +159,35 @@ public final class LineTexBucket extends LineBucket {
float vy = ny - y; float vy = ny - y;
// /* normalize vector */ // /* normalize vector */
double a = Math.sqrt(vx * vx + vy * vy); double dist = Math.sqrt(vx * vx + vy * vy);
// vx /= a; // vx /= dist;
// vy /= a; // vy /= dist;
/* normalized perpendicular to line segment */ /* normalized perpendicular to line segment */
short dx = (short) ((-vy / a) * DIR_SCALE); short dx = (short) ((-vy / dist) * DIR_SCALE);
short dy = (short) ((vx / a) * DIR_SCALE); short dy = (short) ((vx / dist) * DIR_SCALE);
vi.add((short) x, (short) y, dx, dy, (short) lineLength, (short) 0); if (lineLength + dist > Short.MAX_VALUE)
lineLength = Short.MIN_VALUE; // reset lineLength (would cause minimal shift)
lineLength += a;
vi.seek(6);
vi.add((short) nx, (short) ny, dx, dy, (short) lineLength, (short) 0);
if (dist > (Short.MAX_VALUE - Short.MIN_VALUE)) {
// In rare cases sloping lines are larger than max range of short:
// sqrt(x² + y²) > short range. So need to split them in 2 parts.
// Alternatively can set max clip value to:
// (Short.MAX_VALUE / Math.sqrt(2)) / MapRenderer.COORD_SCALE
float ix = (x + (vx / 2));
float iy = (y + (vy / 2));
addShortVertex(vi, (short) x, (short) y, (short) ix, (short) iy,
dx, dy, (short) lineLength, (int) (dist / 2));
addShortVertex(vi, (short) ix, (short) iy, (short) nx, (short) ny,
dx, dy, (short) lineLength, (int) (dist / 2));
} else {
addShortVertex(vi, (short) x, (short) y, (short) nx, (short) ny,
dx, dy, (short) lineLength, (int) dist);
lineLength += dist;
}
x = nx; x = nx;
y = ny; y = ny;
if (evenSegment) {
/* go to second segment */
vi.seek(-12);
evenSegment = false;
/* vertex 0 and 2 were added */
numVertices += 3;
evenQuads++;
} else {
/* go to next block */
evenSegment = true;
/* vertex 1 and 3 were added */
numVertices += 1;
oddQuads++;
}
} }
} }
@ -200,6 +196,32 @@ public final class LineTexBucket extends LineBucket {
vi.seek(12); vi.seek(12);
} }
private void addShortVertex(VertexData vi, short x, short y, short nx, short ny,
short dx, short dy, short lineLength, int dist) {
vi.add(x, y, dx, dy, lineLength, (short) 0);
vi.seek(6);
vi.add(nx, ny, dx, dy, (short) (lineLength + dist), (short) 0);
if (evenSegment) {
/* go to second segment */
vi.seek(-12);
evenSegment = false;
/* vertex 0 and 2 were added */
numVertices += 3;
evenQuads++;
} else {
/* go to next block */
evenSegment = true;
/* vertex 1 and 3 were added */
numVertices += 1;
oddQuads++;
}
}
@Override @Override
protected void clear() { protected void clear() {
evenSegment = true; evenSegment = true;
@ -234,9 +256,9 @@ public final class LineTexBucket extends LineBucket {
uPatternWidth = getUniform("u_pwidth"); uPatternWidth = getUniform("u_pwidth");
uPatternScale = getUniform("u_pscale"); uPatternScale = getUniform("u_pscale");
aPos0 = getAttrib("a_pos0"); aPos0 = getAttrib("a_pos0"); // posX, posY, extrX, extrY
aPos1 = getAttrib("a_pos1"); aPos1 = getAttrib("a_pos1");
aLen0 = getAttrib("a_len0"); aLen0 = getAttrib("a_len0"); // line length, unused
aLen1 = getAttrib("a_len1"); aLen1 = getAttrib("a_len1");
aFlip = getAttrib("a_flip"); aFlip = getAttrib("a_flip");
} }