add heightOffset for Line- and MeshLayer

This commit is contained in:
Hannes Janetzek 2014-02-12 02:08:19 +01:00
parent 27153c8093
commit 8d350238cf
5 changed files with 50 additions and 14 deletions

@ -1 +1 @@
Subproject commit d613072705824f130b1223ca82af2ae148835f41 Subproject commit 329c626e1ab0799019ac06f694227deac5f4702b

View File

@ -117,7 +117,7 @@ public class MapScaleBar extends Layer implements UpdateListener {
mPrevLatitude = latitude; mPrevLatitude = latitude;
double groundResolution = MercatorProjection double groundResolution = MercatorProjection
.calculateGroundResolution(latitude, mapPosition.scale); .groundResolution(latitude, mapPosition.scale);
int[] scaleBarValues; int[] scaleBarValues;
if (mImperialUnits) { if (mImperialUnits) {

View File

@ -57,11 +57,18 @@ public final class MercatorProjection {
* the map scale at which the resolution should be calculated. * the map scale at which the resolution should be calculated.
* @return the ground resolution at the given latitude and zoom level. * @return the ground resolution at the given latitude and zoom level.
*/ */
public static double calculateGroundResolution(double latitude, double scale) { public static double groundResolution(double latitude, double scale) {
return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE return Math.cos(latitude * (Math.PI / 180)) * EARTH_CIRCUMFERENCE
/ (Tile.SIZE * scale); / (Tile.SIZE * scale);
} }
public static float groundResolution(MapPosition pos) {
double lat = MercatorProjection.toLatitude(pos.y);
return (float) (Math.cos(lat * (Math.PI / 180))
* MercatorProjection.EARTH_CIRCUMFERENCE
/ (Tile.SIZE * pos.scale));
}
/** /**
* Projects a longitude coordinate (in degrees) to the range [0.0,1.0] * Projects a longitude coordinate (in degrees) to the range [0.0,1.0]
* *

View File

@ -21,6 +21,7 @@ import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap; import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
@ -57,7 +58,9 @@ public final class LineLayer extends RenderElement {
public float width; public float width;
public boolean roundCap; public boolean roundCap;
private float mMinDist = 1 / 4f; private float mMinDist = 1 / 8f;
public float heightOffset;
LineLayer(int layer) { LineLayer(int layer) {
super(RenderElement.LINE); super(RenderElement.LINE);
@ -77,7 +80,7 @@ public final class LineLayer extends RenderElement {
* For point reduction by minimal distance. Default is 1/4. * For point reduction by minimal distance. Default is 1/4.
*/ */
public void setDropDistance(float minDist) { public void setDropDistance(float minDist) {
mMinDist = minDist < 1 / 4f ? 1 / 4f : minDist; mMinDist = minDist < 1 / 8f ? 1 / 8f : minDist;
} }
public void addLine(GeometryBuffer geom) { public void addLine(GeometryBuffer geom) {
@ -116,10 +119,8 @@ public final class LineLayer extends RenderElement {
short v[] = si.vertices; short v[] = si.vertices;
int opos = si.used; int opos = si.used;
/* /* Note: just a hack to save some vertices, when there are
* Note: just a hack to save some vertices, when there are * more than 200 lines per type. FIXME make optional! */
* more than 200 lines per type. FIXME make optional!
*/
if (rounded && index != null) { if (rounded && index != null) {
int cnt = 0; int cnt = 0;
for (int i = 0, n = index.length; i < n; i++, cnt++) { for (int i = 0, n = index.length; i < n; i++, cnt++) {
@ -589,6 +590,7 @@ public final class LineLayer extends RenderElement {
private static int[] hLineFade = new int[2]; private static int[] hLineFade = new int[2];
private static int[] hLineWidth = new int[2]; private static int[] hLineWidth = new int[2];
private static int[] hLineMode = new int[2]; private static int[] hLineMode = new int[2];
private static int[] hLineHeight = new int[2];
public static int mTexID; public static int mTexID;
static boolean init() { static boolean init() {
@ -616,6 +618,7 @@ public final class LineLayer extends RenderElement {
hLineWidth[i] = GL.glGetUniformLocation(lineProgram[i], "u_width"); hLineWidth[i] = GL.glGetUniformLocation(lineProgram[i], "u_width");
hLineColor[i] = GL.glGetUniformLocation(lineProgram[i], "u_color"); hLineColor[i] = GL.glGetUniformLocation(lineProgram[i], "u_color");
hLineMode[i] = GL.glGetUniformLocation(lineProgram[i], "u_mode"); hLineMode[i] = GL.glGetUniformLocation(lineProgram[i], "u_mode");
hLineHeight[i] = GL.glGetUniformLocation(lineProgram[i], "u_height");
hLineVertexPosition[i] = GL.glGetAttribLocation(lineProgram[i], "a_pos"); hLineVertexPosition[i] = GL.glGetAttribLocation(lineProgram[i], "a_pos");
} }
@ -665,6 +668,7 @@ public final class LineLayer extends RenderElement {
int uLineMode = hLineMode[mode]; int uLineMode = hLineMode[mode];
int uLineColor = hLineColor[mode]; int uLineColor = hLineColor[mode];
int uLineWidth = hLineWidth[mode]; int uLineWidth = hLineWidth[mode];
int uLineHeight = hLineHeight[mode];
GLState.enableVertexArrays(hLineVertexPosition[mode], -1); GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
@ -681,7 +685,7 @@ public final class LineLayer extends RenderElement {
// 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:
// used with orthographic projection, (shader mode == 1) // used with orthographic projection, (shader mode == 1)
double pixel = (mode == SHADER_PROJ) ? 0 : 1.5 / scale; double pixel = (mode == SHADER_PROJ) ? 0.0001 : 1.5 / scale;
GL.glUniform1f(uLineFade, (float) pixel); GL.glUniform1f(uLineFade, (float) pixel);
@ -691,11 +695,21 @@ public final class LineLayer extends RenderElement {
boolean blur = false; boolean blur = false;
double width; double width;
float heightOffset = 0;
GL.glUniform1f(uLineHeight, heightOffset);
RenderElement l = curLayer; RenderElement l = curLayer;
for (; l != null && l.type == RenderElement.LINE; l = l.next) { for (; l != null && l.type == RenderElement.LINE; l = l.next) {
LineLayer ll = (LineLayer) l; LineLayer ll = (LineLayer) l;
Line line = ll.line; Line line = ll.line;
if (ll.heightOffset != heightOffset) {
heightOffset = ll.heightOffset;
GL.glUniform1f(uLineHeight, heightOffset /
MercatorProjection.groundResolution(pos));
}
if (line.fade < pos.zoomLevel) { if (line.fade < pos.zoomLevel) {
GLUtils.setColor(uLineColor, line.color, 1); GLUtils.setColor(uLineColor, line.color, 1);
} else if (line.fade > pos.zoomLevel) { } else if (line.fade > pos.zoomLevel) {
@ -706,7 +720,7 @@ public final class LineLayer extends RenderElement {
} }
if (mode == SHADER_PROJ && blur && line.blur == 0) { if (mode == SHADER_PROJ && blur && line.blur == 0) {
GL.glUniform1f(uLineFade, 0); GL.glUniform1f(uLineFade, (float) pixel);
blur = false; blur = false;
} }
@ -797,13 +811,14 @@ public final class LineLayer extends RenderElement {
// xy hold position, zw extrusion vector // xy hold position, zw extrusion vector
+ "attribute vec4 a_pos;" + "attribute vec4 a_pos;"
+ "uniform float u_mode;" + "uniform float u_mode;"
+ "uniform float u_height;"
+ "varying vec2 v_st;" + "varying vec2 v_st;"
+ "void main() {" + "void main() {"
// scale extrusion to u_width pixel // scale extrusion to u_width pixel
// just ignore the two most insignificant bits. // just ignore the two most insignificant bits.
+ " vec2 dir = a_pos.zw;" + " vec2 dir = a_pos.zw;"
+ " gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), 0.0, 1.0);" + " gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), u_height, 1.0);"
// last two bits hold the texture coordinates. // last two bits hold the texture coordinates.
+ " v_st = abs(mod(dir, 4.0)) - 1.0;" + " v_st = abs(mod(dir, 4.0)) - 1.0;"

View File

@ -22,6 +22,7 @@ import org.oscim.backend.GL20;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
@ -42,6 +43,7 @@ public class MeshLayer extends RenderElement {
VertexItem indiceItems; VertexItem indiceItems;
public Area area; public Area area;
public float heightOffset;
public MeshLayer(int level) { public MeshLayer(int level) {
super(RenderElement.MESH); super(RenderElement.MESH);
@ -106,6 +108,7 @@ public class MeshLayer extends RenderElement {
private static int shaderProgram; private static int shaderProgram;
private static int hMatrix; private static int hMatrix;
private static int hColor; private static int hColor;
private static int hHeightOffset;
private static int hVertexPosition; private static int hVertexPosition;
static boolean init() { static boolean init() {
@ -115,6 +118,7 @@ public class MeshLayer extends RenderElement {
hMatrix = GL.glGetUniformLocation(shaderProgram, "u_mvp"); hMatrix = GL.glGetUniformLocation(shaderProgram, "u_mvp");
hColor = GL.glGetUniformLocation(shaderProgram, "u_color"); hColor = GL.glGetUniformLocation(shaderProgram, "u_color");
hHeightOffset = GL.glGetUniformLocation(shaderProgram, "u_height");
hVertexPosition = GL.glGetAttribLocation(shaderProgram, "a_pos"); hVertexPosition = GL.glGetAttribLocation(shaderProgram, "a_pos");
return true; return true;
} }
@ -130,12 +134,21 @@ public class MeshLayer extends RenderElement {
m.mvp.setAsUniform(hMatrix); m.mvp.setAsUniform(hMatrix);
float heightOffset = 0;
for (; l != null && l.type == RenderElement.MESH; l = l.next) { for (; l != null && l.type == RenderElement.MESH; l = l.next) {
MeshLayer ml = (MeshLayer) l; MeshLayer ml = (MeshLayer) l;
if (ml.indicesVbo == null) if (ml.indicesVbo == null)
continue; continue;
if (ml.heightOffset != heightOffset) {
heightOffset = ml.heightOffset;
GL.glUniform1f(hHeightOffset, heightOffset /
MercatorProjection.groundResolution(pos));
}
ml.indicesVbo.bind(); ml.indicesVbo.bind();
if (ml.area == null) if (ml.area == null)
@ -164,9 +177,10 @@ public class MeshLayer extends RenderElement {
private final static String vertexShader = "" private final static String vertexShader = ""
+ "precision mediump float;" + "precision mediump float;"
+ "uniform mat4 u_mvp;" + "uniform mat4 u_mvp;"
+ "attribute vec4 a_pos;" + "uniform float u_height;"
+ "attribute vec2 a_pos;"
+ "void main() {" + "void main() {"
+ " gl_Position = u_mvp * a_pos;" + " gl_Position = u_mvp * vec4(a_pos, u_height, 1.0);"
+ "}"; + "}";
private final static String fragmentShader = "" private final static String fragmentShader = ""