package/naming reorganization:
- RenderLayer -> LayerRenderer as this LayerRenderer just the rendering implementation of a Layer - not a 'layer' itself - move renderer.sublayer.*Renderer into their respective *Layer classes - move layers.labeling to layers.tile.vector.labeling (until there is a common labeling framework) - remove layers.overlay - move Marker stuff to layers.marker - merge TileRenderer into TileRenderLayer - rename renderer.sublayers to renderer.elements - move layers.tile.* to tiling package - move tilesource.* to tiling.source - rename oscim.view -> oscim.map
This commit is contained in:
parent
c6eedc4df7
commit
67a3cbadf7
@ -1,12 +1,12 @@
|
|||||||
package org.oscim.android.test;
|
package org.oscim.android.test;
|
||||||
|
|
||||||
import org.oscim.android.MapView;
|
import org.oscim.android.MapView;
|
||||||
import org.oscim.layers.labeling.LabelLayer;
|
import org.oscim.layers.tile.vector.BuildingLayer;
|
||||||
import org.oscim.layers.overlay.BuildingOverlay;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.MapTileLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.tilesource.oscimap4.OSciMap4TileSource;
|
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@ -28,10 +28,10 @@ public class MapActivity extends org.oscim.android.MapActivity {
|
|||||||
TileSource tileSource = new OSciMap4TileSource();
|
TileSource tileSource = new OSciMap4TileSource();
|
||||||
tileSource.setOption("url", "http://city.informatik.uni-bremen.de/tiles/vtm");
|
tileSource.setOption("url", "http://city.informatik.uni-bremen.de/tiles/vtm");
|
||||||
|
|
||||||
MapTileLayer l = mMap.setBaseMap(tileSource);
|
VectorTileLayer l = mMap.setBaseMap(tileSource);
|
||||||
//mMap.setDebugSettings(new DebugSettings(false, false, true, false, false));
|
//mMap.setDebugSettings(new DebugSettings(false, false, true, false, false));
|
||||||
|
|
||||||
mMap.getLayers().add(new BuildingOverlay(mMap, l.getTileLayer()));
|
mMap.getLayers().add(new BuildingLayer(mMap, l.getTileLayer()));
|
||||||
mMap.getLayers().add(new LabelLayer(mMap, l.getTileLayer()));
|
mMap.getLayers().add(new LabelLayer(mMap, l.getTileLayer()));
|
||||||
|
|
||||||
mMap.setTheme(InternalRenderTheme.DEFAULT);
|
mMap.setTheme(InternalRenderTheme.DEFAULT);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.android;
|
package org.oscim.android;
|
||||||
|
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
|
@ -17,14 +17,14 @@ package org.oscim.android;
|
|||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.opengl.GLSurfaceView;
|
import android.opengl.GLSurfaceView;
|
||||||
|
|
||||||
public class GLView extends GLSurfaceView {
|
public class GLView extends GLSurfaceView {
|
||||||
|
|
||||||
class GLRenderer extends org.oscim.renderer.GLRenderer implements GLSurfaceView.Renderer{
|
class GLRenderer extends org.oscim.renderer.MapRenderer implements GLSurfaceView.Renderer{
|
||||||
|
|
||||||
public GLRenderer(Map map) {
|
public GLRenderer(Map map) {
|
||||||
super(map);
|
super(map);
|
||||||
|
@ -16,7 +16,7 @@ package org.oscim.android;
|
|||||||
|
|
||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
@ -23,7 +23,7 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
@ -22,8 +22,8 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.backend.canvas.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
import org.oscim.layers.overlay.OverlayItem.HotspotPlace;
|
import org.oscim.layers.marker.MarkerItem.HotspotPlace;
|
||||||
import org.oscim.layers.overlay.OverlayMarker;
|
import org.oscim.layers.marker.MarkerSymbol;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap.Config;
|
import android.graphics.Bitmap.Config;
|
||||||
@ -113,14 +113,14 @@ public final class AndroidGraphics extends CanvasAdapter {
|
|||||||
return new AndroidBitmap(bitmap);
|
return new AndroidBitmap(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OverlayMarker makeMarker(Resources res, int id, HotspotPlace place) {
|
public static MarkerSymbol makeMarker(Resources res, int id, HotspotPlace place) {
|
||||||
|
|
||||||
if (place == null)
|
if (place == null)
|
||||||
place = HotspotPlace.CENTER;
|
place = HotspotPlace.CENTER;
|
||||||
|
|
||||||
Drawable drawable = res.getDrawable(id);
|
Drawable drawable = res.getDrawable(id);
|
||||||
|
|
||||||
return new OverlayMarker(drawableToBitmap(drawable), place);
|
return new MarkerSymbol(drawableToBitmap(drawable), place);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,8 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.backend.canvas.Paint;
|
import org.oscim.backend.canvas.Paint;
|
||||||
import org.oscim.layers.overlay.OverlayItem.HotspotPlace;
|
import org.oscim.layers.marker.MarkerItem.HotspotPlace;
|
||||||
import org.oscim.layers.overlay.OverlayMarker;
|
import org.oscim.layers.marker.MarkerSymbol;
|
||||||
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap.Config;
|
import android.graphics.Bitmap.Config;
|
||||||
@ -107,14 +107,14 @@ public final class AndroidGraphics extends CanvasAdapter {
|
|||||||
return new AndroidBitmap(bitmap);
|
return new AndroidBitmap(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OverlayMarker makeMarker(Resources res, int id, HotspotPlace place) {
|
public static MarkerSymbol makeMarker(Resources res, int id, HotspotPlace place) {
|
||||||
|
|
||||||
if (place == null)
|
if (place == null)
|
||||||
place = HotspotPlace.CENTER;
|
place = HotspotPlace.CENTER;
|
||||||
|
|
||||||
Drawable drawable = res.getDrawable(id);
|
Drawable drawable = res.getDrawable(id);
|
||||||
|
|
||||||
return new OverlayMarker(drawableToBitmap(drawable), place);
|
return new MarkerSymbol(drawableToBitmap(drawable), place);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,8 +7,8 @@ import org.oscim.backend.GL20;
|
|||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.tilesource.oscimap2.OSciMap2TileSource;
|
import org.oscim.tiling.source.oscimap2.OSciMap2TileSource;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ import org.oscim.awt.AwtGraphics;
|
|||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.tilesource.oscimap4.OSciMap4TileSource;
|
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||||
|
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
|
||||||
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
|
||||||
|
@ -9,10 +9,10 @@ import org.oscim.core.MercatorProjection;
|
|||||||
import org.oscim.gdx.GdxMap;
|
import org.oscim.gdx.GdxMap;
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||||
import org.oscim.layers.tile.bitmap.NaturalEarth;
|
import org.oscim.layers.tile.bitmap.NaturalEarth;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.tilesource.oscimap2.OSciMap2TileSource;
|
import org.oscim.tiling.source.oscimap2.OSciMap2TileSource;
|
||||||
import org.oscim.tilesource.oscimap4.OSciMap4TileSource;
|
import org.oscim.tiling.source.oscimap4.OSciMap4TileSource;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.backends.gwt.GwtApplication;
|
import com.badlogic.gdx.backends.gwt.GwtApplication;
|
||||||
@ -39,7 +39,7 @@ class GwtGdxMap extends GdxMap {
|
|||||||
CanvasAdapter.textScale = 0.7f;
|
CanvasAdapter.textScale = 0.7f;
|
||||||
GLAdapter.g = (GL20) Gdx.graphics.getGL20();
|
GLAdapter.g = (GL20) Gdx.graphics.getGL20();
|
||||||
GLAdapter.GDX_WEBGL_QUIRKS = true;
|
GLAdapter.GDX_WEBGL_QUIRKS = true;
|
||||||
GLRenderer.setBackgroundColor(0xffffff);
|
MapRenderer.setBackgroundColor(0xffffff);
|
||||||
//Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
//Gdx.app.setLogLevel(Application.LOG_DEBUG);
|
||||||
|
|
||||||
super.create();
|
super.create();
|
||||||
|
@ -7,8 +7,8 @@ import org.oscim.backend.Log;
|
|||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.GeometryBuffer;
|
import org.oscim.core.GeometryBuffer;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.overlay.PathOverlay;
|
import org.oscim.layers.PathLayer;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
import com.google.gwt.cell.client.AbstractCell;
|
import com.google.gwt.cell.client.AbstractCell;
|
||||||
import com.google.gwt.core.client.JavaScriptObject;
|
import com.google.gwt.core.client.JavaScriptObject;
|
||||||
@ -185,7 +185,7 @@ public class SearchBox {
|
|||||||
final Button searchButton = new Button("Search");
|
final Button searchButton = new Button("Search");
|
||||||
final TextBox searchField = new TextBox();
|
final TextBox searchField = new TextBox();
|
||||||
//searchField.setText("Bremen");
|
//searchField.setText("Bremen");
|
||||||
final PathOverlay mOverlay = new PathOverlay(map, 0xCC0000FF);
|
final PathLayer mOverlay = new PathLayer(map, 0xCC0000FF);
|
||||||
map.getLayers().add(mOverlay);
|
map.getLayers().add(mOverlay);
|
||||||
|
|
||||||
// We can add style names to widgets
|
// We can add style names to widgets
|
||||||
|
@ -20,15 +20,15 @@ import org.oscim.backend.canvas.Bitmap;
|
|||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.gdx.client.GwtBitmap;
|
import org.oscim.gdx.client.GwtBitmap;
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
import org.oscim.layers.tile.TileLayer;
|
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.layers.tile.bitmap.TileSource.FadeStep;
|
||||||
import org.oscim.renderer.sublayers.BitmapLayer;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.BitmapLayer;
|
||||||
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
|
import org.oscim.tiling.TileLoader;
|
||||||
|
import org.oscim.tiling.TileManager;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
import com.google.gwt.event.dom.client.ErrorEvent;
|
import com.google.gwt.event.dom.client.ErrorEvent;
|
||||||
import com.google.gwt.event.dom.client.ErrorHandler;
|
import com.google.gwt.event.dom.client.ErrorHandler;
|
||||||
@ -90,7 +90,7 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
|||||||
public void onLoad(LoadEvent event) {
|
public void onLoad(LoadEvent event) {
|
||||||
|
|
||||||
Bitmap bitmap = new GwtBitmap(img);
|
Bitmap bitmap = new GwtBitmap(img);
|
||||||
tile.layers = new Layers();
|
tile.layers = new ElementLayers();
|
||||||
BitmapLayer l = new BitmapLayer(false);
|
BitmapLayer l = new BitmapLayer(false);
|
||||||
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
||||||
|
|
||||||
|
@ -14,24 +14,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile.vector;
|
package org.oscim.layers.tile.vector;
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NONE;
|
import org.oscim.backend.Log;
|
||||||
|
|
||||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.vector.labeling.WayDecorator;
|
||||||
import org.oscim.layers.tile.TileLoader;
|
import org.oscim.map.DebugSettings;
|
||||||
import org.oscim.layers.tile.TileManager;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.ExtrusionLayer;
|
import org.oscim.renderer.elements.ExtrusionLayer;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.LineTexLayer;
|
||||||
import org.oscim.renderer.sublayers.LineTexLayer;
|
import org.oscim.renderer.elements.PolygonLayer;
|
||||||
import org.oscim.renderer.sublayers.PolygonLayer;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
|
||||||
import org.oscim.theme.IRenderCallback;
|
import org.oscim.theme.IRenderCallback;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.renderinstruction.Area;
|
import org.oscim.theme.renderinstruction.Area;
|
||||||
@ -41,14 +39,14 @@ import org.oscim.theme.renderinstruction.LineSymbol;
|
|||||||
import org.oscim.theme.renderinstruction.RenderInstruction;
|
import org.oscim.theme.renderinstruction.RenderInstruction;
|
||||||
import org.oscim.theme.renderinstruction.Symbol;
|
import org.oscim.theme.renderinstruction.Symbol;
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
import org.oscim.tilesource.ITileDataSink;
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.tilesource.ITileDataSource;
|
import org.oscim.tiling.TileLoader;
|
||||||
import org.oscim.tilesource.ITileDataSource.QueryResult;
|
import org.oscim.tiling.TileManager;
|
||||||
|
import org.oscim.tiling.source.ITileDataSink;
|
||||||
|
import org.oscim.tiling.source.ITileDataSource;
|
||||||
|
import org.oscim.tiling.source.ITileDataSource.QueryResult;
|
||||||
import org.oscim.utils.LineClipper;
|
import org.oscim.utils.LineClipper;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.oscim.view.DebugSettings;
|
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note
|
* @note
|
||||||
@ -60,9 +58,9 @@ import org.oscim.backend.Log;
|
|||||||
* 5. RenderTheme calls IRenderCallback functions with style information
|
* 5. RenderTheme calls IRenderCallback functions with style information
|
||||||
* 6. Styled items become added to MapTile.layers... roughly
|
* 6. Styled items become added to MapTile.layers... roughly
|
||||||
*/
|
*/
|
||||||
public class MapTileLoader extends TileLoader implements IRenderCallback, ITileDataSink {
|
public class VectorTileLoader extends TileLoader implements IRenderCallback, ITileDataSink {
|
||||||
|
|
||||||
private static final String TAG = MapTileLoader.class.getName();
|
private static final String TAG = VectorTileLoader.class.getName();
|
||||||
|
|
||||||
private static final double STROKE_INCREASE = Math.sqrt(2.5);
|
private static final double STROKE_INCREASE = Math.sqrt(2.5);
|
||||||
private static final byte LAYERS = 11;
|
private static final byte LAYERS = 11;
|
||||||
@ -119,7 +117,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public MapTileLoader(TileManager tileManager) {
|
public VectorTileLoader(TileManager tileManager) {
|
||||||
super(tileManager);
|
super(tileManager);
|
||||||
|
|
||||||
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
|
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
|
||||||
@ -172,7 +170,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
* MercatorProjection.EARTH_CIRCUMFERENCE
|
* MercatorProjection.EARTH_CIRCUMFERENCE
|
||||||
/ ((long) Tile.SIZE << mTile.zoomLevel));
|
/ ((long) Tile.SIZE << mTile.zoomLevel));
|
||||||
|
|
||||||
mTile.layers = new Layers();
|
mTile.layers = new ElementLayers();
|
||||||
|
|
||||||
// query database, which calls renderWay and renderPOI
|
// query database, which calls renderWay and renderPOI
|
||||||
// callbacks while processing map tile data.
|
// callbacks while processing map tile data.
|
||||||
@ -210,7 +208,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
mTile.labels = null;
|
mTile.labels = null;
|
||||||
// FIXME add STATE_FAILED?
|
// FIXME add STATE_FAILED?
|
||||||
// in passTile everything but STATE_LOADING is considered failed.
|
// in passTile everything but STATE_LOADING is considered failed.
|
||||||
mTile.state = STATE_NONE;
|
mTile.state = MapTile.STATE_NONE;
|
||||||
|
|
||||||
mTile.loader.jobCompleted(mTile, false);
|
mTile.loader.jobCompleted(mTile, false);
|
||||||
mTile = null;
|
mTile = null;
|
||||||
@ -531,7 +529,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
SymbolItem it = SymbolItem.pool.get();
|
SymbolItem it = SymbolItem.pool.get();
|
||||||
it.x = mElement.points[0];
|
it.x = mElement.points[0];
|
||||||
it.y = mElement.points[1];
|
it.y = mElement.points[1];
|
||||||
it.symbol = symbol.texture;
|
it.texRegion = symbol.texture;
|
||||||
it.billboard = true;
|
it.billboard = true;
|
||||||
|
|
||||||
mTile.symbols = Inlist.push(mTile.symbols, it);
|
mTile.symbols = Inlist.push(mTile.symbols, it);
|
@ -12,7 +12,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
|
import org.oscim.tiling.TileManager;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.utils.Timer;
|
import com.badlogic.gdx.utils.Timer;
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.tilesource.common;
|
package org.oscim.tiling.source.common;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
@ -12,15 +12,16 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.tilesource.common;
|
package org.oscim.tiling.source.common;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.tilesource.ITileDataSink;
|
import org.oscim.tiling.source.ITileDataSink;
|
||||||
import org.oscim.tilesource.ITileDataSource;
|
import org.oscim.tiling.source.ITileDataSource;
|
||||||
|
import org.oscim.tiling.source.ITileDataSource.QueryResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
@ -1,7 +1,7 @@
|
|||||||
package org.oscim.utils.geom;
|
package org.oscim.utils.geom;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.renderer.sublayers.VertexItem;
|
import org.oscim.renderer.elements.VertexItem;
|
||||||
|
|
||||||
import com.google.gwt.core.client.JavaScriptException;
|
import com.google.gwt.core.client.JavaScriptException;
|
||||||
import com.google.gwt.core.client.JsArrayInteger;
|
import com.google.gwt.core.client.JsArrayInteger;
|
||||||
|
@ -4,17 +4,17 @@ import org.oscim.backend.AssetAdapter;
|
|||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.labeling.LabelLayer;
|
import org.oscim.layers.GenericLayer;
|
||||||
import org.oscim.layers.overlay.BuildingOverlay;
|
import org.oscim.layers.tile.vector.BuildingLayer;
|
||||||
import org.oscim.layers.overlay.GenericOverlay;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.MapTileLayer;
|
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.map.Viewport;
|
||||||
|
import org.oscim.renderer.GridRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.layers.GridRenderLayer;
|
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.view.Map;
|
|
||||||
import org.oscim.view.Viewport;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.Application;
|
import com.badlogic.gdx.Application;
|
||||||
import com.badlogic.gdx.ApplicationListener;
|
import com.badlogic.gdx.ApplicationListener;
|
||||||
@ -32,7 +32,7 @@ import com.badlogic.gdx.utils.Timer.Task;
|
|||||||
public class GdxMap implements ApplicationListener {
|
public class GdxMap implements ApplicationListener {
|
||||||
|
|
||||||
protected final Map mMap;
|
protected final Map mMap;
|
||||||
private final GLRenderer mMapRenderer;
|
private final MapRenderer mMapRenderer;
|
||||||
|
|
||||||
boolean mRenderRequest;
|
boolean mRenderRequest;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ public class GdxMap implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mMapRenderer = new GLRenderer(mMap);
|
mMapRenderer = new MapRenderer(mMap);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ public class GdxMap implements ApplicationListener {
|
|||||||
|
|
||||||
if (buildings)
|
if (buildings)
|
||||||
mMap.getLayers().add(
|
mMap.getLayers().add(
|
||||||
new BuildingOverlay(mMap, mMapLayer.getTileLayer()));
|
new BuildingLayer(mMap, mMapLayer.getTileLayer()));
|
||||||
|
|
||||||
if (labels)
|
if (labels)
|
||||||
mMap.getLayers().add(new LabelLayer(mMap,
|
mMap.getLayers().add(new LabelLayer(mMap,
|
||||||
@ -106,16 +106,16 @@ public class GdxMap implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tileGrid)
|
if (tileGrid)
|
||||||
mMap.getLayers().add(new GenericOverlay(mMap,
|
mMap.getLayers().add(new GenericLayer(mMap,
|
||||||
new GridRenderLayer()));
|
new GridRenderer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stage ui;
|
// Stage ui;
|
||||||
// Label fps;
|
// Label fps;
|
||||||
// BitmapFont font;
|
// BitmapFont font;
|
||||||
|
|
||||||
MapTileLayer mMapLayer;
|
VectorTileLayer mMapLayer;
|
||||||
GenericOverlay mGridLayer;
|
GenericLayer mGridLayer;
|
||||||
|
|
||||||
int mHeight, mWidth;
|
int mHeight, mWidth;
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ public class GdxMap implements ApplicationListener {
|
|||||||
|
|
||||||
case Input.Keys.G:
|
case Input.Keys.G:
|
||||||
if (mGridLayer == null) {
|
if (mGridLayer == null) {
|
||||||
mGridLayer = new GenericOverlay(mMap, new GridRenderLayer());
|
mGridLayer = new GenericLayer(mMap, new GridRenderer());
|
||||||
mGridLayer.setEnabled(true);
|
mGridLayer.setEnabled(true);
|
||||||
mMap.getLayers().add(mGridLayer);
|
mMap.getLayers().add(mGridLayer);
|
||||||
} else {
|
} else {
|
||||||
|
13
vtm/src/org/oscim/layers/BitmapLayer.java
Normal file
13
vtm/src/org/oscim/layers/BitmapLayer.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package org.oscim.layers;
|
||||||
|
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.BitmapRenderer;
|
||||||
|
import org.oscim.renderer.LayerRenderer;
|
||||||
|
|
||||||
|
public class BitmapLayer extends GenericLayer {
|
||||||
|
|
||||||
|
public BitmapLayer(Map map, LayerRenderer renderer) {
|
||||||
|
super(map, new BitmapRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
57
vtm/src/org/oscim/layers/CustomRenderLayer.java
Normal file
57
vtm/src/org/oscim/layers/CustomRenderLayer.java
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
package org.oscim.layers;
|
||||||
|
|
||||||
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.LayerRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
|
||||||
|
public class CustomRenderLayer extends Layer {
|
||||||
|
|
||||||
|
private static final String TAG = CustomRenderLayer.class.getName();
|
||||||
|
|
||||||
|
class CustomRenderer extends LayerRenderer {
|
||||||
|
|
||||||
|
|
||||||
|
// functions running on MapRender Thread
|
||||||
|
@Override
|
||||||
|
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
|
||||||
|
int currentState;
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
currentState = someConccurentVariable;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "state " + currentState);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile() {
|
||||||
|
setReady(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(MapPosition pos, Matrices m) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomRenderLayer(Map map, LayerRenderer renderer) {
|
||||||
|
|
||||||
|
super(map);
|
||||||
|
mRenderer = new CustomRenderer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int someConccurentVariable;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
|
|
||||||
|
synchronized (mRenderer) {
|
||||||
|
// chang
|
||||||
|
someConccurentVariable++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,20 +12,20 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers;
|
||||||
|
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.renderer.LayerRenderer;
|
||||||
|
|
||||||
public class GenericOverlay extends Overlay {
|
public class GenericLayer extends Layer {
|
||||||
/**
|
/**
|
||||||
* @param map
|
* @param map
|
||||||
* ...
|
* ...
|
||||||
* @param renderer
|
* @param renderer
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
public GenericOverlay(Map map, RenderLayer renderer) {
|
public GenericLayer(Map map, LayerRenderer renderer) {
|
||||||
super(map);
|
super(map);
|
||||||
mLayer = renderer;
|
mRenderer = renderer;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ package org.oscim.layers;
|
|||||||
|
|
||||||
import org.oscim.backend.input.KeyEvent;
|
import org.oscim.backend.input.KeyEvent;
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
public abstract class InputLayer extends Layer {
|
public abstract class InputLayer extends Layer {
|
||||||
|
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers;
|
package org.oscim.layers;
|
||||||
|
|
||||||
import org.oscim.view.Map;
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.LayerRenderer;
|
||||||
|
|
||||||
public abstract class Layer {
|
public abstract class Layer {
|
||||||
public Layer(Map map) {
|
public Layer(Map map) {
|
||||||
@ -26,11 +26,10 @@ public abstract class Layer {
|
|||||||
private boolean mEnabled = true;
|
private boolean mEnabled = true;
|
||||||
protected final Map mMap;
|
protected final Map mMap;
|
||||||
|
|
||||||
/** RenderLayer used to draw this layer. To be implemented by sub-classes */
|
protected LayerRenderer mRenderer;
|
||||||
protected RenderLayer mLayer;
|
|
||||||
|
|
||||||
public RenderLayer getLayer() {
|
public LayerRenderer getRenderer() {
|
||||||
return mLayer;
|
return mRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,8 +17,8 @@ package org.oscim.layers;
|
|||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.view.Viewport;
|
import org.oscim.map.Viewport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes Viewport for scroll, fling, scale, rotation and tilt gestures
|
* Changes Viewport for scroll, fling, scale, rotation and tilt gestures
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -25,17 +25,16 @@ import org.oscim.core.GeometryBuffer;
|
|||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.LineClipper;
|
import org.oscim.utils.LineClipper;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
/** This class draws a path line in given color. */
|
/** This class draws a path line in given color. */
|
||||||
public class PathOverlay extends Layer {
|
public class PathLayer extends Layer {
|
||||||
|
|
||||||
/** Stores points, converted to the map projection. */
|
/** Stores points, converted to the map projection. */
|
||||||
/* package */protected final ArrayList<GeoPoint> mPoints;
|
/* package */protected final ArrayList<GeoPoint> mPoints;
|
||||||
@ -44,7 +43,7 @@ public class PathOverlay extends Layer {
|
|||||||
/** Line style */
|
/** Line style */
|
||||||
/* package */Line mLineStyle;
|
/* package */Line mLineStyle;
|
||||||
|
|
||||||
class RenderPath extends BasicRenderLayer {
|
class RenderPath extends ElementRenderer {
|
||||||
|
|
||||||
private static final int MIN_DIST = 4;
|
private static final int MIN_DIST = 4;
|
||||||
|
|
||||||
@ -234,17 +233,17 @@ public class PathOverlay extends Layer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathOverlay(Map map, int lineColor, float lineWidth) {
|
public PathLayer(Map map, int lineColor, float lineWidth) {
|
||||||
super(map);
|
super(map);
|
||||||
|
|
||||||
mLineStyle = new Line(lineColor, lineWidth, Cap.BUTT);
|
mLineStyle = new Line(lineColor, lineWidth, Cap.BUTT);
|
||||||
|
|
||||||
this.mPoints = new ArrayList<GeoPoint>();
|
this.mPoints = new ArrayList<GeoPoint>();
|
||||||
|
|
||||||
mLayer = new RenderPath();
|
mRenderer = new RenderPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathOverlay(Map map, int lineColor) {
|
public PathLayer(Map map, int lineColor) {
|
||||||
this(map, lineColor, 2);
|
this(map, lineColor, 2);
|
||||||
}
|
}
|
||||||
|
|
@ -13,17 +13,17 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers.marker;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.Point;
|
import org.oscim.core.Point;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.view.Viewport;
|
import org.oscim.map.Viewport;
|
||||||
|
|
||||||
public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverlay<Item> {
|
public class ItemizedIconLayer<Item extends MarkerItem> extends ItemizedLayer<Item> {
|
||||||
//private static final String TAG = ItemizedIconOverlay.class.getName();
|
//private static final String TAG = ItemizedIconOverlay.class.getName();
|
||||||
|
|
||||||
protected final List<Item> mItemList;
|
protected final List<Item> mItemList;
|
||||||
@ -32,37 +32,25 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
|
|
||||||
private final Point mTmpPoint = new Point();
|
private final Point mTmpPoint = new Point();
|
||||||
|
|
||||||
public ItemizedIconOverlay(
|
public ItemizedIconLayer(Map map, List<Item> list,
|
||||||
final Map map,
|
MarkerSymbol defaultMarker,
|
||||||
final List<Item> pList,
|
ItemizedIconLayer.OnItemGestureListener<Item> onItemGestureListener) {
|
||||||
final OverlayMarker pDefaultMarker,
|
|
||||||
final ItemizedIconOverlay.OnItemGestureListener<Item> pOnItemGestureListener) {
|
|
||||||
|
|
||||||
super(map, pDefaultMarker);
|
super(map, defaultMarker);
|
||||||
|
|
||||||
this.mItemList = pList;
|
this.mItemList = list;
|
||||||
this.mOnItemGestureListener = pOnItemGestureListener;
|
this.mOnItemGestureListener = onItemGestureListener;
|
||||||
populate();
|
populate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// public ItemizedIconOverlay(
|
|
||||||
// final MapView map,
|
|
||||||
// final Context pContext,
|
|
||||||
// final List<Item> pList,
|
|
||||||
// final ItemizedIconOverlay.OnItemGestureListener<Item> pOnItemGestureListener) {
|
|
||||||
// this(map, pList,
|
|
||||||
// null, //pContext.getResources().getDrawable(R.drawable.marker_default),
|
|
||||||
// pOnItemGestureListener);
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onSnapToItem(final int pX, final int pY, final Point pSnapPoint) {
|
public boolean onSnapToItem(int x, int y, Point snapPoint) {
|
||||||
// TODO Implement this!
|
// TODO Implement this!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Item createItem(final int index) {
|
protected Item createItem(int index) {
|
||||||
return mItemList.get(index);
|
return mItemList.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,17 +59,17 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
return Math.min(mItemList.size(), mDrawnItemsLimit);
|
return Math.min(mItemList.size(), mDrawnItemsLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addItem(final Item item) {
|
public boolean addItem(Item item) {
|
||||||
final boolean result = mItemList.add(item);
|
final boolean result = mItemList.add(item);
|
||||||
populate();
|
populate();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItem(final int location, final Item item) {
|
public void addItem(int location, Item item) {
|
||||||
mItemList.add(location, item);
|
mItemList.add(location, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addItems(final List<Item> items) {
|
public boolean addItems(List<Item> items) {
|
||||||
final boolean result = mItemList.addAll(items);
|
final boolean result = mItemList.addAll(items);
|
||||||
populate();
|
populate();
|
||||||
return result;
|
return result;
|
||||||
@ -91,20 +79,20 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
removeAllItems(true);
|
removeAllItems(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllItems(final boolean withPopulate) {
|
public void removeAllItems(boolean withPopulate) {
|
||||||
mItemList.clear();
|
mItemList.clear();
|
||||||
if (withPopulate) {
|
if (withPopulate) {
|
||||||
populate();
|
populate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeItem(final Item item) {
|
public boolean removeItem(Item item) {
|
||||||
final boolean result = mItemList.remove(item);
|
final boolean result = mItemList.remove(item);
|
||||||
populate();
|
populate();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item removeItem(final int position) {
|
public Item removeItem(int position) {
|
||||||
final Item result = mItemList.remove(position);
|
final Item result = mItemList.remove(position);
|
||||||
populate();
|
populate();
|
||||||
return result;
|
return result;
|
||||||
@ -118,18 +106,18 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
* ItemGestureListener methods.
|
* ItemGestureListener methods.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onSingleTapUp(final MotionEvent event) {
|
public boolean onSingleTapUp(MotionEvent event) {
|
||||||
return activateSelectedItems(event, mActiveItemSingleTap) || super.onSingleTapUp(event);
|
return activateSelectedItems(event, mActiveItemSingleTap) || super.onSingleTapUp(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean onSingleTapUpHelper(final int index, final Item item) {
|
protected boolean onSingleTapUpHelper(int index, Item item) {
|
||||||
return this.mOnItemGestureListener.onItemSingleTapUp(index, item);
|
return this.mOnItemGestureListener.onItemSingleTapUp(index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ActiveItem mActiveItemSingleTap = new ActiveItem() {
|
private final ActiveItem mActiveItemSingleTap = new ActiveItem() {
|
||||||
@Override
|
@Override
|
||||||
public boolean run(final int index) {
|
public boolean run(int index) {
|
||||||
final ItemizedIconOverlay<Item> that = ItemizedIconOverlay.this;
|
final ItemizedIconLayer<Item> that = ItemizedIconLayer.this;
|
||||||
if (that.mOnItemGestureListener == null) {
|
if (that.mOnItemGestureListener == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -138,18 +126,18 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onLongPress(final MotionEvent event) {
|
public boolean onLongPress(MotionEvent event) {
|
||||||
return activateSelectedItems(event, mActiveItemLongPress) || super.onLongPress(event);
|
return activateSelectedItems(event, mActiveItemLongPress) || super.onLongPress(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean onLongPressHelper(final int index, final Item item) {
|
protected boolean onLongPressHelper(int index, Item item) {
|
||||||
return this.mOnItemGestureListener.onItemLongPress(index, item);
|
return this.mOnItemGestureListener.onItemLongPress(index, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ActiveItem mActiveItemLongPress = new ActiveItem() {
|
private final ActiveItem mActiveItemLongPress = new ActiveItem() {
|
||||||
@Override
|
@Override
|
||||||
public boolean run(final int index) {
|
public boolean run(final int index) {
|
||||||
final ItemizedIconOverlay<Item> that = ItemizedIconOverlay.this;
|
final ItemizedIconLayer<Item> that = ItemizedIconLayer.this;
|
||||||
if (that.mOnItemGestureListener == null) {
|
if (that.mOnItemGestureListener == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -168,6 +156,7 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
* ..
|
* ..
|
||||||
* @return true if event is handled false otherwise
|
* @return true if event is handled false otherwise
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
private boolean activateSelectedItems(MotionEvent event, ActiveItem task) {
|
private boolean activateSelectedItems(MotionEvent event, ActiveItem task) {
|
||||||
int size = mItemList.size();
|
int size = mItemList.size();
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@ -228,12 +217,12 @@ public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverl
|
|||||||
* ....
|
* ....
|
||||||
*/
|
*/
|
||||||
public static interface OnItemGestureListener<T> {
|
public static interface OnItemGestureListener<T> {
|
||||||
public boolean onItemSingleTapUp(final int index, final T item);
|
public boolean onItemSingleTapUp(int index, T item);
|
||||||
|
|
||||||
public boolean onItemLongPress(final int index, final T item);
|
public boolean onItemLongPress(int index, T item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface ActiveItem {
|
public static interface ActiveItem {
|
||||||
public boolean run(final int aIndex);
|
public boolean run(int aIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,7 +14,7 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers.marker;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// - need to sort items back to front for rendering
|
// - need to sort items back to front for rendering
|
||||||
@ -25,12 +25,12 @@ import org.oscim.core.MapPosition;
|
|||||||
import org.oscim.core.MercatorProjection;
|
import org.oscim.core.MercatorProjection;
|
||||||
import org.oscim.core.Point;
|
import org.oscim.core.Point;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.SymbolLayer;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
|
import org.oscim.renderer.elements.SymbolLayer;
|
||||||
import org.oscim.utils.GeometryUtils;
|
import org.oscim.utils.GeometryUtils;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
/* @author Marc Kurtz
|
/* @author Marc Kurtz
|
||||||
* @author Nicolas Gramlich
|
* @author Nicolas Gramlich
|
||||||
@ -39,7 +39,7 @@ import org.oscim.view.Map;
|
|||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
* */
|
* */
|
||||||
/**
|
/**
|
||||||
* Draws a list of {@link OverlayItem} as markers to a map. The item with the
|
* Draws a list of {@link MarkerItem} as markers to a map. The item with the
|
||||||
* lowest index is drawn as last and therefore the 'topmost' marker. It also
|
* lowest index is drawn as last and therefore the 'topmost' marker. It also
|
||||||
* gets checked for onTap first. This class is generic, because you then you get
|
* gets checked for onTap first. This class is generic, because you then you get
|
||||||
* your custom item-class passed back in onTap().
|
* your custom item-class passed back in onTap().
|
||||||
@ -47,12 +47,12 @@ import org.oscim.view.Map;
|
|||||||
* @param <Item>
|
* @param <Item>
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay implements
|
public abstract class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer implements
|
||||||
Overlay.Snappable {
|
MarkerLayer.Snappable {
|
||||||
|
|
||||||
//private final static String TAG = ItemizedOverlay.class.getName();
|
//private final static String TAG = ItemizedOverlay.class.getName();
|
||||||
|
|
||||||
protected final OverlayMarker mDefaultMarker;
|
protected final MarkerSymbol mDefaultMarker;
|
||||||
protected boolean mDrawFocusedItem = true;
|
protected boolean mDrawFocusedItem = true;
|
||||||
|
|
||||||
class InternalItem {
|
class InternalItem {
|
||||||
@ -72,7 +72,7 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
|
|
||||||
private int mSize;
|
private int mSize;
|
||||||
|
|
||||||
class ItemOverlay extends BasicRenderLayer {
|
class ItemOverlay extends ElementRenderer {
|
||||||
|
|
||||||
private final SymbolLayer mSymbolLayer;
|
private final SymbolLayer mSymbolLayer;
|
||||||
private final float[] mBox = new float[8];
|
private final float[] mBox = new float[8];
|
||||||
@ -152,23 +152,10 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//int state = 0;
|
MarkerSymbol marker = it.item.getMarker();
|
||||||
//if (mDrawFocusedItem && (mFocusedItem == it.item))
|
|
||||||
// state = OverlayItem.ITEM_STATE_FOCUSED_MASK;
|
|
||||||
|
|
||||||
//Drawable marker = it.item.getDrawable();
|
|
||||||
OverlayMarker marker = it.item.getMarker();
|
|
||||||
if (marker == null)
|
if (marker == null)
|
||||||
marker = mDefaultMarker;
|
marker = mDefaultMarker;
|
||||||
|
|
||||||
// if (item.getMarker(state) == null) {
|
|
||||||
// OverlayItem.setState(mDefaultMarker, state);
|
|
||||||
// marker = mDefaultMarker;
|
|
||||||
// } else
|
|
||||||
// marker = item.getMarker(state);
|
|
||||||
|
|
||||||
//mSymbolLayer.addDrawable(marker, state, it.x, it.y);
|
|
||||||
|
|
||||||
SymbolItem s = SymbolItem.pool.get();
|
SymbolItem s = SymbolItem.pool.get();
|
||||||
s.bitmap = marker.getBitmap();
|
s.bitmap = marker.getBitmap();
|
||||||
|
|
||||||
@ -210,18 +197,11 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
*/
|
*/
|
||||||
public abstract int size();
|
public abstract int size();
|
||||||
|
|
||||||
public ItemizedOverlay(Map map, OverlayMarker defaultMarker) {
|
public ItemizedLayer(Map map, MarkerSymbol defaultSymbol) {
|
||||||
super(map);
|
super(map);
|
||||||
|
|
||||||
// if (defaultMarker == null) {
|
mDefaultMarker = defaultSymbol;
|
||||||
// defaultMarker = AndroidGraphics.makeMarker(map.getContext().getResources()
|
mRenderer = new ItemOverlay();
|
||||||
// .getDrawable(R.drawable.marker_default), null);
|
|
||||||
// //throw new IllegalArgumentException("You must pass a default marker to ItemizedOverlay.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
//this.mDefaultMarker = OverlayMarker.makeMarker(pDefaultMarker, null);
|
|
||||||
mDefaultMarker = defaultMarker;
|
|
||||||
mLayer = new ItemOverlay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Point mMapPoint = new Point();
|
private final Point mMapPoint = new Point();
|
||||||
@ -287,39 +267,6 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* See if a given hit point is within the bounds of an item's marker.
|
|
||||||
* Override to modify the way an item is hit tested. The hit point is
|
|
||||||
* relative to the marker's bounds. The default implementation just checks
|
|
||||||
* to see if the hit point is within the touchable bounds of the marker.
|
|
||||||
*
|
|
||||||
* @param item
|
|
||||||
* the item to hit test
|
|
||||||
* @param marker
|
|
||||||
* the item's marker
|
|
||||||
* @param hitX
|
|
||||||
* x coordinate of point to check
|
|
||||||
* @param hitY
|
|
||||||
* y coordinate of point to check
|
|
||||||
* @return true if the hit point is within the marker
|
|
||||||
*/
|
|
||||||
// protected boolean hitTest(final Item item, final android.graphics.drawable.Drawable marker,
|
|
||||||
// final int hitX,
|
|
||||||
// final int hitY) {
|
|
||||||
// return marker.getBounds().contains(hitX, hitY);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether or not to draw the focused item. The default is to draw it,
|
|
||||||
* but some clients may prefer to draw the focused item themselves.
|
|
||||||
*
|
|
||||||
* @param drawFocusedItem
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
public void setDrawFocusedItem(final boolean drawFocusedItem) {
|
|
||||||
mDrawFocusedItem = drawFocusedItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the given Item is found in the overlay, force it to be the current
|
* If the given Item is found in the overlay, force it to be the current
|
||||||
* focus-bearer. Any registered {@@link
|
* focus-bearer. Any registered {@@link
|
||||||
@ -343,63 +290,4 @@ public abstract class ItemizedOverlay<Item extends OverlayItem> extends Overlay
|
|||||||
return mFocusedItem;
|
return mFocusedItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static final Rect mRect = new Rect();
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * Adjusts a drawable's bounds so that (0,0) is a pixel in the location
|
|
||||||
// * described by the hotspot parameter. Useful for "pin"-like graphics. For
|
|
||||||
// * convenience, returns the same drawable that was passed in.
|
|
||||||
// *
|
|
||||||
// * @param marker
|
|
||||||
// * the drawable to adjust
|
|
||||||
// * @param hotspot
|
|
||||||
// * the hotspot for the drawable
|
|
||||||
// * @return the same drawable that was passed in.
|
|
||||||
// */
|
|
||||||
// public static synchronized Drawable boundToHotspot(final Drawable marker, HotspotPlace hotspot) {
|
|
||||||
// final int markerWidth = marker.getIntrinsicWidth();
|
|
||||||
// final int markerHeight = marker.getIntrinsicHeight();
|
|
||||||
//
|
|
||||||
// mRect.set(0, 0, 0 + markerWidth, 0 + markerHeight);
|
|
||||||
//
|
|
||||||
// if (hotspot == null) {
|
|
||||||
// hotspot = HotspotPlace.BOTTOM_CENTER;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// switch (hotspot) {
|
|
||||||
// default:
|
|
||||||
// case NONE:
|
|
||||||
// break;
|
|
||||||
// case CENTER:
|
|
||||||
// mRect.offset(-markerWidth / 2, -markerHeight / 2);
|
|
||||||
// break;
|
|
||||||
// case BOTTOM_CENTER:
|
|
||||||
// mRect.offset(-markerWidth / 2, -markerHeight);
|
|
||||||
// break;
|
|
||||||
// case TOP_CENTER:
|
|
||||||
// mRect.offset(-markerWidth / 2, 0);
|
|
||||||
// break;
|
|
||||||
// case RIGHT_CENTER:
|
|
||||||
// mRect.offset(-markerWidth, -markerHeight / 2);
|
|
||||||
// break;
|
|
||||||
// case LEFT_CENTER:
|
|
||||||
// mRect.offset(0, -markerHeight / 2);
|
|
||||||
// break;
|
|
||||||
// case UPPER_RIGHT_CORNER:
|
|
||||||
// mRect.offset(-markerWidth, 0);
|
|
||||||
// break;
|
|
||||||
// case LOWER_RIGHT_CORNER:
|
|
||||||
// mRect.offset(-markerWidth, -markerHeight);
|
|
||||||
// break;
|
|
||||||
// case UPPER_LEFT_CORNER:
|
|
||||||
// mRect.offset(0, 0);
|
|
||||||
// break;
|
|
||||||
// case LOWER_LEFT_CORNER:
|
|
||||||
// mRect.offset(0, -markerHeight);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// marker.setBounds(mRect);
|
|
||||||
// return marker;
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
105
vtm/src/org/oscim/layers/marker/MarkerItem.java
Normal file
105
vtm/src/org/oscim/layers/marker/MarkerItem.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 osmdroid
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Created by plusminus on 00:02:58 - 03.10.2008
|
||||||
|
package org.oscim.layers.marker;
|
||||||
|
|
||||||
|
import org.oscim.core.GeoPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable class describing a GeoPoint with a Title and a Description.
|
||||||
|
*
|
||||||
|
* @author Nicolas Gramlich
|
||||||
|
* @author Theodore Hong
|
||||||
|
* @author Fred Eisele
|
||||||
|
*/
|
||||||
|
public class MarkerItem {
|
||||||
|
|
||||||
|
public static final int ITEM_STATE_FOCUSED_MASK = 4;
|
||||||
|
public static final int ITEM_STATE_PRESSED_MASK = 1;
|
||||||
|
public static final int ITEM_STATE_SELECTED_MASK = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates a hotspot for an area. This is where the origin (0,0) of a
|
||||||
|
* point will be located relative to the area. In otherwords this acts as an
|
||||||
|
* offset. NONE indicates that no adjustment should be made.
|
||||||
|
*/
|
||||||
|
public enum HotspotPlace {
|
||||||
|
NONE, CENTER, BOTTOM_CENTER,
|
||||||
|
TOP_CENTER, RIGHT_CENTER, LEFT_CENTER,
|
||||||
|
UPPER_RIGHT_CORNER, LOWER_RIGHT_CORNER,
|
||||||
|
UPPER_LEFT_CORNER, LOWER_LEFT_CORNER
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String mUid;
|
||||||
|
public final String mTitle;
|
||||||
|
public final String mDescription;
|
||||||
|
public final GeoPoint mGeoPoint;
|
||||||
|
protected MarkerSymbol mMarker;
|
||||||
|
protected HotspotPlace mHotspotPlace;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param title
|
||||||
|
* this should be <b>singleLine</b> (no <code>'\n'</code> )
|
||||||
|
* @param description
|
||||||
|
* a <b>multiLine</b> description ( <code>'\n'</code> possible)
|
||||||
|
* @param geoPoint
|
||||||
|
* ...
|
||||||
|
*/
|
||||||
|
public MarkerItem(String title, String description, GeoPoint geoPoint) {
|
||||||
|
this(null, title, description, geoPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarkerItem(String uid, String title, String description,
|
||||||
|
GeoPoint geoPoint) {
|
||||||
|
mTitle = title;
|
||||||
|
mDescription = description;
|
||||||
|
mGeoPoint = geoPoint;
|
||||||
|
mUid = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUid() {
|
||||||
|
return mUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSnippet() {
|
||||||
|
return mDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeoPoint getPoint() {
|
||||||
|
return mGeoPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MarkerSymbol getMarker() {
|
||||||
|
return mMarker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarker(MarkerSymbol marker) {
|
||||||
|
mMarker = marker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMarkerHotspot(HotspotPlace place) {
|
||||||
|
mHotspotPlace = (place == null) ? HotspotPlace.BOTTOM_CENTER : place;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotspotPlace getMarkerHotspot() {
|
||||||
|
return mHotspotPlace;
|
||||||
|
}
|
||||||
|
}
|
@ -14,11 +14,11 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers.marker;
|
||||||
|
|
||||||
import org.oscim.core.Point;
|
import org.oscim.core.Point;
|
||||||
import org.oscim.layers.InputLayer;
|
import org.oscim.layers.InputLayer;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class representing an overlay which may be displayed on top of a
|
* Base class representing an overlay which may be displayed on top of a
|
||||||
@ -30,9 +30,9 @@ import org.oscim.view.Map;
|
|||||||
*
|
*
|
||||||
* @author Nicolas Gramlich
|
* @author Nicolas Gramlich
|
||||||
*/
|
*/
|
||||||
public abstract class Overlay extends InputLayer {
|
public abstract class MarkerLayer extends InputLayer {
|
||||||
|
|
||||||
public Overlay(Map map) {
|
public MarkerLayer(Map map) {
|
||||||
super(map);
|
super(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,29 +62,4 @@ public abstract class Overlay extends InputLayer {
|
|||||||
*/
|
*/
|
||||||
boolean onSnapToItem(int x, int y, Point snapPoint);
|
boolean onSnapToItem(int x, int y, Point snapPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
///**
|
|
||||||
// * Since the menu-chain will pass through several independent Overlays, menu
|
|
||||||
// * IDs cannot be fixed at compile time. Overlays should use this method to
|
|
||||||
// * obtain and store a menu id for each menu item at construction time. This
|
|
||||||
// * will ensure that two overlays don't use the same id.
|
|
||||||
// *
|
|
||||||
// * @return an integer suitable to be used as a menu identifier
|
|
||||||
// */
|
|
||||||
//protected final static int getSafeMenuId() {
|
|
||||||
// return sOrdinal.getAndIncrement();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * Similar to <see cref="getSafeMenuId" />, except this reserves a sequence
|
|
||||||
// * of IDs of length <param name="count" />. The returned number is the
|
|
||||||
// * starting index of that sequential list.
|
|
||||||
// *
|
|
||||||
// * @param count
|
|
||||||
// * ....
|
|
||||||
// * @return an integer suitable to be used as a menu identifier
|
|
||||||
// */
|
|
||||||
//protected final static int getSafeMenuIdSequence(int count) {
|
|
||||||
// return sOrdinal.getAndAdd(count);
|
|
||||||
//}
|
|
||||||
}
|
}
|
@ -1,36 +1,22 @@
|
|||||||
/*
|
package org.oscim.layers.marker;
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.layers.overlay;
|
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.Point;
|
import org.oscim.core.Point;
|
||||||
import org.oscim.layers.overlay.OverlayItem.HotspotPlace;
|
import org.oscim.layers.marker.MarkerItem.HotspotPlace;
|
||||||
|
|
||||||
public class OverlayMarker {
|
public class MarkerSymbol {
|
||||||
final Bitmap[] mBitmap;
|
final Bitmap[] mBitmap;
|
||||||
// Hotspot offset
|
// Hotspot offset
|
||||||
final Point[] mOffset;
|
final Point[] mOffset;
|
||||||
|
|
||||||
public OverlayMarker(Bitmap bitmap, float relX, float relY) {
|
public MarkerSymbol(Bitmap bitmap, float relX, float relY) {
|
||||||
mBitmap = new Bitmap[1];
|
mBitmap = new Bitmap[1];
|
||||||
mBitmap[0] = bitmap;
|
mBitmap[0] = bitmap;
|
||||||
mOffset = new Point[1];
|
mOffset = new Point[1];
|
||||||
mOffset[0] = new Point(relX, relY);
|
mOffset[0] = new Point(relX, relY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OverlayMarker(Bitmap bitmap, HotspotPlace hotspot) {
|
public MarkerSymbol(Bitmap bitmap, HotspotPlace hotspot) {
|
||||||
float x = 0, y = 0;
|
float x = 0, y = 0;
|
||||||
switch (hotspot) {
|
switch (hotspot) {
|
||||||
default:
|
default:
|
||||||
@ -88,5 +74,4 @@ public class OverlayMarker {
|
|||||||
return mBitmap[0];
|
return mBitmap[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 osmdroid
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Created by plusminus on 00:02:58 - 03.10.2008
|
|
||||||
package org.oscim.layers.overlay;
|
|
||||||
|
|
||||||
import org.oscim.core.GeoPoint;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Immutable class describing a GeoPoint with a Title and a Description.
|
|
||||||
*
|
|
||||||
* @author Nicolas Gramlich
|
|
||||||
* @author Theodore Hong
|
|
||||||
* @author Fred Eisele
|
|
||||||
*/
|
|
||||||
public class OverlayItem {
|
|
||||||
|
|
||||||
public static final int ITEM_STATE_FOCUSED_MASK = 4;
|
|
||||||
public static final int ITEM_STATE_PRESSED_MASK = 1;
|
|
||||||
public static final int ITEM_STATE_SELECTED_MASK = 2;
|
|
||||||
|
|
||||||
//protected static final Point DEFAULT_MARKER_SIZE = new Point(26, 94);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates a hotspot for an area. This is where the origin (0,0) of a
|
|
||||||
* point will be located relative to the area. In otherwords this acts as an
|
|
||||||
* offset. NONE indicates that no adjustment should be made.
|
|
||||||
*/
|
|
||||||
public enum HotspotPlace {
|
|
||||||
NONE, CENTER, BOTTOM_CENTER,
|
|
||||||
TOP_CENTER, RIGHT_CENTER, LEFT_CENTER,
|
|
||||||
UPPER_RIGHT_CORNER, LOWER_RIGHT_CORNER,
|
|
||||||
UPPER_LEFT_CORNER, LOWER_LEFT_CORNER
|
|
||||||
}
|
|
||||||
|
|
||||||
public final String mUid;
|
|
||||||
public final String mTitle;
|
|
||||||
public final String mDescription;
|
|
||||||
public final GeoPoint mGeoPoint;
|
|
||||||
protected OverlayMarker mMarker;
|
|
||||||
protected HotspotPlace mHotspotPlace;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param aTitle
|
|
||||||
* this should be <b>singleLine</b> (no <code>'\n'</code> )
|
|
||||||
* @param aDescription
|
|
||||||
* a <b>multiLine</b> description ( <code>'\n'</code> possible)
|
|
||||||
* @param aGeoPoint
|
|
||||||
* ...
|
|
||||||
*/
|
|
||||||
public OverlayItem(final String aTitle, final String aDescription, final GeoPoint aGeoPoint) {
|
|
||||||
this(null, aTitle, aDescription, aGeoPoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OverlayItem(final String aUid, final String aTitle, final String aDescription,
|
|
||||||
final GeoPoint aGeoPoint) {
|
|
||||||
mTitle = aTitle;
|
|
||||||
mDescription = aDescription;
|
|
||||||
mGeoPoint = aGeoPoint;
|
|
||||||
mUid = aUid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUid() {
|
|
||||||
return mUid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTitle() {
|
|
||||||
return mTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSnippet() {
|
|
||||||
return mDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GeoPoint getPoint() {
|
|
||||||
return mGeoPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (copied from Google API docs) Returns the marker that should be used when
|
|
||||||
* drawing this item on the map. A null value means that the default marker
|
|
||||||
* should be drawn. Different markers can be returned for different states.
|
|
||||||
* The different markers can have different bounds. The default behavior is
|
|
||||||
* to call {@link setState(android.graphics.drawable.Drawable, int)} on the
|
|
||||||
* overlay item's marker, if it exists, and then return it.
|
|
||||||
* @param stateBitset The current state.
|
|
||||||
* @return The marker for the current state, or null if the default marker
|
|
||||||
* for the overlay should be used.
|
|
||||||
*/
|
|
||||||
public OverlayMarker getMarker() {
|
|
||||||
return mMarker;
|
|
||||||
|
|
||||||
// // marker not specified
|
|
||||||
// if (mMarker == null) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // set marker state appropriately
|
|
||||||
// setState(mMarker, stateBitset);
|
|
||||||
// return mMarker;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMarker(OverlayMarker marker) {
|
|
||||||
mMarker = marker;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMarkerHotspot(final HotspotPlace place) {
|
|
||||||
mHotspotPlace = (place == null) ? HotspotPlace.BOTTOM_CENTER : place;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HotspotPlace getMarkerHotspot() {
|
|
||||||
return mHotspotPlace;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (copied from the Google API docs) Sets the state of a drawable to match a
|
|
||||||
* given state bitset. This is done by converting the state bitset bits
|
|
||||||
* into
|
|
||||||
* a state set of R.attr.state_pressed, R.attr.state_selected and
|
|
||||||
* R.attr.state_focused attributes, and then calling {@link
|
|
||||||
* Drawable.setState(int[])}.
|
|
||||||
*/
|
|
||||||
// public static void setState(final Drawable drawable, final int stateBitset) {
|
|
||||||
// final int[] states = new int[3];
|
|
||||||
// int index = 0;
|
|
||||||
// if ((stateBitset & ITEM_STATE_PRESSED_MASK) > 0)
|
|
||||||
// states[index++] = android.R.attr.state_pressed;
|
|
||||||
// if ((stateBitset & ITEM_STATE_SELECTED_MASK) > 0)
|
|
||||||
// states[index++] = android.R.attr.state_selected;
|
|
||||||
// if ((stateBitset & ITEM_STATE_FOCUSED_MASK) > 0)
|
|
||||||
// states[index++] = android.R.attr.state_focused;
|
|
||||||
//
|
|
||||||
// drawable.setState(states);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public Drawable getDrawable() {
|
|
||||||
// return mMarker;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public int getWidth() {
|
|
||||||
// return mMarker.getIntrinsicWidth();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public int getHeight() {
|
|
||||||
// return mMarker.getIntrinsicHeight();
|
|
||||||
// }
|
|
||||||
}
|
|
@ -18,7 +18,10 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.tiling.TileLoader;
|
||||||
|
import org.oscim.tiling.TileManager;
|
||||||
|
import org.oscim.tiling.TileRenderer;
|
||||||
|
|
||||||
public abstract class TileLayer<T extends TileLoader> extends Layer {
|
public abstract class TileLayer<T extends TileLoader> extends Layer {
|
||||||
//private final static String TAG = TileLayer.class.getName();
|
//private final static String TAG = TileLayer.class.getName();
|
||||||
@ -27,7 +30,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
private final static int CACHE_LIMIT = 250;
|
private final static int CACHE_LIMIT = 250;
|
||||||
|
|
||||||
protected final TileManager mTileManager;
|
protected final TileManager mTileManager;
|
||||||
protected final TileRenderLayer mRenderLayer;
|
protected final TileRenderer mRenderLayer;
|
||||||
|
|
||||||
protected final int mNumTileLoader = 4;
|
protected final int mNumTileLoader = 4;
|
||||||
protected final ArrayList<T> mTileLoader;
|
protected final ArrayList<T> mTileLoader;
|
||||||
@ -43,7 +46,7 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
|
|
||||||
// TileManager responsible for adding visible tiles
|
// TileManager responsible for adding visible tiles
|
||||||
// to load queue and managing in-memory tile cache.
|
// to load queue and managing in-memory tile cache.
|
||||||
mTileManager = new TileManager(map, this, minZoom, maxZoom, cacheLimit);
|
mTileManager = new TileManager(map, minZoom, maxZoom, cacheLimit);
|
||||||
|
|
||||||
// Instantiate TileLoader threads
|
// Instantiate TileLoader threads
|
||||||
mTileLoader = new ArrayList<T>();
|
mTileLoader = new ArrayList<T>();
|
||||||
@ -55,13 +58,13 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
|
|
||||||
// RenderLayer is working in GL Thread and actually
|
// RenderLayer is working in GL Thread and actually
|
||||||
// drawing loaded tiles to screen.
|
// drawing loaded tiles to screen.
|
||||||
mLayer = mRenderLayer = new TileRenderLayer(mTileManager);
|
mRenderer = mRenderLayer = new TileRenderer(mTileManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected T createLoader(TileManager tm);
|
abstract protected T createLoader(TileManager tm);
|
||||||
|
|
||||||
public TileRenderLayer getTileLayer() {
|
public TileRenderer getTileLayer() {
|
||||||
return (TileRenderLayer) mLayer;
|
return (TileRenderer) mRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -73,8 +76,9 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
mInitial = false;
|
mInitial = false;
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (changed)
|
|
||||||
mTileManager.update(mapPosition);
|
if (changed && mTileManager.update(mapPosition))
|
||||||
|
notifyLoaders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -84,12 +88,12 @@ public abstract class TileLayer<T extends TileLoader> extends Layer {
|
|||||||
loader.interrupt();
|
loader.interrupt();
|
||||||
loader.cleanup();
|
loader.cleanup();
|
||||||
|
|
||||||
// try {
|
// try {
|
||||||
// tileWorker.join(10000);
|
// tileWorker.join(10000);
|
||||||
// } catch (InterruptedException e) {
|
// } catch (InterruptedException e) {
|
||||||
// // restore the interrupted status
|
// // restore the interrupted status
|
||||||
// Thread.currentThread().interrupt();
|
// Thread.currentThread().interrupt();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
mTileManager.destroy();
|
mTileManager.destroy();
|
||||||
}
|
}
|
||||||
|
@ -1,336 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.layers.tile;
|
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NEW_DATA;
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_READY;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.Log;
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.renderer.BufferObject;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.RenderLayer;
|
|
||||||
import org.oscim.utils.ScanBox;
|
|
||||||
|
|
||||||
public class TileRenderLayer extends RenderLayer {
|
|
||||||
private final static String TAG = TileRenderLayer.class.getName();
|
|
||||||
|
|
||||||
private final TileManager mTileManager;
|
|
||||||
private int mUploadSerial;
|
|
||||||
|
|
||||||
public TileRenderLayer(TileManager tileManager) {
|
|
||||||
mTileManager = tileManager;
|
|
||||||
mUploadSerial = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int mOverdraw = 0;
|
|
||||||
private float mAlpha = 1;
|
|
||||||
|
|
||||||
public void setOverdrawColor(int color) {
|
|
||||||
mOverdraw = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBitmapAlpha(float alpha) {
|
|
||||||
mAlpha = alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void update(MapPosition pos, boolean positionChanged, Matrices m) {
|
|
||||||
|
|
||||||
if (mAlpha == 0){
|
|
||||||
mTileManager.releaseTiles(mDrawTiles);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean tilesChanged;
|
|
||||||
synchronized (tilelock) {
|
|
||||||
// get current tiles to draw
|
|
||||||
tilesChanged = mTileManager.getActiveTiles(mDrawTiles);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mDrawTiles.cnt == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int tileCnt = mDrawTiles.cnt;
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
if (tilesChanged || positionChanged){
|
|
||||||
updateTileVisibility(pos, m.mapPlane);
|
|
||||||
}
|
|
||||||
|
|
||||||
tileCnt += mNumTileHolder;
|
|
||||||
|
|
||||||
/* prepare tile for rendering */
|
|
||||||
if (compileTileLayers(tiles, tileCnt) > 0) {
|
|
||||||
mUploadSerial++;
|
|
||||||
BufferObject.checkBufferUsage(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
TileRenderer.draw(tiles, tileCnt, pos, m, mAlpha, mOverdraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void compile() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void render(MapPosition pos, Matrices m) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void clearTiles() {
|
|
||||||
// Clear all references to MapTiles as all current
|
|
||||||
// tiles will also be removed from TileManager.
|
|
||||||
synchronized (GLRenderer.drawlock) {
|
|
||||||
mDrawTiles = new TileSet();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** compile tile layer data and upload to VBOs */
|
|
||||||
private static int compileTileLayers(MapTile[] tiles, int tileCnt) {
|
|
||||||
int uploadCnt = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile tile = tiles[i];
|
|
||||||
|
|
||||||
if (!tile.isVisible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tile.state == STATE_READY)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (tile.state == STATE_NEW_DATA) {
|
|
||||||
uploadCnt += uploadTileData(tile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile.holder != null) {
|
|
||||||
// load tile that is referenced by this holder
|
|
||||||
if (tile.holder.state == STATE_NEW_DATA)
|
|
||||||
uploadCnt += uploadTileData(tile.holder);
|
|
||||||
|
|
||||||
tile.state = tile.holder.state;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check near relatives than can serve as proxy
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
MapTile rel = tile.rel.parent.item;
|
|
||||||
if (rel.state == STATE_NEW_DATA)
|
|
||||||
uploadCnt += uploadTileData(rel);
|
|
||||||
|
|
||||||
// dont load child proxies
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int c = 0; c < 4; c++) {
|
|
||||||
if ((tile.proxies & 1 << c) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MapTile rel = tile.rel.get(i);
|
|
||||||
if (rel != null && rel.state == STATE_NEW_DATA)
|
|
||||||
uploadCnt += uploadTileData(rel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uploadCnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int uploadTileData(MapTile tile) {
|
|
||||||
tile.state = STATE_READY;
|
|
||||||
|
|
||||||
// tile might contain extrusion or label layers
|
|
||||||
if (tile.layers == null)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
int newSize = tile.layers.getSize();
|
|
||||||
if (newSize > 0) {
|
|
||||||
|
|
||||||
if (tile.layers.vbo == null)
|
|
||||||
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
|
|
||||||
|
|
||||||
if (!GLRenderer.uploadLayers(tile.layers, newSize, true)) {
|
|
||||||
Log.d(TAG, "BUG uploadTileData " + tile + " failed!");
|
|
||||||
|
|
||||||
BufferObject.release(tile.layers.vbo);
|
|
||||||
tile.layers.vbo = null;
|
|
||||||
tile.layers.clear();
|
|
||||||
tile.layers = null;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Object tilelock = new Object();
|
|
||||||
|
|
||||||
/** set tile isVisible flag true for tiles that intersect view */
|
|
||||||
private void updateTileVisibility(MapPosition pos, float[] box) {
|
|
||||||
|
|
||||||
// lock tiles while updating isVisible state
|
|
||||||
synchronized (tilelock) {
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
int tileZoom = tiles[0].zoomLevel;
|
|
||||||
|
|
||||||
for (int i = 0; i < mDrawTiles.cnt; i++)
|
|
||||||
tiles[i].isVisible = false;
|
|
||||||
|
|
||||||
// count placeholder tiles
|
|
||||||
mNumTileHolder = 0;
|
|
||||||
|
|
||||||
// check visibile tiles
|
|
||||||
mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, box);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update tileSet with currently visible tiles get a TileSet of currently
|
|
||||||
* visible tiles
|
|
||||||
*/
|
|
||||||
public boolean getVisibleTiles(TileSet tileSet) {
|
|
||||||
if (tileSet == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (mDrawTiles == null) {
|
|
||||||
releaseTiles(tileSet);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// same tiles as before
|
|
||||||
// if (tileSet.serial == mDrawTiles.serial)
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
int prevSerial = tileSet.serial;
|
|
||||||
|
|
||||||
// ensure tiles keep visible state
|
|
||||||
synchronized (tilelock) {
|
|
||||||
|
|
||||||
MapTile[] newTiles = mDrawTiles.tiles;
|
|
||||||
int cnt = mDrawTiles.cnt;
|
|
||||||
|
|
||||||
// unlock previous tiles
|
|
||||||
for (int i = 0; i < tileSet.cnt; i++)
|
|
||||||
tileSet.tiles[i].unlock();
|
|
||||||
|
|
||||||
// ensure same size
|
|
||||||
if (tileSet.tiles.length != mDrawTiles.tiles.length) {
|
|
||||||
tileSet.tiles = new MapTile[mDrawTiles.tiles.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
// lock tiles to not be removed from cache
|
|
||||||
tileSet.cnt = 0;
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
MapTile t = newTiles[i];
|
|
||||||
if (t.isVisible && t.state == STATE_READY) {
|
|
||||||
t.lock();
|
|
||||||
tileSet.tiles[tileSet.cnt++] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tileSet.serial = mUploadSerial;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prevSerial != tileSet.serial;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void releaseTiles(TileSet td) {
|
|
||||||
for (int i = 0; i < td.cnt; i++) {
|
|
||||||
td.tiles[i].unlock();
|
|
||||||
td.tiles[i] = null;
|
|
||||||
}
|
|
||||||
td.cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add additional tiles that serve as placeholer when flipping
|
|
||||||
// over date-line.
|
|
||||||
// I dont really like this but cannot think of a better solution:
|
|
||||||
// The other option would be to run scanbox each time for upload,
|
|
||||||
// drawing, proxies and text layer. Adding placeholder only
|
|
||||||
// happens rarely, unless you live on Fidschi
|
|
||||||
|
|
||||||
/* package */int mNumTileHolder;
|
|
||||||
/* package */TileSet mDrawTiles = new TileSet();
|
|
||||||
|
|
||||||
// scanline fill class used to check tile visibility
|
|
||||||
private final ScanBox mScanBox = new ScanBox() {
|
|
||||||
@Override
|
|
||||||
protected void setVisible(int y, int x1, int x2) {
|
|
||||||
int cnt = mDrawTiles.cnt;
|
|
||||||
|
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
|
|
||||||
t.isVisible = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int xmax = 1 << mZoom;
|
|
||||||
if (x1 >= 0 && x2 < xmax)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// add placeholder tiles to show both sides
|
|
||||||
// of date line. a little too complicated...
|
|
||||||
for (int x = x1; x < x2; x++) {
|
|
||||||
MapTile holder = null;
|
|
||||||
MapTile tile = null;
|
|
||||||
boolean found = false;
|
|
||||||
|
|
||||||
if (x >= 0 && x < xmax)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int xx = x;
|
|
||||||
if (x < 0)
|
|
||||||
xx = xmax + x;
|
|
||||||
else
|
|
||||||
xx = x - xmax;
|
|
||||||
|
|
||||||
if (xx < 0 || xx >= xmax)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int i = cnt; i < cnt + mNumTileHolder; i++)
|
|
||||||
if (tiles[i].tileX == x && tiles[i].tileY == y) {
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++)
|
|
||||||
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
|
|
||||||
tile = tiles[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tile == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cnt + mNumTileHolder >= tiles.length){
|
|
||||||
Log.e(TAG, "too many tiles " + cnt + ", " + mNumTileHolder);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
holder = new MapTile(x, y, (byte) mZoom);
|
|
||||||
holder.isVisible = true;
|
|
||||||
holder.holder = tile;
|
|
||||||
tile.isVisible = true;
|
|
||||||
tiles[cnt + mNumTileHolder++] = holder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,304 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.layers.tile;
|
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_READY;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.core.Tile;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.sublayers.BitmapRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.Layer;
|
|
||||||
import org.oscim.renderer.sublayers.LineRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.LineTexRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.PolygonRenderer;
|
|
||||||
import org.oscim.utils.FastMath;
|
|
||||||
import org.oscim.utils.Matrix4;
|
|
||||||
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();
|
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
|
||||||
|
|
||||||
// Counter increases polygon-offset for each tile drawn.
|
|
||||||
private static int mOffsetCnt;
|
|
||||||
|
|
||||||
// Current number of frames drawn, used to not draw a
|
|
||||||
// tile twice per frame.
|
|
||||||
private static int mDrawSerial = 0;
|
|
||||||
|
|
||||||
private static Matrices mMatrices;
|
|
||||||
|
|
||||||
private static float mFade;
|
|
||||||
private static int mOverdraw;
|
|
||||||
|
|
||||||
private static final Matrix4 mProjMatrix = new Matrix4();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
mFade = fade;
|
|
||||||
mOverdraw = overdrawColor;
|
|
||||||
|
|
||||||
mProjMatrix.copy(m.proj);
|
|
||||||
// discard depth projection from tilt, we use depth buffer
|
|
||||||
// for clipping
|
|
||||||
mProjMatrix.setValue(10, 0);
|
|
||||||
mProjMatrix.setValue(14, 0);
|
|
||||||
mProjMatrix.multiplyRhs(m.view);
|
|
||||||
|
|
||||||
GL.glDepthMask(true);
|
|
||||||
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
GL.glDepthFunc(GL20.GL_LESS);
|
|
||||||
|
|
||||||
// Draw visible tiles
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.isVisible && t.state == STATE_READY)
|
|
||||||
drawTile(t, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
double scale = pos.getZoomScale();
|
|
||||||
|
|
||||||
// Draw parent or children as proxy for visibile tiles that dont
|
|
||||||
// have data yet. Proxies are clipped to the region where nothing
|
|
||||||
// was drawn to depth buffer.
|
|
||||||
// TODO draw proxies for placeholder
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) {
|
|
||||||
boolean preferParent = (scale > 1.5) || (pos.zoomLevel - t.zoomLevel < 0);
|
|
||||||
drawProxyTile(t, pos, true, preferParent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw grandparents
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
|
||||||
drawProxyTile(t, pos, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure stencil buffer write is disabled
|
|
||||||
GL.glStencilMask(0x00);
|
|
||||||
GL.glDepthMask(false);
|
|
||||||
|
|
||||||
mDrawSerial++;
|
|
||||||
|
|
||||||
// clear reference
|
|
||||||
mMatrices = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawTile(MapTile tile, MapPosition pos) {
|
|
||||||
// draw parents only once
|
|
||||||
if (tile.lastDraw == mDrawSerial)
|
|
||||||
return;
|
|
||||||
|
|
||||||
tile.lastDraw = mDrawSerial;
|
|
||||||
|
|
||||||
MapTile t = tile;
|
|
||||||
if (t.holder != null)
|
|
||||||
t = t.holder;
|
|
||||||
|
|
||||||
if (t.layers == null || t.layers.vbo == null) {
|
|
||||||
//Log.d(TAG, "missing data " + (t.layers == null) + " " + (t.vbo == null));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
t.layers.vbo.bind();
|
|
||||||
|
|
||||||
// place tile relative to map position
|
|
||||||
int z = tile.zoomLevel;
|
|
||||||
|
|
||||||
float div = FastMath.pow(z - pos.zoomLevel);
|
|
||||||
|
|
||||||
double curScale = Tile.SIZE * pos.scale;
|
|
||||||
double scale = (pos.scale / (1 << z));
|
|
||||||
|
|
||||||
float x = (float) ((tile.x - pos.x) * curScale);
|
|
||||||
float y = (float) ((tile.y - pos.y) * curScale);
|
|
||||||
|
|
||||||
Matrices m = mMatrices;
|
|
||||||
m.mvp.setTransScale(x, y, (float) (scale / GLRenderer.COORD_SCALE));
|
|
||||||
|
|
||||||
m.mvp.multiplyLhs(mProjMatrix);
|
|
||||||
|
|
||||||
// set depth offset (used for clipping to tile boundaries)
|
|
||||||
GL.glPolygonOffset(0, mOffsetCnt++);
|
|
||||||
|
|
||||||
// simple line shader does not take forward shortening into
|
|
||||||
// account. only used when tilt is 0.
|
|
||||||
int simpleShader = (pos.tilt < 1 ? 1 : 0);
|
|
||||||
|
|
||||||
boolean clipped = false;
|
|
||||||
|
|
||||||
for (Layer l = t.layers.baseLayers; l != null;) {
|
|
||||||
switch (l.type) {
|
|
||||||
case Layer.POLYGON:
|
|
||||||
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, div, true);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
l = LineRenderer.draw(t.layers, l, pos, m, div, simpleShader);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Layer.TEXLINE:
|
|
||||||
if (!clipped) {
|
|
||||||
// draw stencil buffer clip region
|
|
||||||
PolygonRenderer.draw(pos, null, m, true, div, true);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
l = LineTexRenderer.draw(t.layers, l, pos, m, div);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// just in case
|
|
||||||
l = l.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Layer l = t.layers.textureLayers; l != null;) {
|
|
||||||
if (!clipped) {
|
|
||||||
// draw stencil buffer clip region
|
|
||||||
PolygonRenderer.draw(pos, null, m, true, div, true);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
// if (!clipped) {
|
|
||||||
// // draw stencil buffer clip region
|
|
||||||
// PolygonRenderer.clip(m);
|
|
||||||
// clipped = true;
|
|
||||||
// }
|
|
||||||
//GLState.test(false, false);
|
|
||||||
switch (l.type) {
|
|
||||||
case Layer.BITMAP:
|
|
||||||
l = BitmapRenderer.draw(l, m, 1, mFade);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
l = l.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PolygonRenderer.drawOver(m, mOverdraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int drawProxyChild(MapTile tile, MapPosition pos) {
|
|
||||||
int drawn = 0;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if ((tile.proxies & 1 << i) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MapTile c = tile.rel.get(i);
|
|
||||||
|
|
||||||
if (c.state == STATE_READY) {
|
|
||||||
drawTile(c, pos);
|
|
||||||
drawn++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return drawn;
|
|
||||||
}
|
|
||||||
|
|
||||||
// just FIXME!
|
|
||||||
private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent,
|
|
||||||
boolean preferParent) {
|
|
||||||
|
|
||||||
QuadTree<MapTile> r = tile.rel;
|
|
||||||
MapTile proxy;
|
|
||||||
|
|
||||||
if (!preferParent) {
|
|
||||||
// prefer drawing children
|
|
||||||
if (drawProxyChild(tile, pos) == 4)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (parent) {
|
|
||||||
// draw parent proxy
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
proxy = r.parent.item;
|
|
||||||
if (proxy.state == STATE_READY) {
|
|
||||||
//Log.d(TAG, "1. draw parent " + proxy);
|
|
||||||
drawTile(proxy, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
|
||||||
// check if parent was already drawn
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
proxy = r.parent.item;
|
|
||||||
if (proxy.state == STATE_READY)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
proxy = r.parent.parent.item;
|
|
||||||
if (proxy.state == STATE_READY)
|
|
||||||
drawTile(proxy, pos);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// prefer drawing parent
|
|
||||||
if (parent) {
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
proxy = r.parent.item;
|
|
||||||
if (proxy != null && proxy.state == STATE_READY) {
|
|
||||||
//Log.d(TAG, "2. draw parent " + proxy);
|
|
||||||
drawTile(proxy, pos);
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drawProxyChild(tile, pos);
|
|
||||||
|
|
||||||
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
|
||||||
// check if parent was already drawn
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
proxy = r.parent.item;
|
|
||||||
if (proxy.state == STATE_READY)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// this will do nothing, just to check
|
|
||||||
if (drawProxyChild(tile, pos) > 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
proxy = r.parent.parent.item;
|
|
||||||
if (proxy.state == STATE_READY)
|
|
||||||
drawTile(proxy, pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -24,15 +24,15 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
import org.oscim.layers.tile.TileLayer;
|
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.layers.tile.bitmap.TileSource.FadeStep;
|
||||||
import org.oscim.renderer.sublayers.BitmapLayer;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.BitmapLayer;
|
||||||
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
|
import org.oscim.tiling.TileLoader;
|
||||||
|
import org.oscim.tiling.TileManager;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
|
|
||||||
public class BitmapTileLayer extends TileLayer<TileLoader> {
|
public class BitmapTileLayer extends TileLayer<TileLoader> {
|
||||||
@ -92,7 +92,7 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
|
|||||||
InputStream inputStream = getInputStream(urlConnection);
|
InputStream inputStream = getInputStream(urlConnection);
|
||||||
Bitmap bitmap = CanvasAdapter.g.decodeBitmap(inputStream);
|
Bitmap bitmap = CanvasAdapter.g.decodeBitmap(inputStream);
|
||||||
|
|
||||||
tile.layers = new Layers();
|
tile.layers = new ElementLayers();
|
||||||
BitmapLayer l = new BitmapLayer(false);
|
BitmapLayer l = new BitmapLayer(false);
|
||||||
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
|
||||||
|
|
||||||
|
@ -12,23 +12,22 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile.test;
|
package org.oscim.layers.tile.example;
|
||||||
|
|
||||||
import org.oscim.view.Map;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
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.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
import org.oscim.layers.tile.TileLayer;
|
import org.oscim.layers.tile.TileLayer;
|
||||||
import org.oscim.layers.tile.TileLoader;
|
import org.oscim.layers.tile.example.TestTileLayer.TestTileLoader;
|
||||||
import org.oscim.layers.tile.TileManager;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.layers.tile.test.TestTileLayer.TestTileLoader;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.tiling.TileLoader;
|
||||||
|
import org.oscim.tiling.TileManager;
|
||||||
|
|
||||||
public class TestTileLayer extends TileLayer<TestTileLoader> {
|
public class TestTileLayer extends TileLayer<TestTileLoader> {
|
||||||
final static String TAG = TestTileLayer.class.getName();
|
final static String TAG = TestTileLayer.class.getName();
|
||||||
@ -53,7 +52,7 @@ public class TestTileLayer extends TileLayer<TestTileLoader> {
|
|||||||
@Override
|
@Override
|
||||||
public boolean executeJob(MapTile tile) {
|
public boolean executeJob(MapTile tile) {
|
||||||
Log.d(TAG, "load tile " + tile);
|
Log.d(TAG, "load tile " + tile);
|
||||||
tile.layers = new Layers();
|
tile.layers = new ElementLayers();
|
||||||
|
|
||||||
LineLayer ll = tile.layers.getLineLayer(0);
|
LineLayer ll = tile.layers.getLineLayer(0);
|
||||||
ll.line = mLineStyle;
|
ll.line = mLineStyle;
|
@ -12,26 +12,28 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.overlay;
|
package org.oscim.layers.tile.vector;
|
||||||
|
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.layers.InputLayer;
|
||||||
import org.oscim.renderer.layers.ExtrusionRenderLayer;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.ExtrusionRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.tiling.TileRenderer;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
*/
|
*/
|
||||||
public class BuildingOverlay extends Overlay {
|
public class BuildingLayer extends InputLayer {
|
||||||
//private final static String TAG = BuildingOverlay.class.getName();
|
//private final static String TAG = BuildingOverlay.class.getName();
|
||||||
|
|
||||||
final ExtrusionRenderLayer mExtLayer;
|
final ExtrusionRenderer mExtLayer;
|
||||||
|
|
||||||
public BuildingOverlay(Map map, org.oscim.layers.tile.TileRenderLayer tileRenderLayer) {
|
public BuildingLayer(Map map, TileRenderer tileRenderer) {
|
||||||
super(map);
|
super(map);
|
||||||
mExtLayer = new ExtrusionRenderLayer(tileRenderLayer) {
|
mExtLayer = new ExtrusionRenderer(tileRenderer) {
|
||||||
private long mStartTime;
|
private long mStartTime;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,7 +72,7 @@ public class BuildingOverlay extends Overlay {
|
|||||||
super.update(pos, changed, m);
|
super.update(pos, changed, m);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mLayer = mExtLayer;
|
mRenderer = mExtLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
//private int multi;
|
//private int multi;
|
@ -18,32 +18,32 @@ import org.oscim.backend.Log;
|
|||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.tile.TileLayer;
|
import org.oscim.layers.tile.TileLayer;
|
||||||
import org.oscim.layers.tile.TileLoader;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.layers.tile.TileManager;
|
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.tilesource.ITileDataSource;
|
import org.oscim.tiling.TileLoader;
|
||||||
import org.oscim.tilesource.MapInfo;
|
import org.oscim.tiling.TileManager;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.ITileDataSource;
|
||||||
import org.oscim.tilesource.TileSource.OpenResult;
|
import org.oscim.tiling.source.MapInfo;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.tiling.source.TileSource;
|
||||||
|
import org.oscim.tiling.source.TileSource.OpenResult;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The vector-tile-map layer. This class manages instances of
|
* The vector-tile-map layer. This class manages instances of
|
||||||
* {@link MapTileLoader} that load and assemble vector tiles
|
* {@link VectorTileLoader} that load and assemble vector tiles
|
||||||
* for rendering.
|
* for rendering.
|
||||||
*/
|
*/
|
||||||
public class MapTileLayer extends TileLayer<MapTileLoader> {
|
public class VectorTileLayer extends TileLayer<VectorTileLoader> {
|
||||||
private final static String TAG = MapTileLayer.class.getName();
|
private final static String TAG = VectorTileLayer.class.getName();
|
||||||
|
|
||||||
private TileSource mTileSource;
|
private TileSource mTileSource;
|
||||||
|
|
||||||
public MapTileLayer(Map map) {
|
public VectorTileLayer(Map map) {
|
||||||
super(map);
|
super(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MapTileLoader createLoader(TileManager tm) {
|
protected VectorTileLoader createLoader(TileManager tm) {
|
||||||
return new MapTileLoader(tm);
|
return new VectorTileLoader(tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +91,7 @@ public class MapTileLayer extends TileLayer<MapTileLoader> {
|
|||||||
public void setRenderTheme(IRenderTheme theme) {
|
public void setRenderTheme(IRenderTheme theme) {
|
||||||
pauseLoaders(true);
|
pauseLoaders(true);
|
||||||
|
|
||||||
for (MapTileLoader g : mTileLoader)
|
for (VectorTileLoader g : mTileLoader)
|
||||||
g.setRenderTheme(theme);
|
g.setRenderTheme(theme);
|
||||||
|
|
||||||
resumeLoaders();
|
resumeLoaders();
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile.vector;
|
package org.oscim.layers.tile.vector;
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NONE;
|
import static org.oscim.tiling.MapTile.STATE_NONE;
|
||||||
|
|
||||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
@ -22,16 +22,15 @@ import org.oscim.core.MercatorProjection;
|
|||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.vector.labeling.WayDecorator;
|
||||||
import org.oscim.layers.tile.TileLoader;
|
import org.oscim.map.DebugSettings;
|
||||||
import org.oscim.layers.tile.TileManager;
|
import org.oscim.renderer.elements.ExtrusionLayer;
|
||||||
import org.oscim.renderer.sublayers.ExtrusionLayer;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.LineTexLayer;
|
||||||
import org.oscim.renderer.sublayers.LineTexLayer;
|
import org.oscim.renderer.elements.PolygonLayer;
|
||||||
import org.oscim.renderer.sublayers.PolygonLayer;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
|
||||||
import org.oscim.theme.IRenderCallback;
|
import org.oscim.theme.IRenderCallback;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.renderinstruction.Area;
|
import org.oscim.theme.renderinstruction.Area;
|
||||||
@ -41,28 +40,31 @@ import org.oscim.theme.renderinstruction.LineSymbol;
|
|||||||
import org.oscim.theme.renderinstruction.RenderInstruction;
|
import org.oscim.theme.renderinstruction.RenderInstruction;
|
||||||
import org.oscim.theme.renderinstruction.Symbol;
|
import org.oscim.theme.renderinstruction.Symbol;
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
import org.oscim.tilesource.ITileDataSink;
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.tilesource.ITileDataSource;
|
import org.oscim.tiling.TileLoader;
|
||||||
import org.oscim.tilesource.ITileDataSource.QueryResult;
|
import org.oscim.tiling.TileManager;
|
||||||
|
import org.oscim.tiling.source.ITileDataSink;
|
||||||
|
import org.oscim.tiling.source.ITileDataSource;
|
||||||
|
import org.oscim.tiling.source.ITileDataSource.QueryResult;
|
||||||
import org.oscim.utils.LineClipper;
|
import org.oscim.utils.LineClipper;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.oscim.view.DebugSettings;
|
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note
|
* @note
|
||||||
* 1. The MapWorkers call MapTileLoader.execute() to load a tile.
|
* 0.
|
||||||
* 2. The tile data will be loaded from current MapDatabase
|
* 1. The ... call MapTileLoader.executeJob() to load a tile.
|
||||||
* 3. MapDatabase calls the IMapDataSink functions
|
* 2. The tile data will be loaded from current TileSource
|
||||||
* implemented by MapTileLoader for WAY and POI items.
|
* 3. TileSource calls the IMapDataSink process()
|
||||||
* 4. these callbacks then call RenderTheme to get the matching style.
|
* . implemented by MapTileLoader for MapElement items.
|
||||||
|
* 4. these callbacks then call RenderTheme to get the matching RenderInstructions (style).
|
||||||
* 5. RenderTheme calls IRenderCallback functions with style information
|
* 5. RenderTheme calls IRenderCallback functions with style information
|
||||||
* 6. Styled items become added to MapTile.layers... roughly
|
* 6. Styled items become added to MapTile.layers...
|
||||||
*/
|
*/
|
||||||
public class MapTileLoader extends TileLoader implements IRenderCallback, ITileDataSink {
|
public class VectorTileLoader extends TileLoader implements IRenderCallback, ITileDataSink {
|
||||||
|
|
||||||
private static final String TAG = MapTileLoader.class.getName();
|
private static final String TAG = VectorTileLoader.class.getName();
|
||||||
|
|
||||||
private static final double STROKE_INCREASE = Math.sqrt(2.5);
|
private static final double STROKE_INCREASE = Math.sqrt(2.5);
|
||||||
private static final byte LAYERS = 11;
|
private static final byte LAYERS = 11;
|
||||||
@ -117,7 +119,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
debug = debugSettings;
|
debug = debugSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapTileLoader(TileManager tileManager) {
|
public VectorTileLoader(TileManager tileManager) {
|
||||||
super(tileManager);
|
super(tileManager);
|
||||||
|
|
||||||
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
|
mClipper = new LineClipper(0, 0, Tile.SIZE, Tile.SIZE, true);
|
||||||
@ -155,7 +157,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
* MercatorProjection.EARTH_CIRCUMFERENCE
|
* MercatorProjection.EARTH_CIRCUMFERENCE
|
||||||
/ ((long) Tile.SIZE << mTile.zoomLevel));
|
/ ((long) Tile.SIZE << mTile.zoomLevel));
|
||||||
|
|
||||||
mTile.layers = new Layers();
|
mTile.layers = new ElementLayers();
|
||||||
|
|
||||||
// query database, which calls renderWay and renderPOI
|
// query database, which calls renderWay and renderPOI
|
||||||
// callbacks while processing map tile data.
|
// callbacks while processing map tile data.
|
||||||
@ -508,7 +510,7 @@ public class MapTileLoader extends TileLoader implements IRenderCallback, ITileD
|
|||||||
SymbolItem it = SymbolItem.pool.get();
|
SymbolItem it = SymbolItem.pool.get();
|
||||||
it.x = mElement.points[0];
|
it.x = mElement.points[0];
|
||||||
it.y = mElement.points[1];
|
it.y = mElement.points[1];
|
||||||
it.symbol = symbol.texture;
|
it.texRegion = symbol.texture;
|
||||||
it.billboard = true;
|
it.billboard = true;
|
||||||
|
|
||||||
mTile.symbols = Inlist.push(mTile.symbols, it);
|
mTile.symbols = Inlist.push(mTile.symbols, it);
|
@ -12,19 +12,19 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.labeling;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
|
|
||||||
class Debug {
|
class Debug {
|
||||||
|
|
||||||
private final static float[] mDebugPoints = new float[4];
|
private final static float[] mDebugPoints = new float[4];
|
||||||
|
|
||||||
static void addDebugBox(Layers dbg, Label l, TextItem ti, int overlaps, boolean prev,
|
static void addDebugBox(ElementLayers dbg, Label l, TextItem ti, int overlaps, boolean prev,
|
||||||
float scale) {
|
float scale) {
|
||||||
|
|
||||||
LineLayer ll;
|
LineLayer ll;
|
||||||
@ -60,7 +60,7 @@ class Debug {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addDebugLayers(Layers dbg) {
|
static void addDebugLayers(ElementLayers dbg) {
|
||||||
int alpha = 0xaaffffff;
|
int alpha = 0xaaffffff;
|
||||||
|
|
||||||
dbg.clear();
|
dbg.clear();
|
@ -12,10 +12,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.labeling;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.utils.OBB2D;
|
import org.oscim.utils.OBB2D;
|
||||||
|
|
||||||
class Label extends TextItem {
|
class Label extends TextItem {
|
@ -12,32 +12,32 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.labeling;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.InputLayer;
|
import org.oscim.layers.InputLayer;
|
||||||
import org.oscim.layers.tile.TileRenderLayer;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.view.Map;
|
import org.oscim.tiling.TileRenderer;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
|
|
||||||
public class LabelLayer extends InputLayer {
|
public class LabelLayer extends InputLayer {
|
||||||
private final static String TAG = LabelLayer.class.getName();
|
private final static String TAG = LabelLayer.class.getName();
|
||||||
final TextRenderLayer mTextLayer;
|
final TextRenderer mTextRenderer;
|
||||||
|
|
||||||
public LabelLayer(Map map, TileRenderLayer tileRenderLayer) {
|
public LabelLayer(Map map, TileRenderer tileRenderLayer) {
|
||||||
super(map);
|
super(map);
|
||||||
|
|
||||||
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
|
//mTextLayer = new org.oscim.renderer.layers.TextRenderLayer(map, tileRenderLayer);
|
||||||
mTextLayer = new TextRenderLayer(map, tileRenderLayer);
|
mTextRenderer = new TextRenderer(map, tileRenderLayer);
|
||||||
mLayer = mTextLayer;
|
mRenderer = mTextRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
if (clear)
|
if (clear)
|
||||||
mTextLayer.clearLabels();
|
mTextRenderer.clearLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int multi;
|
private int multi;
|
||||||
@ -47,17 +47,21 @@ public class LabelLayer extends InputLayer {
|
|||||||
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
int action = e.getAction() & MotionEvent.ACTION_MASK;
|
||||||
if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
if (action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||||
multi++;
|
multi++;
|
||||||
mTextLayer.hold(true);
|
mTextRenderer.hold(true);
|
||||||
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
} else if (action == MotionEvent.ACTION_POINTER_UP) {
|
||||||
multi--;
|
multi--;
|
||||||
if (multi == 0)
|
if (multi == 0)
|
||||||
mTextLayer.hold(false);
|
mTextRenderer.hold(false);
|
||||||
} else if (action == MotionEvent.ACTION_CANCEL) {
|
} else if (action == MotionEvent.ACTION_CANCEL) {
|
||||||
multi = 0;
|
multi = 0;
|
||||||
Log.d(TAG, "cancel " + multi);
|
Log.d(TAG, "cancel " + multi);
|
||||||
mTextLayer.hold(false);
|
mTextRenderer.hold(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.layers.labeling;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// 1. rewrite. seriously
|
// 1. rewrite. seriously
|
||||||
@ -30,30 +30,29 @@ package org.oscim.layers.labeling;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.layers.tile.TileRenderLayer;
|
import org.oscim.map.Viewport;
|
||||||
import org.oscim.layers.tile.TileSet;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.Layer;
|
import org.oscim.renderer.elements.RenderElement;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.LineRenderer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.PolygonRenderer;
|
import org.oscim.renderer.elements.PolygonLayer;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
import org.oscim.renderer.sublayers.SymbolLayer;
|
import org.oscim.renderer.elements.SymbolLayer;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextLayer;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.renderer.sublayers.TextureLayer;
|
import org.oscim.renderer.elements.TextureLayer;
|
||||||
import org.oscim.renderer.sublayers.TextureRenderer;
|
import org.oscim.tiling.MapTile;
|
||||||
|
import org.oscim.tiling.TileRenderer;
|
||||||
|
import org.oscim.tiling.TileSet;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.OBB2D;
|
import org.oscim.utils.OBB2D;
|
||||||
import org.oscim.utils.pool.LList;
|
import org.oscim.utils.pool.LList;
|
||||||
import org.oscim.utils.pool.Pool;
|
import org.oscim.utils.pool.Pool;
|
||||||
import org.oscim.view.Map;
|
|
||||||
import org.oscim.view.Viewport;
|
|
||||||
|
|
||||||
class TextRenderLayer extends BasicRenderLayer {
|
class TextRenderer extends ElementRenderer {
|
||||||
//private final static String TAG = TextRenderLayer.class.getName();
|
//private final static String TAG = TextRenderLayer.class.getName();
|
||||||
|
|
||||||
private final static float MIN_CAPTION_DIST = 5;
|
private final static float MIN_CAPTION_DIST = 5;
|
||||||
@ -130,10 +129,10 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
|
|
||||||
private float mSquareRadius;
|
private float mSquareRadius;
|
||||||
private int mRelabelCnt;
|
private int mRelabelCnt;
|
||||||
private final TileRenderLayer mTileLayer;
|
private final TileRenderer mTileLayer;
|
||||||
private final Map mMap;
|
private final Map mMap;
|
||||||
|
|
||||||
public TextRenderLayer(Map map, TileRenderLayer baseLayer) {
|
public TextRenderer(Map map, TileRenderer baseLayer) {
|
||||||
mMap = map;
|
mMap = map;
|
||||||
mViewport = map.getViewport();
|
mViewport = map.getViewport();
|
||||||
mTileLayer = baseLayer;
|
mTileLayer = baseLayer;
|
||||||
@ -259,7 +258,7 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Layers mDebugLayer;
|
private ElementLayers mDebugLayer;
|
||||||
|
|
||||||
private Label getLabel() {
|
private Label getLabel() {
|
||||||
Label l = (Label) mPool.get();
|
Label l = (Label) mPool.get();
|
||||||
@ -304,9 +303,9 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layers dbg = null;
|
ElementLayers dbg = null;
|
||||||
if (mMap.getDebugSettings().debugLabels)
|
if (mMap.getDebugSettings().debugLabels)
|
||||||
dbg = new Layers();
|
dbg = new ElementLayers();
|
||||||
|
|
||||||
int mw = (mMap.getWidth() + Tile.SIZE) / 2;
|
int mw = (mMap.getWidth() + Tile.SIZE) / 2;
|
||||||
int mh = (mMap.getHeight() + Tile.SIZE) / 2;
|
int mh = (mMap.getHeight() + Tile.SIZE) / 2;
|
||||||
@ -529,7 +528,7 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
if (ti.text.caption){
|
if (ti.text.caption){
|
||||||
if (ti.text.texture != null) {
|
if (ti.text.texture != null) {
|
||||||
SymbolItem s = SymbolItem.pool.get();
|
SymbolItem s = SymbolItem.pool.get();
|
||||||
s.symbol = ti.text.texture;
|
s.texRegion = ti.text.texture;
|
||||||
s.x = ti.x;
|
s.x = ti.x;
|
||||||
s.y = ti.y;
|
s.y = ti.y;
|
||||||
s.billboard = true;
|
s.billboard = true;
|
||||||
@ -559,12 +558,12 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
dx = flipLongitude(dx, maxx);
|
dx = flipLongitude(dx, maxx);
|
||||||
|
|
||||||
for (SymbolItem ti = t.symbols; ti != null; ti = ti.next) {
|
for (SymbolItem ti = t.symbols; ti != null; ti = ti.next) {
|
||||||
if (ti.symbol == null)
|
if (ti.texRegion == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SymbolItem s = SymbolItem.pool.get();
|
SymbolItem s = SymbolItem.pool.get();
|
||||||
|
|
||||||
s.symbol = ti.symbol;
|
s.texRegion = ti.texRegion;
|
||||||
s.x = (float) ((dx + ti.x) * scale);
|
s.x = (float) ((dx + ti.x) * scale);
|
||||||
s.y = (float) ((dy + ti.y) * scale);
|
s.y = (float) ((dy + ti.y) * scale);
|
||||||
s.billboard = true;
|
s.billboard = true;
|
||||||
@ -703,20 +702,20 @@ class TextRenderLayer extends BasicRenderLayer {
|
|||||||
setMatrix(pos, m, true);
|
setMatrix(pos, m, true);
|
||||||
|
|
||||||
if (layers.baseLayers != null) {
|
if (layers.baseLayers != null) {
|
||||||
for (Layer l = layers.baseLayers; l != null;) {
|
for (RenderElement l = layers.baseLayers; l != null;) {
|
||||||
if (l.type == Layer.POLYGON) {
|
if (l.type == RenderElement.POLYGON) {
|
||||||
l = PolygonRenderer.draw(pos, l, m, true, 1, false);
|
l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, false);
|
||||||
} else {
|
} else {
|
||||||
float div = scale * (float) (pos.scale / (1 << pos.zoomLevel));
|
float div = scale * (float) (pos.scale / (1 << pos.zoomLevel));
|
||||||
l = LineRenderer.draw(layers, l, pos, m, div, 0);
|
l = LineLayer.Renderer.draw(layers, l, pos, m, div, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setMatrix(pos, m, false);
|
setMatrix(pos, m, false);
|
||||||
|
|
||||||
for (Layer l = layers.textureLayers; l != null;)
|
for (RenderElement l = layers.textureLayers; l != null;)
|
||||||
l = TextureRenderer.draw(l, scale, m);
|
l = TextureLayer.Renderer.draw(l, scale, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
//private boolean mHolding;
|
//private boolean mHolding;
|
@ -13,12 +13,12 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile.vector;
|
package org.oscim.layers.tile.vector.labeling;
|
||||||
|
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.utils.GeometryUtils;
|
import org.oscim.utils.GeometryUtils;
|
||||||
import org.oscim.utils.LineClipper;
|
import org.oscim.utils.LineClipper;
|
||||||
|
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.view;
|
package org.oscim.map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple DTO to stores flags for debugging rendered map tiles.
|
* A simple DTO to stores flags for debugging rendered map tiles.
|
@ -14,7 +14,7 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.view;
|
package org.oscim.map;
|
||||||
|
|
||||||
import java.util.AbstractList;
|
import java.util.AbstractList;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
@ -23,11 +23,9 @@ import org.oscim.backend.Log;
|
|||||||
import org.oscim.backend.input.KeyEvent;
|
import org.oscim.backend.input.KeyEvent;
|
||||||
import org.oscim.backend.input.MotionEvent;
|
import org.oscim.backend.input.MotionEvent;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Point;
|
|
||||||
import org.oscim.layers.InputLayer;
|
import org.oscim.layers.InputLayer;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
import org.oscim.layers.overlay.Overlay.Snappable;
|
import org.oscim.renderer.LayerRenderer;
|
||||||
import org.oscim.renderer.RenderLayer;
|
|
||||||
|
|
||||||
public class Layers extends AbstractList<Layer> {
|
public class Layers extends AbstractList<Layer> {
|
||||||
private final static String TAG = Layers.class.getName();
|
private final static String TAG = Layers.class.getName();
|
||||||
@ -68,13 +66,13 @@ public class Layers extends AbstractList<Layer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean mDirtyLayers;
|
private boolean mDirtyLayers;
|
||||||
private RenderLayer[] mDrawLayers;
|
private LayerRenderer[] mLayerRenderer;
|
||||||
|
|
||||||
public RenderLayer[] getRenderLayers() {
|
public LayerRenderer[] getLayerRenderer() {
|
||||||
if (mDirtyLayers)
|
if (mDirtyLayers)
|
||||||
updateLayers();
|
updateLayers();
|
||||||
|
|
||||||
return mDrawLayers;
|
return mLayerRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
public void onUpdate(MapPosition mapPosition, boolean changed, boolean clear) {
|
||||||
@ -108,7 +106,7 @@ public class Layers extends AbstractList<Layer> {
|
|||||||
for (int i = 0, n = mLayerList.size(); i < n; i++) {
|
for (int i = 0, n = mLayerList.size(); i < n; i++) {
|
||||||
Layer o = mLayerList.get(i);
|
Layer o = mLayerList.get(i);
|
||||||
|
|
||||||
if (o.getLayer() != null)
|
if (o.getRenderer() != null)
|
||||||
numRenderLayers++;
|
numRenderLayers++;
|
||||||
|
|
||||||
if (o instanceof InputLayer)
|
if (o instanceof InputLayer)
|
||||||
@ -117,14 +115,14 @@ public class Layers extends AbstractList<Layer> {
|
|||||||
mLayers[i] = o;
|
mLayers[i] = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
mDrawLayers = new RenderLayer[numRenderLayers];
|
mLayerRenderer = new LayerRenderer[numRenderLayers];
|
||||||
mInputLayer = new InputLayer[numInputLayers];
|
mInputLayer = new InputLayer[numInputLayers];
|
||||||
|
|
||||||
for (int i = 0, cntR = 0, cntI = 1, n = mLayerList.size(); i < n; i++) {
|
for (int i = 0, cntR = 0, cntI = 1, n = mLayerList.size(); i < n; i++) {
|
||||||
Layer o = mLayerList.get(i);
|
Layer o = mLayerList.get(i);
|
||||||
RenderLayer l = o.getLayer();
|
LayerRenderer l = o.getRenderer();
|
||||||
if (l != null)
|
if (l != null)
|
||||||
mDrawLayers[cntR++] = l;
|
mLayerRenderer[cntR++] = l;
|
||||||
|
|
||||||
if (o instanceof InputLayer) {
|
if (o instanceof InputLayer) {
|
||||||
// sort from top to bottom, so that highest layers
|
// sort from top to bottom, so that highest layers
|
||||||
@ -218,18 +216,6 @@ public class Layers extends AbstractList<Layer> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onSnapToItem(int x, int y, Point snapPoint) {
|
|
||||||
if (mDirtyLayers)
|
|
||||||
updateLayers();
|
|
||||||
|
|
||||||
for (InputLayer o : mInputLayer)
|
|
||||||
if (o instanceof Snappable)
|
|
||||||
if (((Snappable) o).onSnapToItem(x, y, snapPoint))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// /* GestureDetector.OnDoubleTapListener */
|
// /* GestureDetector.OnDoubleTapListener */
|
||||||
//
|
//
|
||||||
// public boolean onDoubleTap(MotionEvent e) {
|
// public boolean onDoubleTap(MotionEvent e) {
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.view;
|
package org.oscim.map;
|
||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
@ -20,13 +20,13 @@ import org.oscim.core.GeoPoint;
|
|||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.layers.MapEventLayer;
|
import org.oscim.layers.MapEventLayer;
|
||||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
import org.oscim.layers.tile.bitmap.BitmapTileLayer;
|
||||||
import org.oscim.layers.tile.vector.MapTileLayer;
|
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||||
import org.oscim.layers.tile.vector.MapTileLoader;
|
import org.oscim.layers.tile.vector.VectorTileLoader;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.theme.IRenderTheme;
|
import org.oscim.theme.IRenderTheme;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
import org.oscim.theme.ThemeLoader;
|
import org.oscim.theme.ThemeLoader;
|
||||||
import org.oscim.tilesource.TileSource;
|
import org.oscim.tiling.source.TileSource;
|
||||||
import org.oscim.utils.async.AsyncExecutor;
|
import org.oscim.utils.async.AsyncExecutor;
|
||||||
|
|
||||||
public abstract class Map {
|
public abstract class Map {
|
||||||
@ -45,7 +45,7 @@ public abstract class Map {
|
|||||||
protected boolean mClearMap;
|
protected boolean mClearMap;
|
||||||
protected final MapEventLayer mEventLayer;
|
protected final MapEventLayer mEventLayer;
|
||||||
|
|
||||||
private MapTileLayer mBaseLayer;
|
private VectorTileLayer mBaseLayer;
|
||||||
//private BitmapTileLayer mBackgroundLayer;
|
//private BitmapTileLayer mBackgroundLayer;
|
||||||
|
|
||||||
public Map() {
|
public Map() {
|
||||||
@ -58,7 +58,7 @@ public abstract class Map {
|
|||||||
mAsyncExecutor = new AsyncExecutor(2);
|
mAsyncExecutor = new AsyncExecutor(2);
|
||||||
|
|
||||||
mDebugSettings = new DebugSettings();
|
mDebugSettings = new DebugSettings();
|
||||||
MapTileLoader.setDebugSettings(mDebugSettings);
|
VectorTileLoader.setDebugSettings(mDebugSettings);
|
||||||
|
|
||||||
mEventLayer = new MapEventLayer(this);
|
mEventLayer = new MapEventLayer(this);
|
||||||
mLayers.add(0, mEventLayer);
|
mLayers.add(0, mEventLayer);
|
||||||
@ -68,8 +68,8 @@ public abstract class Map {
|
|||||||
return mEventLayer;
|
return mEventLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapTileLayer setBaseMap(TileSource tileSource) {
|
public VectorTileLayer setBaseMap(TileSource tileSource) {
|
||||||
mBaseLayer = new MapTileLayer(this);
|
mBaseLayer = new VectorTileLayer(this);
|
||||||
|
|
||||||
mBaseLayer.setTileSource(tileSource);
|
mBaseLayer.setTileSource(tileSource);
|
||||||
mLayers.add(1, mBaseLayer);
|
mLayers.add(1, mBaseLayer);
|
||||||
@ -81,7 +81,7 @@ public abstract class Map {
|
|||||||
mLayers.add(1, tileLayer);
|
mLayers.add(1, tileLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapTileLayer setBaseMap(BitmapTileLayer tileLayer) {
|
public VectorTileLayer setBaseMap(BitmapTileLayer tileLayer) {
|
||||||
mLayers.add(1, tileLayer);
|
mLayers.add(1, tileLayer);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ public abstract class Map {
|
|||||||
|
|
||||||
mCurrentTheme = theme;
|
mCurrentTheme = theme;
|
||||||
mBaseLayer.setRenderTheme(t);
|
mBaseLayer.setRenderTheme(t);
|
||||||
GLRenderer.setBackgroundColor(t.getMapBackground());
|
MapRenderer.setBackgroundColor(t.getMapBackground());
|
||||||
|
|
||||||
clearMap();
|
clearMap();
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package org.oscim.view;
|
package org.oscim.map;
|
||||||
|
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.GeoPoint;
|
import org.oscim.core.GeoPoint;
|
@ -13,7 +13,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.view;
|
package org.oscim.map;
|
||||||
|
|
||||||
import org.oscim.core.BoundingBox;
|
import org.oscim.core.BoundingBox;
|
||||||
import org.oscim.core.Box;
|
import org.oscim.core.Box;
|
@ -12,22 +12,19 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.BitmapLayer;
|
import org.oscim.renderer.elements.BitmapLayer;
|
||||||
import org.oscim.renderer.sublayers.BitmapRenderer;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RenderLayer to draw a custom Bitmap.
|
* RenderLayer to draw a custom Bitmap.
|
||||||
* NOTE: Only modify the Bitmap within a synchronized block!
|
* NOTE: Only modify the Bitmap within a synchronized block!
|
||||||
* synchronized(bitmap){}
|
* synchronized(bitmap){} Then call updateBitmap().
|
||||||
* Then call updateBitmap().
|
|
||||||
*/
|
*/
|
||||||
public class BitmapRenderLayer extends BasicRenderLayer {
|
public class BitmapRenderer extends ElementRenderer {
|
||||||
|
|
||||||
private Bitmap mBitmap;
|
private Bitmap mBitmap;
|
||||||
private int mWidth;
|
private int mWidth;
|
||||||
@ -87,6 +84,6 @@ public class BitmapRenderLayer extends BasicRenderLayer {
|
|||||||
@Override
|
@Override
|
||||||
protected synchronized void render(MapPosition pos, Matrices m) {
|
protected synchronized void render(MapPosition pos, Matrices m) {
|
||||||
m.useScreenCoordinates(false, 8);
|
m.useScreenCoordinates(false, 8);
|
||||||
BitmapRenderer.draw(layers.textureLayers, m, 1, 1);
|
BitmapLayer.Renderer.draw(layers.textureLayers, m, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,33 +12,29 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.elements.BitmapLayer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.elements.RenderElement;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.BitmapRenderer;
|
import org.oscim.renderer.elements.LineTexLayer;
|
||||||
import org.oscim.renderer.sublayers.Layer;
|
import org.oscim.renderer.elements.PolygonLayer;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.TextureLayer;
|
||||||
import org.oscim.renderer.sublayers.LineRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.LineTexRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.PolygonRenderer;
|
|
||||||
import org.oscim.renderer.sublayers.TextureRenderer;
|
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class to use the renderer.sublayers for drawing
|
* Base class to use the renderer.sublayers for drawing
|
||||||
*/
|
*/
|
||||||
public abstract class BasicRenderLayer extends RenderLayer {
|
public abstract class ElementRenderer extends LayerRenderer {
|
||||||
|
|
||||||
public final Layers layers;
|
public final ElementLayers layers;
|
||||||
|
|
||||||
public BasicRenderLayer() {
|
public ElementRenderer() {
|
||||||
layers = new Layers();
|
layers = new ElementLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,18 +54,18 @@ public abstract class BasicRenderLayer extends RenderLayer {
|
|||||||
if (layers.baseLayers != null) {
|
if (layers.baseLayers != null) {
|
||||||
setMatrix(curPos, m, true);
|
setMatrix(curPos, m, true);
|
||||||
|
|
||||||
for (Layer l = layers.baseLayers; l != null;) {
|
for (RenderElement l = layers.baseLayers; l != null;) {
|
||||||
switch (l.type) {
|
switch (l.type) {
|
||||||
case Layer.POLYGON:
|
case RenderElement.POLYGON:
|
||||||
l = PolygonRenderer.draw(curPos, l, m, true, 1, false);
|
l = PolygonLayer.Renderer.draw(curPos, l, m, true, 1, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Layer.LINE:
|
case RenderElement.LINE:
|
||||||
l = LineRenderer.draw(layers, l, curPos, m, div, simple);
|
l = LineLayer.Renderer.draw(layers, l, curPos, m, div, simple);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Layer.TEXLINE:
|
case RenderElement.TEXLINE:
|
||||||
l = LineTexRenderer.draw(layers, l, curPos, m, div);
|
l = LineTexLayer.Renderer.draw(layers, l, curPos, m, div);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,14 +76,14 @@ public abstract class BasicRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
float scale = (float) (pos.scale / curPos.scale);
|
float scale = (float) (pos.scale / curPos.scale);
|
||||||
|
|
||||||
for (Layer l = layers.textureLayers; l != null;) {
|
for (RenderElement l = layers.textureLayers; l != null;) {
|
||||||
switch (l.type) {
|
switch (l.type) {
|
||||||
case Layer.BITMAP:
|
case RenderElement.BITMAP:
|
||||||
l = BitmapRenderer.draw(l, m, 1, 1);
|
l = BitmapLayer.Renderer.draw(l, m, 1, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
l = TextureRenderer.draw(l, scale, m);
|
l = TextureLayer.Renderer.draw(l, scale, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,7 +102,7 @@ public abstract class BasicRenderLayer extends RenderLayer {
|
|||||||
if (layers.vbo == null)
|
if (layers.vbo == null)
|
||||||
layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
|
layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
|
||||||
|
|
||||||
if (GLRenderer.uploadLayers(layers, newSize, true))
|
if (MapRenderer.uploadLayers(layers, newSize, true))
|
||||||
setReady(true);
|
setReady(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,33 +12,33 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.layers.tile.TileRenderLayer;
|
import org.oscim.renderer.elements.ExtrusionLayer;
|
||||||
import org.oscim.layers.tile.TileSet;
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.tiling.TileRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.tiling.TileSet;
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.renderer.RenderLayer;
|
|
||||||
import org.oscim.renderer.sublayers.ExtrusionLayer;
|
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
public class ExtrusionRenderLayer extends RenderLayer {
|
// TODO move MapTile part to BuildingLayer and make
|
||||||
private final static String TAG = ExtrusionRenderLayer.class.getName();
|
// this class work on ExtrusionLayers
|
||||||
|
|
||||||
|
public class ExtrusionRenderer extends LayerRenderer {
|
||||||
|
private final static String TAG = ExtrusionRenderer.class.getName();
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
private final TileRenderLayer mTileLayer;
|
private final TileRenderer mTileLayer;
|
||||||
|
|
||||||
protected float mAlpha = 1;
|
protected float mAlpha = 1;
|
||||||
|
|
||||||
public ExtrusionRenderLayer(TileRenderLayer tileRenderLayer) {
|
public ExtrusionRenderer(TileRenderer tileRenderLayer) {
|
||||||
mTileLayer = tileRenderLayer;
|
mTileLayer = tileRenderLayer;
|
||||||
mTileSet = new TileSet();
|
mTileSet = new TileSet();
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
if (!el.compiled) {
|
if (!el.compiled) {
|
||||||
int numShorts = el.mNumVertices * 8;
|
int numShorts = el.mNumVertices * 8;
|
||||||
el.compile(GLRenderer.getShortBuffer(numShorts));
|
el.compile(MapRenderer.getShortBuffer(numShorts));
|
||||||
GlUtils.checkGlError("...");
|
GlUtils.checkGlError("...");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
for (int i = 0; i < mTileCnt; i++) {
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||||
int d = GLRenderer.depthOffset(t) * 10;
|
int d = MapRenderer.depthOffset(t) * 10;
|
||||||
setMatrix(pos, m, t, d);
|
setMatrix(pos, m, t, d);
|
||||||
m.mvp.setAsUniform(uExtMatrix);
|
m.mvp.setAsUniform(uExtMatrix);
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
|
||||||
|
|
||||||
GL.glDepthFunc(GL20.GL_EQUAL);
|
GL.glDepthFunc(GL20.GL_EQUAL);
|
||||||
int d = GLRenderer.depthOffset(t) * 10;
|
int d = MapRenderer.depthOffset(t) * 10;
|
||||||
setMatrix(pos, m, t, d);
|
setMatrix(pos, m, t, d);
|
||||||
m.mvp.setAsUniform(uExtMatrix);
|
m.mvp.setAsUniform(uExtMatrix);
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ public class ExtrusionRenderLayer extends RenderLayer {
|
|||||||
|
|
||||||
float x = (float) ((tile.x - pos.x) * curScale);
|
float x = (float) ((tile.x - pos.x) * curScale);
|
||||||
float y = (float) ((tile.y - pos.y) * curScale);
|
float y = (float) ((tile.y - pos.y) * curScale);
|
||||||
m.mvp.setTransScale(x, y, scale / GLRenderer.COORD_SCALE);
|
m.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
|
||||||
|
|
||||||
// scale height
|
// scale height
|
||||||
m.mvp.setValue(10, scale / 10);
|
m.mvp.setValue(10, scale / 10);
|
@ -12,21 +12,21 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer;
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
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.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextLayer;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
|
|
||||||
public class GridRenderLayer extends BasicRenderLayer {
|
public class GridRenderer extends ElementRenderer {
|
||||||
// private final static String TILE_FORMAT = "%d/%d/%d";
|
// private final static String TILE_FORMAT = "%d/%d/%d";
|
||||||
private final TextLayer mTextLayer;
|
private final TextLayer mTextLayer;
|
||||||
private final Text mText;
|
private final Text mText;
|
||||||
@ -37,7 +37,7 @@ public class GridRenderLayer extends BasicRenderLayer {
|
|||||||
|
|
||||||
private int mCurX, mCurY, mCurZ;
|
private int mCurX, mCurY, mCurZ;
|
||||||
|
|
||||||
public GridRenderLayer() {
|
public GridRenderer() {
|
||||||
|
|
||||||
int size = Tile.SIZE;
|
int size = Tile.SIZE;
|
||||||
|
|
@ -16,9 +16,9 @@ package org.oscim.renderer;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
|
||||||
public abstract class RenderLayer {
|
public abstract class LayerRenderer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use mMapPosition.copy(position) to keep the position for which
|
* Use mMapPosition.copy(position) to keep the position for which
|
||||||
@ -32,20 +32,20 @@ public abstract class RenderLayer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set 'ready for render' state when layer data is ready for rendering.
|
* Set 'ready for render' state when layer data is ready for rendering.
|
||||||
* This will
|
*
|
||||||
* */
|
* @param true if render() should be called, false otherwise.
|
||||||
protected void setReady(boolean ready){
|
*/
|
||||||
|
protected void setReady(boolean ready) {
|
||||||
isReady = ready;
|
isReady = ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderLayer() {
|
public LayerRenderer() {
|
||||||
mMapPosition = new MapPosition();
|
mMapPosition = new MapPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ////////////////////// GLRender Thread ///////////////////////////
|
* ////////////////////// MapRender Thread ///////////////////////////
|
||||||
* 1. Called first by GLRenderer:
|
* 1. Called first by MapRenderer: Update the state here.
|
||||||
* Update the layer state here.
|
|
||||||
*
|
*
|
||||||
* @param position current MapPosition
|
* @param position current MapPosition
|
||||||
* @param changed
|
* @param changed
|
||||||
@ -64,7 +64,7 @@ public abstract class RenderLayer {
|
|||||||
protected abstract void compile();
|
protected abstract void compile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 3. Draw layer:
|
* 3. Draw layer: called by MapRenderer when isReady == true.
|
||||||
*
|
*
|
||||||
* @param position current MapPosition
|
* @param position current MapPosition
|
||||||
* @param matrices contains the current view- and projection-matrices.
|
* @param matrices contains the current view- and projection-matrices.
|
||||||
@ -100,7 +100,7 @@ public abstract class RenderLayer {
|
|||||||
// x -= 1.0;
|
// x -= 1.0;
|
||||||
|
|
||||||
matrices.mvp.setTransScale((float) (x * tileScale), (float) (y * tileScale),
|
matrices.mvp.setTransScale((float) (x * tileScale), (float) (y * tileScale),
|
||||||
(float) ((position.scale / oPos.scale) / GLRenderer.COORD_SCALE));
|
(float) ((position.scale / oPos.scale) / MapRenderer.COORD_SCALE));
|
||||||
|
|
||||||
matrices.mvp.multiplyLhs(project ? matrices.viewproj : matrices.view);
|
matrices.mvp.multiplyLhs(project ? matrices.viewproj : matrices.view);
|
||||||
}
|
}
|
@ -25,17 +25,17 @@ import org.oscim.backend.GLAdapter;
|
|||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.map.Map;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.map.Viewport;
|
||||||
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
|
import org.oscim.tiling.MapTile;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.utils.Matrix4;
|
import org.oscim.utils.Matrix4;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.oscim.utils.pool.Pool;
|
import org.oscim.utils.pool.Pool;
|
||||||
import org.oscim.view.Map;
|
|
||||||
import org.oscim.view.Viewport;
|
|
||||||
|
|
||||||
public class GLRenderer {
|
public class MapRenderer {
|
||||||
private static final String TAG = GLRenderer.class.getName();
|
private static final String TAG = MapRenderer.class.getName();
|
||||||
|
|
||||||
private static GL20 GL = GLAdapter.get();
|
private static GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ public class GLRenderer {
|
|||||||
* @param map
|
* @param map
|
||||||
* the MapView
|
* the MapView
|
||||||
*/
|
*/
|
||||||
public GLRenderer(Map map) {
|
public MapRenderer(Map map) {
|
||||||
|
|
||||||
mMap = map;
|
mMap = map;
|
||||||
mViewport = map.getViewport();
|
mViewport = map.getViewport();
|
||||||
@ -232,7 +232,7 @@ public class GLRenderer {
|
|||||||
return b.intBuffer;
|
return b.intBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean uploadLayers(Layers layers, int newSize,
|
public static boolean uploadLayers(ElementLayers layers, int newSize,
|
||||||
boolean addFill) {
|
boolean addFill) {
|
||||||
// add fill coordinates
|
// add fill coordinates
|
||||||
if (addFill)
|
if (addFill)
|
||||||
@ -315,10 +315,10 @@ public class GLRenderer {
|
|||||||
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
/* update layers */
|
/* update layers */
|
||||||
RenderLayer[] layers = mMap.getLayers().getRenderLayers();
|
LayerRenderer[] layers = mMap.getLayers().getLayerRenderer();
|
||||||
|
|
||||||
for (int i = 0, n = layers.length; i < n; i++) {
|
for (int i = 0, n = layers.length; i < n; i++) {
|
||||||
RenderLayer renderLayer = layers[i];
|
LayerRenderer renderLayer = layers[i];
|
||||||
|
|
||||||
renderLayer.update(pos, changed, mMatrices);
|
renderLayer.update(pos, changed, mMatrices);
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ public class GLRenderer {
|
|||||||
indices[i + 4] = (short) (j + 1);
|
indices[i + 4] = (short) (j + 1);
|
||||||
indices[i + 5] = (short) (j + 3);
|
indices[i + 5] = (short) (j + 3);
|
||||||
}
|
}
|
||||||
ShortBuffer buf = GLRenderer.getShortBuffer(indices.length);
|
ShortBuffer buf = MapRenderer.getShortBuffer(indices.length);
|
||||||
buf.put(indices);
|
buf.put(indices);
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
||||||
@ -396,7 +396,7 @@ public class GLRenderer {
|
|||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
// initialize default quad
|
// initialize default quad
|
||||||
FloatBuffer floatBuffer = GLRenderer.getFloatBuffer(indices.length);
|
FloatBuffer floatBuffer = MapRenderer.getFloatBuffer(indices.length);
|
||||||
|
|
||||||
float[] quad = new float[] { -1, -1, -1, 1, 1, -1, 1, 1 };
|
float[] quad = new float[] { -1, -1, -1, 1, 1, -1, 1, 1 };
|
||||||
floatBuffer.put(quad);
|
floatBuffer.put(quad);
|
||||||
@ -423,7 +423,7 @@ public class GLRenderer {
|
|||||||
// Log.d(TAG, GL.glGetString(GL20.GL_EXTENSIONS));
|
// Log.d(TAG, GL.glGetString(GL20.GL_EXTENSIONS));
|
||||||
|
|
||||||
// classes that require GL context for initialization
|
// classes that require GL context for initialization
|
||||||
Layers.initRenderer();
|
ElementLayers.initRenderer();
|
||||||
|
|
||||||
// Set up some vertex buffer objects
|
// Set up some vertex buffer objects
|
||||||
BufferObject.init(CACHE_TILES);
|
BufferObject.init(CACHE_TILES);
|
@ -17,7 +17,7 @@ package org.oscim.renderer.atlas;
|
|||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
||||||
import org.oscim.renderer.sublayers.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ import java.util.HashMap;
|
|||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.renderer.sublayers.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
|
|
||||||
|
|
||||||
|
265
vtm/src/org/oscim/renderer/elements/BitmapLayer.java
Normal file
265
vtm/src/org/oscim/renderer/elements/BitmapLayer.java
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renderer for a single bitmap, width and height must be power of 2.
|
||||||
|
*/
|
||||||
|
public class BitmapLayer extends TextureLayer {
|
||||||
|
// private final static String TAG = BitmapLayer.class.getName();
|
||||||
|
private Bitmap mBitmap;
|
||||||
|
private final boolean mReuseBitmap;
|
||||||
|
private final short[] mVertices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param reuseBitmap false if the Bitmap should be recycled after
|
||||||
|
* it is compiled to texture.
|
||||||
|
*/
|
||||||
|
public BitmapLayer(boolean reuseBitmap) {
|
||||||
|
type = RenderElement.BITMAP;
|
||||||
|
mReuseBitmap = reuseBitmap;
|
||||||
|
mVertices = new short[24];
|
||||||
|
|
||||||
|
// used for size calculation of Layers buffer.
|
||||||
|
verticesCnt = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitmap(Bitmap bitmap, int w, int h) {
|
||||||
|
mWidth = w;
|
||||||
|
mHeight = h;
|
||||||
|
|
||||||
|
mBitmap = bitmap;
|
||||||
|
if (this.textures == null)
|
||||||
|
this.textures = new TextureItem(mBitmap);
|
||||||
|
|
||||||
|
TextureItem ti = this.textures;
|
||||||
|
ti.vertices = TextureLayer.Renderer.INDICES_PER_SPRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mWidth, mHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set target dimension to renderthe bitmap
|
||||||
|
*/
|
||||||
|
public void setSize(int w, int h) {
|
||||||
|
mWidth = w;
|
||||||
|
mHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVertices(ShortBuffer sbuf) {
|
||||||
|
short[] buf = mVertices;
|
||||||
|
short w = (short) (mWidth * MapRenderer.COORD_SCALE);
|
||||||
|
short h = (short) (mHeight * MapRenderer.COORD_SCALE);
|
||||||
|
|
||||||
|
short t = 1;
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
// top-left
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
// bot-left
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = h;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = t;
|
||||||
|
// top-right
|
||||||
|
buf[pos++] = w;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = t;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
// bot-right
|
||||||
|
buf[pos++] = w;
|
||||||
|
buf[pos++] = h;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = -1;
|
||||||
|
buf[pos++] = t;
|
||||||
|
buf[pos++] = t;
|
||||||
|
|
||||||
|
this.offset = sbuf.position() * 2; // bytes
|
||||||
|
sbuf.put(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prepare() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
|
||||||
|
if (mBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setVertices(sbuf);
|
||||||
|
|
||||||
|
textures.upload();
|
||||||
|
|
||||||
|
if (!mReuseBitmap) {
|
||||||
|
mBitmap.recycle();
|
||||||
|
mBitmap = null;
|
||||||
|
textures.bitmap = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clear() {
|
||||||
|
|
||||||
|
if (mBitmap != null) {
|
||||||
|
if (!mReuseBitmap)
|
||||||
|
mBitmap.recycle();
|
||||||
|
|
||||||
|
mBitmap = null;
|
||||||
|
textures.bitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureItem.releaseTexture(textures);
|
||||||
|
textures = null;
|
||||||
|
|
||||||
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
vertexItems = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Renderer {
|
||||||
|
|
||||||
|
//private final static String TAG = BitmapRenderer.class.getName();
|
||||||
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
|
public final static boolean debug = true;
|
||||||
|
|
||||||
|
private static int mTextureProgram;
|
||||||
|
private static int hTextureMVMatrix;
|
||||||
|
private static int hTextureProjMatrix;
|
||||||
|
private static int hTextureVertex;
|
||||||
|
private static int hTextureScale;
|
||||||
|
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;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
mTextureProgram = GlUtils.createProgram(textVertexShader,
|
||||||
|
textFragmentShader);
|
||||||
|
|
||||||
|
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
||||||
|
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
||||||
|
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
||||||
|
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 RenderElement draw(RenderElement renderElement, Matrices m, float scale, float alpha) {
|
||||||
|
//GLState.test(false, false);
|
||||||
|
GLState.blend(true);
|
||||||
|
|
||||||
|
GLState.useProgram(mTextureProgram);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
|
TextureLayer tl = (TextureLayer) renderElement;
|
||||||
|
|
||||||
|
if (tl.fixed)
|
||||||
|
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
||||||
|
else
|
||||||
|
GL.glUniform1f(hTextureScale, 1);
|
||||||
|
|
||||||
|
GL.glUniform1f(hTextureScreenScale, 1f / MapRenderer.screenWidth);
|
||||||
|
GL.glUniform1f(hAlpha, alpha);
|
||||||
|
|
||||||
|
m.proj.setAsUniform(hTextureProjMatrix);
|
||||||
|
|
||||||
|
m.mvp.setAsUniform(hTextureMVMatrix);
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, MapRenderer.mQuadIndicesID);
|
||||||
|
|
||||||
|
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
||||||
|
|
||||||
|
ti.bind();
|
||||||
|
|
||||||
|
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
|
// draw up to maxVertices in each iteration
|
||||||
|
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
||||||
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
|
int off = (ti.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
|
GL20.GL_SHORT, false, 12, off);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
|
int numVertices = ti.vertices - i;
|
||||||
|
if (numVertices > maxVertices)
|
||||||
|
numVertices = maxVertices;
|
||||||
|
|
||||||
|
GL.glDrawElements(GL20.GL_TRIANGLES, numVertices,
|
||||||
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return renderElement.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static String textVertexShader = ""
|
||||||
|
+ "precision mediump float; "
|
||||||
|
+ "attribute vec4 vertex;"
|
||||||
|
+ "attribute vec2 tex_coord;"
|
||||||
|
+ "uniform mat4 u_mv;"
|
||||||
|
+ "uniform mat4 u_proj;"
|
||||||
|
+ "uniform float u_scale;"
|
||||||
|
+ "uniform float u_swidth;"
|
||||||
|
+ "varying vec2 tex_c;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||||
|
+ " 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) * u_alpha;"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
@ -21,24 +21,24 @@ import org.oscim.theme.renderinstruction.Line;
|
|||||||
|
|
||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
|
|
||||||
public class Layers {
|
public class ElementLayers {
|
||||||
private final static String TAG = Layers.class.getName();
|
private final static String TAG = ElementLayers.class.getName();
|
||||||
|
|
||||||
public static void initRenderer() {
|
public static void initRenderer() {
|
||||||
LineRenderer.init();
|
LineLayer.Renderer.init();
|
||||||
LineTexRenderer.init();
|
LineTexLayer.Renderer.init();
|
||||||
PolygonRenderer.init();
|
PolygonLayer.Renderer.init();
|
||||||
TextureRenderer.init();
|
TextureLayer.Renderer.init();
|
||||||
BitmapRenderer.init();
|
BitmapLayer.Renderer.init();
|
||||||
TextureItem.init(0);
|
TextureItem.init(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// mixed Polygon- and LineLayer
|
// mixed Polygon- and LineLayer
|
||||||
public Layer baseLayers;
|
public RenderElement baseLayers;
|
||||||
// Text- and SymbolLayer
|
// Text- and SymbolLayer
|
||||||
public Layer textureLayers;
|
public RenderElement textureLayers;
|
||||||
//
|
//
|
||||||
public Layer extrusionLayers;
|
public RenderElement extrusionLayers;
|
||||||
|
|
||||||
// VBO holds all vertex data to draw lines and polygons
|
// VBO holds all vertex data to draw lines and polygons
|
||||||
// after are compilation.
|
// after are compilation.
|
||||||
@ -52,7 +52,7 @@ public class Layers {
|
|||||||
// To not need to switch VertexAttribPointer positions all the time:
|
// To not need to switch VertexAttribPointer positions all the time:
|
||||||
// 1. polygons are packed in VBO at offset 0
|
// 1. polygons are packed in VBO at offset 0
|
||||||
// 2. lines afterwards at lineOffset
|
// 2. lines afterwards at lineOffset
|
||||||
// 3. other layers keep their byte offset in Layer.offset
|
// 3. other layers keep their byte offset in RenderElement.offset
|
||||||
public int lineOffset;
|
public int lineOffset;
|
||||||
public int texLineOffset;
|
public int texLineOffset;
|
||||||
|
|
||||||
@ -60,14 +60,14 @@ public class Layers {
|
|||||||
// used for animations
|
// used for animations
|
||||||
public long time;
|
public long time;
|
||||||
|
|
||||||
private Layer mCurLayer;
|
private RenderElement mCurLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* add the LineLayer for a level with a given Line style. Levels are
|
* add the LineLayer for a level with a given Line style. Levels are
|
||||||
* ordered from bottom (0) to top
|
* ordered from bottom (0) to top
|
||||||
*/
|
*/
|
||||||
public LineLayer addLineLayer(int level, Line style) {
|
public LineLayer addLineLayer(int level, Line style) {
|
||||||
LineLayer ll = (LineLayer) getLayer(level, Layer.LINE);
|
LineLayer ll = (LineLayer) getLayer(level, RenderElement.LINE);
|
||||||
if (ll == null)
|
if (ll == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ public class Layers {
|
|||||||
* bottom (0) to top
|
* bottom (0) to top
|
||||||
*/
|
*/
|
||||||
public LineLayer getLineLayer(int level) {
|
public LineLayer getLineLayer(int level) {
|
||||||
return (LineLayer) getLayer(level, Layer.LINE);
|
return (LineLayer) getLayer(level, RenderElement.LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,7 +91,7 @@ public class Layers {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public PolygonLayer getPolygonLayer(int level) {
|
public PolygonLayer getPolygonLayer(int level) {
|
||||||
return (PolygonLayer) getLayer(level, Layer.POLYGON);
|
return (PolygonLayer) getLayer(level, RenderElement.POLYGON);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,7 +100,7 @@ public class Layers {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public LineTexLayer getLineTexLayer(int level) {
|
public LineTexLayer getLineTexLayer(int level) {
|
||||||
return (LineTexLayer) getLayer(level, Layer.TEXLINE);
|
return (LineTexLayer) getLayer(level, RenderElement.TEXLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextLayer addTextLayer(TextLayer textLayer) {
|
public TextLayer addTextLayer(TextLayer textLayer) {
|
||||||
@ -109,12 +109,12 @@ public class Layers {
|
|||||||
return textLayer;
|
return textLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Layer getLayer(int level, byte type) {
|
private RenderElement getLayer(int level, byte type) {
|
||||||
Layer l = baseLayers;
|
RenderElement l = baseLayers;
|
||||||
Layer layer = null;
|
RenderElement renderElement = null;
|
||||||
|
|
||||||
if (mCurLayer != null && mCurLayer.level == level) {
|
if (mCurLayer != null && mCurLayer.level == level) {
|
||||||
layer = mCurLayer;
|
renderElement = mCurLayer;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (l == null || l.level > level) {
|
if (l == null || l.level > level) {
|
||||||
@ -124,7 +124,7 @@ public class Layers {
|
|||||||
while (true) {
|
while (true) {
|
||||||
// found layer
|
// found layer
|
||||||
if (l.level == level) {
|
if (l.level == level) {
|
||||||
layer = l;
|
renderElement = l;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,40 +136,40 @@ public class Layers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer == null) {
|
if (renderElement == null) {
|
||||||
// add a new Layer
|
// add a new RenderElement
|
||||||
if (type == Layer.LINE)
|
if (type == RenderElement.LINE)
|
||||||
layer = new LineLayer(level);
|
renderElement = new LineLayer(level);
|
||||||
else if (type == Layer.POLYGON)
|
else if (type == RenderElement.POLYGON)
|
||||||
layer = new PolygonLayer(level);
|
renderElement = new PolygonLayer(level);
|
||||||
else if (type == Layer.TEXLINE)
|
else if (type == RenderElement.TEXLINE)
|
||||||
layer = new LineTexLayer(level);
|
renderElement = new LineTexLayer(level);
|
||||||
else
|
else
|
||||||
// TODO throw execption
|
// TODO throw execption
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
// insert at start
|
// insert at start
|
||||||
layer.next = baseLayers;
|
renderElement.next = baseLayers;
|
||||||
baseLayers = layer;
|
baseLayers = renderElement;
|
||||||
} else {
|
} else {
|
||||||
layer.next = l.next;
|
renderElement.next = l.next;
|
||||||
l.next = layer;
|
l.next = renderElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layer.type != type) {
|
if (renderElement.type != type) {
|
||||||
// check if found layer matches requested type
|
// check if found layer matches requested type
|
||||||
Log.d(TAG, "BUG wrong layer " + layer.type + " " + type +
|
Log.d(TAG, "BUG wrong layer " + renderElement.type + " " + type +
|
||||||
" on layer " + layer.level);
|
" on layer " + renderElement.level);
|
||||||
// TODO throw exception
|
// TODO throw exception
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurLayer = layer;
|
mCurLayer = renderElement;
|
||||||
|
|
||||||
return layer;
|
return renderElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static int[] VERTEX_SHORT_CNT = {
|
private final static int[] VERTEX_SHORT_CNT = {
|
||||||
@ -185,10 +185,10 @@ public class Layers {
|
|||||||
public int getSize() {
|
public int getSize() {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
for (Layer l = baseLayers; l != null; l = l.next)
|
for (RenderElement l = baseLayers; l != null; l = l.next)
|
||||||
size += l.verticesCnt * VERTEX_SHORT_CNT[l.type];
|
size += l.verticesCnt * VERTEX_SHORT_CNT[l.type];
|
||||||
|
|
||||||
for (Layer l = textureLayers; l != null; l = l.next)
|
for (RenderElement l = textureLayers; l != null; l = l.next)
|
||||||
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
size += l.verticesCnt * TEXTURE_VERTEX_SHORTS;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -204,14 +204,14 @@ public class Layers {
|
|||||||
size = 8;
|
size = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
size += addLayerItems(sbuf, baseLayers, Layer.POLYGON, pos);
|
size += addLayerItems(sbuf, baseLayers, RenderElement.POLYGON, pos);
|
||||||
|
|
||||||
lineOffset = size * SHORT_BYTES;
|
lineOffset = size * SHORT_BYTES;
|
||||||
size += addLayerItems(sbuf, baseLayers, Layer.LINE, 0);
|
size += addLayerItems(sbuf, baseLayers, RenderElement.LINE, 0);
|
||||||
|
|
||||||
texLineOffset = size * SHORT_BYTES;
|
texLineOffset = size * SHORT_BYTES;
|
||||||
for (Layer l = baseLayers; l != null; l = l.next) {
|
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
||||||
if (l.type == Layer.TEXLINE) {
|
if (l.type == RenderElement.TEXLINE) {
|
||||||
addPoolItems(l, sbuf);
|
addPoolItems(l, sbuf);
|
||||||
// add additional vertex for interleaving,
|
// add additional vertex for interleaving,
|
||||||
// see TexLineLayer.
|
// see TexLineLayer.
|
||||||
@ -219,13 +219,13 @@ public class Layers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
for (RenderElement l = textureLayers; l != null; l = l.next) {
|
||||||
TextureLayer tl = (TextureLayer) l;
|
TextureLayer tl = (TextureLayer) l;
|
||||||
tl.compile(sbuf);
|
tl.compile(sbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extrusion layers are compiled by extrusion overlay
|
// extrusion layers are compiled by extrusion overlay
|
||||||
// for (Layer l = extrusionLayers; l != null; l = l.next) {
|
// for (RenderElement l = extrusionLayers; l != null; l = l.next) {
|
||||||
// ExtrusionLayer tl = (ExtrusionLayer) l;
|
// ExtrusionLayer tl = (ExtrusionLayer) l;
|
||||||
// tl.compile(sbuf);
|
// tl.compile(sbuf);
|
||||||
// }
|
// }
|
||||||
@ -233,7 +233,7 @@ public class Layers {
|
|||||||
|
|
||||||
// optimization for Line- and PolygonLayer:
|
// optimization for Line- and PolygonLayer:
|
||||||
// collect all pool items and add back in one go
|
// collect all pool items and add back in one go
|
||||||
private static int addLayerItems(ShortBuffer sbuf, Layer l, byte type, int pos) {
|
private static int addLayerItems(ShortBuffer sbuf, RenderElement l, byte type, int pos) {
|
||||||
VertexItem last = null, items = null;
|
VertexItem last = null, items = null;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ public class Layers {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addPoolItems(Layer l, ShortBuffer sbuf) {
|
static void addPoolItems(RenderElement l, ShortBuffer sbuf) {
|
||||||
// offset of layer data in vbo
|
// offset of layer data in vbo
|
||||||
l.offset = sbuf.position() * SHORT_BYTES;
|
l.offset = sbuf.position() * SHORT_BYTES;
|
||||||
|
|
||||||
@ -290,7 +290,7 @@ public class Layers {
|
|||||||
public void clear() {
|
public void clear() {
|
||||||
|
|
||||||
// clear line and polygon layers directly
|
// clear line and polygon layers directly
|
||||||
for (Layer l = baseLayers; l != null; l = l.next) {
|
for (RenderElement l = baseLayers; l != null; l = l.next) {
|
||||||
if (l.vertexItems != null) {
|
if (l.vertexItems != null) {
|
||||||
VertexItem.pool.releaseAll(l.vertexItems);
|
VertexItem.pool.releaseAll(l.vertexItems);
|
||||||
l.vertexItems = null;
|
l.vertexItems = null;
|
||||||
@ -299,11 +299,11 @@ public class Layers {
|
|||||||
l.verticesCnt = 0;
|
l.verticesCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = textureLayers; l != null; l = l.next) {
|
for (RenderElement l = textureLayers; l != null; l = l.next) {
|
||||||
l.clear();
|
l.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Layer l = extrusionLayers; l != null; l = l.next) {
|
for (RenderElement l = extrusionLayers; l != null; l = l.next) {
|
||||||
l.clear();
|
l.clear();
|
||||||
}
|
}
|
||||||
baseLayers = null;
|
baseLayers = null;
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ import org.oscim.core.GeometryBuffer;
|
|||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.utils.LineClipper;
|
import org.oscim.utils.LineClipper;
|
||||||
import org.oscim.utils.geom.Triangulator;
|
import org.oscim.utils.geom.Triangulator;
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ import org.oscim.utils.geom.Triangulator;
|
|||||||
* FIXME check if polygon has self intersections or 0/180 degree
|
* FIXME check if polygon has self intersections or 0/180 degree
|
||||||
* angles! or bad things might happen in Triangle
|
* angles! or bad things might happen in Triangle
|
||||||
*/
|
*/
|
||||||
public class ExtrusionLayer extends Layer {
|
public class ExtrusionLayer extends RenderElement {
|
||||||
private final static String TAG = ExtrusionLayer.class.getName();
|
private final static String TAG = ExtrusionLayer.class.getName();
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
private static final float S = GLRenderer.COORD_SCALE;
|
private static final float S = MapRenderer.COORD_SCALE;
|
||||||
private VertexItem mVertices;
|
private VertexItem mVertices;
|
||||||
private VertexItem mCurVertices;
|
private VertexItem mCurVertices;
|
||||||
private VertexItem mIndices[];
|
private VertexItem mIndices[];
|
||||||
@ -62,7 +62,7 @@ public class ExtrusionLayer extends Layer {
|
|||||||
private final float mGroundResolution;
|
private final float mGroundResolution;
|
||||||
|
|
||||||
public ExtrusionLayer(int level, float groundResolution) {
|
public ExtrusionLayer(int level, float groundResolution) {
|
||||||
this.type = Layer.EXTRUSION;
|
this.type = RenderElement.EXTRUSION;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
|
||||||
mGroundResolution = groundResolution;
|
mGroundResolution = groundResolution;
|
954
vtm/src/org/oscim/renderer/elements/LineLayer.java
Normal file
954
vtm/src/org/oscim/renderer/elements/LineLayer.java
Normal file
@ -0,0 +1,954 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.backend.canvas.Paint.Cap;
|
||||||
|
import org.oscim.core.GeometryBuffer;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public final class LineLayer extends RenderElement {
|
||||||
|
private final static String TAG = LineLayer.class.getName();
|
||||||
|
|
||||||
|
private static final float COORD_SCALE = MapRenderer.COORD_SCALE;
|
||||||
|
// scale factor mapping extrusion vector to short values
|
||||||
|
public static final float DIR_SCALE = 2048;
|
||||||
|
// mask for packing last two bits of extrusion vector with texture
|
||||||
|
// coordinates
|
||||||
|
private static final int DIR_MASK = 0xFFFFFFFC;
|
||||||
|
|
||||||
|
// lines referenced by this outline layer
|
||||||
|
public LineLayer outlines;
|
||||||
|
public Line line;
|
||||||
|
public float width;
|
||||||
|
|
||||||
|
public boolean roundCap;
|
||||||
|
|
||||||
|
LineLayer(int layer) {
|
||||||
|
this.level = layer;
|
||||||
|
this.type = RenderElement.LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOutline(LineLayer link) {
|
||||||
|
for (LineLayer l = outlines; l != null; l = l.outlines)
|
||||||
|
if (link == l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
link.outlines = outlines;
|
||||||
|
outlines = link;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* line extrusion is based on code from GLMap
|
||||||
|
* (https://github.com/olofsj/GLMap/)
|
||||||
|
*
|
||||||
|
* @param points
|
||||||
|
* array of points as x,y pairs.
|
||||||
|
* @param index
|
||||||
|
* array of indices holding the length of the individual
|
||||||
|
* line coordinates (i.e. points * 2).
|
||||||
|
* when index is null one a line with points.length
|
||||||
|
* is assumed.
|
||||||
|
* @param closed
|
||||||
|
* whether to connect start- and end-point.
|
||||||
|
*/
|
||||||
|
public void addLine(float[] points, short[] index, boolean closed) {
|
||||||
|
addLine(points, index, -1, closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLine(GeometryBuffer geom) {
|
||||||
|
if (geom.isPoly())
|
||||||
|
addLine(geom.points, geom.index, -1, true);
|
||||||
|
else if (geom.isLine())
|
||||||
|
addLine(geom.points, geom.index, -1, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLine(float[] points, int numPoints, boolean closed) {
|
||||||
|
if (numPoints >= 4)
|
||||||
|
addLine(points, null, numPoints, closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLine(float[] points, short[] index, int numPoints, boolean closed) {
|
||||||
|
float x, y, nextX, nextY;
|
||||||
|
float a, ux, uy, vx, vy, wx, wy;
|
||||||
|
|
||||||
|
int tmax = Tile.SIZE + 4;
|
||||||
|
int tmin = -4;
|
||||||
|
|
||||||
|
boolean rounded = false;
|
||||||
|
boolean squared = false;
|
||||||
|
|
||||||
|
if (line.cap == Cap.ROUND)
|
||||||
|
rounded = true;
|
||||||
|
else if (line.cap == Cap.SQUARE)
|
||||||
|
squared = true;
|
||||||
|
|
||||||
|
if (vertexItems == null)
|
||||||
|
curItem = vertexItems = VertexItem.pool.get();
|
||||||
|
|
||||||
|
VertexItem si = curItem;
|
||||||
|
short v[] = si.vertices;
|
||||||
|
int opos = si.used;
|
||||||
|
|
||||||
|
// FIXME: remove this when switching to oscimap MapDatabase
|
||||||
|
//if (!MapView.enableClosePolygons)
|
||||||
|
// closed = false;
|
||||||
|
|
||||||
|
// Note: just a hack to save some vertices, when there are more than 200 lines
|
||||||
|
// per type
|
||||||
|
if (rounded) {
|
||||||
|
int cnt = 0;
|
||||||
|
for (int i = 0, n = index.length; i < n; i++, cnt++) {
|
||||||
|
if (index[i] < 0)
|
||||||
|
break;
|
||||||
|
if (cnt > 400) {
|
||||||
|
rounded = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roundCap = rounded;
|
||||||
|
|
||||||
|
int n;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
n = 1;
|
||||||
|
if (numPoints > 0) {
|
||||||
|
length = numPoints;
|
||||||
|
} else {
|
||||||
|
length = points.length;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n = index.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, pos = 0; i < n; i++) {
|
||||||
|
if (index != null)
|
||||||
|
length = index[i];
|
||||||
|
|
||||||
|
// check end-marker in indices
|
||||||
|
if (length < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// need at least two points
|
||||||
|
if (length < 4) {
|
||||||
|
pos += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// amount of vertices used
|
||||||
|
// + 2 for drawing triangle-strip
|
||||||
|
// + 4 for round caps
|
||||||
|
// + 2 for closing polygons
|
||||||
|
verticesCnt += length + (rounded ? 6 : 2) + (closed ? 2 : 0);
|
||||||
|
|
||||||
|
int ipos = pos;
|
||||||
|
|
||||||
|
x = points[ipos++];
|
||||||
|
y = points[ipos++];
|
||||||
|
|
||||||
|
nextX = points[ipos++];
|
||||||
|
nextY = points[ipos++];
|
||||||
|
|
||||||
|
// Calculate triangle corners for the given width
|
||||||
|
vx = nextX - x;
|
||||||
|
vy = nextY - y;
|
||||||
|
|
||||||
|
// Unit vector to next node
|
||||||
|
a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
vx /= a;
|
||||||
|
vy /= a;
|
||||||
|
|
||||||
|
// perpendicular on the first segment
|
||||||
|
ux = -vy;
|
||||||
|
uy = vx;
|
||||||
|
|
||||||
|
int ddx, ddy;
|
||||||
|
|
||||||
|
// vertex point coordinate
|
||||||
|
short ox = (short) (x * COORD_SCALE);
|
||||||
|
short oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
|
// vertex extrusion vector, last two bit
|
||||||
|
// encode texture coord.
|
||||||
|
short dx, dy;
|
||||||
|
|
||||||
|
// when the endpoint is outside the tile region omit round caps.
|
||||||
|
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounded && !outside) {
|
||||||
|
// add first vertex twice
|
||||||
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (2 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (2 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start of line
|
||||||
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// outside means line is probably clipped
|
||||||
|
// TODO should align ending with tile boundary
|
||||||
|
// for now, just extend the line a little
|
||||||
|
float tx = vx;
|
||||||
|
float ty = vy;
|
||||||
|
|
||||||
|
if (squared) {
|
||||||
|
tx = 0;
|
||||||
|
ty = 0;
|
||||||
|
} else if (!outside) {
|
||||||
|
tx *= 0.5;
|
||||||
|
ty *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounded)
|
||||||
|
verticesCnt -= 2;
|
||||||
|
|
||||||
|
// add first vertex twice
|
||||||
|
ddx = (int) ((ux - tx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - ty) * DIR_SCALE);
|
||||||
|
dx = (short) (0 | ddx & DIR_MASK);
|
||||||
|
dy = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddx = (int) (-(ux + tx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + ty) * DIR_SCALE);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
x = nextX;
|
||||||
|
y = nextY;
|
||||||
|
boolean flip = false;
|
||||||
|
// Unit vector pointing back to previous node
|
||||||
|
vx *= -1;
|
||||||
|
vy *= -1;
|
||||||
|
|
||||||
|
int end = pos + length;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (ipos < end) {
|
||||||
|
nextX = points[ipos++];
|
||||||
|
nextY = points[ipos++];
|
||||||
|
} else if (closed && ipos < end + 2) {
|
||||||
|
// add startpoint == endpoint
|
||||||
|
nextX = points[pos];
|
||||||
|
nextY = points[pos + 1];
|
||||||
|
ipos += 2;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unit vector pointing forward to next node
|
||||||
|
wx = nextX - x;
|
||||||
|
wy = nextY - y;
|
||||||
|
a = (float) Math.sqrt(wx * wx + wy * wy);
|
||||||
|
wx /= a;
|
||||||
|
wy /= a;
|
||||||
|
|
||||||
|
// Sum of these two vectors points
|
||||||
|
ux = vx + wx;
|
||||||
|
uy = vy + wy;
|
||||||
|
|
||||||
|
// cross-product
|
||||||
|
a = wx * uy - wy * ux;
|
||||||
|
|
||||||
|
if (FastMath.abs(a) < 0.01f) {
|
||||||
|
// Almost straight
|
||||||
|
ux = -wy;
|
||||||
|
uy = wx;
|
||||||
|
} else {
|
||||||
|
ux /= a;
|
||||||
|
uy /= a;
|
||||||
|
|
||||||
|
// avoid miter going to infinity.
|
||||||
|
// TODO add option for round joints
|
||||||
|
if (FastMath.absMaxCmp(ux, uy, 4f)) {
|
||||||
|
ux = vx - wx;
|
||||||
|
uy = vy - wy;
|
||||||
|
|
||||||
|
a = -wy * ux + wx * uy;
|
||||||
|
ux /= a;
|
||||||
|
uy /= a;
|
||||||
|
flip = !flip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ox = (short) (x * COORD_SCALE);
|
||||||
|
oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
if (flip) {
|
||||||
|
ddx = -ddx;
|
||||||
|
ddy = -ddy;
|
||||||
|
}
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
|
|
||||||
|
x = nextX;
|
||||||
|
y = nextY;
|
||||||
|
|
||||||
|
// flip unit vector to point back
|
||||||
|
vx = -wx;
|
||||||
|
vy = -wy;
|
||||||
|
}
|
||||||
|
|
||||||
|
ux = vy;
|
||||||
|
uy = -vx;
|
||||||
|
|
||||||
|
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si.next = VertexItem.pool.get();
|
||||||
|
si = si.next;
|
||||||
|
opos = 0;
|
||||||
|
v = si.vertices;
|
||||||
|
}
|
||||||
|
|
||||||
|
ox = (short) (x * COORD_SCALE);
|
||||||
|
oy = (short) (y * COORD_SCALE);
|
||||||
|
|
||||||
|
if (rounded && !outside) {
|
||||||
|
ddx = (int) (ux * DIR_SCALE);
|
||||||
|
ddy = (int) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
if (flip) {
|
||||||
|
ddx = -ddx;
|
||||||
|
ddy = -ddy;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For rounded line edges
|
||||||
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
|
||||||
|
dx = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK);
|
||||||
|
dy = (short) (0 | (flip ? -ddy : ddy) & DIR_MASK);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add last vertex twice
|
||||||
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | (flip ? -ddx : ddx) & DIR_MASK);
|
||||||
|
dy = (short) (0 | (flip ? -ddy : ddy) & DIR_MASK);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (squared) {
|
||||||
|
vx = 0;
|
||||||
|
vy = 0;
|
||||||
|
} else if (!outside) {
|
||||||
|
vx *= 0.5;
|
||||||
|
vy *= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rounded)
|
||||||
|
verticesCnt -= 2;
|
||||||
|
|
||||||
|
ddx = (int) ((ux - vx) * DIR_SCALE);
|
||||||
|
ddy = (int) ((uy - vy) * DIR_SCALE);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK);
|
||||||
|
v[opos++] = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add last vertex twice
|
||||||
|
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
||||||
|
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
||||||
|
dx = (short) (2 | (flip ? -ddx : ddx) & DIR_MASK);
|
||||||
|
dy = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK);
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos++] = ox;
|
||||||
|
v[opos++] = oy;
|
||||||
|
v[opos++] = dx;
|
||||||
|
v[opos++] = dy;
|
||||||
|
}
|
||||||
|
pos += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
si.used = opos;
|
||||||
|
curItem = si;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
if (vertexItems != null) {
|
||||||
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
vertexItems = null;
|
||||||
|
curItem = null;
|
||||||
|
}
|
||||||
|
verticesCnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Renderer {
|
||||||
|
|
||||||
|
private static GL20 GL;
|
||||||
|
|
||||||
|
private static final int LINE_VERTICES_DATA_POS_OFFSET = 0;
|
||||||
|
|
||||||
|
// factor to normalize extrusion vector and scale to coord scale
|
||||||
|
private final static float COORD_SCALE_BY_DIR_SCALE =
|
||||||
|
MapRenderer.COORD_SCALE / LineLayer.DIR_SCALE;
|
||||||
|
|
||||||
|
// shader handles
|
||||||
|
private static int[] lineProgram = new int[2];
|
||||||
|
private static int[] hLineVertexPosition = new int[2];
|
||||||
|
private static int[] hLineColor = new int[2];
|
||||||
|
private static int[] hLineMatrix = new int[2];
|
||||||
|
private static int[] hLineScale = new int[2];
|
||||||
|
private static int[] hLineWidth = new int[2];
|
||||||
|
private static int[] hLineMode = new int[2];
|
||||||
|
public static int mTexID;
|
||||||
|
|
||||||
|
static boolean init() {
|
||||||
|
GL = GLAdapter.get();
|
||||||
|
|
||||||
|
lineProgram[0] = GlUtils.createProgram(lineVertexShader,
|
||||||
|
lineFragmentShader);
|
||||||
|
if (lineProgram[0] == 0) {
|
||||||
|
Log.e(TAG, "Could not create line program.");
|
||||||
|
//return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lineProgram[1] = GlUtils.createProgram(lineVertexShader,
|
||||||
|
lineSimpleFragmentShader);
|
||||||
|
if (lineProgram[1] == 0) {
|
||||||
|
Log.e(TAG, "Could not create simple line program.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
if (lineProgram[i] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
hLineMatrix[i] = GL.glGetUniformLocation(lineProgram[i], "u_mvp");
|
||||||
|
hLineScale[i] = GL.glGetUniformLocation(lineProgram[i], "u_wscale");
|
||||||
|
hLineWidth[i] = GL.glGetUniformLocation(lineProgram[i], "u_width");
|
||||||
|
hLineColor[i] = GL.glGetUniformLocation(lineProgram[i], "u_color");
|
||||||
|
hLineMode[i] = GL.glGetUniformLocation(lineProgram[i], "u_mode");
|
||||||
|
hLineVertexPosition[i] = GL.glGetAttribLocation(lineProgram[i], "a_pos");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create lookup table as texture for 'length(0..1,0..1)'
|
||||||
|
// using mirrored wrap mode for 'length(-1..1,-1..1)'
|
||||||
|
byte[] pixel = new byte[128 * 128];
|
||||||
|
|
||||||
|
for (int x = 0; x < 128; x++) {
|
||||||
|
float xx = x * x;
|
||||||
|
for (int y = 0; y < 128; y++) {
|
||||||
|
float yy = y * y;
|
||||||
|
int color = (int) (Math.sqrt(xx + yy) * 2);
|
||||||
|
if (color > 255)
|
||||||
|
color = 255;
|
||||||
|
pixel[x + y * 128] = (byte) color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mTexID = GlUtils.loadTexture(pixel, 128, 128, GL20.GL_ALPHA,
|
||||||
|
GL20.GL_NEAREST, GL20.GL_NEAREST,
|
||||||
|
GL20.GL_MIRRORED_REPEAT, GL20.GL_MIRRORED_REPEAT);
|
||||||
|
|
||||||
|
Log.d(TAG, "TEX ID: " + mTexID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RenderElement draw(ElementLayers layers, RenderElement curLayer, MapPosition pos,
|
||||||
|
Matrices m, float div, int mode) {
|
||||||
|
|
||||||
|
if (curLayer == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// FIXME HACK: fallback to simple shader
|
||||||
|
if (lineProgram[mode] == 0)
|
||||||
|
mode = 1;
|
||||||
|
|
||||||
|
GLState.useProgram(lineProgram[mode]);
|
||||||
|
|
||||||
|
GLState.blend(true);
|
||||||
|
|
||||||
|
// Somehow we loose the texture after an indefinite
|
||||||
|
// time, when label/symbol textures are used.
|
||||||
|
// Debugging gl on Desktop is most fun imaginable,
|
||||||
|
// so for now:
|
||||||
|
if (!GLAdapter.GDX_DESKTOP_QUIRKS)
|
||||||
|
GLState.bindTex2D(mTexID);
|
||||||
|
|
||||||
|
int uLineScale = hLineScale[mode];
|
||||||
|
int uLineMode = hLineMode[mode];
|
||||||
|
int uLineColor = hLineColor[mode];
|
||||||
|
int uLineWidth = hLineWidth[mode];
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
|
||||||
|
false, 0, layers.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
|
//glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
|
||||||
|
m.mvp.setAsUniform(hLineMatrix[mode]);
|
||||||
|
|
||||||
|
//int zoom = FastMath.log2((int) pos.absScale);
|
||||||
|
int zoom = pos.zoomLevel;
|
||||||
|
|
||||||
|
double scale = pos.getZoomScale();
|
||||||
|
|
||||||
|
// Line scale factor for non fixed lines: Within a zoom-
|
||||||
|
// level lines would be scaled by the factor 2 by view-matrix.
|
||||||
|
// Though lines should only scale by sqrt(2). This is achieved
|
||||||
|
// by inverting scaling of extrusion vector with: width/sqrt(s).
|
||||||
|
// within one zoom-level: 1 <= s <= 2
|
||||||
|
double s = scale / div;
|
||||||
|
float lineScale = (float) Math.sqrt(s * 2 / 2.2);
|
||||||
|
|
||||||
|
// scale factor to map one pixel on tile to one pixel on screen:
|
||||||
|
// only works with orthographic projection
|
||||||
|
float pixel = 0;
|
||||||
|
|
||||||
|
if (mode == 1)
|
||||||
|
pixel = (float) (1.5 / s);
|
||||||
|
|
||||||
|
GL.glUniform1f(uLineScale, pixel);
|
||||||
|
int lineMode = 0;
|
||||||
|
GL.glUniform1f(uLineMode, lineMode);
|
||||||
|
|
||||||
|
boolean blur = false;
|
||||||
|
|
||||||
|
RenderElement l = curLayer;
|
||||||
|
for (; l != null && l.type == RenderElement.LINE; l = l.next) {
|
||||||
|
LineLayer ll = (LineLayer) l;
|
||||||
|
Line line = ll.line;
|
||||||
|
float width;
|
||||||
|
|
||||||
|
if (line.fade < zoom) {
|
||||||
|
GlUtils.setColor(uLineColor, line.color, 1);
|
||||||
|
} else if (line.fade > zoom) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;
|
||||||
|
GlUtils.setColor(uLineColor, line.color, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0 && blur && line.blur == 0) {
|
||||||
|
GL.glUniform1f(uLineScale, 0);
|
||||||
|
blur = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.outline) {
|
||||||
|
// draw linelayers references by this outline
|
||||||
|
for (LineLayer o = ll.outlines; o != null; o = o.outlines) {
|
||||||
|
|
||||||
|
if (o.line.fixed /* || strokeMaxZoom */) {
|
||||||
|
width = (float) ((ll.width + o.width) / s);
|
||||||
|
} else {
|
||||||
|
width = (float) (ll.width / s + o.width / lineScale);
|
||||||
|
|
||||||
|
// check min-size for outline
|
||||||
|
if (o.line.min > 0 && o.width * lineScale < o.line.min * 2)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glUniform1f(uLineWidth, width * COORD_SCALE_BY_DIR_SCALE);
|
||||||
|
|
||||||
|
if (line.blur != 0) {
|
||||||
|
GL.glUniform1f(uLineScale, (float) (1 - (line.blur / s)));
|
||||||
|
blur = true;
|
||||||
|
} else if (mode == 1) {
|
||||||
|
GL.glUniform1f(uLineScale, pixel / width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.roundCap) {
|
||||||
|
if (lineMode != 1) {
|
||||||
|
lineMode = 1;
|
||||||
|
GL.glUniform1f(uLineMode, lineMode);
|
||||||
|
}
|
||||||
|
} else if (lineMode != 0) {
|
||||||
|
lineMode = 0;
|
||||||
|
GL.glUniform1f(uLineMode, lineMode);
|
||||||
|
}
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (line.fixed /* || strokeMaxZoom */) {
|
||||||
|
// invert scaling of extrusion vectors so that line
|
||||||
|
// width stays the same.
|
||||||
|
width = (float) (ll.width / s);
|
||||||
|
} else {
|
||||||
|
// reduce linear scaling of extrusion vectors so that
|
||||||
|
// line width increases by sqrt(2.2).
|
||||||
|
width = ll.width / lineScale;
|
||||||
|
|
||||||
|
// min-size hack to omit outline when line becomes
|
||||||
|
// very thin
|
||||||
|
if ((ll.line.min > 0) && (ll.width * lineScale < ll.line.min * 2))
|
||||||
|
width = (ll.width - 0.2f) / lineScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glUniform1f(uLineWidth, width * COORD_SCALE_BY_DIR_SCALE);
|
||||||
|
|
||||||
|
if (line.blur != 0) {
|
||||||
|
GL.glUniform1f(uLineScale, line.blur);
|
||||||
|
blur = true;
|
||||||
|
} else if (mode == 1) {
|
||||||
|
GL.glUniform1f(uLineScale, pixel / width);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ll.roundCap) {
|
||||||
|
if (lineMode != 1) {
|
||||||
|
lineMode = 1;
|
||||||
|
GL.glUniform1f(uLineMode, lineMode);
|
||||||
|
}
|
||||||
|
} else if (lineMode != 0) {
|
||||||
|
lineMode = 0;
|
||||||
|
GL.glUniform1f(uLineMode, lineMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static String lineVertexShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
// factor to increase line width relative to scale
|
||||||
|
+ "uniform float u_width;"
|
||||||
|
// xy hold position, zw extrusion vector
|
||||||
|
+ "attribute vec4 a_pos;"
|
||||||
|
+ "uniform float u_mode;"
|
||||||
|
+ "varying vec2 v_st;"
|
||||||
|
+ "void main() {"
|
||||||
|
// scale extrusion to u_width pixel
|
||||||
|
// just ignore the two most insignificant bits of a_st :)
|
||||||
|
+ " vec2 dir = a_pos.zw;"
|
||||||
|
+ " gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), 0.0, 1.0);"
|
||||||
|
// last two bits of a_st hold the texture coordinates
|
||||||
|
// ..maybe one could wrap texture so that `abs` is not required
|
||||||
|
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String lineSimpleFragmentShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform sampler2D tex;"
|
||||||
|
+ "uniform float u_wscale;"
|
||||||
|
+ "uniform float u_mode;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "varying vec2 v_st;"
|
||||||
|
+ "void main() {"
|
||||||
|
//+ " float len;"
|
||||||
|
// (currently required as overlay line renderers dont load the texture)
|
||||||
|
//+ " if (u_mode == 0)"
|
||||||
|
//+ " len = abs(v_st.s);"
|
||||||
|
//+ " else"
|
||||||
|
//+ " len = texture2D(tex, v_st).a;"
|
||||||
|
//+ " len = u_mode * length(v_st);"
|
||||||
|
// this avoids branching, need to check performance
|
||||||
|
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
||||||
|
? " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * length(v_st));"
|
||||||
|
: " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * texture2D(tex, v_st).a);")
|
||||||
|
// interpolate alpha between: 0.0 < 1.0 - len < u_wscale
|
||||||
|
// where wscale is 'filter width' / 'line width' and 0 <= len <= sqrt(2)
|
||||||
|
//+ " gl_FragColor = u_color * smoothstep(0.0, u_wscale, 1.0 - len);"
|
||||||
|
//+ " gl_FragColor = mix(vec4(1.0,0.0,0.0,1.0), u_color, smoothstep(0.0, u_wscale, 1.0 - len));"
|
||||||
|
+ " float alpha = min(1.0, (1.0 - len) / u_wscale);"
|
||||||
|
+ " if (alpha > 0.1)"
|
||||||
|
+ " gl_FragColor = u_color * alpha;"
|
||||||
|
+ " else"
|
||||||
|
+ " discard;"
|
||||||
|
// + "gl_FragColor = vec4(texture2D(tex, v_st).a);"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String lineFragmentShader = ""
|
||||||
|
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform sampler2D tex;"
|
||||||
|
+ "uniform float u_mode;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "uniform float u_wscale;"
|
||||||
|
+ "varying vec2 v_st;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " float len;"
|
||||||
|
+ " float fuzz;"
|
||||||
|
+ " if (u_mode == 0.0){"
|
||||||
|
+ " len = abs(v_st.s);"
|
||||||
|
+ " fuzz = fwidth(v_st.s);"
|
||||||
|
+ " } else {"
|
||||||
|
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
||||||
|
? " len = length(v_st);"
|
||||||
|
: " len = texture2D(tex, v_st).a;")
|
||||||
|
+ " vec2 st_width = fwidth(v_st);"
|
||||||
|
+ " fuzz = max(st_width.s, st_width.t);"
|
||||||
|
+ " }"
|
||||||
|
//+ " gl_FragColor = u_color * smoothstep(0.0, fuzz + u_wscale, 1.0 - len);"
|
||||||
|
// smoothstep is too sharp, guess one could increase extrusion with z..
|
||||||
|
// this looks ok:
|
||||||
|
//+ " gl_FragColor = u_color * min(1.0, (1.0 - len) / (u_wscale + fuzz));"
|
||||||
|
// can be faster according to nvidia docs 'Optimize OpenGL ES 2.0 Performace'
|
||||||
|
+ " gl_FragColor = u_color * clamp((1.0 - len) / (u_wscale + fuzz), 0.0, 1.0);"
|
||||||
|
//+ " gl_FragColor = mix(vec4(0.0,1.0,0.0,1.0), u_color, clamp((1.0 - len) / (u_wscale + fuzz), 0.0, 1.0));"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
// private final static String lineVertexShader = ""
|
||||||
|
// + "precision mediump float;"
|
||||||
|
// + "uniform mat4 u_mvp;"
|
||||||
|
// + "uniform float u_width;"
|
||||||
|
// + "attribute vec4 a_pos;"
|
||||||
|
// + "uniform int u_mode;"
|
||||||
|
// //+ "attribute vec2 a_st;"
|
||||||
|
// + "varying vec2 v_st;"
|
||||||
|
// + "const float dscale = 8.0/2048.0;"
|
||||||
|
// + "void main() {"
|
||||||
|
// // scale extrusion to u_width pixel
|
||||||
|
// // just ignore the two most insignificant bits of a_st :)
|
||||||
|
// + " vec2 dir = a_pos.zw;"
|
||||||
|
// + " gl_Position = u_mvp * vec4(a_pos.xy + (dscale * u_width * dir), 0.0, 1.0);"
|
||||||
|
// // last two bits of a_st hold the texture coordinates
|
||||||
|
// + " v_st = u_width * (abs(mod(dir, 4.0)) - 1.0);"
|
||||||
|
// // use bit operations when available (gles 1.3)
|
||||||
|
// // + " v_st = u_width * vec2(a_st.x & 3 - 1, a_st.y & 3 - 1);"
|
||||||
|
// + "}";
|
||||||
|
//
|
||||||
|
// private final static String lineSimpleFragmentShader = ""
|
||||||
|
// + "precision mediump float;"
|
||||||
|
// + "uniform float u_wscale;"
|
||||||
|
// + "uniform float u_width;"
|
||||||
|
// + "uniform int u_mode;"
|
||||||
|
// + "uniform vec4 u_color;"
|
||||||
|
// + "varying vec2 v_st;"
|
||||||
|
// + "void main() {"
|
||||||
|
// + " float len;"
|
||||||
|
// + " if (u_mode == 0)"
|
||||||
|
// + " len = abs(v_st.s);"
|
||||||
|
// + " else "
|
||||||
|
// + " len = length(v_st);"
|
||||||
|
// // fade to alpha. u_wscale is the width in pixel which should be
|
||||||
|
// // faded, u_width - len the position of this fragment on the
|
||||||
|
// // perpendicular to this line segment. this only works with no
|
||||||
|
// // perspective
|
||||||
|
// //+ " gl_FragColor = min(1.0, (u_width - len) / u_wscale) * u_color;"
|
||||||
|
// + " gl_FragColor = u_color * smoothstep(0.0, u_wscale, (u_width - len));"
|
||||||
|
// + "}";
|
||||||
|
//
|
||||||
|
// private final static String lineFragmentShader = ""
|
||||||
|
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
|
// + "precision mediump float;"
|
||||||
|
// + "uniform float u_wscale;"
|
||||||
|
// + "uniform float u_width;"
|
||||||
|
// + "uniform int u_mode;"
|
||||||
|
// + "uniform vec4 u_color;"
|
||||||
|
// + "varying vec2 v_st;"
|
||||||
|
// + "void main() {"
|
||||||
|
// + " float len;"
|
||||||
|
// + " float fuzz;"
|
||||||
|
// + " if (u_mode == 0){"
|
||||||
|
// + " len = abs(v_st.s);"
|
||||||
|
// + " fuzz = u_wscale + fwidth(v_st.s);"
|
||||||
|
// + " } else {"
|
||||||
|
// + " len = length(v_st);"
|
||||||
|
// + " vec2 st_width = fwidth(v_st);"
|
||||||
|
// + " fuzz = u_wscale + max(st_width.s, st_width.t);"
|
||||||
|
// + " }"
|
||||||
|
// + " gl_FragColor = u_color * min(1.0, (u_width - len) / fuzz);"
|
||||||
|
// + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
551
vtm/src/org/oscim/renderer/elements/LineTexLayer.java
Normal file
551
vtm/src/org/oscim/renderer/elements/LineTexLayer.java
Normal file
@ -0,0 +1,551 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RenderElement for textured or stippled lines
|
||||||
|
*
|
||||||
|
* this would be all so much simpler with geometry shaders...
|
||||||
|
*/
|
||||||
|
public final class LineTexLayer extends RenderElement {
|
||||||
|
|
||||||
|
private final static String TAG = LineTexLayer.class.getName();
|
||||||
|
|
||||||
|
// Interleave two segment quads in one block to be able to use
|
||||||
|
// vertices twice. pos0 and pos1 use the same vertex array where
|
||||||
|
// pos1 has an offset of one vertex. The vertex shader will use
|
||||||
|
// pos0 when the vertexId is even, pos1 when the Id is odd.
|
||||||
|
//
|
||||||
|
// As there is no gl_VertexId in gles 2.0 an additional 'flip'
|
||||||
|
// array is used. Depending on 'flip' extrusion is inverted.
|
||||||
|
//
|
||||||
|
// Indices and flip buffers can be static.
|
||||||
|
//
|
||||||
|
// First pass: using even vertex array positions
|
||||||
|
// (used vertices are in braces)
|
||||||
|
// vertex id 0 1 2 3 4 5 6 7
|
||||||
|
// pos0 x (0) 1 (2) 3 (4) 5 (6) 7 x
|
||||||
|
// pos1 x (0) 1 (2) 3 (4) 5 (6) 7 x
|
||||||
|
// flip 0 1 0 1 0 1 0 1
|
||||||
|
//
|
||||||
|
// Second pass: using odd vertex array positions
|
||||||
|
// vertex id 0 1 2 3 4 5 6 7
|
||||||
|
// pos0 x 0 (1) 2 (3) 4 (5) 6 (7) x
|
||||||
|
// pos1 x 0 (1) 2 (3) 4 (5) 6 (7) x
|
||||||
|
// flip 0 1 0 1 0 1 0 1
|
||||||
|
//
|
||||||
|
// Vertex layout:
|
||||||
|
// [2 short] position,
|
||||||
|
// [2 short] extrusion,
|
||||||
|
// [1 short] line length
|
||||||
|
// [1 short] unused
|
||||||
|
//
|
||||||
|
// indices, for two blocks:
|
||||||
|
// 0, 1, 2,
|
||||||
|
// 2, 1, 3,
|
||||||
|
// 4, 5, 6,
|
||||||
|
// 6, 5, 7,
|
||||||
|
//
|
||||||
|
// BIG NOTE: renderer assumes to be able to offset vertex array position
|
||||||
|
// so that in the first pass 'pos1' offset will be < 0 if no data precedes
|
||||||
|
// - in our case there is always the polygon fill array at start
|
||||||
|
// - see addLine hack otherwise.
|
||||||
|
|
||||||
|
private static final float COORD_SCALE = MapRenderer.COORD_SCALE;
|
||||||
|
// scale factor mapping extrusion vector to short values
|
||||||
|
public static final float DIR_SCALE = 2048;
|
||||||
|
|
||||||
|
// lines referenced by this outline layer
|
||||||
|
public LineLayer outlines;
|
||||||
|
public Line line;
|
||||||
|
public float width;
|
||||||
|
|
||||||
|
public boolean roundCap;
|
||||||
|
|
||||||
|
public int evenQuads;
|
||||||
|
public int oddQuads;
|
||||||
|
|
||||||
|
private boolean evenSegment;
|
||||||
|
|
||||||
|
LineTexLayer(int layer) {
|
||||||
|
this.level = layer;
|
||||||
|
this.type = RenderElement.TEXLINE;
|
||||||
|
this.evenSegment = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLine(float[] points, short[] index) {
|
||||||
|
|
||||||
|
if (vertexItems == null) {
|
||||||
|
curItem = vertexItems = VertexItem.pool.get();
|
||||||
|
|
||||||
|
// HACK add one vertex offset when compiling
|
||||||
|
// buffer otherwise one cant use the full
|
||||||
|
// VertexItem (see Layers.compile)
|
||||||
|
// add the two 'x' at front and end
|
||||||
|
//verticesCnt = 2;
|
||||||
|
|
||||||
|
// the additional end vertex to make sure
|
||||||
|
// not to read outside allocated memory
|
||||||
|
verticesCnt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexItem si = curItem;
|
||||||
|
|
||||||
|
short v[] = si.vertices;
|
||||||
|
int opos = si.used;
|
||||||
|
|
||||||
|
boolean even = evenSegment;
|
||||||
|
|
||||||
|
// reset offset to last written position
|
||||||
|
if (!even)
|
||||||
|
opos -= 12;
|
||||||
|
|
||||||
|
int n;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
n = 1;
|
||||||
|
length = points.length;
|
||||||
|
} else {
|
||||||
|
n = index.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0, pos = 0; i < n; i++) {
|
||||||
|
if (index != null)
|
||||||
|
length = index[i];
|
||||||
|
|
||||||
|
// check end-marker in indices
|
||||||
|
if (length < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// need at least two points
|
||||||
|
if (length < 4) {
|
||||||
|
pos += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipos = pos;
|
||||||
|
|
||||||
|
float x = points[ipos++] * COORD_SCALE;
|
||||||
|
float y = points[ipos++] * COORD_SCALE;
|
||||||
|
|
||||||
|
// randomize a bit
|
||||||
|
float lineLength = (x * x + y * y) % 80;
|
||||||
|
|
||||||
|
int end = pos + length;
|
||||||
|
|
||||||
|
for (; ipos < end;) {
|
||||||
|
float nx = points[ipos++] * COORD_SCALE;
|
||||||
|
float ny = points[ipos++] * COORD_SCALE;
|
||||||
|
|
||||||
|
// Calculate triangle corners for the given width
|
||||||
|
float vx = nx - x;
|
||||||
|
float vy = ny - y;
|
||||||
|
|
||||||
|
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
||||||
|
|
||||||
|
// normal vector
|
||||||
|
vx /= a;
|
||||||
|
vy /= a;
|
||||||
|
|
||||||
|
// perpendicular to line segment
|
||||||
|
float ux = -vy;
|
||||||
|
float uy = vx;
|
||||||
|
|
||||||
|
short dx = (short) (ux * DIR_SCALE);
|
||||||
|
short dy = (short) (uy * DIR_SCALE);
|
||||||
|
|
||||||
|
if (opos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
opos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[opos + 0] = (short) x;
|
||||||
|
v[opos + 1] = (short) y;
|
||||||
|
v[opos + 2] = dx;
|
||||||
|
v[opos + 3] = dy;
|
||||||
|
v[opos + 4] = (short) lineLength;
|
||||||
|
v[opos + 5] = 0;
|
||||||
|
|
||||||
|
lineLength += a;
|
||||||
|
v[opos + 12] = (short) nx;
|
||||||
|
v[opos + 13] = (short) ny;
|
||||||
|
v[opos + 14] = dx;
|
||||||
|
v[opos + 15] = dy;
|
||||||
|
v[opos + 16] = (short) lineLength;
|
||||||
|
v[opos + 17] = 0;
|
||||||
|
|
||||||
|
x = nx;
|
||||||
|
y = ny;
|
||||||
|
|
||||||
|
if (even) {
|
||||||
|
// go to second segment
|
||||||
|
opos += 6;
|
||||||
|
even = false;
|
||||||
|
|
||||||
|
// vertex 0 and 2 were added
|
||||||
|
verticesCnt += 3;
|
||||||
|
evenQuads++;
|
||||||
|
} else {
|
||||||
|
// go to next block
|
||||||
|
even = true;
|
||||||
|
opos += 18;
|
||||||
|
|
||||||
|
// vertex 1 and 3 were added
|
||||||
|
verticesCnt += 1;
|
||||||
|
oddQuads++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
evenSegment = even;
|
||||||
|
|
||||||
|
// advance offset to last written position
|
||||||
|
if (!even)
|
||||||
|
opos += 12;
|
||||||
|
|
||||||
|
si.used = opos;
|
||||||
|
curItem = si;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clear() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static class Renderer {
|
||||||
|
|
||||||
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
|
// factor to normalize extrusion vector and scale to coord scale
|
||||||
|
private final static float COORD_SCALE_BY_DIR_SCALE =
|
||||||
|
MapRenderer.COORD_SCALE / LineLayer.DIR_SCALE;
|
||||||
|
|
||||||
|
private static int shader;
|
||||||
|
private static int hVertexPosition0;
|
||||||
|
private static int hVertexPosition1;
|
||||||
|
private static int hVertexLength0;
|
||||||
|
private static int hVertexLength1;
|
||||||
|
private static int hVertexFlip;
|
||||||
|
private static int hMatrix;
|
||||||
|
private static int hTexColor;
|
||||||
|
private static int hBgColor;
|
||||||
|
private static int hScale;
|
||||||
|
private static int hWidth;
|
||||||
|
private static int hPatternScale;
|
||||||
|
private static int hPatternWidth;
|
||||||
|
|
||||||
|
private static int mVertexFlipID;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
shader = GlUtils.createProgram(vertexShader, fragmentShader);
|
||||||
|
if (shader == 0) {
|
||||||
|
Log.e(TAG, "Could not create program.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hMatrix = GL.glGetUniformLocation(shader, "u_mvp");
|
||||||
|
hTexColor = GL.glGetUniformLocation(shader, "u_color");
|
||||||
|
hBgColor = GL.glGetUniformLocation(shader, "u_bgcolor");
|
||||||
|
hScale = GL.glGetUniformLocation(shader, "u_scale");
|
||||||
|
hWidth = GL.glGetUniformLocation(shader, "u_width");
|
||||||
|
hPatternScale = GL.glGetUniformLocation(shader, "u_pscale");
|
||||||
|
hPatternWidth = GL.glGetUniformLocation(shader, "u_pwidth");
|
||||||
|
|
||||||
|
hVertexPosition0 = GL.glGetAttribLocation(shader, "a_pos0");
|
||||||
|
hVertexPosition1 = GL.glGetAttribLocation(shader, "a_pos1");
|
||||||
|
hVertexLength0 = GL.glGetAttribLocation(shader, "a_len0");
|
||||||
|
hVertexLength1 = GL.glGetAttribLocation(shader, "a_len1");
|
||||||
|
hVertexFlip = GL.glGetAttribLocation(shader, "a_flip");
|
||||||
|
|
||||||
|
int[] vboIds = GlUtils.glGenBuffers(1);
|
||||||
|
mVertexFlipID = vboIds[0];
|
||||||
|
|
||||||
|
// bytes: 0, 1, 0, 1, 0, ...
|
||||||
|
byte[] flip = new byte[MapRenderer.maxQuads * 4];
|
||||||
|
for (int i = 0; i < flip.length; i++)
|
||||||
|
flip[i] = (byte)(i % 2);
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocateDirect(flip.length)
|
||||||
|
.order(ByteOrder.nativeOrder());
|
||||||
|
buf.put(flip);
|
||||||
|
buf.flip();
|
||||||
|
|
||||||
|
ShortBuffer sbuf = buf.asShortBuffer();
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||||
|
GL.glBufferData(GL20.GL_ARRAY_BUFFER, flip.length , sbuf,
|
||||||
|
GL20.GL_STATIC_DRAW);
|
||||||
|
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
// mTexID = new int[10];
|
||||||
|
// byte[] stipple = new byte[2];
|
||||||
|
// stipple[0] = 32;
|
||||||
|
// stipple[1] = 32;
|
||||||
|
// mTexID[0] = GlUtils.loadStippleTexture(stipple);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static int STRIDE = 12;
|
||||||
|
private final static int LEN_OFFSET = 8;
|
||||||
|
|
||||||
|
public static RenderElement draw(ElementLayers layers, RenderElement curLayer,
|
||||||
|
MapPosition pos, Matrices m, float div) {
|
||||||
|
|
||||||
|
// shader failed to compile
|
||||||
|
if (shader == 0)
|
||||||
|
return curLayer.next;
|
||||||
|
|
||||||
|
GLState.blend(true);
|
||||||
|
GLState.useProgram(shader);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(-1, -1);
|
||||||
|
|
||||||
|
GL.glEnableVertexAttribArray(hVertexPosition0);
|
||||||
|
GL.glEnableVertexAttribArray(hVertexPosition1);
|
||||||
|
GL.glEnableVertexAttribArray(hVertexLength0);
|
||||||
|
GL.glEnableVertexAttribArray(hVertexLength1);
|
||||||
|
GL.glEnableVertexAttribArray(hVertexFlip);
|
||||||
|
|
||||||
|
m.mvp.setAsUniform(hMatrix);
|
||||||
|
|
||||||
|
int maxIndices = MapRenderer.maxQuads * 6;
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
MapRenderer.mQuadIndicesID);
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
||||||
|
GL.glVertexAttribPointer(hVertexFlip, 1,
|
||||||
|
GL20.GL_BYTE, false, 0, 0);
|
||||||
|
|
||||||
|
layers.vbo.bind();
|
||||||
|
|
||||||
|
float scale = (float) pos.getZoomScale();
|
||||||
|
|
||||||
|
float s = scale / div;
|
||||||
|
|
||||||
|
//GL.glBindTexture(GL20.GL_TEXTURE_2D, mTexID[0]);
|
||||||
|
|
||||||
|
RenderElement l = curLayer;
|
||||||
|
for (; l != null && l.type == RenderElement.TEXLINE; l = l.next) {
|
||||||
|
LineTexLayer ll = (LineTexLayer) l;
|
||||||
|
Line line = ll.line;
|
||||||
|
|
||||||
|
GlUtils.setColor(hTexColor, line.stippleColor, 1);
|
||||||
|
GlUtils.setColor(hBgColor, line.color, 1);
|
||||||
|
|
||||||
|
float pScale = (int) (s + 0.5f);
|
||||||
|
if (pScale < 1)
|
||||||
|
pScale = 1;
|
||||||
|
|
||||||
|
GL.glUniform1f(hPatternScale, (MapRenderer.COORD_SCALE * line.stipple) / pScale);
|
||||||
|
GL.glUniform1f(hPatternWidth, line.stippleWidth);
|
||||||
|
|
||||||
|
GL.glUniform1f(hScale, scale);
|
||||||
|
// keep line width fixed
|
||||||
|
GL.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
||||||
|
|
||||||
|
// add offset vertex
|
||||||
|
int vOffset = -STRIDE;
|
||||||
|
|
||||||
|
// first pass
|
||||||
|
int allIndices = (ll.evenQuads * 6);
|
||||||
|
for (int i = 0; i < allIndices; i += maxIndices) {
|
||||||
|
int numIndices = allIndices - i;
|
||||||
|
if (numIndices > maxIndices)
|
||||||
|
numIndices = maxIndices;
|
||||||
|
|
||||||
|
// i / 6 * (24 shorts per block * 2 short bytes)
|
||||||
|
int add = (l.offset + i * 8) + vOffset;
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexPosition0,
|
||||||
|
4, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + STRIDE);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexLength0,
|
||||||
|
2, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexPosition1,
|
||||||
|
4, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexLength1,
|
||||||
|
2, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + LEN_OFFSET);
|
||||||
|
|
||||||
|
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
||||||
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// second pass
|
||||||
|
allIndices = (ll.oddQuads * 6);
|
||||||
|
for (int i = 0; i < allIndices; i += maxIndices) {
|
||||||
|
int numIndices = allIndices - i;
|
||||||
|
if (numIndices > maxIndices)
|
||||||
|
numIndices = maxIndices;
|
||||||
|
// i / 6 * (24 shorts per block * 2 short bytes)
|
||||||
|
int add = (l.offset + i * 8) + vOffset;
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexPosition0,
|
||||||
|
4, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + 2 * STRIDE);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexLength0,
|
||||||
|
2, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + 2 * STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexPosition1,
|
||||||
|
4, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + STRIDE);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hVertexLength1,
|
||||||
|
2, GL20.GL_SHORT, false, STRIDE,
|
||||||
|
add + STRIDE + LEN_OFFSET);
|
||||||
|
|
||||||
|
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
||||||
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
//GlUtils.checkGlError(TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GL.glDisableVertexAttribArray(hVertexPosition0);
|
||||||
|
GL.glDisableVertexAttribArray(hVertexPosition1);
|
||||||
|
GL.glDisableVertexAttribArray(hVertexLength0);
|
||||||
|
GL.glDisableVertexAttribArray(hVertexLength1);
|
||||||
|
GL.glDisableVertexAttribArray(hVertexFlip);
|
||||||
|
|
||||||
|
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
final static String vertexShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "uniform float u_pscale;"
|
||||||
|
+ "uniform float u_width;"
|
||||||
|
+ "attribute vec4 a_pos0;"
|
||||||
|
+ "attribute vec4 a_pos1;"
|
||||||
|
+ "attribute vec2 a_len0;"
|
||||||
|
+ "attribute vec2 a_len1;"
|
||||||
|
+ "attribute float a_flip;"
|
||||||
|
+ "varying vec2 v_st;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " vec4 pos;"
|
||||||
|
+ " if (a_flip == 0.0){"
|
||||||
|
//+ " vec2 dir = u_width * a_pos0.zw;"
|
||||||
|
+ " pos = vec4(a_pos0.xy + (u_width * a_pos0.zw), 0.0, 1.0);"
|
||||||
|
+ " v_st = vec2(a_len0.x / u_pscale, 1.0);"
|
||||||
|
+ " } else {"
|
||||||
|
//+ " vec2 dir = u_width * a_pos1.zw;"
|
||||||
|
+ " pos = vec4(a_pos1.xy - (u_width * a_pos1.zw), 0.0, 1.0);"
|
||||||
|
+ " v_st = vec2(a_len1.x / u_pscale, -1.0);"
|
||||||
|
+ " }"
|
||||||
|
+ " gl_Position = u_mvp * pos;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
//*
|
||||||
|
final static String fragmentShader = ""
|
||||||
|
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
|
+ " precision mediump float;"
|
||||||
|
+ " uniform vec4 u_color;"
|
||||||
|
+ " uniform vec4 u_bgcolor;"
|
||||||
|
+ " uniform float u_pwidth;"
|
||||||
|
+ " varying vec2 v_st;"
|
||||||
|
+ " void main() {"
|
||||||
|
// distance on perpendicular to the line
|
||||||
|
+ " float dist = abs(v_st.t);"
|
||||||
|
+ " float fuzz = fwidth(v_st.t);"
|
||||||
|
+ " float fuzz_p = fwidth(v_st.s);"
|
||||||
|
+ " float line_w = smoothstep(0.0, fuzz, 1.0 - dist);"
|
||||||
|
+ " float stipple_w = smoothstep(0.0, fuzz, u_pwidth - dist);"
|
||||||
|
// triangle waveform in the range 0..1 for regular pattern
|
||||||
|
+ " float phase = abs(mod(v_st.s, 2.0) - 1.0);"
|
||||||
|
// interpolate between on/off phase, 0.5 = equal phase length
|
||||||
|
+ " float stipple_p = smoothstep(0.5 - fuzz_p, 0.5 + fuzz_p, phase);"
|
||||||
|
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||||
|
+ " } "; //*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* final static String fragmentShader = ""
|
||||||
|
* + "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
|
* + " precision mediump float;"
|
||||||
|
* + " uniform sampler2D tex;"
|
||||||
|
* + " uniform float u_scale;"
|
||||||
|
* + " uniform vec4 u_color;"
|
||||||
|
* + " uniform vec4 u_bgcolor;"
|
||||||
|
* + " varying vec2 v_st;"
|
||||||
|
* + " void main() {"
|
||||||
|
* + " float len = texture2D(tex, v_st).a;"
|
||||||
|
* + " float tex_w = abs(v_st.t);"
|
||||||
|
* + " vec2 st_width = fwidth(v_st);"
|
||||||
|
* + " float fuzz = max(st_width.s, st_width.t);"
|
||||||
|
* //+ " float fuzz = fwidth(v_st.t);"
|
||||||
|
* //+ " float line_w = 1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w);"
|
||||||
|
* //+ " float stipple_w = 1.0 - smoothstep(0.7 - fuzz, 0.7, tex_w);"
|
||||||
|
* +
|
||||||
|
* " float stipple_p = 1.0 - smoothstep(1.0 - fuzz, 1.0, length(vec2(len*u_scale, v_st.t)));"
|
||||||
|
* + " gl_FragColor = u_bgcolor * stipple_p;"
|
||||||
|
* // +
|
||||||
|
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||||
|
* + "}"; //
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* final static String fragmentShader = ""
|
||||||
|
* + "#extension GL_OES_standard_derivatives : enable\n"
|
||||||
|
* + " precision mediump float;"
|
||||||
|
* + " uniform sampler2D tex;"
|
||||||
|
* + " uniform vec4 u_color;"
|
||||||
|
* + " uniform vec4 u_bgcolor;"
|
||||||
|
* + " uniform float u_pwidth;"
|
||||||
|
* + " varying vec2 v_st;"
|
||||||
|
* + " void main() {"
|
||||||
|
* + " float dist = texture2D(tex, v_st).a;"
|
||||||
|
* + " float tex_w = abs(v_st.t);"
|
||||||
|
* + " vec2 st_width = fwidth(v_st);"
|
||||||
|
* + " float fuzz = max(st_width.s, st_width.t);"
|
||||||
|
* + " float line_w = (1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w));"
|
||||||
|
* +
|
||||||
|
* " float stipple_w = (1.0 - smoothstep(u_pwidth - fuzz, u_pwidth, tex_w));"
|
||||||
|
* + " float stipple_p = smoothstep(0.495, 0.505, dist);"
|
||||||
|
* +
|
||||||
|
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
||||||
|
* + " } "; //
|
||||||
|
*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -22,7 +22,7 @@ import org.oscim.core.GeometryBuffer;
|
|||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
|
|
||||||
public class MeshLayer extends Layer {
|
public class MeshLayer extends RenderElement {
|
||||||
GeometryBuffer mGeom = new GeometryBuffer(10,10);
|
GeometryBuffer mGeom = new GeometryBuffer(10,10);
|
||||||
|
|
||||||
public MeshLayer() {
|
public MeshLayer() {
|
549
vtm/src/org/oscim/renderer/elements/PolygonLayer.java
Normal file
549
vtm/src/org/oscim/renderer/elements/PolygonLayer.java
Normal file
@ -0,0 +1,549 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.theme.renderinstruction.Area;
|
||||||
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
import org.oscim.utils.Matrix4;
|
||||||
|
|
||||||
|
public final class PolygonLayer extends RenderElement {
|
||||||
|
private static final String TAG = PolygonLayer.class.getName();
|
||||||
|
|
||||||
|
private static final float S = MapRenderer.COORD_SCALE;
|
||||||
|
|
||||||
|
public Area area;
|
||||||
|
|
||||||
|
PolygonLayer(int layer) {
|
||||||
|
this.level = layer;
|
||||||
|
this.type = RenderElement.POLYGON;
|
||||||
|
curItem = VertexItem.pool.get();
|
||||||
|
vertexItems = curItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPolygon(float[] points, short[] index) {
|
||||||
|
short center = (short) ((Tile.SIZE >> 1) * S);
|
||||||
|
|
||||||
|
VertexItem si = curItem;
|
||||||
|
short[] v = si.vertices;
|
||||||
|
int outPos = si.used;
|
||||||
|
|
||||||
|
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
||||||
|
int length = index[i];
|
||||||
|
if (length < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// need at least three points
|
||||||
|
if (length < 6) {
|
||||||
|
pos += length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
verticesCnt += length / 2 + 2;
|
||||||
|
|
||||||
|
int inPos = pos;
|
||||||
|
|
||||||
|
if (outPos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
outPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[outPos++] = center;
|
||||||
|
v[outPos++] = center;
|
||||||
|
|
||||||
|
for (int j = 0; j < length; j += 2) {
|
||||||
|
if (outPos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
outPos = 0;
|
||||||
|
}
|
||||||
|
v[outPos++] = (short) (points[inPos++] * S);
|
||||||
|
v[outPos++] = (short) (points[inPos++] * S);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (outPos == VertexItem.SIZE) {
|
||||||
|
si = si.next = VertexItem.pool.get();
|
||||||
|
v = si.vertices;
|
||||||
|
outPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
v[outPos++] = (short) (points[pos + 0] * S);
|
||||||
|
v[outPos++] = (short) (points[pos + 1] * S);
|
||||||
|
|
||||||
|
pos += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
si.used = outPos;
|
||||||
|
curItem = si;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clear() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special Renderer for drawing tile polygon layers
|
||||||
|
*/
|
||||||
|
public static final class Renderer {
|
||||||
|
|
||||||
|
private static GL20 GL;
|
||||||
|
|
||||||
|
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
||||||
|
private static final int STENCIL_BITS = 8;
|
||||||
|
private final static int CLIP_BIT = 0x80;
|
||||||
|
|
||||||
|
private static final float FADE_START = 1.3f;
|
||||||
|
|
||||||
|
private static PolygonLayer[] mFillPolys;
|
||||||
|
|
||||||
|
private static int numShaders = 2;
|
||||||
|
private static int polyShader = 0;
|
||||||
|
private static int texShader = 1;
|
||||||
|
|
||||||
|
private static int[] polygonProgram = new int[numShaders];
|
||||||
|
|
||||||
|
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 boolean enableTexture = false;
|
||||||
|
|
||||||
|
static boolean init() {
|
||||||
|
GL = GLAdapter.get();
|
||||||
|
|
||||||
|
for (int i = 0; i < numShaders; i++) {
|
||||||
|
|
||||||
|
// Set up the program for rendering polygons
|
||||||
|
if (i == 0) {
|
||||||
|
if (MapRenderer.debugView)
|
||||||
|
polygonProgram[i] = GlUtils.createProgram(polygonVertexShaderZ,
|
||||||
|
polygonFragmentShaderZ);
|
||||||
|
else
|
||||||
|
polygonProgram[i] = GlUtils.createProgram(polygonVertexShader,
|
||||||
|
polygonFragmentShader);
|
||||||
|
} else if (i == 1) {
|
||||||
|
polygonProgram[i] = GlUtils.createProgram(textureVertexShader,
|
||||||
|
textureFragmentShader);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (polygonProgram[i] == 0) {
|
||||||
|
Log.e(TAG, "Could not create polygon program.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hPolygonMatrix[i] = GL.glGetUniformLocation(polygonProgram[i], "u_mvp");
|
||||||
|
hPolygonColor[i] = GL.glGetUniformLocation(polygonProgram[i], "u_color");
|
||||||
|
hPolygonScale[i] = GL.glGetUniformLocation(polygonProgram[i], "u_scale");
|
||||||
|
|
||||||
|
hPolygonVertexPosition[i] = GL.glGetAttribLocation(polygonProgram[i], "a_pos");
|
||||||
|
}
|
||||||
|
|
||||||
|
mFillPolys = new PolygonLayer[STENCIL_BITS];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale,
|
||||||
|
float div) {
|
||||||
|
|
||||||
|
/* draw to framebuffer */
|
||||||
|
GL.glColorMask(true, true, true, true);
|
||||||
|
|
||||||
|
/* do not modify stencil buffer */
|
||||||
|
GL.glStencilMask(0x00);
|
||||||
|
int shader = polyShader;
|
||||||
|
|
||||||
|
for (int c = start; c < end; c++) {
|
||||||
|
Area a = mFillPolys[c].area;
|
||||||
|
|
||||||
|
if (enableTexture && a.texture != null) {
|
||||||
|
shader = texShader;
|
||||||
|
setShader(texShader, m);
|
||||||
|
GL.glUniform2f(hPolygonScale[1], FastMath.clamp(scale - 1, 0, 1), div);
|
||||||
|
|
||||||
|
a.texture.bind();
|
||||||
|
|
||||||
|
} else if (a.fade >= zoom) {
|
||||||
|
float f = 1.0f;
|
||||||
|
/* fade in/out */
|
||||||
|
if (a.fade >= zoom) {
|
||||||
|
if (scale > FADE_START)
|
||||||
|
f = scale - 1;
|
||||||
|
else
|
||||||
|
f = FADE_START - 1;
|
||||||
|
}
|
||||||
|
GLState.blend(true);
|
||||||
|
|
||||||
|
GlUtils.setColor(hPolygonColor[shader], a.color, f);
|
||||||
|
|
||||||
|
} else if (a.blend > 0 && a.blend <= zoom) {
|
||||||
|
/* blend colors (not alpha) */
|
||||||
|
GLState.blend(false);
|
||||||
|
|
||||||
|
if (a.blend == zoom)
|
||||||
|
GlUtils.setColorBlend(hPolygonColor[shader],
|
||||||
|
a.color, a.blendColor, scale - 1.0f);
|
||||||
|
else
|
||||||
|
GlUtils.setColor(hPolygonColor[shader], a.blendColor, 1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (a.color < 0xff000000)
|
||||||
|
GLState.blend(true);
|
||||||
|
else
|
||||||
|
GLState.blend(false);
|
||||||
|
|
||||||
|
GlUtils.setColor(hPolygonColor[shader], a.color, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set stencil buffer mask used to draw this layer
|
||||||
|
// also check that clip bit is set to avoid overdraw
|
||||||
|
// of other tiles
|
||||||
|
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
||||||
|
|
||||||
|
/* draw tile fill coordinates */
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (shader != polyShader) {
|
||||||
|
// disable texture shader
|
||||||
|
setShader(polyShader, m);
|
||||||
|
shader = polyShader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// current layer to fill (0 - STENCIL_BITS-1)
|
||||||
|
private static int mCount;
|
||||||
|
|
||||||
|
private static void setShader(int shader, Matrices m) {
|
||||||
|
GLState.useProgram(polygonProgram[shader]);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hPolygonVertexPosition[shader], 2, GL20.GL_SHORT,
|
||||||
|
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
|
|
||||||
|
m.mvp.setAsUniform(hPolygonMatrix[shader]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* draw polygon layers (unil layer.next is not polygon layer)
|
||||||
|
* using stencil buffer method
|
||||||
|
*
|
||||||
|
* @param pos
|
||||||
|
* used to fade layers accorind to 'fade'
|
||||||
|
* in layer.area.
|
||||||
|
* @param renderElement
|
||||||
|
* layer to draw (referencing vertices in current vbo)
|
||||||
|
* @param m
|
||||||
|
* 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 RenderElement draw(MapPosition pos, RenderElement renderElement,
|
||||||
|
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
|
||||||
|
if (first || cur > 5)
|
||||||
|
cur = 0;
|
||||||
|
|
||||||
|
int start = cur;
|
||||||
|
|
||||||
|
RenderElement l = renderElement;
|
||||||
|
for (; l != null && l.type == RenderElement.POLYGON; l = l.next) {
|
||||||
|
PolygonLayer pl = (PolygonLayer) l;
|
||||||
|
|
||||||
|
// fade out polygon layers (set in RenderTheme)
|
||||||
|
if (pl.area.fade > 0 && pl.area.fade > zoom)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cur == start) {
|
||||||
|
drawStencilRegion(first);
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
// op for stencil method polygon drawing
|
||||||
|
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_INVERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFillPolys[cur] = pl;
|
||||||
|
|
||||||
|
// set stencil mask to draw to
|
||||||
|
GL.glStencilMask(1 << cur++);
|
||||||
|
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
||||||
|
|
||||||
|
// draw up to 7 layers into stencil buffer
|
||||||
|
if (cur == STENCIL_BITS - 1) {
|
||||||
|
fillPolygons(m, start, cur, zoom, scale, div);
|
||||||
|
start = cur = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur > 0)
|
||||||
|
fillPolygons(m, start, cur, zoom, scale, div);
|
||||||
|
|
||||||
|
if (clip) {
|
||||||
|
if (first) {
|
||||||
|
drawStencilRegion(first);
|
||||||
|
// disable writes to stencil buffer
|
||||||
|
GL.glStencilMask(0x00);
|
||||||
|
// enable writes to color buffer
|
||||||
|
GL.glColorMask(true, true, true, true);
|
||||||
|
} else {
|
||||||
|
// set test for clip to tile region
|
||||||
|
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mCount = cur;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clip(Matrices m) {
|
||||||
|
setShader(polyShader, m);
|
||||||
|
|
||||||
|
drawStencilRegion(true);
|
||||||
|
// disable writes to stencil buffer
|
||||||
|
GL.glStencilMask(0x00);
|
||||||
|
// enable writes to color buffer
|
||||||
|
GL.glColorMask(true, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a tile filling rectangle to set stencil- and depth buffer
|
||||||
|
* appropriately
|
||||||
|
*
|
||||||
|
* @param first in the first run the clip region is set based on
|
||||||
|
* depth buffer and depth buffer is updated
|
||||||
|
*/
|
||||||
|
static void drawStencilRegion(boolean first) {
|
||||||
|
|
||||||
|
// if (!first) {
|
||||||
|
// GL.glStencilMask(0x7F);
|
||||||
|
// GL.glClear(GL20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
// // disable drawing to color buffer
|
||||||
|
// GL.glColorMask(false, false, false, false);
|
||||||
|
// GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// disable drawing to color buffer
|
||||||
|
GL.glColorMask(false, false, false, false);
|
||||||
|
|
||||||
|
// write to all stencil bits
|
||||||
|
GL.glStencilMask(0xFF);
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
// clear previous clip-region from stencil buffer
|
||||||
|
//GL.glClear(GL20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Draw clip-region into depth and stencil buffer
|
||||||
|
// this is used for tile line and polygon layers.
|
||||||
|
// Depth offset is increased for each tile. Together
|
||||||
|
// with depth test (GL_LESS) this ensures to only
|
||||||
|
// draw where no other tile has drawn yet.
|
||||||
|
GL.glEnable(GL20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
|
// test GL_LESS and write to depth buffer
|
||||||
|
GLState.test(true, true);
|
||||||
|
GL.glDepthMask(true);
|
||||||
|
|
||||||
|
// always pass stencil test and set clip bit
|
||||||
|
GL.glStencilFunc(GL20.GL_ALWAYS, CLIP_BIT, 0x00);
|
||||||
|
} else {
|
||||||
|
// use clip bit from stencil buffer
|
||||||
|
// to clear stencil 'layer-bits' (0x7f)
|
||||||
|
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set clip bit (0x80) for draw region
|
||||||
|
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_REPLACE);
|
||||||
|
|
||||||
|
// draw a quad for the tile region
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (first) {
|
||||||
|
// dont modify depth buffer
|
||||||
|
GL.glDepthMask(false);
|
||||||
|
// test only stencil
|
||||||
|
GLState.test(false, true);
|
||||||
|
|
||||||
|
GL.glDisable(GL20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
|
||||||
|
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawOver(Matrices m, int color) {
|
||||||
|
setShader(polyShader, m);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clear stencilbuffer (tile region) by drawing
|
||||||
|
* a quad with func 'always' and op 'zero'
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (color != 0) {
|
||||||
|
GlUtils.setColor(hPolygonColor[0], color, 1);
|
||||||
|
GLState.blend(true);
|
||||||
|
} else {
|
||||||
|
// disable drawing to framebuffer (will be re-enabled in fill)
|
||||||
|
GL.glColorMask(false, false, false, false);
|
||||||
|
}
|
||||||
|
// always pass stencil test:
|
||||||
|
//glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
||||||
|
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
||||||
|
|
||||||
|
// write to all bits
|
||||||
|
GL.glStencilMask(0xFF);
|
||||||
|
// zero out area to draw to
|
||||||
|
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_ZERO);
|
||||||
|
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (color == 0)
|
||||||
|
GL.glColorMask(true, true, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
||||||
|
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
||||||
|
private static FloatBuffer mDebugFill;
|
||||||
|
|
||||||
|
static void debugDraw(Matrix4 m, float[] coords, int color) {
|
||||||
|
GLState.test(false, false);
|
||||||
|
if (mDebugFill == null) {
|
||||||
|
mDebugFill = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder())
|
||||||
|
.asFloatBuffer();
|
||||||
|
mDebugFill.put(coords);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
mDebugFill.position(0);
|
||||||
|
GLState.useProgram(polygonProgram[0]);
|
||||||
|
GL.glEnableVertexAttribArray(hPolygonVertexPosition[0]);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hPolygonVertexPosition[0], 2, GL20.GL_FLOAT,
|
||||||
|
false, 0, mDebugFill);
|
||||||
|
|
||||||
|
m.setAsUniform(hPolygonMatrix[0]);
|
||||||
|
|
||||||
|
if (color == 0)
|
||||||
|
GlUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor);
|
||||||
|
else
|
||||||
|
GlUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor2);
|
||||||
|
|
||||||
|
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
GlUtils.checkGlError("draw debug");
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static String polygonVertexShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
+ "attribute vec4 a_pos;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mvp * a_pos;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String polygonFragmentShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_FragColor = u_color;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String polygonVertexShaderZ = ""
|
||||||
|
+ "precision highp float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
+ "attribute vec4 a_pos;"
|
||||||
|
+ "varying float z;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mvp * a_pos;"
|
||||||
|
+ " z = gl_Position.z;"
|
||||||
|
+ "}";
|
||||||
|
private final static String polygonFragmentShaderZ = ""
|
||||||
|
+ "precision highp float;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "varying float z;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ "if (z < -1.0)"
|
||||||
|
+ " gl_FragColor = vec4(0.0, z + 2.0, 0.0, 1.0)*0.8;"
|
||||||
|
+ "else if (z < 0.0)"
|
||||||
|
+ " gl_FragColor = vec4(z + 1.0, 0.0, 0.0, 1.0)*0.8;"
|
||||||
|
+ "else if (z < 1.0)"
|
||||||
|
+ " gl_FragColor = vec4(0.0, 0.0, z, 1.0)*0.8;"
|
||||||
|
+ "else"
|
||||||
|
+ " gl_FragColor = vec4(0.0, z - 1.0, 0.0, 1.0)*0.8;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
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 / u_scale.y);"
|
||||||
|
+ " v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);"
|
||||||
|
+ " gl_Position = u_mvp * a_pos;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String textureFragmentShader = ""
|
||||||
|
+ "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 = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -12,15 +12,13 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
/**
|
|
||||||
* @authorHannes Janetzek
|
public abstract class RenderElement extends Inlist<RenderElement>{
|
||||||
*/
|
|
||||||
public abstract class Layer extends Inlist<Layer>{
|
|
||||||
public final static byte LINE = 0;
|
public final static byte LINE = 0;
|
||||||
public final static byte POLYGON = 1;
|
public final static byte POLYGON = 1;
|
||||||
public final static byte TEXLINE = 2;
|
public final static byte TEXLINE = 2;
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.core.Point;
|
import org.oscim.core.Point;
|
||||||
@ -34,7 +34,7 @@ public class SymbolItem extends Inlist<SymbolItem> {
|
|||||||
protected boolean clearItem(SymbolItem it) {
|
protected boolean clearItem(SymbolItem it) {
|
||||||
// drop references
|
// drop references
|
||||||
it.bitmap = null;
|
it.bitmap = null;
|
||||||
it.symbol = null;
|
it.texRegion = null;
|
||||||
it.offset = null;
|
it.offset = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ public class SymbolItem extends Inlist<SymbolItem> {
|
|||||||
public float x;
|
public float x;
|
||||||
public float y;
|
public float y;
|
||||||
|
|
||||||
public TextureRegion symbol;
|
public TextureRegion texRegion;
|
||||||
public Bitmap bitmap;
|
public Bitmap bitmap;
|
||||||
public Point offset;
|
public Point offset;
|
||||||
|
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
private SymbolItem symbols;
|
private SymbolItem symbols;
|
||||||
|
|
||||||
public SymbolLayer() {
|
public SymbolLayer() {
|
||||||
type = Layer.SYMBOL;
|
type = RenderElement.SYMBOL;
|
||||||
fixed = true;
|
fixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,19 +78,19 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
int x = 0;
|
int x = 0;
|
||||||
int y = 0;
|
int y = 0;
|
||||||
|
|
||||||
if (it.symbol != null) {
|
if (it.texRegion != null) {
|
||||||
|
|
||||||
// FIXME this work only with one TextureAtlas per
|
// FIXME this work only with one TextureAtlas per
|
||||||
// SymbolLayer.
|
// SymbolLayer.
|
||||||
if (textures == null) {
|
if (textures == null) {
|
||||||
to = it.symbol.atlas.loadTexture();
|
to = it.texRegion.atlas.loadTexture();
|
||||||
// clone TextureItem to use same texID with
|
// clone TextureItem to use same texID with
|
||||||
// multiple TextureItem
|
// multiple TextureItem
|
||||||
to = TextureItem.clone(to);
|
to = TextureItem.clone(to);
|
||||||
textures = Inlist.append(textures, to);
|
textures = Inlist.append(textures, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureAtlas.Rect r = it.symbol.rect;
|
TextureAtlas.Rect r = it.texRegion.rect;
|
||||||
x = r.x;
|
x = r.x;
|
||||||
y = r.y;
|
y = r.y;
|
||||||
width = r.w;
|
width = r.w;
|
||||||
@ -147,7 +147,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
|
|
||||||
if (it2 == null
|
if (it2 == null
|
||||||
|| (it.bitmap != null && it2.bitmap != it.bitmap)
|
|| (it.bitmap != null && it2.bitmap != it.bitmap)
|
||||||
|| (it.symbol != null && it2.symbol != it.symbol)) {
|
|| (it.texRegion != null && it2.texRegion != it.texRegion)) {
|
||||||
it = it2;
|
it = it2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -171,7 +171,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
pos += 24;
|
pos += 24;
|
||||||
|
|
||||||
// six elements used to draw the four vertices
|
// six elements used to draw the four vertices
|
||||||
to.vertices += TextureRenderer.INDICES_PER_SPRITE;
|
to.vertices += TextureLayer.Renderer.INDICES_PER_SPRITE;
|
||||||
}
|
}
|
||||||
numIndices += to.vertices;
|
numIndices += to.vertices;
|
||||||
}
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
@ -12,11 +12,11 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
||||||
import static org.oscim.renderer.sublayers.TextureItem.TEXTURE_HEIGHT;
|
import static org.oscim.renderer.elements.TextureItem.TEXTURE_HEIGHT;
|
||||||
import static org.oscim.renderer.sublayers.TextureItem.TEXTURE_WIDTH;
|
import static org.oscim.renderer.elements.TextureItem.TEXTURE_WIDTH;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
@ -38,7 +38,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TextLayer() {
|
public TextLayer() {
|
||||||
type = Layer.SYMBOL;
|
type = RenderElement.SYMBOL;
|
||||||
//mCanvas = Graphics.res.getCanvas();
|
//mCanvas = Graphics.res.getCanvas();
|
||||||
mCanvas = CanvasAdapter.g.getCanvas();
|
mCanvas = CanvasAdapter.g.getCanvas();
|
||||||
fixed = true;
|
fixed = true;
|
||||||
@ -244,7 +244,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
buf[pos++] = v1;
|
buf[pos++] = v1;
|
||||||
|
|
||||||
// six indices to draw the four vertices
|
// six indices to draw the four vertices
|
||||||
numIndices += TextureRenderer.INDICES_PER_SPRITE;
|
numIndices += TextureLayer.Renderer.INDICES_PER_SPRITE;
|
||||||
verticesCnt += 4;
|
verticesCnt += 4;
|
||||||
|
|
||||||
if (it.next == null || (it.next.text != it.text)
|
if (it.next == null || (it.next.text != it.text)
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
int[] textureIds = GlUtils.glGenTextures(1);
|
int[] textureIds = GlUtils.glGenTextures(1);
|
||||||
t.id = textureIds[0];
|
t.id = textureIds[0];
|
||||||
initTexture(t);
|
initTexture(t);
|
||||||
if (TextureRenderer.debug)
|
if (TextureLayer.Renderer.debug)
|
||||||
Log.d(TAG, "fill:" + pool.getFill()
|
Log.d(TAG, "fill:" + pool.getFill()
|
||||||
+ " count:" + mTexCnt
|
+ " count:" + mTexCnt
|
||||||
+ " new texture " + t.id);
|
+ " new texture " + t.id);
|
||||||
@ -286,7 +286,7 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
t.height = h;
|
t.height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextureRenderer.debug)
|
if (TextureLayer.Renderer.debug)
|
||||||
GlUtils.checkGlError(TAG);
|
GlUtils.checkGlError(TAG);
|
||||||
}
|
}
|
||||||
|
|
213
vtm/src/org/oscim/renderer/elements/TextureLayer.java
Normal file
213
vtm/src/org/oscim/renderer/elements/TextureLayer.java
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
|
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
||||||
|
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
|
public abstract class TextureLayer extends RenderElement {
|
||||||
|
// holds textures and offset in vbo
|
||||||
|
public TextureItem textures;
|
||||||
|
|
||||||
|
// scale mode
|
||||||
|
public boolean fixed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sbuf
|
||||||
|
* buffer to add vertices
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
|
||||||
|
for (TextureItem to = textures; to != null; to = to.next)
|
||||||
|
to.upload();
|
||||||
|
|
||||||
|
// add vertices to vbo
|
||||||
|
ElementLayers.addPoolItems(this, sbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public boolean prepare();
|
||||||
|
|
||||||
|
static void putSprite(short buf[], int pos,
|
||||||
|
short tx, short ty,
|
||||||
|
short x1, short y1,
|
||||||
|
short x2, short y2,
|
||||||
|
short u1, short v1,
|
||||||
|
short u2, short v2) {
|
||||||
|
|
||||||
|
// top-left
|
||||||
|
buf[pos + 0] = tx;
|
||||||
|
buf[pos + 1] = ty;
|
||||||
|
buf[pos + 2] = x1;
|
||||||
|
buf[pos + 3] = y1;
|
||||||
|
buf[pos + 4] = u1;
|
||||||
|
buf[pos + 5] = v2;
|
||||||
|
// bot-left
|
||||||
|
buf[pos + 6] = tx;
|
||||||
|
buf[pos + 7] = ty;
|
||||||
|
buf[pos + 8] = x1;
|
||||||
|
buf[pos + 9] = y2;
|
||||||
|
buf[pos + 10] = u1;
|
||||||
|
buf[pos + 11] = v1;
|
||||||
|
// top-right
|
||||||
|
buf[pos + 12] = tx;
|
||||||
|
buf[pos + 13] = ty;
|
||||||
|
buf[pos + 14] = x2;
|
||||||
|
buf[pos + 15] = y1;
|
||||||
|
buf[pos + 16] = u2;
|
||||||
|
buf[pos + 17] = v2;
|
||||||
|
// bot-right
|
||||||
|
buf[pos + 18] = tx;
|
||||||
|
buf[pos + 19] = ty;
|
||||||
|
buf[pos + 20] = x2;
|
||||||
|
buf[pos + 21] = y2;
|
||||||
|
buf[pos + 22] = u2;
|
||||||
|
buf[pos + 23] = v1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Renderer {
|
||||||
|
//private final static String TAG = TextureRenderer.class.getName();
|
||||||
|
|
||||||
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
|
public final static boolean debug = false;
|
||||||
|
|
||||||
|
private static int mTextureProgram;
|
||||||
|
private static int hTextureMVMatrix;
|
||||||
|
private static int hTextureProjMatrix;
|
||||||
|
private static int hTextureVertex;
|
||||||
|
private static int hTextureScale;
|
||||||
|
private static int hTextureScreenScale;
|
||||||
|
private static int hTextureTexCoord;
|
||||||
|
private static int hTextureSize;
|
||||||
|
|
||||||
|
public final static int INDICES_PER_SPRITE = 6;
|
||||||
|
final static int VERTICES_PER_SPRITE = 4;
|
||||||
|
final static int SHORTS_PER_VERTICE = 6;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
mTextureProgram = GlUtils.createProgram(textVertexShader,
|
||||||
|
textFragmentShader);
|
||||||
|
|
||||||
|
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
||||||
|
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
||||||
|
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
||||||
|
hTextureSize = GL.glGetUniformLocation(mTextureProgram, "u_div");
|
||||||
|
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
|
||||||
|
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
||||||
|
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RenderElement draw(RenderElement renderElement, float scale, Matrices m) {
|
||||||
|
|
||||||
|
GLState.test(false, false);
|
||||||
|
GLState.blend(true);
|
||||||
|
|
||||||
|
GLState.useProgram(mTextureProgram);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
|
TextureLayer tl = (TextureLayer) renderElement;
|
||||||
|
|
||||||
|
if (tl.fixed)
|
||||||
|
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
||||||
|
else
|
||||||
|
GL.glUniform1f(hTextureScale, 1);
|
||||||
|
|
||||||
|
GL.glUniform1f(hTextureScreenScale, 1f / MapRenderer.screenWidth);
|
||||||
|
|
||||||
|
m.proj.setAsUniform(hTextureProjMatrix);
|
||||||
|
m.mvp.setAsUniform(hTextureMVMatrix);
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, MapRenderer.mQuadIndicesID);
|
||||||
|
|
||||||
|
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
||||||
|
|
||||||
|
ti.bind();
|
||||||
|
|
||||||
|
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
|
GL.glUniform2f(hTextureSize,
|
||||||
|
1f / (ti.width * COORD_SCALE),
|
||||||
|
1f / (ti.height * COORD_SCALE));
|
||||||
|
|
||||||
|
// draw up to maxVertices in each iteration
|
||||||
|
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
||||||
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
|
int off = (ti.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
|
GL20.GL_SHORT, false, 12, off);
|
||||||
|
|
||||||
|
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
|
int numVertices = ti.vertices - i;
|
||||||
|
if (numVertices > maxVertices)
|
||||||
|
numVertices = maxVertices;
|
||||||
|
|
||||||
|
GL.glDrawElements(GL20.GL_TRIANGLES, numVertices,
|
||||||
|
GL20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return renderElement.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static double COORD_DIV = 1.0 / MapRenderer.COORD_SCALE;
|
||||||
|
|
||||||
|
private final static String textVertexShader = ""
|
||||||
|
+ "precision highp float;"
|
||||||
|
+ "attribute vec4 vertex;"
|
||||||
|
+ "attribute vec2 tex_coord;"
|
||||||
|
+ "uniform mat4 u_mv;"
|
||||||
|
+ "uniform mat4 u_proj;"
|
||||||
|
+ "uniform float u_scale;"
|
||||||
|
+ "uniform float u_swidth;"
|
||||||
|
+ "uniform vec2 u_div;"
|
||||||
|
+ "varying vec2 tex_c;"
|
||||||
|
+ "const float coord_scale = " + COORD_DIV + ";"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " vec4 pos;"
|
||||||
|
+ " vec2 dir = vertex.zw;"
|
||||||
|
+ " if (mod(vertex.x, 2.0) == 0.0){"
|
||||||
|
+ " pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));"
|
||||||
|
+ " } else {" // place as billboard
|
||||||
|
+ " vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||||
|
+ " pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.0, 0.0));"
|
||||||
|
+ " }"
|
||||||
|
+ " gl_Position = pos;"
|
||||||
|
+ " tex_c = tex_coord * u_div;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String textFragmentShader = ""
|
||||||
|
+ "precision highp float;"
|
||||||
|
+ "uniform sampler2D tex;"
|
||||||
|
+ "varying vec2 tex_c;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_FragColor = texture2D(tex, tex_c.xy);"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.sublayers;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.oscim.utils.pool.SyncPool;
|
import org.oscim.utils.pool.SyncPool;
|
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renderer for a single bitmap, width and height must be power of 2.
|
|
||||||
*/
|
|
||||||
public class BitmapLayer extends TextureLayer {
|
|
||||||
// private final static String TAG = BitmapLayer.class.getName();
|
|
||||||
private Bitmap mBitmap;
|
|
||||||
private final boolean mReuseBitmap;
|
|
||||||
private final short[] mVertices;
|
|
||||||
/**
|
|
||||||
* @param reuseBitmap false if the Bitmap should be recycled after
|
|
||||||
* it is compiled to texture.
|
|
||||||
* */
|
|
||||||
public BitmapLayer(boolean reuseBitmap) {
|
|
||||||
type = Layer.BITMAP;
|
|
||||||
mReuseBitmap = reuseBitmap;
|
|
||||||
mVertices = new short[24];
|
|
||||||
|
|
||||||
// used for size calculation of Layers buffer.
|
|
||||||
verticesCnt = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBitmap(Bitmap bitmap, int w, int h) {
|
|
||||||
mWidth = w;
|
|
||||||
mHeight = h;
|
|
||||||
|
|
||||||
mBitmap = bitmap;
|
|
||||||
if (this.textures == null)
|
|
||||||
this.textures = new TextureItem(mBitmap);
|
|
||||||
|
|
||||||
TextureItem ti = this.textures;
|
|
||||||
ti.vertices = TextureRenderer.INDICES_PER_SPRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int mWidth, mHeight;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set target dimension to renderthe bitmap */
|
|
||||||
public void setSize(int w, int h){
|
|
||||||
mWidth = w;
|
|
||||||
mHeight = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setVertices(ShortBuffer sbuf){
|
|
||||||
short[] buf = mVertices;
|
|
||||||
short w = (short) (mWidth * GLRenderer.COORD_SCALE);
|
|
||||||
short h = (short) (mHeight* GLRenderer.COORD_SCALE);
|
|
||||||
|
|
||||||
short t = 1;
|
|
||||||
|
|
||||||
int pos = 0;
|
|
||||||
// top-left
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
// bot-left
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = h;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = t;
|
|
||||||
// top-right
|
|
||||||
buf[pos++] = w;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = t;
|
|
||||||
buf[pos++] = 0;
|
|
||||||
// bot-right
|
|
||||||
buf[pos++] = w;
|
|
||||||
buf[pos++] = h;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = -1;
|
|
||||||
buf[pos++] = t;
|
|
||||||
buf[pos++] = t;
|
|
||||||
|
|
||||||
this.offset = sbuf.position() * 2; // bytes
|
|
||||||
sbuf.put(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean prepare() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void compile(ShortBuffer sbuf) {
|
|
||||||
|
|
||||||
if (mBitmap == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setVertices(sbuf);
|
|
||||||
|
|
||||||
textures.upload();
|
|
||||||
|
|
||||||
if (!mReuseBitmap) {
|
|
||||||
mBitmap.recycle();
|
|
||||||
mBitmap = null;
|
|
||||||
textures.bitmap = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void clear() {
|
|
||||||
|
|
||||||
if (mBitmap != null) {
|
|
||||||
if (!mReuseBitmap)
|
|
||||||
mBitmap.recycle();
|
|
||||||
|
|
||||||
mBitmap = null;
|
|
||||||
textures.bitmap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextureItem.releaseTexture(textures);
|
|
||||||
textures = null;
|
|
||||||
|
|
||||||
VertexItem.pool.releaseAll(vertexItems);
|
|
||||||
vertexItems = null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
|
|
||||||
// TODO merge with TextureRenderer
|
|
||||||
|
|
||||||
public final class BitmapRenderer {
|
|
||||||
|
|
||||||
//private final static String TAG = BitmapRenderer.class.getName();
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
|
||||||
|
|
||||||
public final static boolean debug = true;
|
|
||||||
|
|
||||||
private static int mTextureProgram;
|
|
||||||
private static int hTextureMVMatrix;
|
|
||||||
private static int hTextureProjMatrix;
|
|
||||||
private static int hTextureVertex;
|
|
||||||
private static int hTextureScale;
|
|
||||||
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;
|
|
||||||
|
|
||||||
static void init() {
|
|
||||||
mTextureProgram = GlUtils.createProgram(textVertexShader,
|
|
||||||
textFragmentShader);
|
|
||||||
|
|
||||||
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
|
||||||
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
|
||||||
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
|
||||||
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, Matrices m, float scale, float alpha) {
|
|
||||||
//GLState.test(false, false);
|
|
||||||
GLState.blend(true);
|
|
||||||
|
|
||||||
GLState.useProgram(mTextureProgram);
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) layer;
|
|
||||||
|
|
||||||
if (tl.fixed)
|
|
||||||
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
|
||||||
else
|
|
||||||
GL.glUniform1f(hTextureScale, 1);
|
|
||||||
|
|
||||||
|
|
||||||
GL.glUniform1f(hTextureScreenScale, 1f / GLRenderer.screenWidth);
|
|
||||||
GL.glUniform1f(hAlpha, alpha);
|
|
||||||
|
|
||||||
m.proj.setAsUniform(hTextureProjMatrix);
|
|
||||||
|
|
||||||
m.mvp.setAsUniform(hTextureMVMatrix);
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID);
|
|
||||||
|
|
||||||
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
|
||||||
|
|
||||||
ti.bind();
|
|
||||||
|
|
||||||
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
|
|
||||||
|
|
||||||
// draw up to maxVertices in each iteration
|
|
||||||
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
|
||||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
|
||||||
int off = (ti.offset + i) * 8 + tl.offset;
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
|
||||||
GL20.GL_SHORT, false, 12, off);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
|
||||||
|
|
||||||
int numVertices = ti.vertices - i;
|
|
||||||
if (numVertices > maxVertices)
|
|
||||||
numVertices = maxVertices;
|
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numVertices,
|
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
return layer.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String textVertexShader = ""
|
|
||||||
+ "precision mediump float; "
|
|
||||||
+ "attribute vec4 vertex;"
|
|
||||||
+ "attribute vec2 tex_coord;"
|
|
||||||
+ "uniform mat4 u_mv;"
|
|
||||||
+ "uniform mat4 u_proj;"
|
|
||||||
+ "uniform float u_scale;"
|
|
||||||
+ "uniform float u_swidth;"
|
|
||||||
+ "varying vec2 tex_c;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
|
||||||
+ " 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) * u_alpha;"
|
|
||||||
+ "}";
|
|
||||||
}
|
|
@ -1,571 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.backend.canvas.Paint.Cap;
|
|
||||||
import org.oscim.core.GeometryBuffer;
|
|
||||||
import org.oscim.core.Tile;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
|
||||||
import org.oscim.utils.FastMath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public final class LineLayer extends Layer {
|
|
||||||
private static final float COORD_SCALE = GLRenderer.COORD_SCALE;
|
|
||||||
// scale factor mapping extrusion vector to short values
|
|
||||||
public static final float DIR_SCALE = 2048;
|
|
||||||
// mask for packing last two bits of extrusion vector with texture
|
|
||||||
// coordinates
|
|
||||||
private static final int DIR_MASK = 0xFFFFFFFC;
|
|
||||||
|
|
||||||
// lines referenced by this outline layer
|
|
||||||
public LineLayer outlines;
|
|
||||||
public Line line;
|
|
||||||
public float width;
|
|
||||||
|
|
||||||
public boolean roundCap;
|
|
||||||
|
|
||||||
LineLayer(int layer) {
|
|
||||||
this.level = layer;
|
|
||||||
this.type = Layer.LINE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addOutline(LineLayer link) {
|
|
||||||
for (LineLayer l = outlines; l != null; l = l.outlines)
|
|
||||||
if (link == l)
|
|
||||||
return;
|
|
||||||
|
|
||||||
link.outlines = outlines;
|
|
||||||
outlines = link;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* line extrusion is based on code from GLMap
|
|
||||||
* (https://github.com/olofsj/GLMap/)
|
|
||||||
*
|
|
||||||
* @param points
|
|
||||||
* array of points as x,y pairs.
|
|
||||||
* @param index
|
|
||||||
* array of indices holding the length of the individual
|
|
||||||
* line coordinates (i.e. points * 2).
|
|
||||||
* when index is null one a line with points.length
|
|
||||||
* is assumed.
|
|
||||||
* @param closed
|
|
||||||
* whether to connect start- and end-point.
|
|
||||||
*/
|
|
||||||
public void addLine(float[] points, short[] index, boolean closed) {
|
|
||||||
addLine(points, index, -1, closed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLine(GeometryBuffer geom) {
|
|
||||||
if (geom.isPoly())
|
|
||||||
addLine(geom.points, geom.index, -1, true);
|
|
||||||
else if (geom.isLine())
|
|
||||||
addLine(geom.points, geom.index, -1, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLine(float[] points, int numPoints, boolean closed) {
|
|
||||||
if (numPoints >= 4)
|
|
||||||
addLine(points, null, numPoints, closed);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addLine(float[] points, short[] index, int numPoints, boolean closed) {
|
|
||||||
float x, y, nextX, nextY;
|
|
||||||
float a, ux, uy, vx, vy, wx, wy;
|
|
||||||
|
|
||||||
int tmax = Tile.SIZE + 4;
|
|
||||||
int tmin = -4;
|
|
||||||
|
|
||||||
boolean rounded = false;
|
|
||||||
boolean squared = false;
|
|
||||||
|
|
||||||
if (line.cap == Cap.ROUND)
|
|
||||||
rounded = true;
|
|
||||||
else if (line.cap == Cap.SQUARE)
|
|
||||||
squared = true;
|
|
||||||
|
|
||||||
if (vertexItems == null)
|
|
||||||
curItem = vertexItems = VertexItem.pool.get();
|
|
||||||
|
|
||||||
VertexItem si = curItem;
|
|
||||||
short v[] = si.vertices;
|
|
||||||
int opos = si.used;
|
|
||||||
|
|
||||||
// FIXME: remove this when switching to oscimap MapDatabase
|
|
||||||
//if (!MapView.enableClosePolygons)
|
|
||||||
// closed = false;
|
|
||||||
|
|
||||||
// Note: just a hack to save some vertices, when there are more than 200 lines
|
|
||||||
// per type
|
|
||||||
if (rounded) {
|
|
||||||
int cnt = 0;
|
|
||||||
for (int i = 0, n = index.length; i < n; i++, cnt++) {
|
|
||||||
if (index[i] < 0)
|
|
||||||
break;
|
|
||||||
if (cnt > 400) {
|
|
||||||
rounded = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roundCap = rounded;
|
|
||||||
|
|
||||||
int n;
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
if (index == null) {
|
|
||||||
n = 1;
|
|
||||||
if (numPoints > 0) {
|
|
||||||
length = numPoints;
|
|
||||||
} else {
|
|
||||||
length = points.length;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
n = index.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, pos = 0; i < n; i++) {
|
|
||||||
if (index != null)
|
|
||||||
length = index[i];
|
|
||||||
|
|
||||||
// check end-marker in indices
|
|
||||||
if (length < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// need at least two points
|
|
||||||
if (length < 4) {
|
|
||||||
pos += length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// amount of vertices used
|
|
||||||
// + 2 for drawing triangle-strip
|
|
||||||
// + 4 for round caps
|
|
||||||
// + 2 for closing polygons
|
|
||||||
verticesCnt += length + (rounded ? 6 : 2) + (closed ? 2 : 0);
|
|
||||||
|
|
||||||
int ipos = pos;
|
|
||||||
|
|
||||||
x = points[ipos++];
|
|
||||||
y = points[ipos++];
|
|
||||||
|
|
||||||
nextX = points[ipos++];
|
|
||||||
nextY = points[ipos++];
|
|
||||||
|
|
||||||
// Calculate triangle corners for the given width
|
|
||||||
vx = nextX - x;
|
|
||||||
vy = nextY - y;
|
|
||||||
|
|
||||||
// Unit vector to next node
|
|
||||||
a = (float) Math.sqrt(vx * vx + vy * vy);
|
|
||||||
vx /= a;
|
|
||||||
vy /= a;
|
|
||||||
|
|
||||||
// perpendicular on the first segment
|
|
||||||
ux = -vy;
|
|
||||||
uy = vx;
|
|
||||||
|
|
||||||
int ddx, ddy;
|
|
||||||
|
|
||||||
// vertex point coordinate
|
|
||||||
short ox = (short) (x * COORD_SCALE);
|
|
||||||
short oy = (short) (y * COORD_SCALE);
|
|
||||||
|
|
||||||
// vertex extrusion vector, last two bit
|
|
||||||
// encode texture coord.
|
|
||||||
short dx, dy;
|
|
||||||
|
|
||||||
// when the endpoint is outside the tile region omit round caps.
|
|
||||||
boolean outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rounded && !outside) {
|
|
||||||
// add first vertex twice
|
|
||||||
ddx = (int) ((ux - vx) * DIR_SCALE);
|
|
||||||
ddy = (int) ((uy - vy) * DIR_SCALE);
|
|
||||||
dx = (short) (0 | ddx & DIR_MASK);
|
|
||||||
dy = (short) (2 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
|
||||||
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (2 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start of line
|
|
||||||
ddx = (int) (ux * DIR_SCALE);
|
|
||||||
ddy = (int) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// outside means line is probably clipped
|
|
||||||
// TODO should align ending with tile boundary
|
|
||||||
// for now, just extend the line a little
|
|
||||||
float tx = vx;
|
|
||||||
float ty = vy;
|
|
||||||
|
|
||||||
if (squared) {
|
|
||||||
tx = 0;
|
|
||||||
ty = 0;
|
|
||||||
} else if (!outside) {
|
|
||||||
tx *= 0.5;
|
|
||||||
ty *= 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rounded)
|
|
||||||
verticesCnt -= 2;
|
|
||||||
|
|
||||||
// add first vertex twice
|
|
||||||
ddx = (int) ((ux - tx) * DIR_SCALE);
|
|
||||||
ddy = (int) ((uy - ty) * DIR_SCALE);
|
|
||||||
dx = (short) (0 | ddx & DIR_MASK);
|
|
||||||
dy = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ddx = (int) (-(ux + tx) * DIR_SCALE);
|
|
||||||
ddy = (int) (-(uy + ty) * DIR_SCALE);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
x = nextX;
|
|
||||||
y = nextY;
|
|
||||||
boolean flip = false;
|
|
||||||
// Unit vector pointing back to previous node
|
|
||||||
vx *= -1;
|
|
||||||
vy *= -1;
|
|
||||||
|
|
||||||
int end = pos + length;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if (ipos < end) {
|
|
||||||
nextX = points[ipos++];
|
|
||||||
nextY = points[ipos++];
|
|
||||||
} else if (closed && ipos < end + 2) {
|
|
||||||
// add startpoint == endpoint
|
|
||||||
nextX = points[pos];
|
|
||||||
nextY = points[pos + 1];
|
|
||||||
ipos += 2;
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unit vector pointing forward to next node
|
|
||||||
wx = nextX - x;
|
|
||||||
wy = nextY - y;
|
|
||||||
a = (float) Math.sqrt(wx * wx + wy * wy);
|
|
||||||
wx /= a;
|
|
||||||
wy /= a;
|
|
||||||
|
|
||||||
// Sum of these two vectors points
|
|
||||||
ux = vx + wx;
|
|
||||||
uy = vy + wy;
|
|
||||||
|
|
||||||
// cross-product
|
|
||||||
a = wx * uy - wy * ux;
|
|
||||||
|
|
||||||
if (FastMath.abs(a) < 0.01f) {
|
|
||||||
// Almost straight
|
|
||||||
ux = -wy;
|
|
||||||
uy = wx;
|
|
||||||
} else {
|
|
||||||
ux /= a;
|
|
||||||
uy /= a;
|
|
||||||
|
|
||||||
// avoid miter going to infinity.
|
|
||||||
// TODO add option for round joints
|
|
||||||
if (FastMath.absMaxCmp(ux, uy, 4f)) {
|
|
||||||
ux = vx - wx;
|
|
||||||
uy = vy - wy;
|
|
||||||
|
|
||||||
a = -wy * ux + wx * uy;
|
|
||||||
ux /= a;
|
|
||||||
uy /= a;
|
|
||||||
flip = !flip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ox = (short) (x * COORD_SCALE);
|
|
||||||
oy = (short) (y * COORD_SCALE);
|
|
||||||
|
|
||||||
ddx = (int) (ux * DIR_SCALE);
|
|
||||||
ddy = (int) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
if (flip) {
|
|
||||||
ddx = -ddx;
|
|
||||||
ddy = -ddy;
|
|
||||||
}
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
|
||||||
|
|
||||||
x = nextX;
|
|
||||||
y = nextY;
|
|
||||||
|
|
||||||
// flip unit vector to point back
|
|
||||||
vx = -wx;
|
|
||||||
vy = -wy;
|
|
||||||
}
|
|
||||||
|
|
||||||
ux = vy;
|
|
||||||
uy = -vx;
|
|
||||||
|
|
||||||
outside = (x < tmin || x > tmax || y < tmin || y > tmax);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si.next = VertexItem.pool.get();
|
|
||||||
si = si.next;
|
|
||||||
opos = 0;
|
|
||||||
v = si.vertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
ox = (short) (x * COORD_SCALE);
|
|
||||||
oy = (short) (y * COORD_SCALE);
|
|
||||||
|
|
||||||
if (rounded && !outside) {
|
|
||||||
ddx = (int) (ux * DIR_SCALE);
|
|
||||||
ddy = (int) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
if (flip) {
|
|
||||||
ddx = -ddx;
|
|
||||||
ddy = -ddy;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (2 | -ddx & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | -ddy & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For rounded line edges
|
|
||||||
ddx = (int) ((ux - vx) * DIR_SCALE);
|
|
||||||
ddy = (int) ((uy - vy) * DIR_SCALE);
|
|
||||||
|
|
||||||
dx = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK);
|
|
||||||
dy = (short) (0 | (flip ? -ddy : ddy) & DIR_MASK);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add last vertex twice
|
|
||||||
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
|
||||||
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
|
||||||
dx = (short) (2 | (flip ? -ddx : ddx) & DIR_MASK);
|
|
||||||
dy = (short) (0 | (flip ? -ddy : ddy) & DIR_MASK);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (squared) {
|
|
||||||
vx = 0;
|
|
||||||
vy = 0;
|
|
||||||
} else if (!outside) {
|
|
||||||
vx *= 0.5;
|
|
||||||
vy *= 0.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rounded)
|
|
||||||
verticesCnt -= 2;
|
|
||||||
|
|
||||||
ddx = (int) ((ux - vx) * DIR_SCALE);
|
|
||||||
ddy = (int) ((uy - vy) * DIR_SCALE);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = (short) (0 | (flip ? -ddx : ddx) & DIR_MASK);
|
|
||||||
v[opos++] = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add last vertex twice
|
|
||||||
ddx = (int) (-(ux + vx) * DIR_SCALE);
|
|
||||||
ddy = (int) (-(uy + vy) * DIR_SCALE);
|
|
||||||
dx = (short) (2 | (flip ? -ddx : ddx) & DIR_MASK);
|
|
||||||
dy = (short) (1 | (flip ? -ddy : ddy) & DIR_MASK);
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos++] = ox;
|
|
||||||
v[opos++] = oy;
|
|
||||||
v[opos++] = dx;
|
|
||||||
v[opos++] = dy;
|
|
||||||
}
|
|
||||||
pos += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
si.used = opos;
|
|
||||||
curItem = si;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
if (vertexItems != null) {
|
|
||||||
VertexItem.pool.releaseAll(vertexItems);
|
|
||||||
vertexItems = null;
|
|
||||||
curItem = null;
|
|
||||||
}
|
|
||||||
verticesCnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void compile(ShortBuffer sbuf) {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,399 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.backend.Log;
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
|
|
||||||
public final class LineRenderer {
|
|
||||||
private final static String TAG = LineRenderer.class.getName();
|
|
||||||
|
|
||||||
private static GL20 GL;
|
|
||||||
|
|
||||||
private static final int LINE_VERTICES_DATA_POS_OFFSET = 0;
|
|
||||||
|
|
||||||
// factor to normalize extrusion vector and scale to coord scale
|
|
||||||
private final static float COORD_SCALE_BY_DIR_SCALE =
|
|
||||||
GLRenderer.COORD_SCALE / LineLayer.DIR_SCALE;
|
|
||||||
|
|
||||||
// shader handles
|
|
||||||
private static int[] lineProgram = new int[2];
|
|
||||||
private static int[] hLineVertexPosition = new int[2];
|
|
||||||
private static int[] hLineColor = new int[2];
|
|
||||||
private static int[] hLineMatrix = new int[2];
|
|
||||||
private static int[] hLineScale = new int[2];
|
|
||||||
private static int[] hLineWidth = new int[2];
|
|
||||||
private static int[] hLineMode = new int[2];
|
|
||||||
public static int mTexID;
|
|
||||||
|
|
||||||
static boolean init() {
|
|
||||||
GL = GLAdapter.get();
|
|
||||||
|
|
||||||
lineProgram[0] = GlUtils.createProgram(lineVertexShader,
|
|
||||||
lineFragmentShader);
|
|
||||||
if (lineProgram[0] == 0) {
|
|
||||||
Log.e(TAG, "Could not create line program.");
|
|
||||||
//return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lineProgram[1] = GlUtils.createProgram(lineVertexShader,
|
|
||||||
lineSimpleFragmentShader);
|
|
||||||
if (lineProgram[1] == 0) {
|
|
||||||
Log.e(TAG, "Could not create simple line program.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
if (lineProgram[i] == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
hLineMatrix[i] = GL.glGetUniformLocation(lineProgram[i], "u_mvp");
|
|
||||||
hLineScale[i] = GL.glGetUniformLocation(lineProgram[i], "u_wscale");
|
|
||||||
hLineWidth[i] = GL.glGetUniformLocation(lineProgram[i], "u_width");
|
|
||||||
hLineColor[i] = GL.glGetUniformLocation(lineProgram[i], "u_color");
|
|
||||||
hLineMode[i] = GL.glGetUniformLocation(lineProgram[i], "u_mode");
|
|
||||||
hLineVertexPosition[i] = GL.glGetAttribLocation(lineProgram[i], "a_pos");
|
|
||||||
}
|
|
||||||
|
|
||||||
// create lookup table as texture for 'length(0..1,0..1)'
|
|
||||||
// using mirrored wrap mode for 'length(-1..1,-1..1)'
|
|
||||||
byte[] pixel = new byte[128 * 128];
|
|
||||||
|
|
||||||
for (int x = 0; x < 128; x++) {
|
|
||||||
float xx = x * x;
|
|
||||||
for (int y = 0; y < 128; y++) {
|
|
||||||
float yy = y * y;
|
|
||||||
int color = (int) (Math.sqrt(xx + yy) * 2);
|
|
||||||
if (color > 255)
|
|
||||||
color = 255;
|
|
||||||
pixel[x + y * 128] = (byte) color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mTexID = GlUtils.loadTexture(pixel, 128, 128, GL20.GL_ALPHA,
|
|
||||||
GL20.GL_NEAREST, GL20.GL_NEAREST,
|
|
||||||
GL20.GL_MIRRORED_REPEAT, GL20.GL_MIRRORED_REPEAT);
|
|
||||||
|
|
||||||
Log.d(TAG, "TEX ID: " + mTexID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Layer draw(Layers layers, Layer curLayer, MapPosition pos,
|
|
||||||
Matrices m, float div, int mode) {
|
|
||||||
|
|
||||||
if (curLayer == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// FIXME HACK: fallback to simple shader
|
|
||||||
if (lineProgram[mode] == 0)
|
|
||||||
mode = 1;
|
|
||||||
|
|
||||||
GLState.useProgram(lineProgram[mode]);
|
|
||||||
|
|
||||||
GLState.blend(true);
|
|
||||||
|
|
||||||
// Somehow we loose the texture after an indefinite
|
|
||||||
// time, when label/symbol textures are used.
|
|
||||||
// Debugging gl on Desktop is most fun imaginable,
|
|
||||||
// so for now:
|
|
||||||
if (!GLAdapter.GDX_DESKTOP_QUIRKS)
|
|
||||||
GLState.bindTex2D(mTexID);
|
|
||||||
|
|
||||||
int uLineScale = hLineScale[mode];
|
|
||||||
int uLineMode = hLineMode[mode];
|
|
||||||
int uLineColor = hLineColor[mode];
|
|
||||||
int uLineWidth = hLineWidth[mode];
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
|
|
||||||
false, 0, layers.lineOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
|
||||||
|
|
||||||
//glUniformMatrix4fv(hLineMatrix[mode], 1, false, matrix, 0);
|
|
||||||
m.mvp.setAsUniform(hLineMatrix[mode]);
|
|
||||||
|
|
||||||
//int zoom = FastMath.log2((int) pos.absScale);
|
|
||||||
int zoom = pos.zoomLevel;
|
|
||||||
|
|
||||||
double scale = pos.getZoomScale();
|
|
||||||
|
|
||||||
// Line scale factor for non fixed lines: Within a zoom-
|
|
||||||
// level lines would be scaled by the factor 2 by view-matrix.
|
|
||||||
// Though lines should only scale by sqrt(2). This is achieved
|
|
||||||
// by inverting scaling of extrusion vector with: width/sqrt(s).
|
|
||||||
// within one zoom-level: 1 <= s <= 2
|
|
||||||
double s = scale / div;
|
|
||||||
float lineScale = (float) Math.sqrt(s * 2 / 2.2);
|
|
||||||
|
|
||||||
// scale factor to map one pixel on tile to one pixel on screen:
|
|
||||||
// only works with orthographic projection
|
|
||||||
float pixel = 0;
|
|
||||||
|
|
||||||
if (mode == 1)
|
|
||||||
pixel = (float) (1.5 / s);
|
|
||||||
|
|
||||||
GL.glUniform1f(uLineScale, pixel);
|
|
||||||
int lineMode = 0;
|
|
||||||
GL.glUniform1f(uLineMode, lineMode);
|
|
||||||
|
|
||||||
boolean blur = false;
|
|
||||||
|
|
||||||
Layer l = curLayer;
|
|
||||||
for (; l != null && l.type == Layer.LINE; l = l.next) {
|
|
||||||
LineLayer ll = (LineLayer) l;
|
|
||||||
Line line = ll.line;
|
|
||||||
float width;
|
|
||||||
|
|
||||||
if (line.fade < zoom) {
|
|
||||||
GlUtils.setColor(uLineColor, line.color, 1);
|
|
||||||
} else if (line.fade > zoom) {
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;
|
|
||||||
GlUtils.setColor(uLineColor, line.color, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == 0 && blur && line.blur == 0) {
|
|
||||||
GL.glUniform1f(uLineScale, 0);
|
|
||||||
blur = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.outline) {
|
|
||||||
// draw linelayers references by this outline
|
|
||||||
for (LineLayer o = ll.outlines; o != null; o = o.outlines) {
|
|
||||||
|
|
||||||
if (o.line.fixed /* || strokeMaxZoom */) {
|
|
||||||
width = (float) ((ll.width + o.width) / s);
|
|
||||||
} else {
|
|
||||||
width = (float) (ll.width / s + o.width / lineScale);
|
|
||||||
|
|
||||||
// check min-size for outline
|
|
||||||
if (o.line.min > 0 && o.width * lineScale < o.line.min * 2)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glUniform1f(uLineWidth, width * COORD_SCALE_BY_DIR_SCALE);
|
|
||||||
|
|
||||||
if (line.blur != 0) {
|
|
||||||
GL.glUniform1f(uLineScale, (float) (1 - (line.blur / s)));
|
|
||||||
blur = true;
|
|
||||||
} else if (mode == 1) {
|
|
||||||
GL.glUniform1f(uLineScale, pixel / width);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.roundCap) {
|
|
||||||
if (lineMode != 1) {
|
|
||||||
lineMode = 1;
|
|
||||||
GL.glUniform1f(uLineMode, lineMode);
|
|
||||||
}
|
|
||||||
} else if (lineMode != 0) {
|
|
||||||
lineMode = 0;
|
|
||||||
GL.glUniform1f(uLineMode, lineMode);
|
|
||||||
}
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, o.offset, o.verticesCnt);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if (line.fixed /* || strokeMaxZoom */) {
|
|
||||||
// invert scaling of extrusion vectors so that line
|
|
||||||
// width stays the same.
|
|
||||||
width = (float) (ll.width / s);
|
|
||||||
} else {
|
|
||||||
// reduce linear scaling of extrusion vectors so that
|
|
||||||
// line width increases by sqrt(2.2).
|
|
||||||
width = ll.width / lineScale;
|
|
||||||
|
|
||||||
// min-size hack to omit outline when line becomes
|
|
||||||
// very thin
|
|
||||||
if ((ll.line.min > 0) && (ll.width * lineScale < ll.line.min * 2))
|
|
||||||
width = (ll.width - 0.2f) / lineScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glUniform1f(uLineWidth, width * COORD_SCALE_BY_DIR_SCALE);
|
|
||||||
|
|
||||||
if (line.blur != 0) {
|
|
||||||
GL.glUniform1f(uLineScale, line.blur);
|
|
||||||
blur = true;
|
|
||||||
} else if (mode == 1) {
|
|
||||||
GL.glUniform1f(uLineScale, pixel / width);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ll.roundCap) {
|
|
||||||
if (lineMode != 1) {
|
|
||||||
lineMode = 1;
|
|
||||||
GL.glUniform1f(uLineMode, lineMode);
|
|
||||||
}
|
|
||||||
} else if (lineMode != 0) {
|
|
||||||
lineMode = 0;
|
|
||||||
GL.glUniform1f(uLineMode, lineMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String lineVertexShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform mat4 u_mvp;"
|
|
||||||
// factor to increase line width relative to scale
|
|
||||||
+ "uniform float u_width;"
|
|
||||||
// xy hold position, zw extrusion vector
|
|
||||||
+ "attribute vec4 a_pos;"
|
|
||||||
+ "uniform float u_mode;"
|
|
||||||
+ "varying vec2 v_st;"
|
|
||||||
+ "void main() {"
|
|
||||||
// scale extrusion to u_width pixel
|
|
||||||
// just ignore the two most insignificant bits of a_st :)
|
|
||||||
+ " vec2 dir = a_pos.zw;"
|
|
||||||
+ " gl_Position = u_mvp * vec4(a_pos.xy + (u_width * dir), 0.0, 1.0);"
|
|
||||||
// last two bits of a_st hold the texture coordinates
|
|
||||||
// ..maybe one could wrap texture so that `abs` is not required
|
|
||||||
+ " v_st = abs(mod(dir, 4.0)) - 1.0;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String lineSimpleFragmentShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform sampler2D tex;"
|
|
||||||
+ "uniform float u_wscale;"
|
|
||||||
+ "uniform float u_mode;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "varying vec2 v_st;"
|
|
||||||
+ "void main() {"
|
|
||||||
//+ " float len;"
|
|
||||||
// (currently required as overlay line renderers dont load the texture)
|
|
||||||
//+ " if (u_mode == 0)"
|
|
||||||
//+ " len = abs(v_st.s);"
|
|
||||||
//+ " else"
|
|
||||||
//+ " len = texture2D(tex, v_st).a;"
|
|
||||||
//+ " len = u_mode * length(v_st);"
|
|
||||||
// this avoids branching, need to check performance
|
|
||||||
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
|
||||||
? " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * length(v_st));"
|
|
||||||
: " float len = max((1.0 - u_mode) * abs(v_st.s), u_mode * texture2D(tex, v_st).a);")
|
|
||||||
// interpolate alpha between: 0.0 < 1.0 - len < u_wscale
|
|
||||||
// where wscale is 'filter width' / 'line width' and 0 <= len <= sqrt(2)
|
|
||||||
//+ " gl_FragColor = u_color * smoothstep(0.0, u_wscale, 1.0 - len);"
|
|
||||||
//+ " gl_FragColor = mix(vec4(1.0,0.0,0.0,1.0), u_color, smoothstep(0.0, u_wscale, 1.0 - len));"
|
|
||||||
+ " float alpha = min(1.0, (1.0 - len) / u_wscale);"
|
|
||||||
+ " if (alpha > 0.1)"
|
|
||||||
+ " gl_FragColor = u_color * alpha;"
|
|
||||||
+ " else"
|
|
||||||
+ " discard;"
|
|
||||||
// + "gl_FragColor = vec4(texture2D(tex, v_st).a);"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String lineFragmentShader = ""
|
|
||||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform sampler2D tex;"
|
|
||||||
+ "uniform float u_mode;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "uniform float u_wscale;"
|
|
||||||
+ "varying vec2 v_st;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " float len;"
|
|
||||||
+ " float fuzz;"
|
|
||||||
+ " if (u_mode == 0.0){"
|
|
||||||
+ " len = abs(v_st.s);"
|
|
||||||
+ " fuzz = fwidth(v_st.s);"
|
|
||||||
+ " } else {"
|
|
||||||
+ (GLAdapter.GDX_DESKTOP_QUIRKS
|
|
||||||
? " len = length(v_st);"
|
|
||||||
: " len = texture2D(tex, v_st).a;")
|
|
||||||
+ " vec2 st_width = fwidth(v_st);"
|
|
||||||
+ " fuzz = max(st_width.s, st_width.t);"
|
|
||||||
+ " }"
|
|
||||||
//+ " gl_FragColor = u_color * smoothstep(0.0, fuzz + u_wscale, 1.0 - len);"
|
|
||||||
// smoothstep is too sharp, guess one could increase extrusion with z..
|
|
||||||
// this looks ok:
|
|
||||||
//+ " gl_FragColor = u_color * min(1.0, (1.0 - len) / (u_wscale + fuzz));"
|
|
||||||
// can be faster according to nvidia docs 'Optimize OpenGL ES 2.0 Performace'
|
|
||||||
+ " gl_FragColor = u_color * clamp((1.0 - len) / (u_wscale + fuzz), 0.0, 1.0);"
|
|
||||||
//+ " gl_FragColor = mix(vec4(0.0,1.0,0.0,1.0), u_color, clamp((1.0 - len) / (u_wscale + fuzz), 0.0, 1.0));"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
// private final static String lineVertexShader = ""
|
|
||||||
// + "precision mediump float;"
|
|
||||||
// + "uniform mat4 u_mvp;"
|
|
||||||
// + "uniform float u_width;"
|
|
||||||
// + "attribute vec4 a_pos;"
|
|
||||||
// + "uniform int u_mode;"
|
|
||||||
// //+ "attribute vec2 a_st;"
|
|
||||||
// + "varying vec2 v_st;"
|
|
||||||
// + "const float dscale = 8.0/2048.0;"
|
|
||||||
// + "void main() {"
|
|
||||||
// // scale extrusion to u_width pixel
|
|
||||||
// // just ignore the two most insignificant bits of a_st :)
|
|
||||||
// + " vec2 dir = a_pos.zw;"
|
|
||||||
// + " gl_Position = u_mvp * vec4(a_pos.xy + (dscale * u_width * dir), 0.0, 1.0);"
|
|
||||||
// // last two bits of a_st hold the texture coordinates
|
|
||||||
// + " v_st = u_width * (abs(mod(dir, 4.0)) - 1.0);"
|
|
||||||
// // use bit operations when available (gles 1.3)
|
|
||||||
// // + " v_st = u_width * vec2(a_st.x & 3 - 1, a_st.y & 3 - 1);"
|
|
||||||
// + "}";
|
|
||||||
//
|
|
||||||
// private final static String lineSimpleFragmentShader = ""
|
|
||||||
// + "precision mediump float;"
|
|
||||||
// + "uniform float u_wscale;"
|
|
||||||
// + "uniform float u_width;"
|
|
||||||
// + "uniform int u_mode;"
|
|
||||||
// + "uniform vec4 u_color;"
|
|
||||||
// + "varying vec2 v_st;"
|
|
||||||
// + "void main() {"
|
|
||||||
// + " float len;"
|
|
||||||
// + " if (u_mode == 0)"
|
|
||||||
// + " len = abs(v_st.s);"
|
|
||||||
// + " else "
|
|
||||||
// + " len = length(v_st);"
|
|
||||||
// // fade to alpha. u_wscale is the width in pixel which should be
|
|
||||||
// // faded, u_width - len the position of this fragment on the
|
|
||||||
// // perpendicular to this line segment. this only works with no
|
|
||||||
// // perspective
|
|
||||||
// //+ " gl_FragColor = min(1.0, (u_width - len) / u_wscale) * u_color;"
|
|
||||||
// + " gl_FragColor = u_color * smoothstep(0.0, u_wscale, (u_width - len));"
|
|
||||||
// + "}";
|
|
||||||
//
|
|
||||||
// private final static String lineFragmentShader = ""
|
|
||||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
// + "precision mediump float;"
|
|
||||||
// + "uniform float u_wscale;"
|
|
||||||
// + "uniform float u_width;"
|
|
||||||
// + "uniform int u_mode;"
|
|
||||||
// + "uniform vec4 u_color;"
|
|
||||||
// + "varying vec2 v_st;"
|
|
||||||
// + "void main() {"
|
|
||||||
// + " float len;"
|
|
||||||
// + " float fuzz;"
|
|
||||||
// + " if (u_mode == 0){"
|
|
||||||
// + " len = abs(v_st.s);"
|
|
||||||
// + " fuzz = u_wscale + fwidth(v_st.s);"
|
|
||||||
// + " } else {"
|
|
||||||
// + " len = length(v_st);"
|
|
||||||
// + " vec2 st_width = fwidth(v_st);"
|
|
||||||
// + " fuzz = u_wscale + max(st_width.s, st_width.t);"
|
|
||||||
// + " }"
|
|
||||||
// + " gl_FragColor = u_color * min(1.0, (u_width - len) / fuzz);"
|
|
||||||
// + "}";
|
|
||||||
}
|
|
@ -1,236 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Layer for textured or stippled lines
|
|
||||||
*
|
|
||||||
* this would be all so much simpler with geometry shaders...
|
|
||||||
*/
|
|
||||||
public final class LineTexLayer extends Layer {
|
|
||||||
// Interleave two segment quads in one block to be able to use
|
|
||||||
// vertices twice. pos0 and pos1 use the same vertex array where
|
|
||||||
// pos1 has an offset of one vertex. The vertex shader will use
|
|
||||||
// pos0 when the vertexId is even, pos1 when the Id is odd.
|
|
||||||
//
|
|
||||||
// As there is no gl_VertexId in gles 2.0 an additional 'flip'
|
|
||||||
// array is used. Depending on 'flip' extrusion is inverted.
|
|
||||||
//
|
|
||||||
// Indices and flip buffers can be static.
|
|
||||||
//
|
|
||||||
// First pass: using even vertex array positions
|
|
||||||
// (used vertices are in braces)
|
|
||||||
// vertex id 0 1 2 3 4 5 6 7
|
|
||||||
// pos0 x (0) 1 (2) 3 (4) 5 (6) 7 x
|
|
||||||
// pos1 x (0) 1 (2) 3 (4) 5 (6) 7 x
|
|
||||||
// flip 0 1 0 1 0 1 0 1
|
|
||||||
//
|
|
||||||
// Second pass: using odd vertex array positions
|
|
||||||
// vertex id 0 1 2 3 4 5 6 7
|
|
||||||
// pos0 x 0 (1) 2 (3) 4 (5) 6 (7) x
|
|
||||||
// pos1 x 0 (1) 2 (3) 4 (5) 6 (7) x
|
|
||||||
// flip 0 1 0 1 0 1 0 1
|
|
||||||
//
|
|
||||||
// Vertex layout:
|
|
||||||
// [2 short] position,
|
|
||||||
// [2 short] extrusion,
|
|
||||||
// [1 short] line length
|
|
||||||
// [1 short] unused
|
|
||||||
//
|
|
||||||
// indices, for two blocks:
|
|
||||||
// 0, 1, 2,
|
|
||||||
// 2, 1, 3,
|
|
||||||
// 4, 5, 6,
|
|
||||||
// 6, 5, 7,
|
|
||||||
//
|
|
||||||
// BIG NOTE: renderer assumes to be able to offset vertex array position
|
|
||||||
// so that in the first pass 'pos1' offset will be < 0 if no data precedes
|
|
||||||
// - in our case there is always the polygon fill array at start
|
|
||||||
// - see addLine hack otherwise.
|
|
||||||
|
|
||||||
private static final float COORD_SCALE = GLRenderer.COORD_SCALE;
|
|
||||||
// scale factor mapping extrusion vector to short values
|
|
||||||
public static final float DIR_SCALE = 2048;
|
|
||||||
|
|
||||||
// lines referenced by this outline layer
|
|
||||||
public LineLayer outlines;
|
|
||||||
public Line line;
|
|
||||||
public float width;
|
|
||||||
|
|
||||||
public boolean roundCap;
|
|
||||||
|
|
||||||
public int evenQuads;
|
|
||||||
public int oddQuads;
|
|
||||||
|
|
||||||
private boolean evenSegment;
|
|
||||||
|
|
||||||
LineTexLayer(int layer) {
|
|
||||||
this.level = layer;
|
|
||||||
this.type = Layer.TEXLINE;
|
|
||||||
this.evenSegment = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addLine(float[] points, short[] index) {
|
|
||||||
|
|
||||||
if (vertexItems == null) {
|
|
||||||
curItem = vertexItems = VertexItem.pool.get();
|
|
||||||
|
|
||||||
// HACK add one vertex offset when compiling
|
|
||||||
// buffer otherwise one cant use the full
|
|
||||||
// VertexItem (see Layers.compile)
|
|
||||||
// add the two 'x' at front and end
|
|
||||||
//verticesCnt = 2;
|
|
||||||
|
|
||||||
// the additional end vertex to make sure
|
|
||||||
// not to read outside allocated memory
|
|
||||||
verticesCnt = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexItem si = curItem;
|
|
||||||
|
|
||||||
short v[] = si.vertices;
|
|
||||||
int opos = si.used;
|
|
||||||
|
|
||||||
boolean even = evenSegment;
|
|
||||||
|
|
||||||
// reset offset to last written position
|
|
||||||
if (!even)
|
|
||||||
opos -= 12;
|
|
||||||
|
|
||||||
int n;
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
if (index == null) {
|
|
||||||
n = 1;
|
|
||||||
length = points.length;
|
|
||||||
} else {
|
|
||||||
n = index.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, pos = 0; i < n; i++) {
|
|
||||||
if (index != null)
|
|
||||||
length = index[i];
|
|
||||||
|
|
||||||
// check end-marker in indices
|
|
||||||
if (length < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// need at least two points
|
|
||||||
if (length < 4) {
|
|
||||||
pos += length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ipos = pos;
|
|
||||||
|
|
||||||
float x = points[ipos++] * COORD_SCALE;
|
|
||||||
float y = points[ipos++] * COORD_SCALE;
|
|
||||||
|
|
||||||
// randomize a bit
|
|
||||||
float lineLength = (x * x + y * y) % 80;
|
|
||||||
|
|
||||||
int end = pos + length;
|
|
||||||
|
|
||||||
for (; ipos < end;) {
|
|
||||||
float nx = points[ipos++] * COORD_SCALE;
|
|
||||||
float ny = points[ipos++] * COORD_SCALE;
|
|
||||||
|
|
||||||
// Calculate triangle corners for the given width
|
|
||||||
float vx = nx - x;
|
|
||||||
float vy = ny - y;
|
|
||||||
|
|
||||||
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
|
||||||
|
|
||||||
// normal vector
|
|
||||||
vx /= a;
|
|
||||||
vy /= a;
|
|
||||||
|
|
||||||
// perpendicular to line segment
|
|
||||||
float ux = -vy;
|
|
||||||
float uy = vx;
|
|
||||||
|
|
||||||
short dx = (short) (ux * DIR_SCALE);
|
|
||||||
short dy = (short) (uy * DIR_SCALE);
|
|
||||||
|
|
||||||
if (opos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
opos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[opos + 0] = (short) x;
|
|
||||||
v[opos + 1] = (short) y;
|
|
||||||
v[opos + 2] = dx;
|
|
||||||
v[opos + 3] = dy;
|
|
||||||
v[opos + 4] = (short) lineLength;
|
|
||||||
v[opos + 5] = 0;
|
|
||||||
|
|
||||||
lineLength += a;
|
|
||||||
v[opos + 12] = (short) nx;
|
|
||||||
v[opos + 13] = (short) ny;
|
|
||||||
v[opos + 14] = dx;
|
|
||||||
v[opos + 15] = dy;
|
|
||||||
v[opos + 16] = (short) lineLength;
|
|
||||||
v[opos + 17] = 0;
|
|
||||||
|
|
||||||
x = nx;
|
|
||||||
y = ny;
|
|
||||||
|
|
||||||
if (even) {
|
|
||||||
// go to second segment
|
|
||||||
opos += 6;
|
|
||||||
even = false;
|
|
||||||
|
|
||||||
// vertex 0 and 2 were added
|
|
||||||
verticesCnt += 3;
|
|
||||||
evenQuads++;
|
|
||||||
} else {
|
|
||||||
// go to next block
|
|
||||||
even = true;
|
|
||||||
opos += 18;
|
|
||||||
|
|
||||||
// vertex 1 and 3 were added
|
|
||||||
verticesCnt += 1;
|
|
||||||
oddQuads++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
evenSegment = even;
|
|
||||||
|
|
||||||
// advance offset to last written position
|
|
||||||
if (!even)
|
|
||||||
opos += 12;
|
|
||||||
|
|
||||||
si.used = opos;
|
|
||||||
curItem = si;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void clear() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void compile(ShortBuffer sbuf) {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,334 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.backend.Log;
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
|
|
||||||
public class LineTexRenderer {
|
|
||||||
private final static String TAG = LineTexRenderer.class.getName();
|
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
|
||||||
|
|
||||||
// factor to normalize extrusion vector and scale to coord scale
|
|
||||||
private final static float COORD_SCALE_BY_DIR_SCALE =
|
|
||||||
GLRenderer.COORD_SCALE / LineLayer.DIR_SCALE;
|
|
||||||
|
|
||||||
private static int shader;
|
|
||||||
private static int hVertexPosition0;
|
|
||||||
private static int hVertexPosition1;
|
|
||||||
private static int hVertexLength0;
|
|
||||||
private static int hVertexLength1;
|
|
||||||
private static int hVertexFlip;
|
|
||||||
private static int hMatrix;
|
|
||||||
private static int hTexColor;
|
|
||||||
private static int hBgColor;
|
|
||||||
private static int hScale;
|
|
||||||
private static int hWidth;
|
|
||||||
private static int hPatternScale;
|
|
||||||
private static int hPatternWidth;
|
|
||||||
|
|
||||||
private static int mVertexFlipID;
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
shader = GlUtils.createProgram(vertexShader, fragmentShader);
|
|
||||||
if (shader == 0) {
|
|
||||||
Log.e(TAG, "Could not create program.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hMatrix = GL.glGetUniformLocation(shader, "u_mvp");
|
|
||||||
hTexColor = GL.glGetUniformLocation(shader, "u_color");
|
|
||||||
hBgColor = GL.glGetUniformLocation(shader, "u_bgcolor");
|
|
||||||
hScale = GL.glGetUniformLocation(shader, "u_scale");
|
|
||||||
hWidth = GL.glGetUniformLocation(shader, "u_width");
|
|
||||||
hPatternScale = GL.glGetUniformLocation(shader, "u_pscale");
|
|
||||||
hPatternWidth = GL.glGetUniformLocation(shader, "u_pwidth");
|
|
||||||
|
|
||||||
hVertexPosition0 = GL.glGetAttribLocation(shader, "a_pos0");
|
|
||||||
hVertexPosition1 = GL.glGetAttribLocation(shader, "a_pos1");
|
|
||||||
hVertexLength0 = GL.glGetAttribLocation(shader, "a_len0");
|
|
||||||
hVertexLength1 = GL.glGetAttribLocation(shader, "a_len1");
|
|
||||||
hVertexFlip = GL.glGetAttribLocation(shader, "a_flip");
|
|
||||||
|
|
||||||
int[] vboIds = GlUtils.glGenBuffers(1);
|
|
||||||
mVertexFlipID = vboIds[0];
|
|
||||||
|
|
||||||
// bytes: 0, 1, 0, 1, 0, ...
|
|
||||||
byte[] flip = new byte[GLRenderer.maxQuads * 4];
|
|
||||||
for (int i = 0; i < flip.length; i++)
|
|
||||||
flip[i] = (byte)(i % 2);
|
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocateDirect(flip.length)
|
|
||||||
.order(ByteOrder.nativeOrder());
|
|
||||||
buf.put(flip);
|
|
||||||
buf.flip();
|
|
||||||
|
|
||||||
ShortBuffer sbuf = buf.asShortBuffer();
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
|
||||||
GL.glBufferData(GL20.GL_ARRAY_BUFFER, flip.length , sbuf,
|
|
||||||
GL20.GL_STATIC_DRAW);
|
|
||||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
// mTexID = new int[10];
|
|
||||||
// byte[] stipple = new byte[2];
|
|
||||||
// stipple[0] = 32;
|
|
||||||
// stipple[1] = 32;
|
|
||||||
// mTexID[0] = GlUtils.loadStippleTexture(stipple);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static int STRIDE = 12;
|
|
||||||
private final static int LEN_OFFSET = 8;
|
|
||||||
|
|
||||||
public static Layer draw(Layers layers, Layer curLayer,
|
|
||||||
MapPosition pos, Matrices m, float div) {
|
|
||||||
|
|
||||||
// shader failed to compile
|
|
||||||
if (shader == 0)
|
|
||||||
return curLayer.next;
|
|
||||||
|
|
||||||
GLState.blend(true);
|
|
||||||
GLState.useProgram(shader);
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(-1, -1);
|
|
||||||
|
|
||||||
GL.glEnableVertexAttribArray(hVertexPosition0);
|
|
||||||
GL.glEnableVertexAttribArray(hVertexPosition1);
|
|
||||||
GL.glEnableVertexAttribArray(hVertexLength0);
|
|
||||||
GL.glEnableVertexAttribArray(hVertexLength1);
|
|
||||||
GL.glEnableVertexAttribArray(hVertexFlip);
|
|
||||||
|
|
||||||
m.mvp.setAsUniform(hMatrix);
|
|
||||||
|
|
||||||
int maxIndices = GLRenderer.maxQuads * 6;
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
GLRenderer.mQuadIndicesID);
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, mVertexFlipID);
|
|
||||||
GL.glVertexAttribPointer(hVertexFlip, 1,
|
|
||||||
GL20.GL_BYTE, false, 0, 0);
|
|
||||||
|
|
||||||
layers.vbo.bind();
|
|
||||||
|
|
||||||
float scale = (float) pos.getZoomScale();
|
|
||||||
|
|
||||||
float s = scale / div;
|
|
||||||
|
|
||||||
//GL.glBindTexture(GL20.GL_TEXTURE_2D, mTexID[0]);
|
|
||||||
|
|
||||||
Layer l = curLayer;
|
|
||||||
for (; l != null && l.type == Layer.TEXLINE; l = l.next) {
|
|
||||||
LineTexLayer ll = (LineTexLayer) l;
|
|
||||||
Line line = ll.line;
|
|
||||||
|
|
||||||
GlUtils.setColor(hTexColor, line.stippleColor, 1);
|
|
||||||
GlUtils.setColor(hBgColor, line.color, 1);
|
|
||||||
|
|
||||||
float pScale = (int) (s + 0.5f);
|
|
||||||
if (pScale < 1)
|
|
||||||
pScale = 1;
|
|
||||||
|
|
||||||
GL.glUniform1f(hPatternScale, (GLRenderer.COORD_SCALE * line.stipple) / pScale);
|
|
||||||
GL.glUniform1f(hPatternWidth, line.stippleWidth);
|
|
||||||
|
|
||||||
GL.glUniform1f(hScale, scale);
|
|
||||||
// keep line width fixed
|
|
||||||
GL.glUniform1f(hWidth, ll.width / s * COORD_SCALE_BY_DIR_SCALE);
|
|
||||||
|
|
||||||
// add offset vertex
|
|
||||||
int vOffset = -STRIDE;
|
|
||||||
|
|
||||||
// first pass
|
|
||||||
int allIndices = (ll.evenQuads * 6);
|
|
||||||
for (int i = 0; i < allIndices; i += maxIndices) {
|
|
||||||
int numIndices = allIndices - i;
|
|
||||||
if (numIndices > maxIndices)
|
|
||||||
numIndices = maxIndices;
|
|
||||||
|
|
||||||
// i / 6 * (24 shorts per block * 2 short bytes)
|
|
||||||
int add = (l.offset + i * 8) + vOffset;
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition0,
|
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength0,
|
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE + LEN_OFFSET);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition1,
|
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength1,
|
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + LEN_OFFSET);
|
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// second pass
|
|
||||||
allIndices = (ll.oddQuads * 6);
|
|
||||||
for (int i = 0; i < allIndices; i += maxIndices) {
|
|
||||||
int numIndices = allIndices - i;
|
|
||||||
if (numIndices > maxIndices)
|
|
||||||
numIndices = maxIndices;
|
|
||||||
// i / 6 * (24 shorts per block * 2 short bytes)
|
|
||||||
int add = (l.offset + i * 8) + vOffset;
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition0,
|
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + 2 * STRIDE);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength0,
|
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + 2 * STRIDE + LEN_OFFSET);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexPosition1,
|
|
||||||
4, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hVertexLength1,
|
|
||||||
2, GL20.GL_SHORT, false, STRIDE,
|
|
||||||
add + STRIDE + LEN_OFFSET);
|
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numIndices,
|
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
}
|
|
||||||
//GlUtils.checkGlError(TAG);
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
GL.glDisableVertexAttribArray(hVertexPosition0);
|
|
||||||
GL.glDisableVertexAttribArray(hVertexPosition1);
|
|
||||||
GL.glDisableVertexAttribArray(hVertexLength0);
|
|
||||||
GL.glDisableVertexAttribArray(hVertexLength1);
|
|
||||||
GL.glDisableVertexAttribArray(hVertexFlip);
|
|
||||||
|
|
||||||
//GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
final static String vertexShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform mat4 u_mvp;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "uniform float u_pscale;"
|
|
||||||
+ "uniform float u_width;"
|
|
||||||
+ "attribute vec4 a_pos0;"
|
|
||||||
+ "attribute vec4 a_pos1;"
|
|
||||||
+ "attribute vec2 a_len0;"
|
|
||||||
+ "attribute vec2 a_len1;"
|
|
||||||
+ "attribute float a_flip;"
|
|
||||||
+ "varying vec2 v_st;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " vec4 pos;"
|
|
||||||
+ " if (a_flip == 0.0){"
|
|
||||||
//+ " vec2 dir = u_width * a_pos0.zw;"
|
|
||||||
+ " pos = vec4(a_pos0.xy + (u_width * a_pos0.zw), 0.0, 1.0);"
|
|
||||||
+ " v_st = vec2(a_len0.x / u_pscale, 1.0);"
|
|
||||||
+ " } else {"
|
|
||||||
//+ " vec2 dir = u_width * a_pos1.zw;"
|
|
||||||
+ " pos = vec4(a_pos1.xy - (u_width * a_pos1.zw), 0.0, 1.0);"
|
|
||||||
+ " v_st = vec2(a_len1.x / u_pscale, -1.0);"
|
|
||||||
+ " }"
|
|
||||||
+ " gl_Position = u_mvp * pos;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
//*
|
|
||||||
final static String fragmentShader = ""
|
|
||||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
+ " precision mediump float;"
|
|
||||||
+ " uniform vec4 u_color;"
|
|
||||||
+ " uniform vec4 u_bgcolor;"
|
|
||||||
+ " uniform float u_pwidth;"
|
|
||||||
+ " varying vec2 v_st;"
|
|
||||||
+ " void main() {"
|
|
||||||
// distance on perpendicular to the line
|
|
||||||
+ " float dist = abs(v_st.t);"
|
|
||||||
+ " float fuzz = fwidth(v_st.t);"
|
|
||||||
+ " float fuzz_p = fwidth(v_st.s);"
|
|
||||||
+ " float line_w = smoothstep(0.0, fuzz, 1.0 - dist);"
|
|
||||||
+ " float stipple_w = smoothstep(0.0, fuzz, u_pwidth - dist);"
|
|
||||||
// triangle waveform in the range 0..1 for regular pattern
|
|
||||||
+ " float phase = abs(mod(v_st.s, 2.0) - 1.0);"
|
|
||||||
// interpolate between on/off phase, 0.5 = equal phase length
|
|
||||||
+ " float stipple_p = smoothstep(0.5 - fuzz_p, 0.5 + fuzz_p, phase);"
|
|
||||||
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
|
||||||
+ " } "; //*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* final static String fragmentShader = ""
|
|
||||||
* + "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
* + " precision mediump float;"
|
|
||||||
* + " uniform sampler2D tex;"
|
|
||||||
* + " uniform float u_scale;"
|
|
||||||
* + " uniform vec4 u_color;"
|
|
||||||
* + " uniform vec4 u_bgcolor;"
|
|
||||||
* + " varying vec2 v_st;"
|
|
||||||
* + " void main() {"
|
|
||||||
* + " float len = texture2D(tex, v_st).a;"
|
|
||||||
* + " float tex_w = abs(v_st.t);"
|
|
||||||
* + " vec2 st_width = fwidth(v_st);"
|
|
||||||
* + " float fuzz = max(st_width.s, st_width.t);"
|
|
||||||
* //+ " float fuzz = fwidth(v_st.t);"
|
|
||||||
* //+ " float line_w = 1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w);"
|
|
||||||
* //+ " float stipple_w = 1.0 - smoothstep(0.7 - fuzz, 0.7, tex_w);"
|
|
||||||
* +
|
|
||||||
* " float stipple_p = 1.0 - smoothstep(1.0 - fuzz, 1.0, length(vec2(len*u_scale, v_st.t)));"
|
|
||||||
* + " gl_FragColor = u_bgcolor * stipple_p;"
|
|
||||||
* // +
|
|
||||||
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
|
||||||
* + "}"; //
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* final static String fragmentShader = ""
|
|
||||||
* + "#extension GL_OES_standard_derivatives : enable\n"
|
|
||||||
* + " precision mediump float;"
|
|
||||||
* + " uniform sampler2D tex;"
|
|
||||||
* + " uniform vec4 u_color;"
|
|
||||||
* + " uniform vec4 u_bgcolor;"
|
|
||||||
* + " uniform float u_pwidth;"
|
|
||||||
* + " varying vec2 v_st;"
|
|
||||||
* + " void main() {"
|
|
||||||
* + " float dist = texture2D(tex, v_st).a;"
|
|
||||||
* + " float tex_w = abs(v_st.t);"
|
|
||||||
* + " vec2 st_width = fwidth(v_st);"
|
|
||||||
* + " float fuzz = max(st_width.s, st_width.t);"
|
|
||||||
* + " float line_w = (1.0 - smoothstep(1.0 - fuzz, 1.0, tex_w));"
|
|
||||||
* +
|
|
||||||
* " float stipple_w = (1.0 - smoothstep(u_pwidth - fuzz, u_pwidth, tex_w));"
|
|
||||||
* + " float stipple_p = smoothstep(0.495, 0.505, dist);"
|
|
||||||
* +
|
|
||||||
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
|
|
||||||
* + " } "; //
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
public class MeshRenderer {
|
|
||||||
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.core.Tile;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.theme.renderinstruction.Area;
|
|
||||||
|
|
||||||
public final class PolygonLayer extends Layer {
|
|
||||||
private static final float S = GLRenderer.COORD_SCALE;
|
|
||||||
|
|
||||||
public Area area;
|
|
||||||
|
|
||||||
PolygonLayer(int layer) {
|
|
||||||
this.level = layer;
|
|
||||||
this.type = Layer.POLYGON;
|
|
||||||
curItem = VertexItem.pool.get();
|
|
||||||
vertexItems = curItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPolygon(float[] points, short[] index) {
|
|
||||||
short center = (short) ((Tile.SIZE >> 1) * S);
|
|
||||||
|
|
||||||
VertexItem si = curItem;
|
|
||||||
short[] v = si.vertices;
|
|
||||||
int outPos = si.used;
|
|
||||||
|
|
||||||
for (int i = 0, pos = 0, n = index.length; i < n; i++) {
|
|
||||||
int length = index[i];
|
|
||||||
if (length < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// need at least three points
|
|
||||||
if (length < 6) {
|
|
||||||
pos += length;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
verticesCnt += length / 2 + 2;
|
|
||||||
|
|
||||||
int inPos = pos;
|
|
||||||
|
|
||||||
if (outPos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
outPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[outPos++] = center;
|
|
||||||
v[outPos++] = center;
|
|
||||||
|
|
||||||
for (int j = 0; j < length; j += 2) {
|
|
||||||
if (outPos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
outPos = 0;
|
|
||||||
}
|
|
||||||
v[outPos++] = (short) (points[inPos++] * S);
|
|
||||||
v[outPos++] = (short) (points[inPos++] * S);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outPos == VertexItem.SIZE) {
|
|
||||||
si = si.next = VertexItem.pool.get();
|
|
||||||
v = si.vertices;
|
|
||||||
outPos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
v[outPos++] = (short) (points[pos + 0] * S);
|
|
||||||
v[outPos++] = (short) (points[pos + 1] * S);
|
|
||||||
|
|
||||||
pos += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
si.used = outPos;
|
|
||||||
curItem = si;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void compile(ShortBuffer sbuf) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void clear() {
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,466 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.FloatBuffer;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.backend.Log;
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.theme.renderinstruction.Area;
|
|
||||||
import org.oscim.utils.FastMath;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
import org.oscim.utils.Matrix4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Special Renderer for drawing tile polygon layers
|
|
||||||
*/
|
|
||||||
public final class PolygonRenderer {
|
|
||||||
private static final String TAG = PolygonRenderer.class.getName();
|
|
||||||
|
|
||||||
private static GL20 GL;
|
|
||||||
|
|
||||||
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
|
|
||||||
private static final int STENCIL_BITS = 8;
|
|
||||||
private final static int CLIP_BIT = 0x80;
|
|
||||||
|
|
||||||
private static final float FADE_START = 1.3f;
|
|
||||||
|
|
||||||
private static PolygonLayer[] mFillPolys;
|
|
||||||
|
|
||||||
private static int numShaders = 2;
|
|
||||||
private static int polyShader = 0;
|
|
||||||
private static int texShader = 1;
|
|
||||||
|
|
||||||
private static int[] polygonProgram = new int[numShaders];
|
|
||||||
|
|
||||||
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 boolean enableTexture = false;
|
|
||||||
|
|
||||||
static boolean init() {
|
|
||||||
GL = GLAdapter.get();
|
|
||||||
|
|
||||||
for (int i = 0; i < numShaders; i++) {
|
|
||||||
|
|
||||||
// Set up the program for rendering polygons
|
|
||||||
if (i == 0) {
|
|
||||||
if (GLRenderer.debugView)
|
|
||||||
polygonProgram[i] = GlUtils.createProgram(polygonVertexShaderZ,
|
|
||||||
polygonFragmentShaderZ);
|
|
||||||
else
|
|
||||||
polygonProgram[i] = GlUtils.createProgram(polygonVertexShader,
|
|
||||||
polygonFragmentShader);
|
|
||||||
} else if (i == 1) {
|
|
||||||
polygonProgram[i] = GlUtils.createProgram(textureVertexShader,
|
|
||||||
textureFragmentShader);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (polygonProgram[i] == 0) {
|
|
||||||
Log.e(TAG, "Could not create polygon program.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hPolygonMatrix[i] = GL.glGetUniformLocation(polygonProgram[i], "u_mvp");
|
|
||||||
hPolygonColor[i] = GL.glGetUniformLocation(polygonProgram[i], "u_color");
|
|
||||||
hPolygonScale[i] = GL.glGetUniformLocation(polygonProgram[i], "u_scale");
|
|
||||||
|
|
||||||
hPolygonVertexPosition[i] = GL.glGetAttribLocation(polygonProgram[i], "a_pos");
|
|
||||||
}
|
|
||||||
|
|
||||||
mFillPolys = new PolygonLayer[STENCIL_BITS];
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale,
|
|
||||||
float div) {
|
|
||||||
|
|
||||||
/* draw to framebuffer */
|
|
||||||
GL.glColorMask(true, true, true, true);
|
|
||||||
|
|
||||||
/* do not modify stencil buffer */
|
|
||||||
GL.glStencilMask(0x00);
|
|
||||||
int shader = polyShader;
|
|
||||||
|
|
||||||
for (int c = start; c < end; c++) {
|
|
||||||
Area a = mFillPolys[c].area;
|
|
||||||
|
|
||||||
if (enableTexture && a.texture != null){
|
|
||||||
shader = texShader;
|
|
||||||
setShader(texShader, m);
|
|
||||||
GL.glUniform2f(hPolygonScale[1], FastMath.clamp(scale - 1, 0, 1), div);
|
|
||||||
|
|
||||||
a.texture.bind();
|
|
||||||
|
|
||||||
} else if (a.fade >= zoom) {
|
|
||||||
float f = 1.0f;
|
|
||||||
/* fade in/out */
|
|
||||||
if (a.fade >= zoom) {
|
|
||||||
if (scale > FADE_START)
|
|
||||||
f = scale - 1;
|
|
||||||
else
|
|
||||||
f = FADE_START - 1;
|
|
||||||
}
|
|
||||||
GLState.blend(true);
|
|
||||||
|
|
||||||
GlUtils.setColor(hPolygonColor[shader], a.color, f);
|
|
||||||
|
|
||||||
} else if (a.blend > 0 && a.blend <= zoom) {
|
|
||||||
/* blend colors (not alpha) */
|
|
||||||
GLState.blend(false);
|
|
||||||
|
|
||||||
if (a.blend == zoom)
|
|
||||||
GlUtils.setColorBlend(hPolygonColor[shader],
|
|
||||||
a.color, a.blendColor, scale - 1.0f);
|
|
||||||
else
|
|
||||||
GlUtils.setColor(hPolygonColor[shader], a.blendColor, 1);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (a.color < 0xff000000)
|
|
||||||
GLState.blend(true);
|
|
||||||
else
|
|
||||||
GLState.blend(false);
|
|
||||||
|
|
||||||
GlUtils.setColor(hPolygonColor[shader], a.color, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set stencil buffer mask used to draw this layer
|
|
||||||
// also check that clip bit is set to avoid overdraw
|
|
||||||
// of other tiles
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
|
|
||||||
|
|
||||||
/* draw tile fill coordinates */
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
if (shader != polyShader) {
|
|
||||||
// disable texture shader
|
|
||||||
setShader(polyShader, m);
|
|
||||||
shader = polyShader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// current layer to fill (0 - STENCIL_BITS-1)
|
|
||||||
private static int mCount;
|
|
||||||
|
|
||||||
private static void setShader(int shader, Matrices m) {
|
|
||||||
GLState.useProgram(polygonProgram[shader]);
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hPolygonVertexPosition[shader], 2, GL20.GL_SHORT,
|
|
||||||
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
|
||||||
|
|
||||||
m.mvp.setAsUniform(hPolygonMatrix[shader]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* draw polygon layers (unil layer.next is not polygon layer)
|
|
||||||
* using stencil buffer method
|
|
||||||
*
|
|
||||||
* @param pos
|
|
||||||
* used to fade layers accorind to 'fade'
|
|
||||||
* in layer.area.
|
|
||||||
* @param layer
|
|
||||||
* layer to draw (referencing vertices in current vbo)
|
|
||||||
* @param m
|
|
||||||
* 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, 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
|
|
||||||
if (first || cur > 5)
|
|
||||||
cur = 0;
|
|
||||||
|
|
||||||
int start = cur;
|
|
||||||
|
|
||||||
Layer l = layer;
|
|
||||||
for (; l != null && l.type == Layer.POLYGON; l = l.next) {
|
|
||||||
PolygonLayer pl = (PolygonLayer) l;
|
|
||||||
|
|
||||||
// fade out polygon layers (set in RenderTheme)
|
|
||||||
if (pl.area.fade > 0 && pl.area.fade > zoom)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (cur == start) {
|
|
||||||
drawStencilRegion(first);
|
|
||||||
first = false;
|
|
||||||
|
|
||||||
// op for stencil method polygon drawing
|
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_INVERT);
|
|
||||||
}
|
|
||||||
|
|
||||||
mFillPolys[cur] = pl;
|
|
||||||
|
|
||||||
// set stencil mask to draw to
|
|
||||||
GL.glStencilMask(1 << cur++);
|
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.verticesCnt);
|
|
||||||
|
|
||||||
// draw up to 7 layers into stencil buffer
|
|
||||||
if (cur == STENCIL_BITS - 1) {
|
|
||||||
fillPolygons(m, start, cur, zoom, scale, div);
|
|
||||||
start = cur = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur > 0)
|
|
||||||
fillPolygons(m, start, cur, zoom, scale, div);
|
|
||||||
|
|
||||||
if (clip) {
|
|
||||||
if (first) {
|
|
||||||
drawStencilRegion(first);
|
|
||||||
// disable writes to stencil buffer
|
|
||||||
GL.glStencilMask(0x00);
|
|
||||||
// enable writes to color buffer
|
|
||||||
GL.glColorMask(true, true, true, true);
|
|
||||||
} else {
|
|
||||||
// set test for clip to tile region
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mCount = cur;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clip(Matrices m){
|
|
||||||
setShader(polyShader, m);
|
|
||||||
|
|
||||||
drawStencilRegion(true);
|
|
||||||
// disable writes to stencil buffer
|
|
||||||
GL.glStencilMask(0x00);
|
|
||||||
// enable writes to color buffer
|
|
||||||
GL.glColorMask(true, true, true, true);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Draw a tile filling rectangle to set stencil- and depth buffer
|
|
||||||
* appropriately
|
|
||||||
*
|
|
||||||
* @param first in the first run the clip region is set based on
|
|
||||||
* depth buffer and depth buffer is updated
|
|
||||||
*/
|
|
||||||
static void drawStencilRegion(boolean first) {
|
|
||||||
|
|
||||||
// if (!first) {
|
|
||||||
// GL.glStencilMask(0x7F);
|
|
||||||
// GL.glClear(GL20.GL_STENCIL_BUFFER_BIT);
|
|
||||||
// // disable drawing to color buffer
|
|
||||||
// GL.glColorMask(false, false, false, false);
|
|
||||||
// GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// disable drawing to color buffer
|
|
||||||
GL.glColorMask(false, false, false, false);
|
|
||||||
|
|
||||||
// write to all stencil bits
|
|
||||||
GL.glStencilMask(0xFF);
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
// clear previous clip-region from stencil buffer
|
|
||||||
//GL.glClear(GL20.GL_STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
// Draw clip-region into depth and stencil buffer
|
|
||||||
// this is used for tile line and polygon layers.
|
|
||||||
// Depth offset is increased for each tile. Together
|
|
||||||
// with depth test (GL_LESS) this ensures to only
|
|
||||||
// draw where no other tile has drawn yet.
|
|
||||||
GL.glEnable(GL20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
|
|
||||||
// test GL_LESS and write to depth buffer
|
|
||||||
GLState.test(true, true);
|
|
||||||
GL.glDepthMask(true);
|
|
||||||
|
|
||||||
// always pass stencil test and set clip bit
|
|
||||||
GL.glStencilFunc(GL20.GL_ALWAYS, CLIP_BIT, 0x00);
|
|
||||||
} else {
|
|
||||||
// use clip bit from stencil buffer
|
|
||||||
// to clear stencil 'layer-bits' (0x7f)
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set clip bit (0x80) for draw region
|
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_REPLACE);
|
|
||||||
|
|
||||||
// draw a quad for the tile region
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
// dont modify depth buffer
|
|
||||||
GL.glDepthMask(false);
|
|
||||||
// test only stencil
|
|
||||||
GLState.test(false, true);
|
|
||||||
|
|
||||||
GL.glDisable(GL20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void drawOver(Matrices m, int color) {
|
|
||||||
setShader(polyShader, m);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* clear stencilbuffer (tile region) by drawing
|
|
||||||
* a quad with func 'always' and op 'zero'
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (color != 0) {
|
|
||||||
GlUtils.setColor(hPolygonColor[0], color, 1);
|
|
||||||
GLState.blend(true);
|
|
||||||
} else {
|
|
||||||
// disable drawing to framebuffer (will be re-enabled in fill)
|
|
||||||
GL.glColorMask(false, false, false, false);
|
|
||||||
}
|
|
||||||
// always pass stencil test:
|
|
||||||
//glStencilFunc(GL_ALWAYS, 0x00, 0x00);
|
|
||||||
GL.glStencilFunc(GL20.GL_EQUAL, CLIP_BIT, CLIP_BIT);
|
|
||||||
|
|
||||||
// write to all bits
|
|
||||||
GL.glStencilMask(0xFF);
|
|
||||||
// zero out area to draw to
|
|
||||||
GL.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_ZERO);
|
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
if (color == 0)
|
|
||||||
GL.glColorMask(true, true, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float[] debugFillColor = { 0.3f, 0.0f, 0.0f, 0.3f };
|
|
||||||
private static float[] debugFillColor2 = { .8f, .8f, .8f, .8f };
|
|
||||||
private static FloatBuffer mDebugFill;
|
|
||||||
|
|
||||||
static void debugDraw(Matrix4 m, float[] coords, int color) {
|
|
||||||
GLState.test(false, false);
|
|
||||||
if (mDebugFill == null) {
|
|
||||||
mDebugFill = ByteBuffer.allocateDirect(32).order(ByteOrder.nativeOrder())
|
|
||||||
.asFloatBuffer();
|
|
||||||
mDebugFill.put(coords);
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
mDebugFill.position(0);
|
|
||||||
GLState.useProgram(polygonProgram[0]);
|
|
||||||
GL.glEnableVertexAttribArray(hPolygonVertexPosition[0]);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hPolygonVertexPosition[0], 2, GL20.GL_FLOAT,
|
|
||||||
false, 0, mDebugFill);
|
|
||||||
|
|
||||||
m.setAsUniform(hPolygonMatrix[0]);
|
|
||||||
|
|
||||||
if (color == 0)
|
|
||||||
GlUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor);
|
|
||||||
else
|
|
||||||
GlUtils.glUniform4fv(hPolygonColor[0], 1, debugFillColor2);
|
|
||||||
|
|
||||||
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
|
|
||||||
GlUtils.checkGlError("draw debug");
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static String polygonVertexShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform mat4 u_mvp;"
|
|
||||||
+ "attribute vec4 a_pos;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_Position = u_mvp * a_pos;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String polygonFragmentShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_FragColor = u_color;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String polygonVertexShaderZ = ""
|
|
||||||
+ "precision highp float;"
|
|
||||||
+ "uniform mat4 u_mvp;"
|
|
||||||
+ "attribute vec4 a_pos;"
|
|
||||||
+ "varying float z;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_Position = u_mvp * a_pos;"
|
|
||||||
+ " z = gl_Position.z;"
|
|
||||||
+ "}";
|
|
||||||
private final static String polygonFragmentShaderZ = ""
|
|
||||||
+ "precision highp float;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "varying float z;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ "if (z < -1.0)"
|
|
||||||
+ " gl_FragColor = vec4(0.0, z + 2.0, 0.0, 1.0)*0.8;"
|
|
||||||
+ "else if (z < 0.0)"
|
|
||||||
+ " gl_FragColor = vec4(z + 1.0, 0.0, 0.0, 1.0)*0.8;"
|
|
||||||
+ "else if (z < 1.0)"
|
|
||||||
+ " gl_FragColor = vec4(0.0, 0.0, z, 1.0)*0.8;"
|
|
||||||
+ "else"
|
|
||||||
+ " gl_FragColor = vec4(0.0, z - 1.0, 0.0, 1.0)*0.8;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
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 / u_scale.y);"
|
|
||||||
+ " v_st2 = clamp(a_pos.xy, 0.0, 1.0) * (4.0 / u_scale.y);"
|
|
||||||
+ " gl_Position = u_mvp * a_pos;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String textureFragmentShader = ""
|
|
||||||
+ "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 = mix(texture2D(tex, v_st), texture2D(tex, v_st2), u_scale.x);"
|
|
||||||
+ "}";
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
public abstract class TextureLayer extends Layer {
|
|
||||||
// holds textures and offset in vbo
|
|
||||||
public TextureItem textures;
|
|
||||||
|
|
||||||
// scale mode
|
|
||||||
public boolean fixed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sbuf
|
|
||||||
* buffer to add vertices
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void compile(ShortBuffer sbuf) {
|
|
||||||
|
|
||||||
for (TextureItem to = textures; to != null; to = to.next)
|
|
||||||
to.upload();
|
|
||||||
|
|
||||||
// add vertices to vbo
|
|
||||||
Layers.addPoolItems(this, sbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public boolean prepare();
|
|
||||||
|
|
||||||
static void putSprite(short buf[], int pos,
|
|
||||||
short tx, short ty,
|
|
||||||
short x1, short y1,
|
|
||||||
short x2, short y2,
|
|
||||||
short u1, short v1,
|
|
||||||
short u2, short v2) {
|
|
||||||
|
|
||||||
// top-left
|
|
||||||
buf[pos + 0] = tx;
|
|
||||||
buf[pos + 1] = ty;
|
|
||||||
buf[pos + 2] = x1;
|
|
||||||
buf[pos + 3] = y1;
|
|
||||||
buf[pos + 4] = u1;
|
|
||||||
buf[pos + 5] = v2;
|
|
||||||
// bot-left
|
|
||||||
buf[pos + 6] = tx;
|
|
||||||
buf[pos + 7] = ty;
|
|
||||||
buf[pos + 8] = x1;
|
|
||||||
buf[pos + 9] = y2;
|
|
||||||
buf[pos + 10] = u1;
|
|
||||||
buf[pos + 11] = v1;
|
|
||||||
// top-right
|
|
||||||
buf[pos + 12] = tx;
|
|
||||||
buf[pos + 13] = ty;
|
|
||||||
buf[pos + 14] = x2;
|
|
||||||
buf[pos + 15] = y1;
|
|
||||||
buf[pos + 16] = u2;
|
|
||||||
buf[pos + 17] = v2;
|
|
||||||
// bot-right
|
|
||||||
buf[pos + 18] = tx;
|
|
||||||
buf[pos + 19] = ty;
|
|
||||||
buf[pos + 20] = x2;
|
|
||||||
buf[pos + 21] = y2;
|
|
||||||
buf[pos + 22] = u2;
|
|
||||||
buf[pos + 23] = v1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,151 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012, 2013 Hannes Janetzek
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
|
||||||
* terms of the GNU Lesser General Public License as published by the Free Software
|
|
||||||
* Foundation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.oscim.renderer.sublayers;
|
|
||||||
|
|
||||||
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
|
||||||
|
|
||||||
import org.oscim.backend.GL20;
|
|
||||||
import org.oscim.backend.GLAdapter;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
|
|
||||||
public final class TextureRenderer {
|
|
||||||
//private final static String TAG = TextureRenderer.class.getName();
|
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
|
||||||
|
|
||||||
public final static boolean debug = false;
|
|
||||||
|
|
||||||
private static int mTextureProgram;
|
|
||||||
private static int hTextureMVMatrix;
|
|
||||||
private static int hTextureProjMatrix;
|
|
||||||
private static int hTextureVertex;
|
|
||||||
private static int hTextureScale;
|
|
||||||
private static int hTextureScreenScale;
|
|
||||||
private static int hTextureTexCoord;
|
|
||||||
private static int hTextureSize;
|
|
||||||
|
|
||||||
public final static int INDICES_PER_SPRITE = 6;
|
|
||||||
final static int VERTICES_PER_SPRITE = 4;
|
|
||||||
final static int SHORTS_PER_VERTICE = 6;
|
|
||||||
|
|
||||||
static void init() {
|
|
||||||
mTextureProgram = GlUtils.createProgram(textVertexShader,
|
|
||||||
textFragmentShader);
|
|
||||||
|
|
||||||
hTextureMVMatrix = GL.glGetUniformLocation(mTextureProgram, "u_mv");
|
|
||||||
hTextureProjMatrix = GL.glGetUniformLocation(mTextureProgram, "u_proj");
|
|
||||||
hTextureScale = GL.glGetUniformLocation(mTextureProgram, "u_scale");
|
|
||||||
hTextureSize = GL.glGetUniformLocation(mTextureProgram, "u_div");
|
|
||||||
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
|
|
||||||
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
|
||||||
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Layer draw(Layer layer, float scale, Matrices m) {
|
|
||||||
|
|
||||||
GLState.test(false, false);
|
|
||||||
GLState.blend(true);
|
|
||||||
|
|
||||||
GLState.useProgram(mTextureProgram);
|
|
||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) layer;
|
|
||||||
|
|
||||||
if (tl.fixed)
|
|
||||||
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
|
||||||
else
|
|
||||||
GL.glUniform1f(hTextureScale, 1);
|
|
||||||
|
|
||||||
GL.glUniform1f(hTextureScreenScale, 1f / GLRenderer.screenWidth);
|
|
||||||
|
|
||||||
m.proj.setAsUniform(hTextureProjMatrix);
|
|
||||||
m.mvp.setAsUniform(hTextureMVMatrix);
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID);
|
|
||||||
|
|
||||||
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
|
||||||
|
|
||||||
ti.bind();
|
|
||||||
|
|
||||||
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
|
|
||||||
|
|
||||||
GL.glUniform2f(hTextureSize,
|
|
||||||
1f / (ti.width * COORD_SCALE),
|
|
||||||
1f / (ti.height * COORD_SCALE));
|
|
||||||
|
|
||||||
// draw up to maxVertices in each iteration
|
|
||||||
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
|
||||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
|
||||||
int off = (ti.offset + i) * 8 + tl.offset;
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
|
||||||
GL20.GL_SHORT, false, 12, off);
|
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
|
||||||
|
|
||||||
int numVertices = ti.vertices - i;
|
|
||||||
if (numVertices > maxVertices)
|
|
||||||
numVertices = maxVertices;
|
|
||||||
|
|
||||||
GL.glDrawElements(GL20.GL_TRIANGLES, numVertices,
|
|
||||||
GL20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
|
|
||||||
return layer.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final static double COORD_DIV = 1.0 / GLRenderer.COORD_SCALE;
|
|
||||||
|
|
||||||
private final static String textVertexShader = ""
|
|
||||||
+ "precision highp float;"
|
|
||||||
+ "attribute vec4 vertex;"
|
|
||||||
+ "attribute vec2 tex_coord;"
|
|
||||||
+ "uniform mat4 u_mv;"
|
|
||||||
+ "uniform mat4 u_proj;"
|
|
||||||
+ "uniform float u_scale;"
|
|
||||||
+ "uniform float u_swidth;"
|
|
||||||
+ "uniform vec2 u_div;"
|
|
||||||
+ "varying vec2 tex_c;"
|
|
||||||
+ "const float coord_scale = " + COORD_DIV + ";"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " vec4 pos;"
|
|
||||||
+ " vec2 dir = vertex.zw;"
|
|
||||||
+ " if (mod(vertex.x, 2.0) == 0.0){"
|
|
||||||
+ " pos = u_proj * (u_mv * vec4(vertex.xy + dir * u_scale, 0.0, 1.0));"
|
|
||||||
+ " } else {" // place as billboard
|
|
||||||
+ " vec4 center = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
|
||||||
+ " pos = u_proj * (center + vec4(dir * (coord_scale * u_swidth), 0.0, 0.0));"
|
|
||||||
+ " }"
|
|
||||||
+ " gl_Position = pos;"
|
|
||||||
+ " tex_c = tex_coord * u_div;"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
private final static String textFragmentShader = ""
|
|
||||||
+ "precision highp float;"
|
|
||||||
+ "uniform sampler2D tex;"
|
|
||||||
+ "varying vec2 tex_c;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_FragColor = texture2D(tex, tex_c.xy);"
|
|
||||||
+ "}";
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package org.oscim.renderer.layers.test;
|
package org.oscim.renderer.test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -6,18 +6,18 @@ import org.oscim.backend.Log;
|
|||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.backend.canvas.Paint.Cap;
|
import org.oscim.backend.canvas.Paint.Cap;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas;
|
import org.oscim.renderer.atlas.TextureAtlas;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas.Slot;
|
import org.oscim.renderer.atlas.TextureAtlas.Slot;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
import org.oscim.renderer.sublayers.LineLayer;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextLayer;
|
||||||
import org.oscim.renderer.sublayers.TextLayer;
|
|
||||||
import org.oscim.theme.renderinstruction.Line;
|
import org.oscim.theme.renderinstruction.Line;
|
||||||
import org.oscim.theme.renderinstruction.Text;
|
import org.oscim.theme.renderinstruction.Text;
|
||||||
|
|
||||||
public class AtlasRenderLayer extends BasicRenderLayer {
|
public class AtlasRenderLayer extends ElementRenderer {
|
||||||
|
|
||||||
public AtlasRenderLayer() {
|
public AtlasRenderLayer() {
|
||||||
|
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer.test;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
@ -21,11 +21,11 @@ import java.nio.FloatBuffer;
|
|||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.GLAdapter;
|
import org.oscim.backend.GLAdapter;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.renderer.LayerRenderer;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.view.Map;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -35,7 +35,7 @@ import org.oscim.view.Map;
|
|||||||
* https://github.com/dalinaum/opengl-es-book-samples/tree/master/Android
|
* https://github.com/dalinaum/opengl-es-book-samples/tree/master/Android
|
||||||
* */
|
* */
|
||||||
|
|
||||||
public class CustomRenderLayer extends RenderLayer {
|
public class CustomRenderer extends LayerRenderer {
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ public class CustomRenderLayer extends RenderLayer {
|
|||||||
};
|
};
|
||||||
private boolean mInitialized;
|
private boolean mInitialized;
|
||||||
|
|
||||||
public CustomRenderLayer(Map map) {
|
public CustomRenderer(Map map) {
|
||||||
mMap = map;
|
mMap = map;
|
||||||
}
|
}
|
||||||
|
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers;
|
package org.oscim.renderer.test;
|
||||||
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
@ -21,10 +21,10 @@ import org.oscim.backend.GLAdapter;
|
|||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.GLState;
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.RenderLayer;
|
import org.oscim.renderer.LayerRenderer;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ import org.oscim.utils.GlUtils;
|
|||||||
* https://github.com/dalinaum/opengl-es-book-samples/tree/master/Android
|
* https://github.com/dalinaum/opengl-es-book-samples/tree/master/Android
|
||||||
* */
|
* */
|
||||||
|
|
||||||
public class CustomRenderLayer2 extends RenderLayer {
|
public class CustomRenderer2 extends LayerRenderer {
|
||||||
|
|
||||||
private static final GL20 GL = GLAdapter.get();
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ public class CustomRenderLayer2 extends RenderLayer {
|
|||||||
private BufferObject mVBO;
|
private BufferObject mVBO;
|
||||||
|
|
||||||
int mZoom = -1;
|
int mZoom = -1;
|
||||||
float mCellScale = 60 * GLRenderer.COORD_SCALE;
|
float mCellScale = 60 * MapRenderer.COORD_SCALE;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
|
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
|
||||||
@ -84,7 +84,7 @@ public class CustomRenderLayer2 extends RenderLayer {
|
|||||||
vertices[i * 2 + 0] = (float) Math.cos(Math.PI * 2 * i / 6) * mCellScale;
|
vertices[i * 2 + 0] = (float) Math.cos(Math.PI * 2 * i / 6) * mCellScale;
|
||||||
vertices[i * 2 + 1] = (float) Math.sin(Math.PI * 2 * i / 6) * mCellScale;
|
vertices[i * 2 + 1] = (float) Math.sin(Math.PI * 2 * i / 6) * mCellScale;
|
||||||
}
|
}
|
||||||
FloatBuffer buf = GLRenderer.getFloatBuffer(12);
|
FloatBuffer buf = MapRenderer.getFloatBuffer(12);
|
||||||
buf.put(vertices);
|
buf.put(vertices);
|
||||||
buf.flip();
|
buf.flip();
|
||||||
|
|
@ -12,18 +12,18 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers.test;
|
package org.oscim.renderer.test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.oscim.backend.BitmapUtils;
|
import org.oscim.backend.BitmapUtils;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
import org.oscim.renderer.sublayers.SymbolLayer;
|
import org.oscim.renderer.elements.SymbolLayer;
|
||||||
|
|
||||||
public class SymbolRenderLayer extends BasicRenderLayer {
|
public class SymbolRenderLayer extends ElementRenderer {
|
||||||
boolean initialize = true;
|
boolean initialize = true;
|
||||||
|
|
||||||
public SymbolRenderLayer() {
|
public SymbolRenderLayer() {
|
@ -12,14 +12,14 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.renderer.layers.test;
|
package org.oscim.renderer.test;
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.ElementRenderer;
|
||||||
import org.oscim.renderer.layers.BasicRenderLayer;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
|
|
||||||
public class TestRenderLayer extends BasicRenderLayer {
|
public class TestRenderLayer extends ElementRenderer {
|
||||||
|
|
||||||
TextItem labels;
|
TextItem labels;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ public class TestRenderLayer extends BasicRenderLayer {
|
|||||||
public TestRenderLayer() {
|
public TestRenderLayer() {
|
||||||
|
|
||||||
// draw a rectangle
|
// draw a rectangle
|
||||||
//LineLayer ll = (LineLayer) layers.getLayer(1, Layer.LINE);
|
//LineLayer ll = (LineLayer) layers.getLayer(1, RenderElement.LINE);
|
||||||
//ll.line = new Line(Color.BLUE, 1.0f, Cap.BUTT);
|
//ll.line = new Line(Color.BLUE, 1.0f, Cap.BUTT);
|
||||||
//ll.width = 2;
|
//ll.width = 2;
|
||||||
// float[] points = {
|
// float[] points = {
|
||||||
@ -61,7 +61,7 @@ public class TestRenderLayer extends BasicRenderLayer {
|
|||||||
// lt.addLine(points2, null);
|
// lt.addLine(points2, null);
|
||||||
|
|
||||||
//
|
//
|
||||||
// PolygonLayer pl = (PolygonLayer) layers.getLayer(0, Layer.POLYGON);
|
// PolygonLayer pl = (PolygonLayer) layers.getLayer(0, RenderElement.POLYGON);
|
||||||
// pl.area = new Area(Color.argb(128, 255, 0, 0));
|
// pl.area = new Area(Color.argb(128, 255, 0, 0));
|
||||||
//
|
//
|
||||||
// float[] ppoints = {
|
// float[] ppoints = {
|
@ -33,7 +33,7 @@ import org.oscim.backend.canvas.Paint.FontFamily;
|
|||||||
import org.oscim.backend.canvas.Paint.FontStyle;
|
import org.oscim.backend.canvas.Paint.FontStyle;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas;
|
import org.oscim.renderer.atlas.TextureAtlas;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
||||||
import org.oscim.renderer.sublayers.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.theme.renderinstruction.Area;
|
import org.oscim.theme.renderinstruction.Area;
|
||||||
import org.oscim.theme.renderinstruction.AreaLevel;
|
import org.oscim.theme.renderinstruction.AreaLevel;
|
||||||
import org.oscim.theme.renderinstruction.Circle;
|
import org.oscim.theme.renderinstruction.Circle;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.theme.renderinstruction;
|
package org.oscim.theme.renderinstruction;
|
||||||
|
|
||||||
import org.oscim.renderer.sublayers.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
import org.oscim.theme.IRenderCallback;
|
import org.oscim.theme.IRenderCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,6 @@ import org.oscim.backend.canvas.Paint;
|
|||||||
import org.oscim.backend.canvas.Paint.Align;
|
import org.oscim.backend.canvas.Paint.Align;
|
||||||
import org.oscim.backend.canvas.Paint.FontFamily;
|
import org.oscim.backend.canvas.Paint.FontFamily;
|
||||||
import org.oscim.backend.canvas.Paint.FontStyle;
|
import org.oscim.backend.canvas.Paint.FontStyle;
|
||||||
import org.oscim.backend.canvas.Paint.Style;
|
|
||||||
import org.oscim.renderer.atlas.TextureRegion;
|
import org.oscim.renderer.atlas.TextureRegion;
|
||||||
import org.oscim.theme.IRenderCallback;
|
import org.oscim.theme.IRenderCallback;
|
||||||
|
|
||||||
@ -86,7 +85,7 @@ public final class Text extends RenderInstruction {
|
|||||||
|
|
||||||
if (strokeWidth > 0) {
|
if (strokeWidth > 0) {
|
||||||
stroke = CanvasAdapter.g.getPaint();
|
stroke = CanvasAdapter.g.getPaint();
|
||||||
stroke.setStyle(Style.STROKE);
|
stroke.setStyle(Paint.Style.STROKE);
|
||||||
stroke.setTextAlign(Align.CENTER);
|
stroke.setTextAlign(Align.CENTER);
|
||||||
stroke.setTypeface(fontFamily, fontStyle);
|
stroke.setTypeface(fontFamily, fontStyle);
|
||||||
stroke.setColor(outline);
|
stroke.setColor(outline);
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_LOADING;
|
import static org.oscim.tiling.MapTile.STATE_LOADING;
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NONE;
|
import static org.oscim.tiling.MapTile.STATE_NONE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
* A JobQueue keeps the list of pending jobs for a MapView and prioritizes them.
|
@ -12,13 +12,13 @@
|
|||||||
* You should have received a copy of the GNU Lesser General License along with
|
* You should have received a copy of the GNU Lesser General License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
import org.oscim.renderer.sublayers.Layers;
|
import org.oscim.renderer.elements.ElementLayers;
|
||||||
import org.oscim.renderer.sublayers.SymbolItem;
|
import org.oscim.renderer.elements.SymbolItem;
|
||||||
import org.oscim.renderer.sublayers.TextItem;
|
import org.oscim.renderer.elements.TextItem;
|
||||||
import org.oscim.utils.quadtree.QuadTree;
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,7 +76,7 @@ public class MapTile extends Tile {
|
|||||||
public TextItem labels;
|
public TextItem labels;
|
||||||
public SymbolItem symbols;
|
public SymbolItem symbols;
|
||||||
|
|
||||||
public Layers layers;
|
public ElementLayers layers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tile is in view region. Set by GLRenderer.
|
* Tile is in view region. Set by GLRenderer.
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort Tiles by 'distance' value.
|
* Sort Tiles by 'distance' value.
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
import org.oscim.utils.PausableThread;
|
import org.oscim.utils.PausableThread;
|
||||||
|
|
@ -13,11 +13,11 @@
|
|||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_LOADING;
|
import static org.oscim.tiling.MapTile.STATE_LOADING;
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NEW_DATA;
|
import static org.oscim.tiling.MapTile.STATE_NEW_DATA;
|
||||||
import static org.oscim.layers.tile.MapTile.STATE_NONE;
|
import static org.oscim.tiling.MapTile.STATE_NONE;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -25,13 +25,13 @@ import java.util.Arrays;
|
|||||||
import org.oscim.backend.Log;
|
import org.oscim.backend.Log;
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.map.Map;
|
||||||
|
import org.oscim.map.Viewport;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.ScanBox;
|
import org.oscim.utils.ScanBox;
|
||||||
import org.oscim.utils.quadtree.QuadTree;
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
import org.oscim.utils.quadtree.QuadTreeIndex;
|
import org.oscim.utils.quadtree.QuadTreeIndex;
|
||||||
import org.oscim.view.Map;
|
|
||||||
import org.oscim.view.Viewport;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @TODO - prefetching to cache file - this class should probably not be in
|
* @TODO - prefetching to cache file - this class should probably not be in
|
||||||
@ -110,11 +110,11 @@ public class TileManager {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private final float[] mMapPlane = new float[8];
|
private final float[] mMapPlane = new float[8];
|
||||||
private final TileLayer<?> mTileLayer;
|
//private final TileLayer<?> mTileLayer;
|
||||||
|
|
||||||
public TileManager(Map map, TileLayer<?> tileLayer, int minZoom, int maxZoom, int cacheLimit) {
|
public TileManager(Map map, int minZoom, int maxZoom, int cacheLimit) {
|
||||||
mMap = map;
|
mMap = map;
|
||||||
mTileLayer = tileLayer;
|
//mTileLayer = tileLayer;
|
||||||
mMaxZoom = maxZoom;
|
mMaxZoom = maxZoom;
|
||||||
mMinZoom = minZoom;
|
mMinZoom = minZoom;
|
||||||
mCacheLimit = cacheLimit;
|
mCacheLimit = cacheLimit;
|
||||||
@ -147,7 +147,7 @@ public class TileManager {
|
|||||||
|
|
||||||
// sync with GLRender thread
|
// sync with GLRender thread
|
||||||
// ... and labeling thread?
|
// ... and labeling thread?
|
||||||
synchronized (GLRenderer.drawlock) {
|
synchronized (MapRenderer.drawlock) {
|
||||||
|
|
||||||
if (!first) {
|
if (!first) {
|
||||||
// pass VBOs and VertexItems back to pools
|
// pass VBOs and VertexItems back to pools
|
||||||
@ -186,7 +186,7 @@ public class TileManager {
|
|||||||
* @param pos
|
* @param pos
|
||||||
* current MapPosition
|
* current MapPosition
|
||||||
*/
|
*/
|
||||||
public synchronized void update(MapPosition pos) {
|
public synchronized boolean update(MapPosition pos) {
|
||||||
// clear JobQueue and set tiles to state == NONE.
|
// clear JobQueue and set tiles to state == NONE.
|
||||||
// one could also append new tiles and sort in JobQueue
|
// one could also append new tiles and sort in JobQueue
|
||||||
// but this has the nice side-effect that MapWorkers dont
|
// but this has the nice side-effect that MapWorkers dont
|
||||||
@ -207,7 +207,7 @@ public class TileManager {
|
|||||||
match = z;
|
match = z;
|
||||||
}
|
}
|
||||||
if (match == 0)
|
if (match == 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
tileZoom = match;
|
tileZoom = match;
|
||||||
}
|
}
|
||||||
@ -265,7 +265,7 @@ public class TileManager {
|
|||||||
|
|
||||||
/* Add tile jobs to queue */
|
/* Add tile jobs to queue */
|
||||||
if (mJobs.isEmpty())
|
if (mJobs.isEmpty())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
MapTile[] jobs = new MapTile[mJobs.size()];
|
MapTile[] jobs = new MapTile[mJobs.size()];
|
||||||
jobs = mJobs.toArray(jobs);
|
jobs = mJobs.toArray(jobs);
|
||||||
@ -274,7 +274,8 @@ public class TileManager {
|
|||||||
// sets tiles to state == LOADING
|
// sets tiles to state == LOADING
|
||||||
|
|
||||||
jobQueue.setJobs(jobs);
|
jobQueue.setJobs(jobs);
|
||||||
mTileLayer.notifyLoaders();
|
//mTileLayer.notifyLoaders();
|
||||||
|
|
||||||
mJobs.clear();
|
mJobs.clear();
|
||||||
|
|
||||||
/* limit cache items */
|
/* limit cache items */
|
||||||
@ -284,6 +285,8 @@ public class TileManager {
|
|||||||
mTilesForUpload > MAX_TILES_IN_QUEUE)
|
mTilesForUpload > MAX_TILES_IN_QUEUE)
|
||||||
|
|
||||||
limitCache(pos, remove);
|
limitCache(pos, remove);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** only used in setmapDatabase -- deprecate? */
|
/** only used in setmapDatabase -- deprecate? */
|
615
vtm/src/org/oscim/tiling/TileRenderer.java
Normal file
615
vtm/src/org/oscim/tiling/TileRenderer.java
Normal file
@ -0,0 +1,615 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.tiling;
|
||||||
|
|
||||||
|
import static org.oscim.tiling.MapTile.STATE_NEW_DATA;
|
||||||
|
import static org.oscim.tiling.MapTile.STATE_READY;
|
||||||
|
|
||||||
|
import org.oscim.backend.GL20;
|
||||||
|
import org.oscim.backend.GLAdapter;
|
||||||
|
import org.oscim.backend.Log;
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.BufferObject;
|
||||||
|
import org.oscim.renderer.LayerRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer;
|
||||||
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.elements.BitmapLayer;
|
||||||
|
import org.oscim.renderer.elements.RenderElement;
|
||||||
|
import org.oscim.renderer.elements.LineLayer;
|
||||||
|
import org.oscim.renderer.elements.LineTexLayer;
|
||||||
|
import org.oscim.renderer.elements.PolygonLayer;
|
||||||
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.Matrix4;
|
||||||
|
import org.oscim.utils.ScanBox;
|
||||||
|
import org.oscim.utils.quadtree.QuadTree;
|
||||||
|
|
||||||
|
public class TileRenderer extends LayerRenderer {
|
||||||
|
private final static String TAG = TileRenderer.class.getName();
|
||||||
|
|
||||||
|
private final TileManager mTileManager;
|
||||||
|
private int mUploadSerial;
|
||||||
|
|
||||||
|
public TileRenderer(TileManager tileManager) {
|
||||||
|
mTileManager = tileManager;
|
||||||
|
mUploadSerial = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int mOverdraw = 0;
|
||||||
|
private float mAlpha = 1;
|
||||||
|
|
||||||
|
public void setOverdrawColor(int color) {
|
||||||
|
mOverdraw = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitmapAlpha(float alpha) {
|
||||||
|
mAlpha = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void update(MapPosition pos, boolean positionChanged, Matrices m) {
|
||||||
|
|
||||||
|
if (mAlpha == 0){
|
||||||
|
mTileManager.releaseTiles(mDrawTiles);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean tilesChanged;
|
||||||
|
synchronized (tilelock) {
|
||||||
|
// get current tiles to draw
|
||||||
|
tilesChanged = mTileManager.getActiveTiles(mDrawTiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mDrawTiles.cnt == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int tileCnt = mDrawTiles.cnt;
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
if (tilesChanged || positionChanged){
|
||||||
|
updateTileVisibility(pos, m.mapPlane);
|
||||||
|
}
|
||||||
|
|
||||||
|
tileCnt += mNumTileHolder;
|
||||||
|
|
||||||
|
/* prepare tile for rendering */
|
||||||
|
if (compileTileLayers(tiles, tileCnt) > 0) {
|
||||||
|
mUploadSerial++;
|
||||||
|
BufferObject.checkBufferUsage(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
draw(tiles, tileCnt, pos, m, mAlpha, mOverdraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void clearTiles() {
|
||||||
|
// Clear all references to MapTiles as all current
|
||||||
|
// tiles will also be removed from TileManager.
|
||||||
|
synchronized (MapRenderer.drawlock) {
|
||||||
|
mDrawTiles = new TileSet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** compile tile layer data and upload to VBOs */
|
||||||
|
private static int compileTileLayers(MapTile[] tiles, int tileCnt) {
|
||||||
|
int uploadCnt = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile tile = tiles[i];
|
||||||
|
|
||||||
|
if (!tile.isVisible)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tile.state == STATE_READY)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tile.state == STATE_NEW_DATA) {
|
||||||
|
uploadCnt += uploadTileData(tile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.holder != null) {
|
||||||
|
// load tile that is referenced by this holder
|
||||||
|
if (tile.holder.state == STATE_NEW_DATA)
|
||||||
|
uploadCnt += uploadTileData(tile.holder);
|
||||||
|
|
||||||
|
tile.state = tile.holder.state;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check near relatives than can serve as proxy
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
MapTile rel = tile.rel.parent.item;
|
||||||
|
if (rel.state == STATE_NEW_DATA)
|
||||||
|
uploadCnt += uploadTileData(rel);
|
||||||
|
|
||||||
|
// dont load child proxies
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int c = 0; c < 4; c++) {
|
||||||
|
if ((tile.proxies & 1 << c) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MapTile rel = tile.rel.get(i);
|
||||||
|
if (rel != null && rel.state == STATE_NEW_DATA)
|
||||||
|
uploadCnt += uploadTileData(rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uploadCnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int uploadTileData(MapTile tile) {
|
||||||
|
tile.state = STATE_READY;
|
||||||
|
|
||||||
|
// tile might contain extrusion or label layers
|
||||||
|
if (tile.layers == null)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int newSize = tile.layers.getSize();
|
||||||
|
if (newSize > 0) {
|
||||||
|
|
||||||
|
if (tile.layers.vbo == null)
|
||||||
|
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
|
||||||
|
|
||||||
|
if (!MapRenderer.uploadLayers(tile.layers, newSize, true)) {
|
||||||
|
Log.d(TAG, "BUG uploadTileData " + tile + " failed!");
|
||||||
|
|
||||||
|
BufferObject.release(tile.layers.vbo);
|
||||||
|
tile.layers.vbo = null;
|
||||||
|
tile.layers.clear();
|
||||||
|
tile.layers = null;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object tilelock = new Object();
|
||||||
|
|
||||||
|
/** set tile isVisible flag true for tiles that intersect view */
|
||||||
|
private void updateTileVisibility(MapPosition pos, float[] box) {
|
||||||
|
|
||||||
|
// lock tiles while updating isVisible state
|
||||||
|
synchronized (tilelock) {
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
int tileZoom = tiles[0].zoomLevel;
|
||||||
|
|
||||||
|
for (int i = 0; i < mDrawTiles.cnt; i++)
|
||||||
|
tiles[i].isVisible = false;
|
||||||
|
|
||||||
|
// count placeholder tiles
|
||||||
|
mNumTileHolder = 0;
|
||||||
|
|
||||||
|
// check visibile tiles
|
||||||
|
mScanBox.scan(pos.x, pos.y, pos.scale, tileZoom, box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update tileSet with currently visible tiles get a TileSet of currently
|
||||||
|
* visible tiles
|
||||||
|
*/
|
||||||
|
public boolean getVisibleTiles(TileSet tileSet) {
|
||||||
|
if (tileSet == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (mDrawTiles == null) {
|
||||||
|
releaseTiles(tileSet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// same tiles as before
|
||||||
|
// if (tileSet.serial == mDrawTiles.serial)
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
int prevSerial = tileSet.serial;
|
||||||
|
|
||||||
|
// ensure tiles keep visible state
|
||||||
|
synchronized (tilelock) {
|
||||||
|
|
||||||
|
MapTile[] newTiles = mDrawTiles.tiles;
|
||||||
|
int cnt = mDrawTiles.cnt;
|
||||||
|
|
||||||
|
// unlock previous tiles
|
||||||
|
for (int i = 0; i < tileSet.cnt; i++)
|
||||||
|
tileSet.tiles[i].unlock();
|
||||||
|
|
||||||
|
// ensure same size
|
||||||
|
if (tileSet.tiles.length != mDrawTiles.tiles.length) {
|
||||||
|
tileSet.tiles = new MapTile[mDrawTiles.tiles.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
// lock tiles to not be removed from cache
|
||||||
|
tileSet.cnt = 0;
|
||||||
|
for (int i = 0; i < cnt; i++) {
|
||||||
|
MapTile t = newTiles[i];
|
||||||
|
if (t.isVisible && t.state == STATE_READY) {
|
||||||
|
t.lock();
|
||||||
|
tileSet.tiles[tileSet.cnt++] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tileSet.serial = mUploadSerial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prevSerial != tileSet.serial;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void releaseTiles(TileSet td) {
|
||||||
|
for (int i = 0; i < td.cnt; i++) {
|
||||||
|
td.tiles[i].unlock();
|
||||||
|
td.tiles[i] = null;
|
||||||
|
}
|
||||||
|
td.cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add additional tiles that serve as placeholer when flipping
|
||||||
|
// over date-line.
|
||||||
|
// I dont really like this but cannot think of a better solution:
|
||||||
|
// The other option would be to run scanbox each time for upload,
|
||||||
|
// drawing, proxies and text layer. Adding placeholder only
|
||||||
|
// happens rarely, unless you live on Fidschi
|
||||||
|
|
||||||
|
/* package */int mNumTileHolder;
|
||||||
|
/* package */TileSet mDrawTiles = new TileSet();
|
||||||
|
|
||||||
|
// scanline fill class used to check tile visibility
|
||||||
|
private final ScanBox mScanBox = new ScanBox() {
|
||||||
|
@Override
|
||||||
|
protected void setVisible(int y, int x1, int x2) {
|
||||||
|
int cnt = mDrawTiles.cnt;
|
||||||
|
|
||||||
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
|
|
||||||
|
for (int i = 0; i < cnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.tileY == y && t.tileX >= x1 && t.tileX < x2)
|
||||||
|
t.isVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int xmax = 1 << mZoom;
|
||||||
|
if (x1 >= 0 && x2 < xmax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add placeholder tiles to show both sides
|
||||||
|
// of date line. a little too complicated...
|
||||||
|
for (int x = x1; x < x2; x++) {
|
||||||
|
MapTile holder = null;
|
||||||
|
MapTile tile = null;
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
|
if (x >= 0 && x < xmax)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int xx = x;
|
||||||
|
if (x < 0)
|
||||||
|
xx = xmax + x;
|
||||||
|
else
|
||||||
|
xx = x - xmax;
|
||||||
|
|
||||||
|
if (xx < 0 || xx >= xmax)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int i = cnt; i < cnt + mNumTileHolder; i++)
|
||||||
|
if (tiles[i].tileX == x && tiles[i].tileY == y) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int i = 0; i < cnt; i++)
|
||||||
|
if (tiles[i].tileX == xx && tiles[i].tileY == y) {
|
||||||
|
tile = tiles[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (cnt + mNumTileHolder >= tiles.length){
|
||||||
|
Log.e(TAG, "too many tiles " + cnt + ", " + mNumTileHolder);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
holder = new MapTile(x, y, (byte) mZoom);
|
||||||
|
holder.isVisible = true;
|
||||||
|
holder.holder = tile;
|
||||||
|
tile.isVisible = true;
|
||||||
|
tiles[cnt + mNumTileHolder++] = holder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static final GL20 GL = GLAdapter.get();
|
||||||
|
|
||||||
|
// Counter increases polygon-offset for each tile drawn.
|
||||||
|
private static int mOffsetCnt;
|
||||||
|
|
||||||
|
// Current number of frames drawn, used to not draw a
|
||||||
|
// tile twice per frame.
|
||||||
|
private static int mDrawSerial = 0;
|
||||||
|
|
||||||
|
private static Matrices mMatrices;
|
||||||
|
|
||||||
|
private static float mFade;
|
||||||
|
//private static int mOverdraw;
|
||||||
|
|
||||||
|
private static final Matrix4 mProjMatrix = new Matrix4();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw tiles:
|
||||||
|
*
|
||||||
|
* @param fade
|
||||||
|
* alpha value for bitmap tiles
|
||||||
|
* @param overdrawColor
|
||||||
|
* draw color on top, e.g. to darken the layer temporarily
|
||||||
|
*/
|
||||||
|
private void draw(MapTile[] tiles, int tileCnt, MapPosition pos, Matrices m, float fade,
|
||||||
|
int overdrawColor) {
|
||||||
|
|
||||||
|
mOffsetCnt = -2048;
|
||||||
|
mMatrices = m;
|
||||||
|
|
||||||
|
mFade = fade;
|
||||||
|
//mOverdraw = overdrawColor;
|
||||||
|
|
||||||
|
mProjMatrix.copy(m.proj);
|
||||||
|
// discard depth projection from tilt, we use depth buffer
|
||||||
|
// for clipping
|
||||||
|
mProjMatrix.setValue(10, 0);
|
||||||
|
mProjMatrix.setValue(14, 0);
|
||||||
|
mProjMatrix.multiplyRhs(m.view);
|
||||||
|
|
||||||
|
GL.glDepthMask(true);
|
||||||
|
GL.glClear(GL20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
GL.glDepthFunc(GL20.GL_LESS);
|
||||||
|
|
||||||
|
// Draw visible tiles
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.isVisible && t.state == STATE_READY)
|
||||||
|
drawTile(t, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
double scale = pos.getZoomScale();
|
||||||
|
|
||||||
|
// Draw parent or children as proxy for visibile tiles that dont
|
||||||
|
// have data yet. Proxies are clipped to the region where nothing
|
||||||
|
// was drawn to depth buffer.
|
||||||
|
// TODO draw proxies for placeholder
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) {
|
||||||
|
boolean preferParent = (scale > 1.5) || (pos.zoomLevel - t.zoomLevel < 0);
|
||||||
|
drawProxyTile(t, pos, true, preferParent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw grandparents
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
||||||
|
drawProxyTile(t, pos, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure stencil buffer write is disabled
|
||||||
|
GL.glStencilMask(0x00);
|
||||||
|
GL.glDepthMask(false);
|
||||||
|
|
||||||
|
mDrawSerial++;
|
||||||
|
|
||||||
|
// clear reference
|
||||||
|
mMatrices = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawTile(MapTile tile, MapPosition pos) {
|
||||||
|
// draw parents only once
|
||||||
|
if (tile.lastDraw == mDrawSerial)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tile.lastDraw = mDrawSerial;
|
||||||
|
|
||||||
|
MapTile t = tile;
|
||||||
|
if (t.holder != null)
|
||||||
|
t = t.holder;
|
||||||
|
|
||||||
|
if (t.layers == null || t.layers.vbo == null) {
|
||||||
|
//Log.d(TAG, "missing data " + (t.layers == null) + " " + (t.vbo == null));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.layers.vbo.bind();
|
||||||
|
|
||||||
|
// place tile relative to map position
|
||||||
|
int z = tile.zoomLevel;
|
||||||
|
|
||||||
|
float div = FastMath.pow(z - pos.zoomLevel);
|
||||||
|
|
||||||
|
double curScale = Tile.SIZE * pos.scale;
|
||||||
|
double scale = (pos.scale / (1 << z));
|
||||||
|
|
||||||
|
float x = (float) ((tile.x - pos.x) * curScale);
|
||||||
|
float y = (float) ((tile.y - pos.y) * curScale);
|
||||||
|
|
||||||
|
Matrices m = mMatrices;
|
||||||
|
m.mvp.setTransScale(x, y, (float) (scale / MapRenderer.COORD_SCALE));
|
||||||
|
|
||||||
|
m.mvp.multiplyLhs(mProjMatrix);
|
||||||
|
|
||||||
|
// set depth offset (used for clipping to tile boundaries)
|
||||||
|
GL.glPolygonOffset(0, mOffsetCnt++);
|
||||||
|
|
||||||
|
// simple line shader does not take forward shortening into
|
||||||
|
// account. only used when tilt is 0.
|
||||||
|
int simpleShader = (pos.tilt < 1 ? 1 : 0);
|
||||||
|
|
||||||
|
boolean clipped = false;
|
||||||
|
|
||||||
|
for (RenderElement l = t.layers.baseLayers; l != null;) {
|
||||||
|
switch (l.type) {
|
||||||
|
case RenderElement.POLYGON:
|
||||||
|
l = PolygonLayer.Renderer.draw(pos, l, m, !clipped, div, true);
|
||||||
|
clipped = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RenderElement.LINE:
|
||||||
|
if (!clipped) {
|
||||||
|
// draw stencil buffer clip region
|
||||||
|
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
|
||||||
|
clipped = true;
|
||||||
|
}
|
||||||
|
l = LineLayer.Renderer.draw(t.layers, l, pos, m, div, simpleShader);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RenderElement.TEXLINE:
|
||||||
|
if (!clipped) {
|
||||||
|
// draw stencil buffer clip region
|
||||||
|
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
|
||||||
|
clipped = true;
|
||||||
|
}
|
||||||
|
l = LineTexLayer.Renderer.draw(t.layers, l, pos, m, div);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// just in case
|
||||||
|
l = l.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RenderElement l = t.layers.textureLayers; l != null;) {
|
||||||
|
if (!clipped) {
|
||||||
|
// draw stencil buffer clip region
|
||||||
|
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
|
||||||
|
clipped = true;
|
||||||
|
}
|
||||||
|
// if (!clipped) {
|
||||||
|
// // draw stencil buffer clip region
|
||||||
|
// PolygonRenderer.clip(m);
|
||||||
|
// clipped = true;
|
||||||
|
// }
|
||||||
|
//GLState.test(false, false);
|
||||||
|
switch (l.type) {
|
||||||
|
case RenderElement.BITMAP:
|
||||||
|
l = BitmapLayer.Renderer.draw(l, m, 1, mFade);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
l = l.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PolygonLayer.Renderer.drawOver(m, mOverdraw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int drawProxyChild(MapTile tile, MapPosition pos) {
|
||||||
|
int drawn = 0;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if ((tile.proxies & 1 << i) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MapTile c = tile.rel.get(i);
|
||||||
|
|
||||||
|
if (c.state == STATE_READY) {
|
||||||
|
drawTile(c, pos);
|
||||||
|
drawn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return drawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawProxyTile(MapTile tile, MapPosition pos, boolean parent,
|
||||||
|
boolean preferParent) {
|
||||||
|
|
||||||
|
QuadTree<MapTile> r = tile.rel;
|
||||||
|
MapTile proxy;
|
||||||
|
|
||||||
|
if (!preferParent) {
|
||||||
|
// prefer drawing children
|
||||||
|
if (drawProxyChild(tile, pos) == 4)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
// draw parent proxy
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
proxy = r.parent.item;
|
||||||
|
if (proxy.state == STATE_READY) {
|
||||||
|
//Log.d(TAG, "1. draw parent " + proxy);
|
||||||
|
drawTile(proxy, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
|
// check if parent was already drawn
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
proxy = r.parent.item;
|
||||||
|
if (proxy.state == STATE_READY)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy = r.parent.parent.item;
|
||||||
|
if (proxy.state == STATE_READY)
|
||||||
|
drawTile(proxy, pos);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// prefer drawing parent
|
||||||
|
if (parent) {
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
proxy = r.parent.item;
|
||||||
|
if (proxy != null && proxy.state == STATE_READY) {
|
||||||
|
//Log.d(TAG, "2. draw parent " + proxy);
|
||||||
|
drawTile(proxy, pos);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
drawProxyChild(tile, pos);
|
||||||
|
|
||||||
|
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
||||||
|
// check if parent was already drawn
|
||||||
|
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
||||||
|
proxy = r.parent.item;
|
||||||
|
if (proxy.state == STATE_READY)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// this will do nothing, just to check
|
||||||
|
if (drawProxyChild(tile, pos) > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
proxy = r.parent.parent.item;
|
||||||
|
if (proxy.state == STATE_READY)
|
||||||
|
drawTile(proxy, pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void render(MapPosition position, Matrices matrices) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.layers.tile;
|
package org.oscim.tiling;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.tilesource;
|
package org.oscim.tiling.source;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
@ -12,7 +12,7 @@
|
|||||||
* You should have received a copy of the GNU Lesser General Public License along with
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package org.oscim.tilesource;
|
package org.oscim.tiling.source;
|
||||||
|
|
||||||
import org.oscim.core.MapElement;
|
import org.oscim.core.MapElement;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user