Location renderer: allow external shaders, move existing to glsl files, closes #317

This commit is contained in:
Emux 2017-03-04 19:13:06 +02:00
parent d1ce52ef52
commit f061e06d94
6 changed files with 143 additions and 120 deletions

View File

@ -5,6 +5,7 @@
- Symbol rotation [#294](https://github.com/mapsforge/vtm/issues/294)
- Marker clustering [#312](https://github.com/mapsforge/vtm/issues/312)
- Osmagray theme [#300](https://github.com/mapsforge/vtm/issues/300)
- Location renderer custom shaders [#317](https://github.com/mapsforge/vtm/issues/317)
- OkHttp external cache [#135](https://github.com/mapsforge/vtm/issues/135)
- Texture atlas improvements [#301](https://github.com/mapsforge/vtm/pull/301) [#304](https://github.com/mapsforge/vtm/pull/304)
- Many other minor improvements and bug fixes

View File

@ -22,6 +22,7 @@ import android.os.Bundle;
import org.oscim.core.MapPosition;
import org.oscim.layers.LocationLayer;
import org.oscim.renderer.LocationRenderer;
public class LocationActivity extends SimpleMapActivity implements LocationListener {
private LocationLayer locationLayer;
@ -35,6 +36,7 @@ public class LocationActivity extends SimpleMapActivity implements LocationListe
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationLayer = new LocationLayer(mMap);
locationLayer.locationRenderer.setShader("location_1_reverse");
locationLayer.setEnabled(false);
mMap.layers().add(locationLayer);
}

View File

@ -0,0 +1,44 @@
#ifdef GLES
precision mediump float;
#endif
uniform mat4 u_mvp;
uniform float u_phase;
uniform float u_scale;
attribute vec2 a_pos;
varying vec2 v_tex;
void main() {
gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);
v_tex = a_pos;
}
$$
#ifdef GLES
precision mediump float;
#endif
varying vec2 v_tex;
uniform float u_scale;
uniform float u_phase;
uniform vec2 u_dir;
void main() {
float len = 1.0 - length(v_tex);
if (u_dir.x == 0.0 && u_dir.y == 0.0){
gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * len;
} else {
// outer ring
float a = smoothstep(0.0, 2.0 / u_scale, len);
// inner ring
float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len);
// center point
float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));
vec2 dir = normalize(v_tex);
float d = 1.0 - dot(dir, u_dir);
// 0.5 width of viewshed
d = clamp(step(0.5, d), 0.4, 0.7);
// - subtract inner from outer to create the outline
// - multiply by viewshed
// - add center point
a = d * (a - (b + c)) + c;
gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;
}
}

View File

@ -0,0 +1,44 @@
#ifdef GLES
precision mediump float;
#endif
uniform mat4 u_mvp;
uniform float u_phase;
uniform float u_scale;
attribute vec2 a_pos;
varying vec2 v_tex;
void main() {
gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);
v_tex = a_pos;
}
$$
#ifdef GLES
precision mediump float;
#endif
varying vec2 v_tex;
uniform float u_scale;
uniform float u_phase;
uniform vec2 u_dir;
void main() {
float len = 1.0 - length(v_tex);
if (u_dir.x == 0.0 && u_dir.y == 0.0){
gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * len;
} else {
// outer ring
float a = smoothstep(0.0, 2.0 / u_scale, len);
// inner ring
float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len);
// center point
float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));
vec2 dir = normalize(v_tex);
float d = dot(dir, u_dir);
// 0.5 width of viewshed
d = clamp(step(0.5, d), 0.4, 0.7);
// - subtract inner from outer to create the outline
// - multiply by viewshed
// - add center point
a = d * (a - (b + c)) + c;
gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;
}
}

View File

@ -0,0 +1,40 @@
#ifdef GLES
precision mediump float;
#endif
uniform mat4 u_mvp;
uniform float u_phase;
uniform float u_scale;
attribute vec2 a_pos;
varying vec2 v_tex;
void main() {
gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);
v_tex = a_pos;
}
$$
#ifdef GLES
precision mediump float;
#endif
varying vec2 v_tex;
uniform float u_scale;
uniform float u_phase;
uniform vec2 u_dir;
void main() {
float len = 1.0 - length(v_tex);
// outer ring
float a = smoothstep(0.0, 2.0 / u_scale, len);
// inner ring
float b = 0.8 * smoothstep(3.0 / u_scale, 4.0 / u_scale, len);
// center point
float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));
vec2 dir = normalize(v_tex);
float d = dot(dir, u_dir);
// 0.5 width of viewshed
d = clamp(smoothstep(0.7, 0.7 + 2.0/u_scale, d) * len, 0.0, 1.0);
// - subtract inner from outer to create the outline
// - multiply by viewshed
// - add center point
a = max(d, (a - (b + c)) + c);
gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;
}

View File

@ -1,7 +1,7 @@
/*
* Copyright 2013 Ahmad Saleem
* Copyright 2013 Hannes Janetzek
* Copyright 2016 devemux86
* Copyright 2016-2017 devemux86
* Copyright 2016 ocsike
* Copyright 2017 Mathieu De Brito
*
@ -37,11 +37,10 @@ public class LocationRenderer extends LayerRenderer {
private static final float CIRCLE_SIZE = 60;
private static final int SHOW_ACCURACY_ZOOM = 16;
public enum Shader {SHADER_1, SHADER_1_REVERSE, SHADER_2}
private final Map mMap;
private final Layer mLayer;
private String mShaderFile;
private int mShaderProgram;
private int hVertexPosition;
private int hMatrixPosition;
@ -64,7 +63,6 @@ public class LocationRenderer extends LayerRenderer {
private Callback mCallback;
private final Point mLocation = new Point(Double.NaN, Double.NaN);
private double mRadius;
private Shader mShader = Shader.SHADER_1;
private int mShowAccuracyZoom = SHOW_ACCURACY_ZOOM;
public LocationRenderer(Map map, Layer layer) {
@ -82,8 +80,8 @@ public class LocationRenderer extends LayerRenderer {
mRadius = radius;
}
public void setShader(Shader shader) {
mShader = shader;
public void setShader(String shaderFile) {
mShaderFile = shaderFile;
}
public void setShowAccuracyZoom(int showAccuracyZoom) {
@ -244,126 +242,20 @@ public class LocationRenderer extends LayerRenderer {
}
private boolean init() {
int shader = 0;
switch (mShader) {
case SHADER_1:
shader = GLShader.createProgram(vShaderStr, fShaderStr1);
break;
case SHADER_1_REVERSE:
shader = GLShader.createProgram(vShaderStr, fShaderStr1Reverse);
break;
case SHADER_2:
shader = GLShader.createProgram(vShaderStr, fShaderStr2);
break;
}
if (shader == 0)
int program = GLShader.loadShader(mShaderFile != null ? mShaderFile : "location_1");
if (program == 0)
return false;
mShaderProgram = shader;
hVertexPosition = gl.getAttribLocation(shader, "a_pos");
hMatrixPosition = gl.getUniformLocation(shader, "u_mvp");
hPhase = gl.getUniformLocation(shader, "u_phase");
hScale = gl.getUniformLocation(shader, "u_scale");
hDirection = gl.getUniformLocation(shader, "u_dir");
mShaderProgram = program;
hVertexPosition = gl.getAttribLocation(program, "a_pos");
hMatrixPosition = gl.getUniformLocation(program, "u_mvp");
hPhase = gl.getUniformLocation(program, "u_phase");
hScale = gl.getUniformLocation(program, "u_scale");
hDirection = gl.getUniformLocation(program, "u_dir");
return true;
}
private static final String vShaderStr = ""
+ "precision mediump float;"
+ "uniform mat4 u_mvp;"
+ "uniform float u_phase;"
+ "uniform float u_scale;"
+ "attribute vec2 a_pos;"
+ "varying vec2 v_tex;"
+ "void main() {"
+ " gl_Position = u_mvp * vec4(a_pos * u_scale * u_phase, 0.0, 1.0);"
+ " v_tex = a_pos;"
+ "}";
private static final String fShaderStr1 = ""
+ "precision mediump float;"
+ "varying vec2 v_tex;"
+ "uniform float u_scale;"
+ "uniform float u_phase;"
+ "uniform vec2 u_dir;"
+ "void main() {"
+ " float len = 1.0 - length(v_tex);"
+ " if (u_dir.x == 0.0 && u_dir.y == 0.0){"
+ " gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * len;"
+ " } else {"
/// outer ring
+ " float a = smoothstep(0.0, 2.0 / u_scale, len);"
/// inner ring
+ " float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len);"
/// center point
+ " float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));"
+ " vec2 dir = normalize(v_tex);"
+ " float d = 1.0 - dot(dir, u_dir); "
/// 0.5 width of viewshed
+ " d = clamp(step(0.5, d), 0.4, 0.7);"
/// - subtract inner from outer to create the outline
/// - multiply by viewshed
/// - add center point
+ " a = d * (a - (b + c)) + c;"
+ " gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;"
+ "}}";
private static final String fShaderStr1Reverse = ""
+ "precision mediump float;"
+ "varying vec2 v_tex;"
+ "uniform float u_scale;"
+ "uniform float u_phase;"
+ "uniform vec2 u_dir;"
+ "void main() {"
+ " float len = 1.0 - length(v_tex);"
+ " if (u_dir.x == 0.0 && u_dir.y == 0.0){"
+ " gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * len;"
+ " } else {"
/// outer ring
+ " float a = smoothstep(0.0, 2.0 / u_scale, len);"
/// inner ring
+ " float b = 0.5 * smoothstep(4.0 / u_scale, 5.0 / u_scale, len);"
/// center point
+ " float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));"
+ " vec2 dir = normalize(v_tex);"
+ " float d = dot(dir, u_dir); "
/// 0.5 width of viewshed
+ " d = clamp(step(0.5, d), 0.4, 0.7);"
/// - subtract inner from outer to create the outline
/// - multiply by viewshed
/// - add center point
+ " a = d * (a - (b + c)) + c;"
+ " gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;"
+ "}}";
private static final String fShaderStr2 = ""
+ "precision mediump float;"
+ "varying vec2 v_tex;"
+ "uniform float u_scale;"
+ "uniform float u_phase;"
+ "uniform vec2 u_dir;"
+ "void main() {"
+ " float len = 1.0 - length(v_tex);"
/// outer ring
+ " float a = smoothstep(0.0, 2.0 / u_scale, len);"
/// inner ring
+ " float b = 0.8 * smoothstep(3.0 / u_scale, 4.0 / u_scale, len);"
/// center point
+ " float c = 0.5 * (1.0 - smoothstep(14.0 / u_scale, 16.0 / u_scale, 1.0 - len));"
+ " vec2 dir = normalize(v_tex);"
+ " float d = dot(dir, u_dir); "
/// 0.5 width of viewshed
+ " d = clamp(smoothstep(0.7, 0.7 + 2.0/u_scale, d) * len, 0.0, 1.0);"
/// - subtract inner from outer to create the outline
/// - multiply by viewshed
/// - add center point
+ " a = max(d, (a - (b + c)) + c);"
+ " gl_FragColor = vec4(0.2, 0.2, 0.8, 1.0) * a;"
+ "}";
public interface Callback {
float getRotation();
}