From f962dddf50bd042d10a9575ba9f371162b033893 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Mon, 17 Jun 2013 02:15:02 +0200 Subject: [PATCH] pass zoom-level relative 'scale divider' to PolygonRenderer - use scale div for blending pattern textures --- .../layers/labeling/TextRenderLayer.java | 12 +--- src/org/oscim/layers/tile/TileRenderer.java | 6 +- .../renderer/layers/BasicRenderLayer.java | 2 +- .../renderer/layers/TextRenderLayer.java | 2 +- .../renderer/sublayers/PolygonRenderer.java | 64 ++++++++++++------- 5 files changed, 47 insertions(+), 39 deletions(-) diff --git a/src/org/oscim/layers/labeling/TextRenderLayer.java b/src/org/oscim/layers/labeling/TextRenderLayer.java index c9b3215a..bf101e17 100644 --- a/src/org/oscim/layers/labeling/TextRenderLayer.java +++ b/src/org/oscim/layers/labeling/TextRenderLayer.java @@ -114,13 +114,6 @@ public class TextRenderLayer extends BasicRenderLayer { } - - // class ActiveTile { - // MapTile tile; - // int activeLabels; - // Label labels; - // } - private float mSquareRadius; private int mRelabelCnt; private final TileRenderLayer mTileLayer; @@ -551,7 +544,6 @@ public class TextRenderLayer extends BasicRenderLayer { return true; } - @Override public synchronized void update(MapPosition pos, boolean changed, Matrices matrices) { @@ -612,7 +604,7 @@ public class TextRenderLayer extends BasicRenderLayer { } } - /*private */void cleanup() { + /* private */void cleanup() { mPool.releaseAll(mPrevLabels); mPrevLabels = null; mTileSet.clear(); @@ -660,7 +652,7 @@ public class TextRenderLayer extends BasicRenderLayer { for (Layer l = layers.baseLayers; l != null;) { if (l.type == Layer.POLYGON) { - l = PolygonRenderer.draw(pos, l, m, true, false); + l = PolygonRenderer.draw(pos, l, m, true, 1, false); } else { float div = scale * (float) (pos.scale / (1 << pos.zoomLevel)); l = LineRenderer.draw(layers, l, pos, m, div, 0); diff --git a/src/org/oscim/layers/tile/TileRenderer.java b/src/org/oscim/layers/tile/TileRenderer.java index 152465f3..617a6b4a 100644 --- a/src/org/oscim/layers/tile/TileRenderer.java +++ b/src/org/oscim/layers/tile/TileRenderer.java @@ -156,14 +156,14 @@ public class TileRenderer { for (Layer l = t.layers.baseLayers; l != null;) { switch (l.type) { case Layer.POLYGON: - l = PolygonRenderer.draw(pos, l, m, !clipped, true); + l = PolygonRenderer.draw(pos, l, m, !clipped, div, true); clipped = true; break; case Layer.LINE: if (!clipped) { // draw stencil buffer clip region - PolygonRenderer.draw(pos, null, m, true, true); + PolygonRenderer.draw(pos, null, m, true, div, true); clipped = true; } l = LineRenderer.draw(t.layers, l, pos, m, div, simpleShader); @@ -172,7 +172,7 @@ public class TileRenderer { case Layer.TEXLINE: if (!clipped) { // draw stencil buffer clip region - PolygonRenderer.draw(pos, null, m, true, true); + PolygonRenderer.draw(pos, null, m, true, div, true); clipped = true; } l = LineTexRenderer.draw(t.layers, l, pos, m, div); diff --git a/src/org/oscim/renderer/layers/BasicRenderLayer.java b/src/org/oscim/renderer/layers/BasicRenderLayer.java index d4fc940f..b8ee51c7 100644 --- a/src/org/oscim/renderer/layers/BasicRenderLayer.java +++ b/src/org/oscim/renderer/layers/BasicRenderLayer.java @@ -64,7 +64,7 @@ public abstract class BasicRenderLayer extends RenderLayer { for (Layer l = layers.baseLayers; l != null;) { switch (l.type) { case Layer.POLYGON: - l = PolygonRenderer.draw(curPos, l, m, true, false); + l = PolygonRenderer.draw(curPos, l, m, true, 1, false); break; case Layer.LINE: diff --git a/src/org/oscim/renderer/layers/TextRenderLayer.java b/src/org/oscim/renderer/layers/TextRenderLayer.java index 73ed67b9..bc6f64e0 100644 --- a/src/org/oscim/renderer/layers/TextRenderLayer.java +++ b/src/org/oscim/renderer/layers/TextRenderLayer.java @@ -744,7 +744,7 @@ public class TextRenderLayer extends BasicRenderLayer { for (Layer l = layers.baseLayers; l != null;) { if (l.type == Layer.POLYGON) { - l = PolygonRenderer.draw(pos, l, m, true, false); + l = PolygonRenderer.draw(pos, l, m, true, 1, false); } else { float div = scale * (float) (pos.scale / (1 << pos.zoomLevel)); l = LineRenderer.draw(layers, l, pos, m, div, 0); diff --git a/src/org/oscim/renderer/sublayers/PolygonRenderer.java b/src/org/oscim/renderer/sublayers/PolygonRenderer.java index 8a962cf2..8116515a 100644 --- a/src/org/oscim/renderer/sublayers/PolygonRenderer.java +++ b/src/org/oscim/renderer/sublayers/PolygonRenderer.java @@ -42,6 +42,7 @@ import org.oscim.renderer.GLRenderer.Matrices; import org.oscim.renderer.GLState; import org.oscim.theme.renderinstruction.Area; import org.oscim.theme.renderinstruction.BitmapUtils; +import org.oscim.utils.FastMath; import org.oscim.utils.GlUtils; import org.oscim.utils.Matrix4; @@ -49,6 +50,9 @@ import android.graphics.Bitmap; import android.opengl.GLES20; import android.opengl.GLUtils; +/** + * Special Renderer for drawing tile polygon layers + */ public final class PolygonRenderer { private static final String TAG = PolygonRenderer.class.getName(); @@ -69,6 +73,7 @@ public final class PolygonRenderer { private static int[] hPolygonVertexPosition = new int[numShaders]; private static int[] hPolygonMatrix = new int[numShaders]; private static int[] hPolygonColor = new int[numShaders]; + private static int[] hPolygonScale = new int[numShaders]; private static int mTexWater; private static int mTexWood; @@ -97,14 +102,16 @@ public final class PolygonRenderer { } hPolygonMatrix[i] = glGetUniformLocation(polygonProgram[i], "u_mvp"); hPolygonColor[i] = glGetUniformLocation(polygonProgram[i], "u_color"); + hPolygonScale[i] = glGetUniformLocation(polygonProgram[i], "u_scale"); + hPolygonVertexPosition[i] = glGetAttribLocation(polygonProgram[i], "a_pos"); } mFillPolys = new PolygonLayer[STENCIL_BITS]; - //mTexWood = loadSprite("jar:grass3.png"); - //mTexWater = loadSprite("jar:water2.png"); - //mTexGrass= loadSprite("jar:grass2.png"); + mTexWood = loadSprite("jar:grass3.png"); + mTexWater = loadSprite("jar:water2.png"); + mTexGrass = loadSprite("jar:grass2.png"); return true; } @@ -129,7 +136,7 @@ public final class PolygonRenderer { return textures[0]; } - private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale) { + private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale, float div) { /* draw to framebuffer */ glColorMask(true, true, true, true); @@ -141,17 +148,18 @@ public final class PolygonRenderer { for (int c = start; c < end; c++) { Area a = mFillPolys[c].area; - //if (a.color == 0xFFAFC5E3 || a.color == 0xffd1dbc7 || a.color == 0xffa3ca7b) { - // shader = texShader; - // setShader(texShader, m); - // if (a.color == 0xFFAFC5E3) - // GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWater); - // else if (a.color == 0xffd1dbc7) - // GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWood); - // else - // GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexGrass); - //} else - if (a.fade >= zoom) { + if (a.color == 0xFFAFC5E3 || a.color == 0xffd1dbc7 || a.color == 0xffa3ca7b) { + shader = texShader; + setShader(texShader, m); + + GLES20.glUniform2f(hPolygonScale[1], FastMath.clamp(scale - 1, 0, 1), div); + if (a.color == 0xFFAFC5E3) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWater); + else if (a.color == 0xffd1dbc7) + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexWood); + else + GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexGrass); + } else if (a.fade >= zoom) { float f = 1.0f; /* fade in/out */ if (a.fade >= zoom) { @@ -228,19 +236,23 @@ public final class PolygonRenderer { * current Matrices * @param first * pass true to clear stencil buffer region + * @param div + * scale relative to 'base scale' of the tile * @param clip * clip to first quad in current vbo * @return * next layer */ public static Layer draw(MapPosition pos, Layer layer, - Matrices m, boolean first, boolean clip) { + Matrices m, boolean first, float div, boolean clip) { GLState.test(false, true); setShader(polyShader, m); int zoom = pos.zoomLevel; + float scale = (float) pos.getZoomScale(); + int cur = mCount; // reset start when only one layer left in stencil buffer @@ -249,7 +261,6 @@ public final class PolygonRenderer { int start = cur; - float scale = (float) pos.getZoomScale(); Layer l = layer; for (; l != null && l.type == Layer.POLYGON; l = l.next) { @@ -276,13 +287,13 @@ public final class PolygonRenderer { // draw up to 7 layers into stencil buffer if (cur == STENCIL_BITS - 1) { - fillPolygons(m, start, cur, zoom, scale); + fillPolygons(m, start, cur, zoom, scale, div); start = cur = 0; } } if (cur > 0) - fillPolygons(m, start, cur, zoom, scale); + fillPolygons(m, start, cur, zoom, scale, div); if (clip) { if (first) { @@ -402,11 +413,11 @@ public final class PolygonRenderer { static void debugDraw(Matrix4 m, float[] coords, int color) { GLState.test(false, false); - if (mDebugFill == null) + if (mDebugFill == null) { mDebugFill = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder()) .asFloatBuffer(); - - mDebugFill.put(coords); + mDebugFill.put(coords); + } GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); @@ -471,10 +482,13 @@ public final class PolygonRenderer { private final static String textureVertexShader = "" + "precision mediump float;" + "uniform mat4 u_mvp;" + + "uniform vec2 u_scale;" + "attribute vec4 a_pos;" + "varying vec2 v_st;" + + "varying vec2 v_st2;" + "void main() {" - + " v_st = clamp(a_pos.xy, 0.0, 1.0) * 2.0;" + + " v_st = clamp(a_pos.xy, 0.0, 1.0) * (2.0 / u_scale.y);" + + " v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);" + " gl_Position = u_mvp * a_pos;" + "}"; @@ -482,8 +496,10 @@ public final class PolygonRenderer { + "precision mediump float;" + "uniform vec4 u_color;" + "uniform sampler2D tex;" + + "uniform vec2 u_scale;" + "varying vec2 v_st;" + + "varying vec2 v_st2;" + "void main() {" - + " gl_FragColor = texture2D(tex, v_st);" + + " gl_FragColor = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);" + "}"; }