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

View File

@ -19,8 +19,8 @@ package org.oscim.layers;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;
import org.oscim.map.Map.UpdateListener;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.LayerRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -32,7 +32,7 @@ public class CustomRenderLayer extends Layer implements UpdateListener {
// functions running on MapRender Thread
@Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
protected void update(GLViewport v) {
int currentState;
synchronized (this) {
@ -48,7 +48,7 @@ public class CustomRenderLayer extends Layer implements UpdateListener {
}
@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.map.Map;
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.LineLayer;
import org.oscim.theme.styles.Line;
@ -194,10 +194,10 @@ public class PathLayer extends Layer {
private int mCurZ = -1;
@Override
public synchronized void update(MapPosition pos, boolean changed, Matrices m) {
int tz = 1 << pos.zoomLevel;
int tx = (int) (pos.x * tz);
int ty = (int) (pos.y * tz);
public synchronized void update(GLViewport v) {
int tz = 1 << v.pos.zoomLevel;
int tx = (int) (v.pos.x * tz);
int ty = (int) (v.pos.y * tz);
// update layers when map moved by at least one tile
if ((tx != mCurX || ty != mCurY || tz != mCurZ) || mUpdatePoints) {

View File

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

View File

@ -16,11 +16,10 @@
*/
package org.oscim.layers.tile.vector;
import org.oscim.core.MapPosition;
import org.oscim.layers.Layer;
import org.oscim.map.Map;
import org.oscim.renderer.ExtrusionRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.GLViewport;
import org.oscim.utils.FastMath;
public class BuildingLayer extends Layer {
@ -34,9 +33,9 @@ public class BuildingLayer extends Layer {
private long mStartTime;
@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 (mAlpha < 1) {
@ -66,7 +65,7 @@ public class BuildingLayer extends Layer {
mStartTime = 0;
}
//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.core.MapPosition;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem;
@ -79,7 +79,7 @@ class Debug {
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) {
// //setMatrix(pos, m, true);
//

View File

@ -30,11 +30,10 @@ package org.oscim.layers.tile.vector.labeling;
// 5 QuadTree might be handy
//
import org.oscim.core.MapPosition;
import org.oscim.layers.tile.vector.labeling.LabelLayer.Worker;
import org.oscim.renderer.ElementRenderer;
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.TextureLayer;
import org.slf4j.Logger;
@ -53,8 +52,7 @@ class TextRenderer extends ElementRenderer {
long lastDraw = 0;
@Override
public synchronized void update(MapPosition pos, boolean changed,
Matrices matrices) {
public synchronized void update(GLViewport v) {
LabelTask t;
synchronized (mWorker) {
@ -75,18 +73,18 @@ class TextRenderer extends ElementRenderer {
}
@Override
public synchronized void render(MapPosition pos, Matrices m) {
public synchronized void render(GLViewport v) {
GLState.test(false, false);
//Debug.draw(pos, layers);
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;)
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;
public Map() {
mViewport = new ViewController(this);
mAnimator = new Animator(this, mViewport);
mViewport = new ViewController();
mAnimator = new Animator(this);
mLayers = new Layers(this);
mAsyncExecutor = new AsyncExecutor(2);
mMapPosition = new MapPosition();
mEventLayer = new MapEventLayer(this);
mLayers.add(0, mEventLayer);
}
public MapEventLayer getEventLayer() {
@ -272,7 +272,6 @@ public abstract class Map {
boolean changed = false;
MapPosition pos = mMapPosition;
// get the current MapPosition
changed |= mViewport.getMapPosition(pos);
if (mUpdateListeners == null) {
@ -316,5 +315,4 @@ public abstract class Map {
public boolean handleGesture(Gesture g, MotionEvent e) {
return mLayers.handleGesture(g, e);
}
}

View File

@ -8,10 +8,6 @@ import org.oscim.utils.FastMath;
public class ViewController extends Viewport {
ViewController(Map map) {
super(map);
}
public synchronized void setScreenSize(int width, int height) {
mHeight = height;
mWidth = width;
@ -37,7 +33,7 @@ public class ViewController extends Viewport {
/* set inverse projection matrix (without scaling) */
mProjMatrix.get(tmp);
GLMatrix.invertM(tmp, 0, tmp, 0);
mProjMatrixI.set(tmp);
mProjMatrixInverse.set(tmp);
mProjMatrixUnscaled.copy(mProjMatrix);
@ -65,10 +61,10 @@ public class ViewController extends Viewport {
mPos.x = x;
mPos.y = y;
// clamp latitude
/* clamp latitude */
mPos.y = FastMath.clamp(mPos.y, 0, 1);
// wrap longitude
/* wrap longitude */
while (mPos.x > 1)
mPos.x -= 1;
while (mPos.x < 0)
@ -180,27 +176,27 @@ public class ViewController extends Viewport {
* 0. apply rotate
* 1. apply tilt */
mRotMatrix.setRotation(mPos.angle, 0, 0, 1);
mRotationMatrix.setRotation(mPos.angle, 0, 0, 1);
mTmpMatrix.setRotation(mPos.tilt, 1, 0, 0);
/* 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: */
/* invert scale */
mUnprojMatrix.setScale(mWidth, mWidth, 1);
/* invert rotation and tilt */
mTmpMatrix.transposeM(mRotMatrix);
mTmpMatrix.transposeM(mRotationMatrix);
/* (AB)^-1 = B^-1*A^-1, invert scale, tilt and rotation */
mTmpMatrix.multiplyLhs(mUnprojMatrix);
/* (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 mProjMatrixUnscaled = new GLMatrix();
protected final GLMatrix mProjMatrixI = new GLMatrix();
protected final GLMatrix mRotMatrix = new GLMatrix();
protected final GLMatrix mProjMatrixInverse = new GLMatrix();
protected final GLMatrix mRotationMatrix = 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 mTmpMatrix = new GLMatrix();
@ -71,7 +71,7 @@ public class Viewport {
/** scale map plane at VIEW_DISTANCE to near plane */
public final static float VIEW_SCALE = (VIEW_NEAR / VIEW_DISTANCE) * 0.5f;
Viewport(Map map) {
protected Viewport() {
mPos.scale = MIN_SCALE;
mPos.x = 0.5;
mPos.y = 0.5;
@ -83,7 +83,9 @@ public class Viewport {
* Get the current MapPosition.
*
* @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) {
@ -104,24 +106,6 @@ public class Viewport {
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
* 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
* and the map plane */
* and the map plane
*/
protected float getDepth(float y) {
if (y == 0)
return 0;
@ -208,11 +194,10 @@ public class Viewport {
public synchronized BoundingBox getBBox(int expand) {
getBBox(mMapBBox, expand);
// scale map-pixel coordinates at current scale to
// absolute coordinates and apply mercator projection.
/* scale map-pixel coordinates at current scale to
* absolute coordinates and apply mercator projection. */
double minLon = MercatorProjection.toLongitude(mMapBBox.minX);
double maxLon = MercatorProjection.toLongitude(mMapBBox.maxX);
// sic(k)
double minLat = MercatorProjection.toLatitude(mMapBBox.maxY);
double maxLat = MercatorProjection.toLatitude(mMapBBox.minY);
@ -334,9 +319,26 @@ public class Viewport {
mv[2] = 0;
mv[3] = 1;
mVPMatrix.prj(mv);
mViewProjMatrix.prj(mv);
out.x = (mv[0] * (mWidth / 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;
import org.oscim.backend.canvas.Bitmap;
import org.oscim.core.MapPosition;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.BitmapLayer;
/**
@ -56,7 +54,7 @@ public class BitmapRenderer extends ElementRenderer {
}
@Override
protected synchronized void update(MapPosition pos, boolean changed, Matrices m) {
protected synchronized void update(GLViewport v) {
if (!initialized) {
layers.clear();
@ -84,8 +82,8 @@ public class BitmapRenderer extends ElementRenderer {
}
@Override
protected synchronized void render(MapPosition pos, Matrices m) {
m.useScreenCoordinates(false, 8);
BitmapLayer.Renderer.draw(layers.getTextureLayers(), m, 1, 1);
protected synchronized void render(GLViewport v) {
v.useScreenCoordinates(false, 8);
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.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.BitmapLayer;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.LineLayer;
@ -78,35 +77,35 @@ public abstract class ElementRenderer extends LayerRenderer {
* Render all 'layers'
*/
@Override
protected synchronized void render(MapPosition pos, Matrices m) {
protected synchronized void render(GLViewport v) {
MapPosition layerPos = mMapPosition;
layers.vbo.bind();
GLState.test(false, false);
GLState.blend(true);
float div = (float) (pos.scale / layerPos.scale);
float div = (float) (v.pos.scale / layerPos.scale);
RenderElement l = layers.getBaseLayers();
if (l != null)
setMatrix(pos, m, true);
setMatrix(v, true);
while (l != null) {
if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(l, m, pos, 1, true, 0);
l = PolygonLayer.Renderer.draw(l, v, 1, true, 0);
continue;
}
if (l.type == LINE) {
l = LineLayer.Renderer.draw(l, m, pos, div, layers);
l = LineLayer.Renderer.draw(l, v, div, layers);
continue;
}
if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(l, m, pos, div, layers);
l = LineTexLayer.Renderer.draw(l, v, div, layers);
continue;
}
if (l.type == MESH) {
l = MeshLayer.Renderer.draw(l, m, pos);
l = MeshLayer.Renderer.draw(l, v);
continue;
}
log.debug("invalid layer {}", l.type);
@ -115,14 +114,14 @@ public abstract class ElementRenderer extends LayerRenderer {
l = layers.getTextureLayers();
if (l != null)
setMatrix(pos, m, false);
setMatrix(v, false);
while (l != null) {
if (l.type == BITMAP) {
l = BitmapLayer.Renderer.draw(l, m, 1, 1);
l = BitmapLayer.Renderer.draw(l, v, 1, 1);
continue;
}
if (l.type == SYMBOL) {
l = TextureLayer.Renderer.draw(l, m, div);
l = TextureLayer.Renderer.draw(l, v, div);
continue;
}
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
* are assumed to be scaled by MapRenderer.COORD_SCALE (== 8).
*
* @param position
* current MapPosition
* @param matrices
* current Matrices
* @param v
* GLViewport
* @param project
* 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;
double tileScale = Tile.SIZE * position.scale;
double tileScale = Tile.SIZE * v.pos.scale;
double x = oPos.x - position.x;
double y = oPos.y - position.y;
double x = oPos.x - v.pos.x;
double y = oPos.y - v.pos.y;
if (mFlipOnDateLine) {
//wrap around date-line
@ -207,23 +204,20 @@ public abstract class ElementRenderer extends LayerRenderer {
x -= 1.0;
}
matrices.mvp.setTransScale((float) (x * tileScale),
(float) (y * tileScale),
(float) (position.scale / oPos.scale)
/ MapRenderer.COORD_SCALE);
v.mvp.setTransScale((float) (x * tileScale),
(float) (y * tileScale),
(float) (v.pos.scale / oPos.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
* MapPosition and the last updated Overlay MapPosition and add
* matrices.viewproj
*
* @param position ...
* @param matrices ...
* MapPosition and the last updated Overlay MapPosition and applies
* view-projection-matrix.
*/
protected void setMatrix(MapPosition position, Matrices matrices) {
setMatrix(position, matrices, true);
protected void setMatrix(GLViewport v) {
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.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.ExtrusionLayer;
import org.oscim.tiling.MapTile;
import org.oscim.tiling.TileRenderer;
@ -91,7 +89,7 @@ public class ExtrusionRenderer extends LayerRenderer {
}
@Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
protected void update(GLViewport v) {
if (!initialized && !initShader())
return;
@ -99,7 +97,7 @@ public class ExtrusionRenderer extends LayerRenderer {
if (shaderProgram[0] == 0)
return;
if (mAlpha == 0 || pos.zoomLevel < 16) {
if (mAlpha == 0 || v.pos.zoomLevel < 16) {
setReady(false);
return;
}
@ -180,7 +178,7 @@ public class ExtrusionRenderer extends LayerRenderer {
private final boolean debug = false;
@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
// 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++) {
ExtrusionLayer el = tiles[i].layers.getExtrusionLayers();
setMatrix(pos, m, tiles[i], 0);
m.mvp.setAsUniform(uExtMatrix);
setMatrix(v, tiles[i], 0);
v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.bind();
el.vboVertices.bind();
@ -240,7 +238,7 @@ public class ExtrusionRenderer extends LayerRenderer {
GLState.useProgram(shaderProgram[SHADER]);
GLState.enableVertexArrays(uExtVertexPosition, -1);
if (pos.scale < (1 << 18)) {
if (v.pos.scale < (1 << 18)) {
// chances are high that one moves through a building
// with scale > 2 also draw back sides in this case.
GL.glEnable(GL20.GL_CULL_FACE);
@ -256,8 +254,8 @@ public class ExtrusionRenderer extends LayerRenderer {
MapTile t = tiles[i];
ExtrusionLayer el = t.layers.getExtrusionLayers();
int d = MapRenderer.depthOffset(t) * 10;
setMatrix(pos, m, t, d);
m.mvp.setAsUniform(uExtMatrix);
setMatrix(v, t, d);
v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.bind();
el.vboVertices.bind();
@ -292,8 +290,8 @@ public class ExtrusionRenderer extends LayerRenderer {
GL.glDepthFunc(GL20.GL_EQUAL);
int d = MapRenderer.depthOffset(t) * 10;
setMatrix(pos, m, t, d);
m.mvp.setAsUniform(uExtMatrix);
setMatrix(v, t, d);
v.mvp.setAsUniform(uExtMatrix);
el.vboIndices.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:
GL.glDepthFunc(GL20.GL_LEQUAL);
m.mvp.addDepthOffset(100);
m.mvp.setAsUniform(uExtMatrix);
v.mvp.addDepthOffset(100);
v.mvp.setAsUniform(uExtMatrix);
GL.glUniform1i(uExtMode, 3);
GL.glDrawElements(GL20.GL_LINES, el.mIndiceCnt[3],
@ -335,7 +333,7 @@ public class ExtrusionRenderer extends LayerRenderer {
tiles[i] = null;
}
if (pos.scale < (1 << 18))
if (v.pos.scale < (1 << 18))
GL.glDisable(GL20.GL_CULL_FACE);
GL.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, 0);
@ -343,15 +341,15 @@ public class ExtrusionRenderer extends LayerRenderer {
mTileLayer.releaseTiles(mTileSet);
}
private static void setMatrix(MapPosition pos, Matrices m,
private static void setMatrix(GLViewport m,
MapTile tile, int delta) {
int z = tile.zoomLevel;
double curScale = Tile.SIZE * pos.scale;
float scale = (float) (pos.scale / (1 << z));
double curScale = Tile.SIZE * m.pos.scale;
float scale = (float) (m.pos.scale / (1 << z));
float x = (float) ((tile.x - pos.x) * curScale);
float y = (float) ((tile.y - pos.y) * curScale);
float x = (float) ((tile.x - m.pos.x) * curScale);
float y = (float) ((tile.y - m.pos.y) * curScale);
m.mvp.setTransScale(x, y, scale / MapRenderer.COORD_SCALE);
// 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.Paint.Cap;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.Tile;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.LineLayer;
import org.oscim.renderer.elements.TextItem;
import org.oscim.renderer.elements.TextLayer;
@ -114,13 +112,13 @@ public class GridRenderer extends ElementRenderer {
}
@Override
protected void update(MapPosition pos, boolean changed, Matrices m) {
protected void update(GLViewport v) {
// scale coordinates relative to current 'zoom-level' to
// get the position as the nearest tile coordinate
int z = 1 << pos.zoomLevel;
int x = (int) (pos.x * z);
int y = (int) (pos.y * z);
int z = 1 << v.pos.zoomLevel;
int x = (int) (v.pos.x * z);
int y = (int) (v.pos.y * z);
// update layers when map moved by at least one tile
if (x == mCurX && y == mCurY && z == mCurZ)
@ -130,13 +128,13 @@ public class GridRenderer extends ElementRenderer {
mCurY = y;
mCurZ = z;
mMapPosition.copy(pos);
mMapPosition.copy(v.pos);
mMapPosition.x = (double) x / z;
mMapPosition.y = (double) y / z;
mMapPosition.scale = z;
if (mText != null) {
addLabels(x, y, pos.zoomLevel);
addLabels(x, y, v.pos.zoomLevel);
layers.setBaseLayers(mLineLayer);
mLineLayer.addLine(mLines);
compile();

View File

@ -17,8 +17,6 @@
package org.oscim.renderer;
import org.oscim.backend.GL20;
import org.oscim.core.MapPosition;
import org.oscim.renderer.MapRenderer.Matrices;
public abstract class LayerRenderer {
@ -64,8 +62,7 @@ public abstract class LayerRenderer {
* @param matrices contains the current view- and projection-matrices
* and 'mvp' matrix for temporary use.
*/
protected abstract void update(MapPosition position, boolean changed,
Matrices matrices);
protected abstract void update(GLViewport viewport);
/**
* 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-
* 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.GLAdapter;
import org.oscim.backend.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.map.Map;
import org.oscim.map.Viewport;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.tiling.MapTile;
import org.oscim.utils.pool.Inlist;
@ -42,55 +40,20 @@ public class MapRenderer {
/** scale factor used for short vertices */
public static final float COORD_SCALE = 8.0f;
public static int screenWidth, screenHeight;
private final Map mMap;
private final MapPosition mMapPosition;
private final GLViewport mViewport;
public class Matrices {
/** 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 float[] mClearColor;
private static int mQuadIndicesID;
private static int mQuadVerticesID;
public final static int maxQuads = 64;
private static volatile boolean mUpdateColor = false;
private static boolean mUpdateColor;
public static long frametime;
private static boolean rerender;
// 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
@ -138,9 +101,8 @@ public class MapRenderer {
public MapRenderer(Map map) {
mMap = map;
mMapPosition = new MapPosition();
mMatrices = new Matrices();
mViewport = new GLViewport();
mBufferPool = new BufferPool();
// FIXME should be done in 'destroy' method
@ -220,8 +182,6 @@ public class MapRenderer {
mUpdateColor = false;
}
// some GL implementation do not clear these
// buffers unless writes are enabled.
GL.glDepthMask(true);
GL.glStencilMask(0xFF);
@ -237,27 +197,14 @@ public class MapRenderer {
GLState.useProgram(-1);
mMap.animator().updateAnimation();
mViewport.setFrom(mMap.viewport());
MapPosition pos = mMapPosition;
Viewport viewport = mMap.viewport();
boolean changed = false;
synchronized (viewport) {
// get current MapPosition
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);
}
if (GLAdapter.debugView) {
// modify this to scale only the view, to see
// which tiles are rendered
mViewport.mvp.setScale(0.5f, 0.5f, 1);
mViewport.viewproj.multiplyLhs(mViewport.mvp);
mViewport.proj.multiplyLhs(mViewport.mvp);
}
/* update layers */
@ -271,10 +218,10 @@ public class MapRenderer {
renderer.isInitialized = true;
}
renderer.update(pos, changed, mMatrices);
renderer.update(mViewport);
if (renderer.isReady)
renderer.render(pos, mMatrices);
renderer.render(mViewport);
if (GLAdapter.debug)
GLUtils.checkGlError(renderer.getClass().getName());
@ -301,14 +248,12 @@ public class MapRenderer {
if (width <= 0 || height <= 0)
return;
screenWidth = width;
screenHeight = height;
mMap.viewport().getMatrix(null, mMatrices.proj, null);
//mMap.viewport().getMatrix(null, mMatrices.proj, null);
mViewport.initFrom(mMap.viewport());
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);
@ -413,8 +358,6 @@ public class MapRenderer {
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
* 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.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
/**
* 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");
}
public static RenderElement draw(RenderElement renderElement, Matrices m, float scale,
public static RenderElement draw(RenderElement renderElement, GLViewport v, float scale,
float alpha) {
//GLState.test(false, false);
GLState.blend(true);
@ -197,12 +197,12 @@ public class BitmapLayer extends TextureLayer {
else
GL.glUniform1f(hTextureScale, 1);
GL.glUniform1f(hTextureScreenScale, 1f / MapRenderer.screenWidth);
GL.glUniform1f(hTextureScreenScale, 1f / v.getWidth());
GL.glUniform1f(hAlpha, alpha);
m.proj.setAsUniform(hTextureProjMatrix);
v.proj.setAsUniform(hTextureProjMatrix);
m.mvp.setAsUniform(hTextureMVMatrix);
v.mvp.setAsUniform(hTextureMVMatrix);
MapRenderer.bindQuadIndicesVBO(true);

View File

@ -20,13 +20,12 @@ import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.core.Tile;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Line;
import org.oscim.utils.FastMath;
import org.oscim.utils.pool.Inlist;
@ -644,15 +643,15 @@ public final class LineLayer extends RenderElement {
return true;
}
public static RenderElement draw(RenderElement curLayer, Matrices m,
MapPosition pos, float scale, ElementLayers layers) {
public static RenderElement draw(RenderElement curLayer, GLViewport v,
float scale, ElementLayers layers) {
if (curLayer == null)
return null;
// simple line shader does not take forward shortening into
// 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.blend(true);
@ -675,7 +674,7 @@ public final class LineLayer extends RenderElement {
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
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-
// 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;
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);
} else if (line.fade > pos.zoomLevel) {
} else if (line.fade > v.pos.zoomLevel) {
continue;
} else {
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.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Line;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
@ -326,8 +325,8 @@ public final class LineTexLayer extends RenderElement {
private final static int STRIDE = 12;
private final static int LEN_OFFSET = 8;
public static RenderElement draw(RenderElement curLayer, Matrices m,
MapPosition pos, float div, ElementLayers layers) {
public static RenderElement draw(RenderElement curLayer, GLViewport v,
float div, ElementLayers layers) {
if (shader == 0)
return curLayer.next;
@ -343,7 +342,7 @@ public final class LineTexLayer extends RenderElement {
GL.glEnableVertexAttribArray(hVertexLength1);
GL.glEnableVertexAttribArray(hVertexFlip);
m.mvp.setAsUniform(hMatrix);
v.mvp.setAsUniform(hMatrix);
int maxIndices = MapRenderer.maxQuads * 6;
@ -355,7 +354,7 @@ public final class LineTexLayer extends RenderElement {
layers.vbo.bind();
float scale = (float) pos.getZoomScale();
float scale = (float) v.pos.getZoomScale();
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));"
+ " } "; //*/
/*
* final static String fragmentShader = ""
/* final static String fragmentShader = ""
* + "#extension GL_OES_standard_derivatives : enable\n"
* + " precision mediump float;"
* + " uniform sampler2D tex;"
@ -528,10 +526,8 @@ public final class LineTexLayer extends RenderElement {
* + " gl_FragColor = u_bgcolor * 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"
* + " precision mediump float;"
* + " uniform sampler2D tex;"
@ -550,8 +546,7 @@ public final class LineTexLayer extends RenderElement {
* + " float stipple_p = smoothstep(0.495, 0.505, dist);"
* +
* " 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.canvas.Color;
import org.oscim.core.GeometryBuffer;
import org.oscim.core.MapPosition;
import org.oscim.core.MercatorProjection;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.theme.styles.Area;
import org.oscim.utils.Tessellator;
import org.oscim.utils.pool.Inlist;
@ -123,8 +122,7 @@ public class MeshLayer extends RenderElement {
return true;
}
public static RenderElement draw(RenderElement l, Matrices m,
MapPosition pos) {
public static RenderElement draw(RenderElement l, GLViewport v) {
GLState.blend(true);
@ -132,7 +130,7 @@ public class MeshLayer extends RenderElement {
GLState.enableVertexArrays(hVertexPosition, -1);
m.mvp.setAsUniform(hMatrix);
v.mvp.setAsUniform(hMatrix);
float heightOffset = 0;
GL.glUniform1f(hHeightOffset, heightOffset);
@ -147,7 +145,7 @@ public class MeshLayer extends RenderElement {
heightOffset = ml.heightOffset;
GL.glUniform1f(hHeightOffset, heightOffset /
MercatorProjection.groundResolution(pos));
MercatorProjection.groundResolution(v.pos));
}
ml.indicesVbo.bind();

View File

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

View File

@ -23,8 +23,8 @@ import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.renderer.elements.TextureItem.TexturePool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -140,7 +140,7 @@ public abstract class TextureLayer extends RenderElement {
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.blend(true);
@ -156,8 +156,8 @@ public abstract class TextureLayer extends RenderElement {
else
GL.glUniform1f(hTextureScale, 1);
m.proj.setAsUniform(hTextureProjMatrix);
m.mvp.setAsUniform(hTextureMVMatrix);
v.proj.setAsUniform(hTextureProjMatrix);
v.mvp.setAsUniform(hTextureMVMatrix);
MapRenderer.bindQuadIndicesVBO(true);

View File

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

View File

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

View File

@ -25,8 +25,8 @@ import org.oscim.core.MapPosition;
import org.oscim.map.Map;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
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
@ -60,7 +60,7 @@ public class CustomRenderer extends LayerRenderer {
// ---------- everything below runs in GLRender Thread ----------
@Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
protected void update(GLViewport v) {
if (!mInitialized) {
if (!init())
return;
@ -68,7 +68,7 @@ public class CustomRenderer extends LayerRenderer {
mInitialized = true;
// fix current MapPosition
mMapPosition.copy(pos);
mMapPosition.copy(v.pos);
compile();
}
@ -85,7 +85,7 @@ public class CustomRenderer extends LayerRenderer {
}
@Override
protected void render(MapPosition pos, Matrices m) {
protected void render(GLViewport v) {
// Use the program object
GLState.useProgram(mProgramObject);
@ -110,9 +110,9 @@ public class CustomRenderer extends LayerRenderer {
float ratio = 1f / mMap.getWidth();
m.mvp.setScale(ratio, ratio, 1);
m.mvp.multiplyLhs(m.proj);
m.mvp.setAsUniform(hMatrixPosition);
v.mvp.setScale(ratio, ratio, 1);
v.mvp.multiplyLhs(v.proj);
v.mvp.setAsUniform(hMatrixPosition);
// Draw the triangle
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.canvas.Color;
import org.oscim.core.MapPosition;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.ElementRenderer;
import org.oscim.renderer.GLState;
import org.oscim.renderer.GLUtils;
import org.oscim.renderer.GLViewport;
import org.oscim.renderer.MapRenderer;
import org.oscim.renderer.MapRenderer.Matrices;
import org.oscim.utils.FastMath;
/*
@ -52,7 +51,7 @@ public class CustomRenderer2 extends ElementRenderer {
float mCellScale = 60 * MapRenderer.COORD_SCALE;
@Override
protected void update(MapPosition pos, boolean changed, Matrices matrices) {
protected void update(GLViewport v) {
if (!mInitialized) {
if (!init())
return;
@ -67,9 +66,9 @@ public class CustomRenderer2 extends ElementRenderer {
}
if (mZoom != pos.zoomLevel) {
mMapPosition.copy(pos);
mZoom = pos.zoomLevel;
if (mZoom != v.pos.zoomLevel) {
mMapPosition.copy(v.pos);
mZoom = v.pos.zoomLevel;
}
}
@ -92,7 +91,7 @@ public class CustomRenderer2 extends ElementRenderer {
}
@Override
protected void render(MapPosition pos, Matrices m) {
protected void render(GLViewport v) {
// Use the program object
GLState.useProgram(mProgramObject);
@ -111,8 +110,8 @@ public class CustomRenderer2 extends ElementRenderer {
/* apply view and projection matrices */
// set mvp (tmp) matrix relative to mMapPosition
// i.e. fixed on the map
setMatrix(pos, m);
m.mvp.setAsUniform(hMatrixPosition);
setMatrix(v);
v.mvp.setAsUniform(hMatrixPosition);
final int offset_x = 4;
final int offset_y = 16;

View File

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

View File

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