add FadeStep for fading BitmapTileLayer depending on map scale

add setAlpha method to TileRenderLayer to fade bitmap tiles
This commit is contained in:
Hannes Janetzek 2013-08-03 04:15:44 +02:00
parent daf43858bb
commit 2aa2683581
11 changed files with 128 additions and 41 deletions

View File

@ -340,12 +340,15 @@ public class TileManager {
return true;
}
// /**
// * @param tiles ...
// */
// public void releaseTiles(TileSet tiles) {
//
// }
/**
* @param tiles ...
*/
public void releaseTiles(TileSet tileSet) {
// unlock previously active tiles
for (int i = 0, n = tileSet.cnt; i < n; i++)
tileSet.tiles[i].unlock();
tileSet.cnt = 0;
}
/* package */MapTile addTile(int x, int y, int zoomLevel) {
MapTile tile;

View File

@ -39,16 +39,24 @@ public class TileRenderLayer extends RenderLayer {
mUploadSerial = 0;
}
boolean mFaded;
private int mOverdraw = 0;
private float mAlpha = 1;
public void setFaded(boolean faded) {
mFaded = faded;
public void setOverdrawColor(int color) {
mOverdraw = color;
}
public void setBitmapAlpha(float alpha) {
mAlpha = alpha;
}
@Override
public void update(MapPosition pos, boolean positionChanged, Matrices m) {
//mMapPosition.copy(pos);
if (mAlpha == 0){
mTileManager.releaseTiles(mDrawTiles);
return;
}
boolean tilesChanged;
synchronized (tilelock) {
@ -74,7 +82,7 @@ public class TileRenderLayer extends RenderLayer {
BufferObject.checkBufferUsage(false);
}
TileRenderer.draw(tiles, tileCnt, pos, m, mFaded);
TileRenderer.draw(tiles, tileCnt, pos, m, mAlpha, mOverdraw);
}
@Override
@ -327,5 +335,4 @@ public class TileRenderLayer extends RenderLayer {
}
}
};
}

View File

@ -35,7 +35,6 @@ import org.oscim.utils.quadtree.QuadTree;
* This class is for rendering the Line- and PolygonLayers of visible MapTiles.
* For visible tiles that do not have data available yet its parent in children
* tiles are rendered when available.
*
*/
public class TileRenderer {
//private final static String TAG = TileRenderer.class.getName();
@ -50,14 +49,28 @@ public class TileRenderer {
private static int mDrawSerial = 0;
private static Matrices mMatrices;
private static boolean mFaded;
private static float mFade;
private static int mOverdraw;
private static final Matrix4 mProjMatrix = new Matrix4();
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos, Matrices m, boolean fade) {
/**
* Draw tiles:
*
* @param fade
* alpha value for bitmap tiles
* @param overdrawColor
* draw color on top, e.g. to darken the layer temporarily
*/
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos, Matrices m, float fade,
int overdrawColor) {
mOffsetCnt = -2048;
mMatrices = m;
mFaded = fade;
mFade = fade;
mOverdraw = overdrawColor;
mProjMatrix.copy(m.proj);
// discard depth projection from tilt, we use depth buffer
@ -197,7 +210,7 @@ public class TileRenderer {
//GLState.test(false, false);
switch (l.type) {
case Layer.BITMAP:
l = BitmapRenderer.draw(l, 1, m);
l = BitmapRenderer.draw(l, m, 1, mFade);
break;
default:
@ -205,11 +218,7 @@ public class TileRenderer {
}
}
// clear clip-region and could also draw 'fade-effect'
if (mFaded)
PolygonRenderer.drawOver(m, true, 0x22000000);
else
PolygonRenderer.drawOver(m, false, 0);
PolygonRenderer.drawOver(m, mOverdraw);
}
private static int drawProxyChild(MapTile tile, MapPosition pos) {

View File

@ -53,4 +53,9 @@ public abstract class AbstractTileSource implements TileSource {
result = prime * result + this.port;
return result;
}
@Override
public FadeStep[] getFadeSteps() {
return null;
}
}

View File

@ -20,27 +20,63 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.zip.GZIPInputStream;
import org.oscim.view.MapView;
import org.oscim.backend.CanvasAdapter;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.layers.tile.MapTile;
import org.oscim.layers.tile.TileLayer;
import org.oscim.layers.tile.TileLoader;
import org.oscim.layers.tile.TileManager;
import org.oscim.layers.tile.bitmap.TileSource.FadeStep;
import org.oscim.renderer.sublayers.BitmapLayer;
import org.oscim.renderer.sublayers.Layers;
import org.oscim.utils.FastMath;
import org.oscim.view.MapView;
public class BitmapTileLayer extends TileLayer<TileLoader> {
private static final int TIMEOUT_CONNECT = 5000;
private static final int TIMEOUT_READ = 10000;
protected static final String TAG = BitmapTileLayer.class.getName();
final TileSource mTileSource;
private final FadeStep[] mFade;
public BitmapTileLayer(MapView mapView, TileSource tileSource) {
super(mapView, tileSource.getZoomLevelMin(), tileSource.getZoomLevelMax(), 100);
mTileSource = tileSource;
mFade = mTileSource.getFadeSteps();
}
@Override
public void onUpdate(MapPosition pos, boolean changed, boolean clear) {
super.onUpdate(pos, changed, clear);
if (mFade == null) {
mRenderLayer.setBitmapAlpha(1);
return;
}
float alpha = 0;
for (FadeStep f : mFade) {
if (pos.scale < f.scaleStart || pos.scale > f.scaleEnd)
continue;
if (f.alphaStart == f.alphaEnd) {
alpha = f.alphaStart;
break;
}
double range = f.scaleEnd / f.scaleStart;
float a = (float)((range - (pos.scale / f.scaleStart)) / range);
a = FastMath.clamp(a, 0, 1);
// interpolate alpha between start and end
alpha = a * f.alphaStart + (1 - a) * f.alphaEnd;
break;
}
mRenderLayer.setBitmapAlpha(alpha);
}
@Override
@ -61,7 +97,6 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
tile.layers.textureLayers = l;
} catch (Exception e) {
e.printStackTrace();
return false;

View File

@ -20,10 +20,11 @@ import java.net.URL;
import org.oscim.core.Tile;
public class NaturalEarth extends AbstractTileSource {
public static final NaturalEarth INSTANCE = new NaturalEarth("city.informatik.uni-bremen.de", 80);
public static final NaturalEarth INSTANCE = new NaturalEarth("city.informatik.uni-bremen.de",
80);
private static final int PARALLEL_REQUESTS_LIMIT = 4;
private static final String PROTOCOL = "http";
private static final int ZOOM_LEVEL_MAX = 6;
private static final int ZOOM_LEVEL_MAX = 8;
private static final int ZOOM_LEVEL_MIN = 0;
public NaturalEarth(String hostName, int port) {
@ -38,12 +39,14 @@ public class NaturalEarth extends AbstractTileSource {
@Override
public URL getTileUrl(Tile tile) throws MalformedURLException {
StringBuilder stringBuilder = new StringBuilder(32);
stringBuilder.append("/osci/ne_image2/");
stringBuilder.append("/tiles/ne/");
//stringBuilder.append("/osci/ne_image2/");
stringBuilder.append(tile.zoomLevel);
stringBuilder.append('/');
stringBuilder.append(tile.tileX);
stringBuilder.append('/');
stringBuilder.append((1 << tile.zoomLevel) - tile.tileY - 1);
stringBuilder.append(tile.tileY);
stringBuilder.append(".png");
return new URL(PROTOCOL, this.hostName, this.port, stringBuilder.toString());
@ -58,4 +61,14 @@ public class NaturalEarth extends AbstractTileSource {
public byte getZoomLevelMin() {
return ZOOM_LEVEL_MIN;
}
@Override
public FadeStep[] getFadeSteps() {
return new FadeStep[] {
new FadeStep(ZOOM_LEVEL_MIN, ZOOM_LEVEL_MAX - 1, 1, 0.7f),
// dont fade between zoom-min/max
// fade above zoom max + 2, interpolate 1 to 0
new FadeStep(ZOOM_LEVEL_MAX - 1, ZOOM_LEVEL_MAX + 1, 0.7f, 0)
};
}
}

View File

@ -39,4 +39,18 @@ public interface TileSource {
* @return the minimum zoom level which this {@code TileSource} supports.
*/
byte getZoomLevelMin();
FadeStep[] getFadeSteps();
public class FadeStep{
public final double scaleStart, scaleEnd;
public final float alphaStart, alphaEnd;
public FadeStep(int zoomStart, int zoomEnd, float alphaStart, float alphaEnd) {
this.scaleStart = 1 << zoomStart;
this.scaleEnd = 1 << zoomEnd;
this.alphaStart = alphaStart;
this.alphaEnd = alphaEnd;
}
}
}

View File

@ -85,7 +85,7 @@ public abstract class BasicRenderLayer extends RenderLayer {
for (Layer l = layers.textureLayers; l != null;) {
switch (l.type) {
case Layer.BITMAP:
l = BitmapRenderer.draw(l, 1, m);
l = BitmapRenderer.draw(l, m, 1, 1);
break;
default:

View File

@ -92,6 +92,6 @@ public class BitmapRenderLayer extends BasicRenderLayer {
@Override
public synchronized void render(MapPosition pos, Matrices m) {
m.useScreenCoordinates(false, 8);
BitmapRenderer.draw(layers.textureLayers, 1, m);
BitmapRenderer.draw(layers.textureLayers, m, 1, 1);
}
}

View File

@ -39,6 +39,8 @@ public final class BitmapRenderer {
private static int hTextureScreenScale;
private static int hTextureTexCoord;
private static int hAlpha;
public final static int INDICES_PER_SPRITE = 6;
final static int VERTICES_PER_SPRITE = 4;
final static int SHORTS_PER_VERTICE = 6;
@ -53,9 +55,10 @@ public final class BitmapRenderer {
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
hAlpha = GL.glGetUniformLocation(mTextureProgram, "u_alpha");
}
public static Layer draw(Layer layer, float scale, Matrices m) {
public static Layer draw(Layer layer, Matrices m, float scale, float alpha) {
//GLState.test(false, false);
GLState.blend(true);
@ -70,7 +73,9 @@ public final class BitmapRenderer {
else
GL.glUniform1f(hTextureScale, 1);
GL.glUniform1f(hTextureScreenScale, 1f / GLRenderer.screenWidth);
GL.glUniform1f(hAlpha, alpha);
m.proj.setAsUniform(hTextureProjMatrix);
@ -109,9 +114,6 @@ public final class BitmapRenderer {
return layer.next;
}
//private final static double TEX_COORD_DIV = 1.0 / (1024 * COORD_SCALE);
//private final static double COORD_DIV = 1.0 / GLRenderer.COORD_SCALE;
private final static String textVertexShader = ""
+ "precision mediump float; "
+ "attribute vec4 vertex;"
@ -121,18 +123,17 @@ public final class BitmapRenderer {
+ "uniform float u_scale;"
+ "uniform float u_swidth;"
+ "varying vec2 tex_c;"
//+ "const vec2 div = vec2(" + TEX_COORD_DIV + "," + TEX_COORD_DIV + ");"
//+ "const float coord_scale = " + COORD_DIV + ";"
+ "void main() {"
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
+ " tex_c = tex_coord;" // * div;"
+ " tex_c = tex_coord;"
+ "}";
private final static String textFragmentShader = ""
+ "precision mediump float;"
+ "uniform sampler2D tex;"
+ "uniform float u_alpha;"
+ "varying vec2 tex_c;"
+ "void main() {"
+ " gl_FragColor = texture2D(tex, tex_c.xy);"
+ " gl_FragColor = texture2D(tex, tex_c.xy) * u_alpha;"
+ "}";
}

View File

@ -338,7 +338,7 @@ public final class PolygonRenderer {
}
}
public static void drawOver(Matrices m, boolean drawColor, int color) {
public static void drawOver(Matrices m, int color) {
setShader(polyShader, m);
/*
@ -346,7 +346,7 @@ public final class PolygonRenderer {
* a quad with func 'always' and op 'zero'
*/
if (drawColor) {
if (color != 0) {
GlUtils.setColor(hPolygonColor[0], color, 1);
GLState.blend(true);
} else {
@ -364,7 +364,7 @@ public final class PolygonRenderer {
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
if (!drawColor)
if (color == 0)
GL.glColorMask(true, true, true, true);
}