big refactor: copy Viewport state for rendering

This commit is contained in:
Hannes Janetzek 2014-02-16 04:15:25 +01:00
parent 91d1e7b1a6
commit 79b5a09ac8
30 changed files with 348 additions and 381 deletions

@ -1 +1 @@
Subproject commit 329c626e1ab0799019ac06f694227deac5f4702b Subproject commit 0558c06ed068929a53897dc4ab6b98d4a79e0192

View File

@ -25,7 +25,7 @@ import org.oscim.layers.tile.vector.VectorTileLayer;
import org.oscim.layers.tile.vector.labeling.LabelLayer; import org.oscim.layers.tile.vector.labeling.LabelLayer;
import org.oscim.map.Layers; import org.oscim.map.Layers;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.map.Viewport; import org.oscim.map.ViewController;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.theme.InternalRenderTheme; import org.oscim.theme.InternalRenderTheme;
import org.oscim.tiling.source.TileSource; import org.oscim.tiling.source.TileSource;
@ -178,7 +178,7 @@ public abstract class GdxMap implements ApplicationListener {
mMapRenderer.onSurfaceChanged(w, h); mMapRenderer.onSurfaceChanged(w, h);
InputMultiplexer mux = new InputMultiplexer(); InputMultiplexer mux = new InputMultiplexer();
ViewController controller = new ViewController(); MapController controller = new MapController();
GestureDetector gestureDetector = new GestureDetector(20, 0.5f, 2, 0.05f, controller); GestureDetector gestureDetector = new GestureDetector(20, 0.5f, 2, 0.05f, controller);
mux.addProcessor(new TouchHandler()); mux.addProcessor(new TouchHandler());
mux.addProcessor(gestureDetector); mux.addProcessor(gestureDetector);
@ -241,10 +241,10 @@ public abstract class GdxMap implements ApplicationListener {
class TouchHandler implements InputProcessor { class TouchHandler implements InputProcessor {
private Viewport mMapPosition; private ViewController mViewport;
public TouchHandler() { public TouchHandler() {
mMapPosition = mMap.viewport(); mViewport = mMap.viewport();
} }
private boolean mActiveScale; private boolean mActiveScale;
@ -261,29 +261,35 @@ public abstract class GdxMap implements ApplicationListener {
switch (keycode) { switch (keycode) {
case Input.Keys.UP: case Input.Keys.UP:
mMapPosition.moveMap(0, -50); mViewport.moveMap(0, -50);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.DOWN: case Input.Keys.DOWN:
mMapPosition.moveMap(0, 50); mViewport.moveMap(0, 50);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.LEFT: case Input.Keys.LEFT:
mMapPosition.moveMap(-50, 0); mViewport.moveMap(-50, 0);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.RIGHT: case Input.Keys.RIGHT:
mMapPosition.moveMap(50, 0); mViewport.moveMap(50, 0);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.M: case Input.Keys.M:
mMapPosition.scaleMap(1.05f, 0, 0); mViewport.scaleMap(1.05f, 0, 0);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.N: case Input.Keys.N:
mMapPosition.scaleMap(0.95f, 0, 0); mViewport.scaleMap(0.95f, 0, 0);
mMap.updateMap(true); mMap.updateMap(true);
break; break;
case Input.Keys.NUM_1:
mMap.animator().animateZoom(500, 0.5, 0, 0);
break;
case Input.Keys.NUM_2:
mMap.animator().animateZoom(500, 2, 0, 0);
break;
case Input.Keys.D: case Input.Keys.D:
mMap.setTheme(InternalRenderTheme.DEFAULT); mMap.setTheme(InternalRenderTheme.DEFAULT);
@ -361,14 +367,14 @@ public abstract class GdxMap implements ApplicationListener {
if (mActiveScale) { if (mActiveScale) {
// changed = mMapPosition.tilt((screenY - mStartY) / 5f); // changed = mMapPosition.tilt((screenY - mStartY) / 5f);
changed = mMapPosition.scaleMap(1 - (screenY - mPosY) / 100f, 0, 0); changed = mViewport.scaleMap(1 - (screenY - mPosY) / 100f, 0, 0);
mPosY = screenY; mPosY = screenY;
} }
if (mActiveRotate) { if (mActiveRotate) {
mMapPosition.rotateMap((screenX - mPosX) / 500f, 0, 0); mViewport.rotateMap((screenX - mPosX) / 500f, 0, 0);
mPosX = screenX; mPosX = screenX;
mMapPosition.tiltMap((screenY - mPosY) / 10f); mViewport.tiltMap((screenY - mPosY) / 10f);
mPosY = screenY; mPosY = screenY;
changed = true; changed = true;
} }
@ -391,12 +397,12 @@ public abstract class GdxMap implements ApplicationListener {
if (amount > 0) { if (amount > 0) {
mMap.animator().animateZoom(150, 0.8f, 0, 0); mMap.animator().animateZoom(250, 0.9f, 0, 0);
} else { } else {
float fx = mPosX - mMap.getWidth() / 2; float fx = mPosX - mMap.getWidth() / 2;
float fy = mPosY - mMap.getHeight() / 2; float fy = mPosY - mMap.getHeight() / 2;
mMap.animator().animateZoom(150, 1.25f, fx, fy); mMap.animator().animateZoom(250, 1.111f, fx, fy);
} }
mMap.updateMap(false); mMap.updateMap(false);
@ -404,7 +410,7 @@ public abstract class GdxMap implements ApplicationListener {
} }
} }
class ViewController implements GestureListener { class MapController implements GestureListener {
private boolean mayFling = true; private boolean mayFling = true;
@ -434,10 +440,10 @@ public abstract class GdxMap implements ApplicationListener {
protected static final double PINCH_ROTATE_THRESHOLD = 0.02; protected static final double PINCH_ROTATE_THRESHOLD = 0.02;
protected static final float PINCH_TILT_THRESHOLD = 1f; protected static final float PINCH_TILT_THRESHOLD = 1f;
private Viewport mMapPosition; private ViewController mViewport;
public ViewController() { public MapController() {
mMapPosition = mMap.viewport(); mViewport = mMap.viewport();
} }
@Override @Override
@ -475,7 +481,7 @@ public abstract class GdxMap implements ApplicationListener {
if (mPinch) if (mPinch)
return true; return true;
mMapPosition.moveMap(deltaX, deltaY); mViewport.moveMap(deltaX, deltaY);
mMap.updateMap(true); mMap.updateMap(true);
return false; return false;
@ -560,7 +566,7 @@ public abstract class GdxMap implements ApplicationListener {
// log.debug("zoom " + deltaPinchWidth + " " + scale + " " + // log.debug("zoom " + deltaPinchWidth + " " + scale + " " +
// mSumScale); // mSumScale);
changed = mMapPosition.scaleMap(scale, fx, fy); changed = mViewport.scaleMap(scale, fx, fy);
} }
if (!mBeginRotate && Math.abs(slope) < 1) { if (!mBeginRotate && Math.abs(slope) < 1) {
@ -572,7 +578,7 @@ public abstract class GdxMap implements ApplicationListener {
if ((my > threshold && my2 > threshold) if ((my > threshold && my2 > threshold)
|| (my < -threshold && my2 < -threshold)) { || (my < -threshold && my2 < -threshold)) {
mBeginTilt = true; mBeginTilt = true;
changed = mMapPosition.tiltMap(my / 5); changed = mViewport.tiltMap(my / 5);
} }
} }
@ -600,7 +606,7 @@ public abstract class GdxMap implements ApplicationListener {
float x = (float) (mFocusX * rcos + mFocusY * -rsin - mFocusX); float x = (float) (mFocusX * rcos + mFocusY * -rsin - mFocusX);
float y = (float) (mFocusX * rsin + mFocusY * rcos - mFocusY); float y = (float) (mFocusX * rsin + mFocusY * rcos - mFocusY);
mMapPosition.rotateMap(da, x, y); mViewport.rotateMap(da, x, y);
changed = true; changed = true;
} }
} }

View File

@ -19,8 +19,8 @@ package org.oscim.layers;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.map.Map.UpdateListener; import org.oscim.map.Map.UpdateListener;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer; import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -32,7 +32,7 @@ public class CustomRenderLayer extends Layer implements UpdateListener {
// functions running on MapRender Thread // functions running on MapRender Thread
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) { protected void update(GLViewport v) {
int currentState; int currentState;
synchronized (this) { synchronized (this) {
@ -48,7 +48,7 @@ public class CustomRenderLayer extends Layer implements UpdateListener {
} }
@Override @Override
protected void render(MapPosition pos, Matrices m) { protected void render(GLViewport v) {
} }
} }

View File

@ -29,7 +29,7 @@ import org.oscim.core.MercatorProjection;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.theme.styles.Line; import org.oscim.theme.styles.Line;
@ -194,10 +194,10 @@ public class PathLayer extends Layer {
private int mCurZ = -1; private int mCurZ = -1;
@Override @Override
public synchronized void update(MapPosition pos, boolean changed, Matrices m) { public synchronized void update(GLViewport v) {
int tz = 1 << pos.zoomLevel; int tz = 1 << v.pos.zoomLevel;
int tx = (int) (pos.x * tz); int tx = (int) (v.pos.x * tz);
int ty = (int) (pos.y * tz); int ty = (int) (v.pos.y * tz);
// update layers when map moved by at least one tile // update layers when map moved by at least one tile
if ((tx != mCurX || ty != mCurY || tz != mCurZ) || mUpdatePoints) { if ((tx != mCurX || ty != mCurY || tz != mCurZ) || mUpdatePoints) {

View File

@ -19,12 +19,11 @@ package org.oscim.layers.marker;
import java.util.Comparator; import java.util.Comparator;
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.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.SymbolItem; import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.SymbolLayer; import org.oscim.renderer.elements.SymbolLayer;
import org.oscim.utils.TimSort; import org.oscim.utils.TimSort;
@ -72,16 +71,15 @@ public class MarkerRenderer extends ElementRenderer {
} }
@Override @Override
public synchronized void update(MapPosition pos, boolean changed, Matrices m) { public synchronized void update(GLViewport v) {
if (!v.changed() && !mUpdate)
if (!changed && !mUpdate)
return; return;
mUpdate = false; mUpdate = false;
double mx = pos.x; double mx = v.pos.x;
double my = pos.y; double my = v.pos.y;
double scale = Tile.SIZE * pos.scale; double scale = Tile.SIZE * v.pos.scale;
//int changesInvisible = 0; //int changesInvisible = 0;
//int changedVisible = 0; //int changedVisible = 0;
@ -89,7 +87,7 @@ public class MarkerRenderer extends ElementRenderer {
mMarkerLayer.map().viewport().getMapExtents(mBox, mExtents); mMarkerLayer.map().viewport().getMapExtents(mBox, mExtents);
long flip = (long) (Tile.SIZE * pos.scale) >> 1; long flip = (long) (Tile.SIZE * v.pos.scale) >> 1;
if (mItems == null) { if (mItems == null) {
if (layers.getTextureLayers() != null) { if (layers.getTextureLayers() != null) {
@ -99,7 +97,7 @@ public class MarkerRenderer extends ElementRenderer {
return; return;
} }
double angle = Math.toRadians(pos.angle); double angle = Math.toRadians(v.pos.angle);
float cos = (float) Math.cos(angle); float cos = (float) Math.cos(angle);
float sin = (float) Math.sin(angle); float sin = (float) Math.sin(angle);
@ -144,7 +142,7 @@ public class MarkerRenderer extends ElementRenderer {
return; return;
} }
/* keep position for current state */ /* keep position for current state */
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
mMapPosition.angle = -mMapPosition.angle; mMapPosition.angle = -mMapPosition.angle;
sort(mItems, 0, mItems.length); sort(mItems, 0, mItems.length);

View File

@ -16,11 +16,10 @@
*/ */
package org.oscim.layers.tile.vector; package org.oscim.layers.tile.vector;
import org.oscim.core.MapPosition;
import org.oscim.layers.Layer; import org.oscim.layers.Layer;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.renderer.ExtrusionRenderer; import org.oscim.renderer.ExtrusionRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
public class BuildingLayer extends Layer { public class BuildingLayer extends Layer {
@ -34,9 +33,9 @@ public class BuildingLayer extends Layer {
private long mStartTime; private long mStartTime;
@Override @Override
public void update(MapPosition pos, boolean changed, Matrices m) { public void update(GLViewport v) {
boolean show = pos.scale >= (1 << MIN_ZOOM); boolean show = v.pos.scale >= (1 << MIN_ZOOM);
if (show) { if (show) {
if (mAlpha < 1) { if (mAlpha < 1) {
@ -66,7 +65,7 @@ public class BuildingLayer extends Layer {
mStartTime = 0; mStartTime = 0;
} }
//log.debug(show + " > " + mAlpha); //log.debug(show + " > " + mAlpha);
super.update(pos, changed, m); super.update(v);
} }
}; };

View File

@ -18,7 +18,7 @@ package org.oscim.layers.tile.vector.labeling;
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.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem; import org.oscim.renderer.elements.TextItem;
@ -79,7 +79,7 @@ class Debug {
dbg.addLineLayer(5, new Line((Color.MAGENTA & alpha), 2)); dbg.addLineLayer(5, new Line((Color.MAGENTA & alpha), 2));
} }
public static void draw(MapPosition pos, Matrices m, ElementLayers layers) { public static void draw(MapPosition pos, GLViewport m, ElementLayers layers) {
// if (layers.baseLayers != null) { // if (layers.baseLayers != null) {
// //setMatrix(pos, m, true); // //setMatrix(pos, m, true);
// //

View File

@ -30,11 +30,10 @@ package org.oscim.layers.tile.vector.labeling;
// 5 QuadTree might be handy // 5 QuadTree might be handy
// //
import org.oscim.core.MapPosition;
import org.oscim.layers.tile.vector.labeling.LabelLayer.Worker; import org.oscim.layers.tile.vector.labeling.LabelLayer.Worker;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.RenderElement; import org.oscim.renderer.elements.RenderElement;
import org.oscim.renderer.elements.TextureLayer; import org.oscim.renderer.elements.TextureLayer;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -53,8 +52,7 @@ class TextRenderer extends ElementRenderer {
long lastDraw = 0; long lastDraw = 0;
@Override @Override
public synchronized void update(MapPosition pos, boolean changed, public synchronized void update(GLViewport v) {
Matrices matrices) {
LabelTask t; LabelTask t;
synchronized (mWorker) { synchronized (mWorker) {
@ -75,18 +73,18 @@ class TextRenderer extends ElementRenderer {
} }
@Override @Override
public synchronized void render(MapPosition pos, Matrices m) { public synchronized void render(GLViewport v) {
GLState.test(false, false); GLState.test(false, false);
//Debug.draw(pos, layers); //Debug.draw(pos, layers);
layers.vbo.bind(); layers.vbo.bind();
float scale = (float) (pos.scale / mMapPosition.scale); float scale = (float) (v.pos.scale / mMapPosition.scale);
setMatrix(pos, m, false); setMatrix(v, false);
for (RenderElement l = layers.getTextureLayers(); l != null;) for (RenderElement l = layers.getTextureLayers(); l != null;)
l = TextureLayer.Renderer.draw(l, m, scale); l = TextureLayer.Renderer.draw(l, v, scale);
} }
} }

View File

@ -80,16 +80,16 @@ public abstract class Map {
protected boolean mClearMap = true; protected boolean mClearMap = true;
public Map() { public Map() {
mViewport = new ViewController(this); mViewport = new ViewController();
mAnimator = new Animator(this, mViewport); mAnimator = new Animator(this);
mLayers = new Layers(this); mLayers = new Layers(this);
mAsyncExecutor = new AsyncExecutor(2); mAsyncExecutor = new AsyncExecutor(2);
mMapPosition = new MapPosition(); mMapPosition = new MapPosition();
mEventLayer = new MapEventLayer(this); mEventLayer = new MapEventLayer(this);
mLayers.add(0, mEventLayer); mLayers.add(0, mEventLayer);
} }
public MapEventLayer getEventLayer() { public MapEventLayer getEventLayer() {
@ -272,7 +272,6 @@ public abstract class Map {
boolean changed = false; boolean changed = false;
MapPosition pos = mMapPosition; MapPosition pos = mMapPosition;
// get the current MapPosition
changed |= mViewport.getMapPosition(pos); changed |= mViewport.getMapPosition(pos);
if (mUpdateListeners == null) { if (mUpdateListeners == null) {
@ -316,5 +315,4 @@ public abstract class Map {
public boolean handleGesture(Gesture g, MotionEvent e) { public boolean handleGesture(Gesture g, MotionEvent e) {
return mLayers.handleGesture(g, e); return mLayers.handleGesture(g, e);
} }
} }

View File

@ -8,10 +8,6 @@ import org.oscim.utils.FastMath;
public class ViewController extends Viewport { public class ViewController extends Viewport {
ViewController(Map map) {
super(map);
}
public synchronized void setScreenSize(int width, int height) { public synchronized void setScreenSize(int width, int height) {
mHeight = height; mHeight = height;
mWidth = width; mWidth = width;
@ -37,7 +33,7 @@ public class ViewController extends Viewport {
/* set inverse projection matrix (without scaling) */ /* set inverse projection matrix (without scaling) */
mProjMatrix.get(tmp); mProjMatrix.get(tmp);
GLMatrix.invertM(tmp, 0, tmp, 0); GLMatrix.invertM(tmp, 0, tmp, 0);
mProjMatrixI.set(tmp); mProjMatrixInverse.set(tmp);
mProjMatrixUnscaled.copy(mProjMatrix); mProjMatrixUnscaled.copy(mProjMatrix);
@ -65,10 +61,10 @@ public class ViewController extends Viewport {
mPos.x = x; mPos.x = x;
mPos.y = y; mPos.y = y;
// clamp latitude /* clamp latitude */
mPos.y = FastMath.clamp(mPos.y, 0, 1); mPos.y = FastMath.clamp(mPos.y, 0, 1);
// wrap longitude /* wrap longitude */
while (mPos.x > 1) while (mPos.x > 1)
mPos.x -= 1; mPos.x -= 1;
while (mPos.x < 0) while (mPos.x < 0)
@ -180,27 +176,27 @@ public class ViewController extends Viewport {
* 0. apply rotate * 0. apply rotate
* 1. apply tilt */ * 1. apply tilt */
mRotMatrix.setRotation(mPos.angle, 0, 0, 1); mRotationMatrix.setRotation(mPos.angle, 0, 0, 1);
mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0); mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0);
/* apply first rotation, then tilt */ /* apply first rotation, then tilt */
mRotMatrix.multiplyLhs(mTmpMatrix); mRotationMatrix.multiplyLhs(mTmpMatrix);
mViewMatrix.copy(mRotMatrix); mViewMatrix.copy(mRotationMatrix);
mVPMatrix.multiplyMM(mProjMatrix, mViewMatrix); mViewProjMatrix.multiplyMM(mProjMatrix, mViewMatrix);
/* inverse projection matrix: */ /* inverse projection matrix: */
/* invert scale */ /* invert scale */
mUnprojMatrix.setScale(mWidth, mWidth, 1); mUnprojMatrix.setScale(mWidth, mWidth, 1);
/* invert rotation and tilt */ /* invert rotation and tilt */
mTmpMatrix.transposeM(mRotMatrix); mTmpMatrix.transposeM(mRotationMatrix);
/* (AB)^-1 = B^-1*A^-1, invert scale, tilt and rotation */ /* (AB)^-1 = B^-1*A^-1, invert scale, tilt and rotation */
mTmpMatrix.multiplyLhs(mUnprojMatrix); mTmpMatrix.multiplyLhs(mUnprojMatrix);
/* (AB)^-1 = B^-1*A^-1, invert projection */ /* (AB)^-1 = B^-1*A^-1, invert projection */
mUnprojMatrix.multiplyMM(mTmpMatrix, mProjMatrixI); mUnprojMatrix.multiplyMM(mTmpMatrix, mProjMatrixInverse);
} }
} }

View File

@ -48,10 +48,10 @@ public class Viewport {
protected final GLMatrix mProjMatrix = new GLMatrix(); protected final GLMatrix mProjMatrix = new GLMatrix();
protected final GLMatrix mProjMatrixUnscaled = new GLMatrix(); protected final GLMatrix mProjMatrixUnscaled = new GLMatrix();
protected final GLMatrix mProjMatrixI = new GLMatrix(); protected final GLMatrix mProjMatrixInverse = new GLMatrix();
protected final GLMatrix mRotMatrix = new GLMatrix(); protected final GLMatrix mRotationMatrix = new GLMatrix();
protected final GLMatrix mViewMatrix = new GLMatrix(); protected final GLMatrix mViewMatrix = new GLMatrix();
protected final GLMatrix mVPMatrix = new GLMatrix(); protected final GLMatrix mViewProjMatrix = new GLMatrix();
protected final GLMatrix mUnprojMatrix = new GLMatrix(); protected final GLMatrix mUnprojMatrix = new GLMatrix();
protected final GLMatrix mTmpMatrix = new GLMatrix(); protected final GLMatrix mTmpMatrix = new GLMatrix();
@ -71,7 +71,7 @@ public class Viewport {
/** scale map plane at VIEW_DISTANCE to near plane */ /** scale map plane at VIEW_DISTANCE to near plane */
public final static float VIEW_SCALE = (VIEW_NEAR / VIEW_DISTANCE) * 0.5f; public final static float VIEW_SCALE = (VIEW_NEAR / VIEW_DISTANCE) * 0.5f;
Viewport(Map map) { protected Viewport() {
mPos.scale = MIN_SCALE; mPos.scale = MIN_SCALE;
mPos.x = 0.5; mPos.x = 0.5;
mPos.y = 0.5; mPos.y = 0.5;
@ -83,7 +83,9 @@ public class Viewport {
* Get the current MapPosition. * Get the current MapPosition.
* *
* @param pos MapPosition to be updated. * @param pos MapPosition to be updated.
* @return true if current position is different from pos. *
* @return true iff current position is different from
* passed position.
*/ */
public synchronized boolean getMapPosition(MapPosition pos) { public synchronized boolean getMapPosition(MapPosition pos) {
@ -104,24 +106,6 @@ public class Viewport {
return changed; return changed;
} }
/**
* Get a copy of current matrices
*
* @param view view Matrix
* @param proj projection Matrix
* @param vp view and projection
*/
public synchronized void getMatrix(GLMatrix view, GLMatrix proj, GLMatrix vp) {
if (view != null)
view.copy(mViewMatrix);
if (proj != null)
proj.copy(mProjMatrix);
if (vp != null)
vp.copy(mVPMatrix);
}
/** /**
* Get the inverse projection of the viewport, i.e. the * Get the inverse projection of the viewport, i.e. the
* coordinates with z==0 that will be projected exactly * coordinates with z==0 that will be projected exactly
@ -155,9 +139,11 @@ public class Viewport {
} }
} }
/* Get Z-value of the map-plane for a point on screen - /**
* Get Z-value of the map-plane for a point on screen -
* calculate the intersection of a ray from camera origin * calculate the intersection of a ray from camera origin
* and the map plane */ * and the map plane
*/
protected float getDepth(float y) { protected float getDepth(float y) {
if (y == 0) if (y == 0)
return 0; return 0;
@ -208,11 +194,10 @@ public class Viewport {
public synchronized BoundingBox getBBox(int expand) { public synchronized BoundingBox getBBox(int expand) {
getBBox(mMapBBox, expand); getBBox(mMapBBox, expand);
// scale map-pixel coordinates at current scale to /* scale map-pixel coordinates at current scale to
// absolute coordinates and apply mercator projection. * absolute coordinates and apply mercator projection. */
double minLon = MercatorProjection.toLongitude(mMapBBox.minX); double minLon = MercatorProjection.toLongitude(mMapBBox.minX);
double maxLon = MercatorProjection.toLongitude(mMapBBox.maxX); double maxLon = MercatorProjection.toLongitude(mMapBBox.maxX);
// sic(k)
double minLat = MercatorProjection.toLatitude(mMapBBox.maxY); double minLat = MercatorProjection.toLatitude(mMapBBox.maxY);
double maxLat = MercatorProjection.toLatitude(mMapBBox.minY); double maxLat = MercatorProjection.toLatitude(mMapBBox.minY);
@ -334,9 +319,26 @@ public class Viewport {
mv[2] = 0; mv[2] = 0;
mv[3] = 1; mv[3] = 1;
mVPMatrix.prj(mv); mViewProjMatrix.prj(mv);
out.x = (mv[0] * (mWidth / 2)); out.x = (mv[0] * (mWidth / 2));
out.y = -(mv[1] * (mHeight / 2)); out.y = -(mv[1] * (mHeight / 2));
} }
public synchronized boolean copy(Viewport viewport) {
mUnprojMatrix.copy(viewport.mUnprojMatrix);
mRotationMatrix.copy(viewport.mRotationMatrix);
mViewMatrix.copy(viewport.mViewMatrix);
mViewProjMatrix.copy(viewport.mViewProjMatrix);
return viewport.getMapPosition(mPos);
}
public synchronized void initFrom(Viewport viewport) {
mProjMatrix.copy(viewport.mProjMatrix);
mProjMatrixUnscaled.copy(viewport.mProjMatrixUnscaled);
mProjMatrixInverse.copy(viewport.mProjMatrixInverse);
mHeight = viewport.mHeight;
mWidth = viewport.mWidth;
}
} }

View File

@ -17,8 +17,6 @@
package org.oscim.renderer; package org.oscim.renderer;
import org.oscim.backend.canvas.Bitmap; import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapPosition;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.BitmapLayer; import org.oscim.renderer.elements.BitmapLayer;
/** /**
@ -56,7 +54,7 @@ public class BitmapRenderer extends ElementRenderer {
} }
@Override @Override
protected synchronized void update(MapPosition pos, boolean changed, Matrices m) { protected synchronized void update(GLViewport v) {
if (!initialized) { if (!initialized) {
layers.clear(); layers.clear();
@ -84,8 +82,8 @@ public class BitmapRenderer extends ElementRenderer {
} }
@Override @Override
protected synchronized void render(MapPosition pos, Matrices m) { protected synchronized void render(GLViewport v) {
m.useScreenCoordinates(false, 8); v.useScreenCoordinates(false, 8);
BitmapLayer.Renderer.draw(layers.getTextureLayers(), m, 1, 1); BitmapLayer.Renderer.draw(layers.getTextureLayers(), v, 1, 1);
} }
} }

View File

@ -28,7 +28,6 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.core.MapPosition; import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.BitmapLayer; import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
@ -78,35 +77,35 @@ public abstract class ElementRenderer extends LayerRenderer {
* Render all 'layers' * Render all 'layers'
*/ */
@Override @Override
protected synchronized void render(MapPosition pos, Matrices m) { protected synchronized void render(GLViewport v) {
MapPosition layerPos = mMapPosition; MapPosition layerPos = mMapPosition;
layers.vbo.bind(); layers.vbo.bind();
GLState.test(false, false); GLState.test(false, false);
GLState.blend(true); GLState.blend(true);
float div = (float) (pos.scale / layerPos.scale); float div = (float) (v.pos.scale / layerPos.scale);
RenderElement l = layers.getBaseLayers(); RenderElement l = layers.getBaseLayers();
if (l != null) if (l != null)
setMatrix(pos, m, true); setMatrix(v, true);
while (l != null) { while (l != null) {
if (l.type == POLYGON) { if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(l, m, pos, 1, true, 0); l = PolygonLayer.Renderer.draw(l, v, 1, true, 0);
continue; continue;
} }
if (l.type == LINE) { if (l.type == LINE) {
l = LineLayer.Renderer.draw(l, m, pos, div, layers); l = LineLayer.Renderer.draw(l, v, div, layers);
continue; continue;
} }
if (l.type == TEXLINE) { if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(l, m, pos, div, layers); l = LineTexLayer.Renderer.draw(l, v, div, layers);
continue; continue;
} }
if (l.type == MESH) { if (l.type == MESH) {
l = MeshLayer.Renderer.draw(l, m, pos); l = MeshLayer.Renderer.draw(l, v);
continue; continue;
} }
log.debug("invalid layer {}", l.type); log.debug("invalid layer {}", l.type);
@ -115,14 +114,14 @@ public abstract class ElementRenderer extends LayerRenderer {
l = layers.getTextureLayers(); l = layers.getTextureLayers();
if (l != null) if (l != null)
setMatrix(pos, m, false); setMatrix(v, false);
while (l != null) { while (l != null) {
if (l.type == BITMAP) { if (l.type == BITMAP) {
l = BitmapLayer.Renderer.draw(l, m, 1, 1); l = BitmapLayer.Renderer.draw(l, v, 1, 1);
continue; continue;
} }
if (l.type == SYMBOL) { if (l.type == SYMBOL) {
l = TextureLayer.Renderer.draw(l, m, div); l = TextureLayer.Renderer.draw(l, v, div);
continue; continue;
} }
log.debug("invalid layer {}", l.type); log.debug("invalid layer {}", l.type);
@ -184,20 +183,18 @@ public abstract class ElementRenderer extends LayerRenderer {
* Use this to 'stick' your layer to the map. Note: Vertex coordinates * Use this to 'stick' your layer to the map. Note: Vertex coordinates
* are assumed to be scaled by MapRenderer.COORD_SCALE (== 8). * are assumed to be scaled by MapRenderer.COORD_SCALE (== 8).
* *
* @param position * @param v
* current MapPosition * GLViewport
* @param matrices
* current Matrices
* @param project * @param project
* if true apply view- and projection, or just view otherwise. * if true apply view- and projection, or just view otherwise.
*/ */
protected void setMatrix(MapPosition position, Matrices matrices, boolean project) { protected void setMatrix(GLViewport v, boolean project) {
MapPosition oPos = mMapPosition; MapPosition oPos = mMapPosition;
double tileScale = Tile.SIZE * position.scale; double tileScale = Tile.SIZE * v.pos.scale;
double x = oPos.x - position.x; double x = oPos.x - v.pos.x;
double y = oPos.y - position.y; double y = oPos.y - v.pos.y;
if (mFlipOnDateLine) { if (mFlipOnDateLine) {
//wrap around date-line //wrap around date-line
@ -207,23 +204,20 @@ public abstract class ElementRenderer extends LayerRenderer {
x -= 1.0; x -= 1.0;
} }
matrices.mvp.setTransScale((float) (x * tileScale), v.mvp.setTransScale((float) (x * tileScale),
(float) (y * tileScale), (float) (y * tileScale),
(float) (position.scale / oPos.scale) (float) (v.pos.scale / oPos.scale)
/ MapRenderer.COORD_SCALE); / MapRenderer.COORD_SCALE);
matrices.mvp.multiplyLhs(project ? matrices.viewproj : matrices.view); v.mvp.multiplyLhs(project ? v.viewproj : v.view);
} }
/** /**
* Utility: Set matrices.mvp matrix relative to the difference of current * Utility: Set matrices.mvp matrix relative to the difference of current
* MapPosition and the last updated Overlay MapPosition and add * MapPosition and the last updated Overlay MapPosition and applies
* matrices.viewproj * view-projection-matrix.
*
* @param position ...
* @param matrices ...
*/ */
protected void setMatrix(MapPosition position, Matrices matrices) { protected void setMatrix(GLViewport v) {
setMatrix(position, matrices, true); setMatrix(v, true);
} }
} }

View File

@ -21,9 +21,7 @@ import static org.oscim.tiling.MapTile.State.READY;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.ExtrusionLayer; import org.oscim.renderer.elements.ExtrusionLayer;
import org.oscim.tiling.MapTile; import org.oscim.tiling.MapTile;
import org.oscim.tiling.TileRenderer; import org.oscim.tiling.TileRenderer;
@ -91,7 +89,7 @@ public class ExtrusionRenderer extends LayerRenderer {
} }
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) { protected void update(GLViewport v) {
if (!initialized && !initShader()) if (!initialized && !initShader())
return; return;
@ -99,7 +97,7 @@ public class ExtrusionRenderer extends LayerRenderer {
if (shaderProgram[0] == 0) if (shaderProgram[0] == 0)
return; return;
if (mAlpha == 0 || pos.zoomLevel < 16) { if (mAlpha == 0 || v.pos.zoomLevel < 16) {
setReady(false); setReady(false);
return; return;
} }
@ -180,7 +178,7 @@ public class ExtrusionRenderer extends LayerRenderer {
private final boolean debug = false; private final boolean debug = false;
@Override @Override
protected void render(MapPosition pos, Matrices m) { protected void render(GLViewport v) {
// TODO one could render in one pass to texture and then draw the texture // TODO one could render in one pass to texture and then draw the texture
// with alpha... might be faster and would allow postprocessing outlines. // with alpha... might be faster and would allow postprocessing outlines.
@ -205,8 +203,8 @@ public class ExtrusionRenderer extends LayerRenderer {
for (int i = 0; i < mTileCnt; i++) { for (int i = 0; i < mTileCnt; i++) {
ExtrusionLayer el = tiles[i].layers.getExtrusionLayers(); ExtrusionLayer el = tiles[i].layers.getExtrusionLayers();
setMatrix(pos, m, tiles[i], 0); setMatrix(v, tiles[i], 0);
m.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.bind(); el.vboIndices.bind();
el.vboVertices.bind(); el.vboVertices.bind();
@ -240,7 +238,7 @@ public class ExtrusionRenderer extends LayerRenderer {
GLState.useProgram(shaderProgram[SHADER]); GLState.useProgram(shaderProgram[SHADER]);
GLState.enableVertexArrays(uExtVertexPosition, -1); GLState.enableVertexArrays(uExtVertexPosition, -1);
if (pos.scale < (1 << 18)) { if (v.pos.scale < (1 << 18)) {
// chances are high that one moves through a building // chances are high that one moves through a building
// with scale > 2 also draw back sides in this case. // with scale > 2 also draw back sides in this case.
GL.glEnable(GL20.GL_CULL_FACE); GL.glEnable(GL20.GL_CULL_FACE);
@ -256,8 +254,8 @@ public class ExtrusionRenderer extends LayerRenderer {
MapTile t = tiles[i]; MapTile t = tiles[i];
ExtrusionLayer el = t.layers.getExtrusionLayers(); ExtrusionLayer el = t.layers.getExtrusionLayers();
int d = MapRenderer.depthOffset(t) * 10; int d = MapRenderer.depthOffset(t) * 10;
setMatrix(pos, m, t, d); setMatrix(v, t, d);
m.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.bind(); el.vboIndices.bind();
el.vboVertices.bind(); el.vboVertices.bind();
@ -292,8 +290,8 @@ public class ExtrusionRenderer extends LayerRenderer {
GL.glDepthFunc(GL20.GL_EQUAL); GL.glDepthFunc(GL20.GL_EQUAL);
int d = MapRenderer.depthOffset(t) * 10; int d = MapRenderer.depthOffset(t) * 10;
setMatrix(pos, m, t, d); setMatrix(v, t, d);
m.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.bind(); el.vboIndices.bind();
el.vboVertices.bind(); el.vboVertices.bind();
@ -323,8 +321,8 @@ public class ExtrusionRenderer extends LayerRenderer {
// same depth values as polygons, so add offset and draw gl_lequal: // same depth values as polygons, so add offset and draw gl_lequal:
GL.glDepthFunc(GL20.GL_LEQUAL); GL.glDepthFunc(GL20.GL_LEQUAL);
m.mvp.addDepthOffset(100); v.mvp.addDepthOffset(100);
m.mvp.setAsUniform(uExtMatrix); v.mvp.setAsUniform(uExtMatrix);
GL.glUniform1i(uExtMode, 3); GL.glUniform1i(uExtMode, 3);
GL.glDrawElements(GL20.GL_LINES, el.mIndiceCnt[3], GL.glDrawElements(GL20.GL_LINES, el.mIndiceCnt[3],
@ -335,7 +333,7 @@ public class ExtrusionRenderer extends LayerRenderer {
tiles[i] = null; tiles[i] = null;
} }
if (pos.scale < (1 << 18)) if (v.pos.scale < (1 << 18))
GL.glDisable(GL20.GL_CULL_FACE); GL.glDisable(GL20.GL_CULL_FACE);
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0); GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
@ -343,15 +341,15 @@ public class ExtrusionRenderer extends LayerRenderer {
mTileLayer.releaseTiles(mTileSet); mTileLayer.releaseTiles(mTileSet);
} }
private static void setMatrix(MapPosition pos, Matrices m, private static void setMatrix(GLViewport m,
MapTile tile, int delta) { MapTile tile, int delta) {
int z = tile.zoomLevel; int z = tile.zoomLevel;
double curScale = Tile.SIZE * pos.scale; double curScale = Tile.SIZE * m.pos.scale;
float scale = (float) (pos.scale / (1 << z)); float scale = (float) (m.pos.scale / (1 << z));
float x = (float) ((tile.x - pos.x) * curScale); float x = (float) ((tile.x - m.pos.x) * curScale);
float y = (float) ((tile.y - pos.y) * curScale); float y = (float) ((tile.y - m.pos.y) * curScale);
m.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE); m.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
// scale height // scale height

View File

@ -0,0 +1,57 @@
package org.oscim.renderer;
import org.oscim.core.MapPosition;
import org.oscim.map.Viewport;
public class GLViewport extends Viewport {
/** Do not modify! */
public final GLMatrix viewproj = mViewProjMatrix;
/** Do not modify! */
public final GLMatrix proj = mProjMatrix;
/** Do not modify! */
public final GLMatrix view = mViewMatrix;
/** Do not modify! */
public final float[] plane = new float[8];
/** For temporary use, to setup MVP-Matrix */
public final GLMatrix mvp = new GLMatrix();
public final MapPosition pos = mPos;
/**
* Set MVP so that coordinates are in screen pixel coordinates with 0,0
* being center
*/
public void useScreenCoordinates(boolean center, float scale) {
float ratio = (1f / (scale * mWidth));
if (center)
mvp.setScale(ratio, ratio, ratio);
else
mvp.setTransScale((-mWidth / 2) * ratio * scale,
(-mHeight / 2) * ratio * scale,
ratio);
mvp.multiplyLhs(proj);
}
protected boolean changed;
public boolean changed() {
return changed;
}
void setFrom(Viewport viewport) {
changed = super.copy(viewport);
getMapExtents(plane, 0);
}
public float getWidth() {
return mWidth;
}
public float getHeight() {
return mHeight;
}
}

View File

@ -19,9 +19,7 @@ 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.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem; import org.oscim.renderer.elements.TextItem;
import org.oscim.renderer.elements.TextLayer; import org.oscim.renderer.elements.TextLayer;
@ -114,13 +112,13 @@ public class GridRenderer extends ElementRenderer {
} }
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices m) { protected void update(GLViewport v) {
// scale coordinates relative to current 'zoom-level' to // scale coordinates relative to current 'zoom-level' to
// get the position as the nearest tile coordinate // get the position as the nearest tile coordinate
int z = 1 << pos.zoomLevel; int z = 1 << v.pos.zoomLevel;
int x = (int) (pos.x * z); int x = (int) (v.pos.x * z);
int y = (int) (pos.y * z); int y = (int) (v.pos.y * z);
// update layers when map moved by at least one tile // update layers when map moved by at least one tile
if (x == mCurX && y == mCurY && z == mCurZ) if (x == mCurX && y == mCurY && z == mCurZ)
@ -130,13 +128,13 @@ public class GridRenderer extends ElementRenderer {
mCurY = y; mCurY = y;
mCurZ = z; mCurZ = z;
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
mMapPosition.x = (double) x / z; mMapPosition.x = (double) x / z;
mMapPosition.y = (double) y / z; mMapPosition.y = (double) y / z;
mMapPosition.scale = z; mMapPosition.scale = z;
if (mText != null) { if (mText != null) {
addLabels(x, y, pos.zoomLevel); addLabels(x, y, v.pos.zoomLevel);
layers.setBaseLayers(mLineLayer); layers.setBaseLayers(mLineLayer);
mLineLayer.addLine(mLines); mLineLayer.addLine(mLines);
compile(); compile();

View File

@ -17,8 +17,6 @@
package org.oscim.renderer; package org.oscim.renderer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.core.MapPosition;
import org.oscim.renderer.MapRenderer.Matrices;
public abstract class LayerRenderer { public abstract class LayerRenderer {
@ -64,8 +62,7 @@ public abstract class LayerRenderer {
* @param matrices contains the current view- and projection-matrices * @param matrices contains the current view- and projection-matrices
* and 'mvp' matrix for temporary use. * and 'mvp' matrix for temporary use.
*/ */
protected abstract void update(MapPosition position, boolean changed, protected abstract void update(GLViewport viewport);
Matrices matrices);
/** /**
* 2. Draw layer: called by MapRenderer when isReady == true. * 2. Draw layer: called by MapRenderer when isReady == true.
@ -75,6 +72,6 @@ public abstract class LayerRenderer {
* 'matrices.mvp' is for temporary use to build the model- * 'matrices.mvp' is for temporary use to build the model-
* view-projection to set as uniform. * view-projection to set as uniform.
*/ */
protected abstract void render(MapPosition position, Matrices matrices); protected abstract void render(GLViewport viewport);
} }

View File

@ -25,9 +25,7 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter; 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.map.Map; import org.oscim.map.Map;
import org.oscim.map.Viewport;
import org.oscim.renderer.elements.ElementLayers; import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.MapTile; import org.oscim.tiling.MapTile;
import org.oscim.utils.pool.Inlist; import org.oscim.utils.pool.Inlist;
@ -42,55 +40,20 @@ public class MapRenderer {
/** scale factor used for short vertices */ /** scale factor used for short vertices */
public static final float COORD_SCALE = 8.0f; public static final float COORD_SCALE = 8.0f;
public static int screenWidth, screenHeight;
private final Map mMap; private final Map mMap;
private final MapPosition mMapPosition; private final GLViewport mViewport;
public class Matrices { private static float[] mClearColor;
/** Do not modify! */
public final GLMatrix viewproj = new GLMatrix();
/** Do not modify! */
public final GLMatrix proj = new GLMatrix();
/** Do not modify! */
public final GLMatrix view = new GLMatrix();
/** Do not modify! */
public final float[] plane = new float[8];
/** For temporary use, to setup MVP-Matrix */
public final GLMatrix mvp = new GLMatrix();
/**
* Set MVP so that coordinates are in screen pixel coordinates with 0,0
* being center
*/
public void useScreenCoordinates(boolean center, float scale) {
float ratio = (1f / (scale * screenWidth));
if (center)
mvp.setScale(ratio, ratio, ratio);
else
mvp.setTransScale(
(-screenWidth / 2) * ratio * scale,
(-screenHeight / 2) * ratio * scale,
ratio);
mvp.multiplyLhs(proj);
}
}
private final Matrices mMatrices;
private static float[] mClearColor = null;
private static int mQuadIndicesID; private static int mQuadIndicesID;
private static int mQuadVerticesID; private static int mQuadVerticesID;
public final static int maxQuads = 64; public final static int maxQuads = 64;
private static volatile boolean mUpdateColor = false; private static boolean mUpdateColor;
public static long frametime; public static long frametime;
private static boolean rerender;
// Do not use the same buffer to upload data within a frame twice // Do not use the same buffer to upload data within a frame twice
// - Contrary to what the OpenGL doc says data seems *not* to be // - Contrary to what the OpenGL doc says data seems *not* to be
@ -138,9 +101,8 @@ public class MapRenderer {
public MapRenderer(Map map) { public MapRenderer(Map map) {
mMap = map; mMap = map;
mMapPosition = new MapPosition();
mMatrices = new Matrices(); mViewport = new GLViewport();
mBufferPool = new BufferPool(); mBufferPool = new BufferPool();
// FIXME should be done in 'destroy' method // FIXME should be done in 'destroy' method
@ -220,8 +182,6 @@ public class MapRenderer {
mUpdateColor = false; mUpdateColor = false;
} }
// some GL implementation do not clear these
// buffers unless writes are enabled.
GL.glDepthMask(true); GL.glDepthMask(true);
GL.glStencilMask(0xFF); GL.glStencilMask(0xFF);
@ -237,27 +197,14 @@ public class MapRenderer {
GLState.useProgram(-1); GLState.useProgram(-1);
mMap.animator().updateAnimation(); mMap.animator().updateAnimation();
mViewport.setFrom(mMap.viewport());
MapPosition pos = mMapPosition; if (GLAdapter.debugView) {
Viewport viewport = mMap.viewport(); // modify this to scale only the view, to see
boolean changed = false; // which tiles are rendered
mViewport.mvp.setScale(0.5f, 0.5f, 1);
synchronized (viewport) { mViewport.viewproj.multiplyLhs(mViewport.mvp);
// get current MapPosition mViewport.proj.multiplyLhs(mViewport.mvp);
changed = viewport.getMapPosition(pos);
if (changed)
viewport.getMapExtents(mMatrices.plane, 0);
viewport.getMatrix(mMatrices.view, mMatrices.proj, mMatrices.viewproj);
if (GLAdapter.debugView) {
// modify this to scale only the view, to see
// which tiles are rendered
mMatrices.mvp.setScale(0.5f, 0.5f, 1);
mMatrices.viewproj.multiplyLhs(mMatrices.mvp);
mMatrices.proj.multiplyLhs(mMatrices.mvp);
}
} }
/* update layers */ /* update layers */
@ -271,10 +218,10 @@ public class MapRenderer {
renderer.isInitialized = true; renderer.isInitialized = true;
} }
renderer.update(pos, changed, mMatrices); renderer.update(mViewport);
if (renderer.isReady) if (renderer.isReady)
renderer.render(pos, mMatrices); renderer.render(mViewport);
if (GLAdapter.debug) if (GLAdapter.debug)
GLUtils.checkGlError(renderer.getClass().getName()); GLUtils.checkGlError(renderer.getClass().getName());
@ -301,14 +248,12 @@ public class MapRenderer {
if (width <= 0 || height <= 0) if (width <= 0 || height <= 0)
return; return;
screenWidth = width; //mMap.viewport().getMatrix(null, mMatrices.proj, null);
screenHeight = height; mViewport.initFrom(mMap.viewport());
mMap.viewport().getMatrix(null, mMatrices.proj, null);
GL.glViewport(0, 0, width, height); GL.glViewport(0, 0, width, height);
GL.glScissor(0, 0, width, height);
GL.glEnable(GL20.GL_SCISSOR_TEST); //GL.glScissor(0, 0, width, height);
//GL.glEnable(GL20.GL_SCISSOR_TEST);
GL.glClearStencil(0x00); GL.glClearStencil(0x00);
@ -413,8 +358,6 @@ public class MapRenderer {
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, bind ? mQuadIndicesID : 0); GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, bind ? mQuadIndicesID : 0);
} }
private static boolean rerender;
/** /**
* Trigger next redraw from GL-Thread. This should be used to animate * Trigger next redraw from GL-Thread. This should be used to animate
* LayerRenderers instead of calling Map.render(). * LayerRenderers instead of calling Map.render().

View File

@ -22,8 +22,8 @@ import org.oscim.backend.GL20;
import org.oscim.backend.canvas.Bitmap; import org.oscim.backend.canvas.Bitmap;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
/** /**
* Renderer for a single bitmap, width and height must be power of 2. * Renderer for a single bitmap, width and height must be power of 2.
@ -181,7 +181,7 @@ public class BitmapLayer extends TextureLayer {
hAlpha = GL.glGetUniformLocation(mTextureProgram, "u_alpha"); hAlpha = GL.glGetUniformLocation(mTextureProgram, "u_alpha");
} }
public static RenderElement draw(RenderElement renderElement, Matrices m, float scale, public static RenderElement draw(RenderElement renderElement, GLViewport v, float scale,
float alpha) { float alpha) {
//GLState.test(false, false); //GLState.test(false, false);
GLState.blend(true); GLState.blend(true);
@ -197,12 +197,12 @@ public class BitmapLayer extends TextureLayer {
else else
GL.glUniform1f(hTextureScale, 1); GL.glUniform1f(hTextureScale, 1);
GL.glUniform1f(hTextureScreenScale, 1f / MapRenderer.screenWidth); GL.glUniform1f(hTextureScreenScale, 1f / v.getWidth());
GL.glUniform1f(hAlpha, alpha); GL.glUniform1f(hAlpha, alpha);
m.proj.setAsUniform(hTextureProjMatrix); v.proj.setAsUniform(hTextureProjMatrix);
m.mvp.setAsUniform(hTextureMVMatrix); v.mvp.setAsUniform(hTextureMVMatrix);
MapRenderer.bindQuadIndicesVBO(true); MapRenderer.bindQuadIndicesVBO(true);

View File

@ -20,13 +20,12 @@ import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter; import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap; import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection; import org.oscim.core.MercatorProjection;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Line; import org.oscim.theme.styles.Line;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.oscim.utils.pool.Inlist; import org.oscim.utils.pool.Inlist;
@ -644,15 +643,15 @@ public final class LineLayer extends RenderElement {
return true; return true;
} }
public static RenderElement draw(RenderElement curLayer, Matrices m, public static RenderElement draw(RenderElement curLayer, GLViewport v,
MapPosition pos, float scale, ElementLayers layers) { float scale, ElementLayers layers) {
if (curLayer == null) if (curLayer == null)
return null; return null;
// simple line shader does not take forward shortening into // simple line shader does not take forward shortening into
// account. only used when tilt is 0. // account. only used when tilt is 0.
int mode = pos.tilt < 1 ? 1 : 0; int mode = v.pos.tilt < 1 ? 1 : 0;
GLState.useProgram(lineProgram[mode]); GLState.useProgram(lineProgram[mode]);
GLState.blend(true); GLState.blend(true);
@ -675,7 +674,7 @@ public final class LineLayer extends RenderElement {
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT, GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
false, 0, layers.offset[LINE]); false, 0, layers.offset[LINE]);
m.mvp.setAsUniform(hLineMatrix[mode]); v.mvp.setAsUniform(hLineMatrix[mode]);
// Line scale factor for non fixed lines: Within a zoom- // Line scale factor for non fixed lines: Within a zoom-
// level lines would be scaled by the factor 2 by view-matrix. // level lines would be scaled by the factor 2 by view-matrix.
@ -707,12 +706,12 @@ public final class LineLayer extends RenderElement {
heightOffset = ll.heightOffset; heightOffset = ll.heightOffset;
GL.glUniform1f(uLineHeight, heightOffset / GL.glUniform1f(uLineHeight, heightOffset /
MercatorProjection.groundResolution(pos)); MercatorProjection.groundResolution(v.pos));
} }
if (line.fade < pos.zoomLevel) { if (line.fade < v.pos.zoomLevel) {
GLUtils.setColor(uLineColor, line.color, 1); GLUtils.setColor(uLineColor, line.color, 1);
} else if (line.fade > pos.zoomLevel) { } else if (line.fade > v.pos.zoomLevel) {
continue; continue;
} else { } else {
float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1; float alpha = (float) (scale > 1.2 ? scale : 1.2) - 1;

View File

@ -22,11 +22,10 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Line; import org.oscim.theme.styles.Line;
import org.oscim.utils.pool.Inlist; import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -326,8 +325,8 @@ public final class LineTexLayer extends RenderElement {
private final static int STRIDE = 12; private final static int STRIDE = 12;
private final static int LEN_OFFSET = 8; private final static int LEN_OFFSET = 8;
public static RenderElement draw(RenderElement curLayer, Matrices m, public static RenderElement draw(RenderElement curLayer, GLViewport v,
MapPosition pos, float div, ElementLayers layers) { float div, ElementLayers layers) {
if (shader == 0) if (shader == 0)
return curLayer.next; return curLayer.next;
@ -343,7 +342,7 @@ public final class LineTexLayer extends RenderElement {
GL.glEnableVertexAttribArray(hVertexLength1); GL.glEnableVertexAttribArray(hVertexLength1);
GL.glEnableVertexAttribArray(hVertexFlip); GL.glEnableVertexAttribArray(hVertexFlip);
m.mvp.setAsUniform(hMatrix); v.mvp.setAsUniform(hMatrix);
int maxIndices = MapRenderer.maxQuads * 6; int maxIndices = MapRenderer.maxQuads * 6;
@ -355,7 +354,7 @@ public final class LineTexLayer extends RenderElement {
layers.vbo.bind(); layers.vbo.bind();
float scale = (float) pos.getZoomScale(); float scale = (float) v.pos.getZoomScale();
float s = scale / div; float s = scale / div;
@ -506,8 +505,7 @@ public final class LineTexLayer extends RenderElement {
+ " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));" + " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
+ " } "; //*/ + " } "; //*/
/* /* final static String fragmentShader = ""
* final static String fragmentShader = ""
* + "#extension GL_OES_standard_derivatives : enable\n" * + "#extension GL_OES_standard_derivatives : enable\n"
* + " precision mediump float;" * + " precision mediump float;"
* + " uniform sampler2D tex;" * + " uniform sampler2D tex;"
@ -528,10 +526,8 @@ public final class LineTexLayer extends RenderElement {
* + " gl_FragColor = u_bgcolor * stipple_p;" * + " gl_FragColor = u_bgcolor * stipple_p;"
* // + * // +
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));" * " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
* + "}"; // * + "}"; // */
*/ /* final static String fragmentShader = ""
/*
* final static String fragmentShader = ""
* + "#extension GL_OES_standard_derivatives : enable\n" * + "#extension GL_OES_standard_derivatives : enable\n"
* + " precision mediump float;" * + " precision mediump float;"
* + " uniform sampler2D tex;" * + " uniform sampler2D tex;"
@ -550,8 +546,7 @@ public final class LineTexLayer extends RenderElement {
* + " float stipple_p = smoothstep(0.495, 0.505, dist);" * + " float stipple_p = smoothstep(0.495, 0.505, dist);"
* + * +
* " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));" * " gl_FragColor = line_w * mix(u_bgcolor, u_color, min(stipple_w, stipple_p));"
* + " } "; // * + " } "; // */
*/
} }
} }

View File

@ -21,13 +21,12 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection; import org.oscim.core.MercatorProjection;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Area; import org.oscim.theme.styles.Area;
import org.oscim.utils.Tessellator; import org.oscim.utils.Tessellator;
import org.oscim.utils.pool.Inlist; import org.oscim.utils.pool.Inlist;
@ -123,8 +122,7 @@ public class MeshLayer extends RenderElement {
return true; return true;
} }
public static RenderElement draw(RenderElement l, Matrices m, public static RenderElement draw(RenderElement l, GLViewport v) {
MapPosition pos) {
GLState.blend(true); GLState.blend(true);
@ -132,7 +130,7 @@ public class MeshLayer extends RenderElement {
GLState.enableVertexArrays(hVertexPosition, -1); GLState.enableVertexArrays(hVertexPosition, -1);
m.mvp.setAsUniform(hMatrix); v.mvp.setAsUniform(hMatrix);
float heightOffset = 0; float heightOffset = 0;
GL.glUniform1f(hHeightOffset, heightOffset); GL.glUniform1f(hHeightOffset, heightOffset);
@ -147,7 +145,7 @@ public class MeshLayer extends RenderElement {
heightOffset = ml.heightOffset; heightOffset = ml.heightOffset;
GL.glUniform1f(hHeightOffset, heightOffset / GL.glUniform1f(hHeightOffset, heightOffset /
MercatorProjection.groundResolution(pos)); MercatorProjection.groundResolution(v.pos));
} }
ml.indicesVbo.bind(); ml.indicesVbo.bind();

View File

@ -23,13 +23,12 @@ 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.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.renderer.GLMatrix; import org.oscim.renderer.GLMatrix;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Area; import org.oscim.theme.styles.Area;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.oscim.utils.math.Interpolation; import org.oscim.utils.math.Interpolation;
@ -171,8 +170,8 @@ public final class PolygonLayer extends RenderElement {
return true; return true;
} }
private static void fillPolygons(Matrices m, int start, int end, int zoom, float scale, private static void fillPolygons(GLViewport v, int start, int end, int zoom,
float div) { float scale, float div) {
/* draw to framebuffer */ /* draw to framebuffer */
GL.glColorMask(true, true, true, true); GL.glColorMask(true, true, true, true);
@ -186,7 +185,7 @@ public final class PolygonLayer extends RenderElement {
if (enableTexture && a.texture != null) { if (enableTexture && a.texture != null) {
shader = texShader; shader = texShader;
setShader(texShader, m); setShader(texShader, v);
float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE); float num = FastMath.clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
float transition = Interpolation.exp5.apply(FastMath.clamp(scale - 1, 0, 1)); float transition = Interpolation.exp5.apply(FastMath.clamp(scale - 1, 0, 1));
GL.glUniform2f(hPolygonScale[1], transition, div / num); GL.glUniform2f(hPolygonScale[1], transition, div / num);
@ -237,7 +236,7 @@ public final class PolygonLayer extends RenderElement {
if (shader != polyShader) { if (shader != polyShader) {
// disable texture shader // disable texture shader
setShader(polyShader, m); setShader(polyShader, v);
shader = polyShader; shader = polyShader;
} }
} }
@ -246,7 +245,7 @@ public final class PolygonLayer extends RenderElement {
// current layer to fill (0 - STENCIL_BITS-1) // current layer to fill (0 - STENCIL_BITS-1)
private static int mCount; private static int mCount;
private static void setShader(int shader, Matrices m) { private static void setShader(int shader, GLViewport v) {
GLState.useProgram(polygonProgram[shader]); GLState.useProgram(polygonProgram[shader]);
GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1); GLState.enableVertexArrays(hPolygonVertexPosition[shader], -1);
@ -255,16 +254,17 @@ public final class PolygonLayer extends RenderElement {
GL20.GL_SHORT, false, 0, GL20.GL_SHORT, false, 0,
POLYGON_VERTICES_DATA_POS_OFFSET); POLYGON_VERTICES_DATA_POS_OFFSET);
m.mvp.setAsUniform(hPolygonMatrix[shader]); v.mvp.setAsUniform(hPolygonMatrix[shader]);
} }
/** /**
* draw polygon layers (unil layer.next is not polygon layer) * draw polygon layers (until layer.next is not polygon layer)
* using stencil buffer method * using stencil buffer method
*
* @param renderElement * @param renderElement
* layer to draw (referencing vertices in current vbo) * layer to draw (referencing vertices in current vbo)
* @param m * @param v
* current Matrices * GLViewport
* @param pos * @param pos
* used to fade layers according to 'fade' in * used to fade layers according to 'fade' in
* layer.area style * layer.area style
@ -278,15 +278,15 @@ public final class PolygonLayer extends RenderElement {
* @return * @return
* next layer * next layer
*/ */
public static RenderElement draw(RenderElement renderElement, Matrices m, public static RenderElement draw(RenderElement renderElement, GLViewport v,
MapPosition pos, float div, boolean first, int clipMode) { float div, boolean first, int clipMode) {
GLState.test(false, true); GLState.test(false, true);
setShader(polyShader, m); setShader(polyShader, v);
int zoom = pos.zoomLevel; int zoom = v.pos.zoomLevel;
float scale = (float) pos.getZoomScale(); float scale = (float) v.pos.getZoomScale();
int cur = mCount; int cur = mCount;
@ -321,13 +321,13 @@ public final class PolygonLayer extends RenderElement {
// draw up to 7 layers into stencil buffer // draw up to 7 layers into stencil buffer
if (cur == STENCIL_BITS - 1) { if (cur == STENCIL_BITS - 1) {
fillPolygons(m, start, cur, zoom, scale, div); fillPolygons(v, start, cur, zoom, scale, div);
start = cur = 0; start = cur = 0;
} }
} }
if (cur > 0) if (cur > 0)
fillPolygons(m, start, cur, zoom, scale, div); fillPolygons(v, start, cur, zoom, scale, div);
if (clipMode > 0) { if (clipMode > 0) {
if (first) { if (first) {
@ -347,8 +347,8 @@ public final class PolygonLayer extends RenderElement {
return l; return l;
} }
public static void clip(Matrices m) { public static void clip(GLViewport v) {
setShader(polyShader, m); setShader(polyShader, v);
drawStencilRegion(true, 1); drawStencilRegion(true, 1);
// disable writes to stencil buffer // disable writes to stencil buffer
@ -418,8 +418,8 @@ public final class PolygonLayer extends RenderElement {
* a quad with func 'always' and op 'zero'. Using 'color' * a quad with func 'always' and op 'zero'. Using 'color'
* and 'alpha' for a fake fade effect. * and 'alpha' for a fake fade effect.
*/ */
public static void drawOver(Matrices m, int color, float alpha) { public static void drawOver(GLViewport v, int color, float alpha) {
setShader(polyShader, m); setShader(polyShader, v);
if (color != 0) { if (color != 0) {
GLUtils.setColor(hPolygonColor[0], color, alpha); GLUtils.setColor(hPolygonColor[0], color, alpha);

View File

@ -23,8 +23,8 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.TextureItem.TexturePool; import org.oscim.renderer.elements.TextureItem.TexturePool;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -140,7 +140,7 @@ public abstract class TextureLayer extends RenderElement {
pool.init(0); pool.init(0);
} }
public static RenderElement draw(RenderElement l, Matrices m, float scale) { public static RenderElement draw(RenderElement l, GLViewport v, float scale) {
GLState.test(false, false); GLState.test(false, false);
GLState.blend(true); GLState.blend(true);
@ -156,8 +156,8 @@ public abstract class TextureLayer extends RenderElement {
else else
GL.glUniform1f(hTextureScale, 1); GL.glUniform1f(hTextureScale, 1);
m.proj.setAsUniform(hTextureProjMatrix); v.proj.setAsUniform(hTextureProjMatrix);
m.mvp.setAsUniform(hTextureMVMatrix); v.mvp.setAsUniform(hTextureMVMatrix);
MapRenderer.bindQuadIndicesVBO(true); MapRenderer.bindQuadIndicesVBO(true);

View File

@ -20,9 +20,8 @@ import java.util.Arrays;
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.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
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;
@ -131,10 +130,10 @@ public class AtlasRenderLayer extends ElementRenderer {
boolean initial = true; boolean initial = true;
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices m) { protected void update(GLViewport v) {
if (initial) { if (initial) {
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
initial = false; initial = false;
compile(); compile();

View File

@ -4,10 +4,9 @@ import java.util.List;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.Point; import org.oscim.core.Point;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.theme.styles.Line; import org.oscim.theme.styles.Line;
import org.oscim.utils.geom.BezierPath; import org.oscim.utils.geom.BezierPath;
@ -61,10 +60,10 @@ public class BezierPathLayer extends ElementRenderer {
} }
@Override @Override
protected synchronized void update(MapPosition pos, boolean changed, Matrices m) { protected synchronized void update(GLViewport v) {
if (mMapPosition.scale == 0) if (mMapPosition.scale == 0)
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
if (!isReady()) { if (!isReady()) {
compile(); compile();

View File

@ -25,8 +25,8 @@ import org.oscim.core.MapPosition;
import org.oscim.map.Map; import org.oscim.map.Map;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer; import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
/* /*
* This is an example how to integrate custom OpenGL drawing routines as map overlay * This is an example how to integrate custom OpenGL drawing routines as map overlay
@ -60,7 +60,7 @@ public class CustomRenderer extends LayerRenderer {
// ---------- everything below runs in GLRender Thread ---------- // ---------- everything below runs in GLRender Thread ----------
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) { protected void update(GLViewport v) {
if (!mInitialized) { if (!mInitialized) {
if (!init()) if (!init())
return; return;
@ -68,7 +68,7 @@ public class CustomRenderer extends LayerRenderer {
mInitialized = true; mInitialized = true;
// fix current MapPosition // fix current MapPosition
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
compile(); compile();
} }
@ -85,7 +85,7 @@ public class CustomRenderer extends LayerRenderer {
} }
@Override @Override
protected void render(MapPosition pos, Matrices m) { protected void render(GLViewport v) {
// Use the program object // Use the program object
GLState.useProgram(mProgramObject); GLState.useProgram(mProgramObject);
@ -110,9 +110,9 @@ public class CustomRenderer extends LayerRenderer {
float ratio = 1f / mMap.getWidth(); float ratio = 1f / mMap.getWidth();
m.mvp.setScale(ratio, ratio, 1); v.mvp.setScale(ratio, ratio, 1);
m.mvp.multiplyLhs(m.proj); v.mvp.multiplyLhs(v.proj);
m.mvp.setAsUniform(hMatrixPosition); v.mvp.setAsUniform(hMatrixPosition);
// Draw the triangle // Draw the triangle
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4); GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, 4);

View File

@ -20,13 +20,12 @@ import java.nio.FloatBuffer;
import org.oscim.backend.GL20; import org.oscim.backend.GL20;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLState; import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils; import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
/* /*
@ -52,7 +51,7 @@ public class CustomRenderer2 extends ElementRenderer {
float mCellScale = 60 * MapRenderer.COORD_SCALE; float mCellScale = 60 * MapRenderer.COORD_SCALE;
@Override @Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) { protected void update(GLViewport v) {
if (!mInitialized) { if (!mInitialized) {
if (!init()) if (!init())
return; return;
@ -67,9 +66,9 @@ public class CustomRenderer2 extends ElementRenderer {
} }
if (mZoom != pos.zoomLevel) { if (mZoom != v.pos.zoomLevel) {
mMapPosition.copy(pos); mMapPosition.copy(v.pos);
mZoom = pos.zoomLevel; mZoom = v.pos.zoomLevel;
} }
} }
@ -92,7 +91,7 @@ public class CustomRenderer2 extends ElementRenderer {
} }
@Override @Override
protected void render(MapPosition pos, Matrices m) { protected void render(GLViewport v) {
// Use the program object // Use the program object
GLState.useProgram(mProgramObject); GLState.useProgram(mProgramObject);
@ -111,8 +110,8 @@ public class CustomRenderer2 extends ElementRenderer {
/* apply view and projection matrices */ /* apply view and projection matrices */
// set mvp (tmp) matrix relative to mMapPosition // set mvp (tmp) matrix relative to mMapPosition
// i.e. fixed on the map // i.e. fixed on the map
setMatrix(pos, m); setMatrix(v);
m.mvp.setAsUniform(hMatrixPosition); v.mvp.setAsUniform(hMatrixPosition);
final int offset_x = 4; final int offset_x = 4;
final int offset_y = 16; final int offset_y = 16;

View File

@ -17,9 +17,8 @@
package org.oscim.renderer.test; package org.oscim.renderer.test;
import org.oscim.backend.CanvasAdapter; import org.oscim.backend.CanvasAdapter;
import org.oscim.core.MapPosition;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.MapRenderer.Matrices; import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.SymbolItem; import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.SymbolLayer; import org.oscim.renderer.elements.SymbolLayer;
@ -43,10 +42,10 @@ public class SymbolRenderLayer extends ElementRenderer {
} }
@Override @Override
protected void update(MapPosition position, boolean changed, Matrices matrices) { protected void update(GLViewport v) {
if (initialize) { if (initialize) {
initialize = false; initialize = false;
mMapPosition.copy(position); mMapPosition.copy(v.pos);
compile(); compile();
} }
} }

View File

@ -31,9 +31,9 @@ import org.oscim.core.Tile;
import org.oscim.renderer.BufferObject; import org.oscim.renderer.BufferObject;
import org.oscim.renderer.ElementRenderer; import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLMatrix; import org.oscim.renderer.GLMatrix;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer; import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.MapRenderer; import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.BitmapLayer; import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.LineLayer; import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.LineTexLayer; import org.oscim.renderer.elements.LineTexLayer;
@ -76,7 +76,6 @@ public class TileRenderer extends LayerRenderer {
private int mClipMode; private int mClipMode;
private GLMatrix mViewProj = new GLMatrix(); private GLMatrix mViewProj = new GLMatrix();
private Matrices mMatrices;
/** /**
* Threadsafe * Threadsafe
@ -96,7 +95,7 @@ public class TileRenderer extends LayerRenderer {
* synced with clearTiles, setOverdrawColor and setBitmapAlpha * synced with clearTiles, setOverdrawColor and setBitmapAlpha
*/ */
@Override @Override
protected synchronized void update(MapPosition pos, boolean changed, Matrices m) { protected synchronized void update(GLViewport v) {
if (mAlpha == 0) { if (mAlpha == 0) {
mTileManager.releaseTiles(mDrawTiles); mTileManager.releaseTiles(mDrawTiles);
@ -118,16 +117,16 @@ public class TileRenderer extends LayerRenderer {
/* discard depth projection from tilt, depth buffer /* discard depth projection from tilt, depth buffer
* is used for clipping */ * is used for clipping */
mViewProj.copy(m.proj); mViewProj.copy(v.proj);
mViewProj.setValue(10, 0); mViewProj.setValue(10, 0);
mViewProj.setValue(14, 0); mViewProj.setValue(14, 0);
mViewProj.multiplyRhs(m.view); mViewProj.multiplyRhs(v.view);
int tileCnt = mDrawTiles.cnt; int tileCnt = mDrawTiles.cnt;
MapTile[] tiles = mDrawTiles.tiles; MapTile[] tiles = mDrawTiles.tiles;
if (tilesChanged || changed) { if (tilesChanged || v.changed()) {
updateTileVisibility(pos, m.plane); updateTileVisibility(v.pos, v.plane);
} }
tileCnt += mNumTileHolder; tileCnt += mNumTileHolder;
@ -138,7 +137,6 @@ public class TileRenderer extends LayerRenderer {
BufferObject.checkBufferUsage(false); BufferObject.checkBufferUsage(false);
} }
mMatrices = m;
mClipMode = 1; mClipMode = 1;
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
@ -153,7 +151,7 @@ public class TileRenderer extends LayerRenderer {
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible && t.state == READY) if (t.isVisible && t.state == READY)
drawTile(t, pos); drawTile(t, v);
} }
@ -167,15 +165,15 @@ public class TileRenderer extends LayerRenderer {
GL.glDepthFunc(GL20.GL_LESS); GL.glDepthFunc(GL20.GL_LESS);
/* draw child or parent proxies */ /* draw child or parent proxies */
boolean preferParent = (pos.getZoomScale() < 1.5) boolean preferParent = (v.pos.getZoomScale() < 1.5)
|| (pos.zoomLevel < tiles[0].zoomLevel); || (v.pos.zoomLevel < tiles[0].zoomLevel);
for (int i = 0; i < tileCnt; i++) { for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i]; MapTile t = tiles[i];
if (t.isVisible if (t.isVisible
&& (t.state != READY) && (t.state != READY)
&& (t.holder == null)) { && (t.holder == null)) {
drawProxyTile(t, pos, true, preferParent); drawProxyTile(t, v, true, preferParent);
} }
} }
@ -185,7 +183,7 @@ public class TileRenderer extends LayerRenderer {
if (t.isVisible if (t.isVisible
&& (t.state != READY) && (t.state != READY)
&& (t.holder == null)) && (t.holder == null))
drawProxyTile(t, pos, false, false); drawProxyTile(t, v, false, false);
} }
GL.glDepthMask(false); GL.glDepthMask(false);
} }
@ -194,11 +192,10 @@ public class TileRenderer extends LayerRenderer {
GL.glStencilMask(0x00); GL.glStencilMask(0x00);
mDrawSerial++; mDrawSerial++;
mMatrices = null;
} }
@Override @Override
protected void render(MapPosition position, Matrices matrices) { protected void render(GLViewport v) {
/* render in update() so that tiles cannot vanish in between. */ /* render in update() so that tiles cannot vanish in between. */
} }
@ -439,7 +436,7 @@ public class TileRenderer extends LayerRenderer {
return maxFade; return maxFade;
} }
private void drawTile(MapTile tile, MapPosition pos) { private void drawTile(MapTile tile, GLViewport v) {
/* ensure to draw parents only once */ /* ensure to draw parents only once */
if (tile.lastDraw == mDrawSerial) if (tile.lastDraw == mDrawSerial)
return; return;
@ -454,7 +451,7 @@ public class TileRenderer extends LayerRenderer {
return; return;
t.layers.vbo.bind(); t.layers.vbo.bind();
MapPosition pos = v.pos;
/* place tile relative to map position */ /* place tile relative to map position */
int z = tile.zoomLevel; int z = tile.zoomLevel;
float div = FastMath.pow(z - pos.zoomLevel); float div = FastMath.pow(z - pos.zoomLevel);
@ -465,9 +462,9 @@ public class TileRenderer extends LayerRenderer {
/* scale relative to zoom-level of this tile */ /* scale relative to zoom-level of this tile */
float scale = (float) (pos.scale / (1 << z)); float scale = (float) (pos.scale / (1 << z));
Matrices m = mMatrices; //GLViewport v = mMatrices;
m.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE); v.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
m.mvp.multiplyLhs(mViewProj); v.mvp.multiplyLhs(mViewProj);
boolean clipped = false; boolean clipped = false;
int mode = mClipMode; int mode = mClipMode;
@ -475,25 +472,25 @@ public class TileRenderer extends LayerRenderer {
while (l != null) { while (l != null) {
if (l.type == POLYGON) { if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(l, m, pos, div, !clipped, mode); l = PolygonLayer.Renderer.draw(l, v, div, !clipped, mode);
clipped = true; clipped = true;
continue; continue;
} }
if (!clipped) { if (!clipped) {
/* draw stencil buffer clip region */ /* draw stencil buffer clip region */
PolygonLayer.Renderer.draw(null, m, pos, div, true, mode); PolygonLayer.Renderer.draw(null, v, div, true, mode);
clipped = true; clipped = true;
} }
if (l.type == LINE) { if (l.type == LINE) {
l = LineLayer.Renderer.draw(l, m, pos, scale, t.layers); l = LineLayer.Renderer.draw(l, v, scale, t.layers);
continue; continue;
} }
if (l.type == TEXLINE) { if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(l, m, pos, div, t.layers); l = LineTexLayer.Renderer.draw(l, v, div, t.layers);
continue; continue;
} }
if (l.type == MESH) { if (l.type == MESH) {
l = MeshLayer.Renderer.draw(l, m, pos); l = MeshLayer.Renderer.draw(l, v);
continue; continue;
} }
/* just in case */ /* just in case */
@ -503,11 +500,11 @@ public class TileRenderer extends LayerRenderer {
l = t.layers.getTextureLayers(); l = t.layers.getTextureLayers();
while (l != null) { while (l != null) {
if (!clipped) { if (!clipped) {
PolygonLayer.Renderer.draw(null, m, pos, div, true, mode); PolygonLayer.Renderer.draw(null, v, div, true, mode);
clipped = true; clipped = true;
} }
if (l.type == BITMAP) { if (l.type == BITMAP) {
l = BitmapLayer.Renderer.draw(l, m, 1, mRenderAlpha); l = BitmapLayer.Renderer.draw(l, v, 1, mRenderAlpha);
continue; continue;
} }
l = l.next; l = l.next;
@ -518,25 +515,25 @@ public class TileRenderer extends LayerRenderer {
if (debugOverdraw) { if (debugOverdraw) {
if (t.zoomLevel > pos.zoomLevel) if (t.zoomLevel > pos.zoomLevel)
PolygonLayer.Renderer.drawOver(m, Color.BLUE, 0.5f); PolygonLayer.Renderer.drawOver(v, Color.BLUE, 0.5f);
else if (t.zoomLevel < pos.zoomLevel) else if (t.zoomLevel < pos.zoomLevel)
PolygonLayer.Renderer.drawOver(m, Color.RED, 0.5f); PolygonLayer.Renderer.drawOver(v, Color.RED, 0.5f);
else else
PolygonLayer.Renderer.drawOver(m, Color.GREEN, 0.5f); PolygonLayer.Renderer.drawOver(v, Color.GREEN, 0.5f);
return; return;
} }
if (mRenderOverdraw != 0 && MapRenderer.frametime - t.fadeTime < FADE_TIME) { if (mRenderOverdraw != 0 && MapRenderer.frametime - t.fadeTime < FADE_TIME) {
float fade = 1 - (MapRenderer.frametime - t.fadeTime) / FADE_TIME; float fade = 1 - (MapRenderer.frametime - t.fadeTime) / FADE_TIME;
PolygonLayer.Renderer.drawOver(m, mRenderOverdraw, fade * fade); PolygonLayer.Renderer.drawOver(v, mRenderOverdraw, fade * fade);
MapRenderer.animate(); MapRenderer.animate();
} else { } else {
PolygonLayer.Renderer.drawOver(m, 0, 1); PolygonLayer.Renderer.drawOver(v, 0, 1);
} }
} }
private int drawProxyChild(MapTile tile, MapPosition pos) { private int drawProxyChild(MapTile tile, GLViewport v) {
int drawn = 0; int drawn = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
if ((tile.proxies & 1 << i) == 0) if ((tile.proxies & 1 << i) == 0)
@ -545,14 +542,14 @@ public class TileRenderer extends LayerRenderer {
MapTile c = tile.node.child(i); MapTile c = tile.node.child(i);
if (c.state == READY) { if (c.state == READY) {
drawTile(c, pos); drawTile(c, v);
drawn++; drawn++;
} }
} }
return drawn; return drawn;
} }
protected void drawProxyTile(MapTile tile, MapPosition pos, protected void drawProxyTile(MapTile tile, GLViewport v,
boolean parent, boolean preferParent) { boolean parent, boolean preferParent) {
TileNode r = tile.node; TileNode r = tile.node;
@ -560,7 +557,7 @@ public class TileRenderer extends LayerRenderer {
if (!preferParent) { if (!preferParent) {
/* prefer drawing children */ /* prefer drawing children */
if (drawProxyChild(tile, pos) == 4) if (drawProxyChild(tile, v) == 4)
return; return;
if (parent) { if (parent) {
@ -569,7 +566,7 @@ public class TileRenderer extends LayerRenderer {
proxy = r.parent.item; proxy = r.parent.item;
if (proxy.state == READY) { if (proxy.state == READY) {
//log.debug("1. draw parent " + proxy); //log.debug("1. draw parent " + proxy);
drawTile(proxy, pos); drawTile(proxy, v);
} }
} }
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
@ -582,7 +579,7 @@ public class TileRenderer extends LayerRenderer {
proxy = r.parent.parent.item; proxy = r.parent.parent.item;
if (proxy.state == READY) if (proxy.state == READY)
drawTile(proxy, pos); drawTile(proxy, v);
} }
} else { } else {
/* prefer drawing parent */ /* prefer drawing parent */
@ -591,12 +588,12 @@ public class TileRenderer extends LayerRenderer {
proxy = r.parent.item; proxy = r.parent.item;
if (proxy != null && proxy.state == READY) { if (proxy != null && proxy.state == READY) {
//log.debug("2. draw parent " + proxy); //log.debug("2. draw parent " + proxy);
drawTile(proxy, pos); drawTile(proxy, v);
return; return;
} }
} }
drawProxyChild(tile, pos); drawProxyChild(tile, v);
} else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
/* check if parent was already drawn */ /* check if parent was already drawn */
@ -606,12 +603,12 @@ public class TileRenderer extends LayerRenderer {
return; return;
} }
/* this will do nothing, just to check */ /* this will do nothing, just to check */
if (drawProxyChild(tile, pos) > 0) if (drawProxyChild(tile, v) > 0)
return; return;
proxy = r.parent.parent.item; proxy = r.parent.parent.item;
if (proxy.state == READY) if (proxy.state == READY)
drawTile(proxy, pos); drawTile(proxy, v);
} }
} }
} }