From f061e06d94788584b94c243ffe692ee3a4806ab3 Mon Sep 17 00:00:00 2001 From: Emux Date: Sat, 4 Mar 2017 19:13:06 +0200 Subject: [PATCH] Location renderer: allow external shaders, move existing to glsl files, closes #317 --- docs/Changelog.md | 1 + .../oscim/android/test/LocationActivity.java | 2 + vtm/resources/assets/shaders/location_1.glsl | 44 ++++++ .../assets/shaders/location_1_reverse.glsl | 44 ++++++ vtm/resources/assets/shaders/location_2.glsl | 40 ++++++ .../org/oscim/renderer/LocationRenderer.java | 132 ++---------------- 6 files changed, 143 insertions(+), 120 deletions(-) create mode 100644 vtm/resources/assets/shaders/location_1.glsl create mode 100644 vtm/resources/assets/shaders/location_1_reverse.glsl create mode 100644 vtm/resources/assets/shaders/location_2.glsl diff --git a/docs/Changelog.md b/docs/Changelog.md index 153724b9..44189bb4 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -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 diff --git a/vtm-android-example/src/org/oscim/android/test/LocationActivity.java b/vtm-android-example/src/org/oscim/android/test/LocationActivity.java index 772e0567..7b600b31 100644 --- a/vtm-android-example/src/org/oscim/android/test/LocationActivity.java +++ b/vtm-android-example/src/org/oscim/android/test/LocationActivity.java @@ -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); } diff --git a/vtm/resources/assets/shaders/location_1.glsl b/vtm/resources/assets/shaders/location_1.glsl new file mode 100644 index 00000000..e6100681 --- /dev/null +++ b/vtm/resources/assets/shaders/location_1.glsl @@ -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; + } +} diff --git a/vtm/resources/assets/shaders/location_1_reverse.glsl b/vtm/resources/assets/shaders/location_1_reverse.glsl new file mode 100644 index 00000000..4b0c4678 --- /dev/null +++ b/vtm/resources/assets/shaders/location_1_reverse.glsl @@ -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; + } +} diff --git a/vtm/resources/assets/shaders/location_2.glsl b/vtm/resources/assets/shaders/location_2.glsl new file mode 100644 index 00000000..81688d5e --- /dev/null +++ b/vtm/resources/assets/shaders/location_2.glsl @@ -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; +} diff --git a/vtm/src/org/oscim/renderer/LocationRenderer.java b/vtm/src/org/oscim/renderer/LocationRenderer.java index 2e082335..fc68f77c 100644 --- a/vtm/src/org/oscim/renderer/LocationRenderer.java +++ b/vtm/src/org/oscim/renderer/LocationRenderer.java @@ -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(); }