diff --git a/src/org/oscim/renderer/BaseLayer.java b/src/org/oscim/renderer/BaseMap.java similarity index 76% rename from src/org/oscim/renderer/BaseLayer.java rename to src/org/oscim/renderer/BaseMap.java index 5f263ae8..a4c4c3a7 100644 --- a/src/org/oscim/renderer/BaseLayer.java +++ b/src/org/oscim/renderer/BaseMap.java @@ -30,8 +30,8 @@ import android.opengl.Matrix; /** * @author Hannes Janetzek */ -public class BaseLayer { - private final static String TAG = BaseLayer.class.getName(); +public class BaseMap { + private final static String TAG = BaseMap.class.getName(); // used to not draw a tile twice per frame. private static int mDrawSerial = 0; @@ -47,10 +47,14 @@ public class BaseLayer { mfProjMatrix[14] = 0; } + private static int mDrawCnt; + static void draw(MapTile[] tiles, int tileCnt, MapPosition pos) { //long start = SystemClock.uptimeMillis(); Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0); + mDrawCnt = 0; + GLES20.glEnable(GL_POLYGON_OFFSET_FILL); LineRenderer.beginLines(); for (int i = 0; i < tileCnt; i++) { @@ -66,8 +70,15 @@ public class BaseLayer { for (int i = 0; i < tileCnt; i++) { MapTile t = tiles[i]; if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) - drawProxyTile(t, pos); + drawProxyTile(t, pos, true); } + + for (int i = 0; i < tileCnt; i++) { + MapTile t = tiles[i]; + if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) + drawProxyTile(t, pos, false); + } + LineRenderer.endLines(); GLES20.glDisable(GL_POLYGON_OFFSET_FILL); @@ -106,7 +117,8 @@ public class BaseLayer { Matrix.multiplyMM(mvp, 0, mVPMatrix, 0, mvp, 0); // set depth offset (used for clipping to tile boundaries) - GLES20.glPolygonOffset(-1, -GLRenderer.depthOffset(t)); + //GLES20.glPolygonOffset(-1, -GLRenderer.depthOffset(t)); + GLES20.glPolygonOffset(-1, (mDrawCnt++)); GLES20.glBindBuffer(GL_ARRAY_BUFFER, t.vbo.id); @@ -148,7 +160,7 @@ public class BaseLayer { // } } - private static boolean drawProxyChild(MapTile tile, MapPosition pos) { + private static int drawProxyChild(MapTile tile, MapPosition pos) { int drawn = 0; for (int i = 0; i < 4; i++) { if ((tile.proxies & 1 << i) == 0) @@ -161,45 +173,63 @@ public class BaseLayer { drawn++; } } - return drawn == 4; + return drawn; } - private static void drawProxyTile(MapTile tile, MapPosition pos) { + private static void drawProxyTile(MapTile tile, MapPosition pos, boolean parent) { int diff = pos.zoomLevel - tile.zoomLevel; - boolean drawn = false; if (pos.scale > 1.5f || diff < 0) { // prefer drawing children - if (!drawProxyChild(tile, pos)) { + if (drawProxyChild(tile, pos) == 4) + return; + + if (parent) { + // draw parent proxy if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { MapTile t = tile.rel.parent.tile; - if (t.state == STATE_READY) { - drawTile(t, pos); - drawn = true; - } - } - - if (!drawn && (tile.proxies & MapTile.PROXY_GRAMPA) != 0) { - MapTile t = tile.rel.parent.parent.tile; if (t.state == STATE_READY) drawTile(t, pos); - } + } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { + // check if parent was already drawn + if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { + MapTile t = tile.rel.parent.tile; + if (t.state == STATE_READY) + return; + } + + MapTile t = tile.rel.parent.parent.tile; + if (t.state == STATE_READY) + drawTile(t, pos); } } else { // prefer drawing parent - MapTile t = tile.rel.parent.tile; + if (parent) { + MapTile t = tile.rel.parent.tile; - if (t != null && t.state == STATE_READY) { - drawTile(t, pos); + if (t != null && t.state == STATE_READY) { + drawTile(t, pos); + return; - } else if (!drawProxyChild(tile, pos)) { - - if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { - t = tile.rel.parent.parent.tile; - if (t.state == STATE_READY) - drawTile(t, pos); } + + drawProxyChild(tile, pos); + + } else if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) { + // check if parent was already drawn + if ((tile.proxies & MapTile.PROXY_PARENT) != 0) { + MapTile t = tile.rel.parent.tile; + if (t.state == STATE_READY) + return; + } + // this will do nothing, just to check + if (drawProxyChild(tile, pos) > 0) + return; + + MapTile t = tile.rel.parent.parent.tile; + if (t.state == STATE_READY) + drawTile(t, pos); } } } diff --git a/src/org/oscim/renderer/GLRenderer.java b/src/org/oscim/renderer/GLRenderer.java index e0b68420..495292e8 100644 --- a/src/org/oscim/renderer/GLRenderer.java +++ b/src/org/oscim/renderer/GLRenderer.java @@ -82,7 +82,8 @@ public class GLRenderer implements GLSurfaceView.Renderer { private static float[] mTileCoords = new float[8]; private static float[] mDebugCoords = new float[8]; - private static float[] mClearColor = null; + //private + static float[] mClearColor = null; private static boolean mUpdateColor = false; // drawlock to synchronize Main- and GL-Thread @@ -339,12 +340,14 @@ public class GLRenderer implements GLSurfaceView.Renderer { if (mUpdateColor) { float cc[] = mClearColor; GLES20.glClearColor(cc[0], cc[1], cc[2], cc[3]); + //GLES20.glClearColor(0.8f, 0.8f, 0.8f, 1); mUpdateColor = false; } // Note: it seems faster to also clear the stencil buffer even // when not needed. probaly otherwise it is masked out from the // depth buffer as they share the same memory region afaik + // or for a better reason see OpenGL Insights chapter 23. GLES20.glDepthMask(true); GLES20.glStencilMask(0xFF); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT @@ -457,7 +460,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { overlays.get(i).update(mMapPosition, changed, tilesChanged); /* draw base layer */ - BaseLayer.draw(tiles, tileCnt, pos); + BaseMap.draw(tiles, tileCnt, pos); // start drawing while overlays uploading textures, etc GLES20.glFlush(); @@ -470,6 +473,7 @@ public class GLRenderer implements GLSurfaceView.Renderer { for (int i = 0, n = overlays.size(); i < n; i++) { RenderOverlay renderOverlay = overlays.get(i); + // helper to compile layers into single vbo if (renderOverlay.newData) { if (renderOverlay.vbo == null) { renderOverlay.vbo = BufferObject.get(); @@ -477,7 +481,6 @@ public class GLRenderer implements GLSurfaceView.Renderer { if (renderOverlay.vbo == null) continue; } - if (uploadOverlayData(renderOverlay)) renderOverlay.isReady = true; } @@ -562,9 +565,11 @@ public class GLRenderer implements GLSurfaceView.Renderer { Matrix.multiplyMM(mProjMatrix, 0, mMVPMatrix, 0, mProjMatrix, 0); } - BaseLayer.setProjection(mProjMatrix); + BaseMap.setProjection(mProjMatrix); GLES20.glViewport(0, 0, width, height); + //GLES20.glScissor(0, 0, width, height); + //GLES20.glEnable(GLES20.GL_SCISSOR_TEST); if (!mNewSurface) { mMapView.redrawMap();