refactor: move rendering of base layers to separate class
- keep track of GL state in GLState
This commit is contained in:
parent
99ce02a9bd
commit
e50ea0c2ba
215
src/org/oscim/renderer/BaseLayer.java
Normal file
215
src/org/oscim/renderer/BaseLayer.java
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 OpenScienceMap
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer;
|
||||||
|
|
||||||
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
|
import static android.opengl.GLES20.GL_DEPTH_TEST;
|
||||||
|
import static android.opengl.GLES20.GL_POLYGON_OFFSET_FILL;
|
||||||
|
import static org.oscim.generator.JobTile.STATE_READY;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.layer.Layer;
|
||||||
|
import org.oscim.utils.FastMath;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
import android.opengl.Matrix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public class BaseLayer {
|
||||||
|
|
||||||
|
// used to not draw a tile twice per frame.
|
||||||
|
private static int mDrawSerial = 0;
|
||||||
|
private static float[] mMVPMatrix = new float[16];
|
||||||
|
|
||||||
|
private static float[] mVPMatrix = new float[16];
|
||||||
|
private static float[] mfProjMatrix = new float[16];
|
||||||
|
|
||||||
|
static void setProjection(float[] projMatrix) {
|
||||||
|
System.arraycopy(projMatrix, 0, mfProjMatrix, 0, 16);
|
||||||
|
// set to zero: we modify the z value with polygon-offset for clipping
|
||||||
|
mfProjMatrix[10] = 0;
|
||||||
|
mfProjMatrix[14] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw(MapTile[] tiles, int tileCnt, MapPosition pos) {
|
||||||
|
|
||||||
|
Matrix.multiplyMM(mVPMatrix, 0, mfProjMatrix, 0, pos.viewMatrix, 0);
|
||||||
|
|
||||||
|
/* draw base layer */
|
||||||
|
GLES20.glEnable(GL_DEPTH_TEST);
|
||||||
|
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
// mDrawCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.isVisible && t.state == STATE_READY)
|
||||||
|
drawTile(t, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// proxies are clipped to the region where nothing was drawn to depth
|
||||||
|
// buffer.
|
||||||
|
// TODO draw all parent before grandparent
|
||||||
|
// TODO draw proxies for placeholder...
|
||||||
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
||||||
|
drawProxyTile(t, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
GLES20.glDisable(GL_DEPTH_TEST);
|
||||||
|
mDrawSerial++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drawTile(MapTile tile, MapPosition pos) {
|
||||||
|
// draw parents only once
|
||||||
|
if (tile.lastDraw == mDrawSerial)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
||||||
|
|
||||||
|
tile.lastDraw = mDrawSerial;
|
||||||
|
|
||||||
|
float[] mvp = mMVPMatrix;
|
||||||
|
setMatrix(mvp, tile, div, pos);
|
||||||
|
|
||||||
|
if (tile.holder != null)
|
||||||
|
tile = tile.holder;
|
||||||
|
|
||||||
|
if (tile.layers == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLES20.glPolygonOffset(0, GLRenderer.depthOffset(tile));
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
||||||
|
|
||||||
|
boolean clipped = false;
|
||||||
|
int simpleShader = 0; // mRotate ? 0 : 1;
|
||||||
|
|
||||||
|
for (Layer l = tile.layers.layers; l != null;) {
|
||||||
|
|
||||||
|
switch (l.type) {
|
||||||
|
case Layer.POLYGON:
|
||||||
|
|
||||||
|
GLES20.glDisable(GL_BLEND);
|
||||||
|
l = PolygonRenderer.draw(pos, l, mvp, !clipped, true);
|
||||||
|
clipped = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Layer.LINE:
|
||||||
|
if (!clipped) {
|
||||||
|
PolygonRenderer.draw(pos, null, mvp, true, true);
|
||||||
|
clipped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glEnable(GL_BLEND);
|
||||||
|
l = LineRenderer.draw(pos, l, mvp, div, simpleShader,
|
||||||
|
tile.layers.lineOffset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (tile.layers.textureLayers != null) {
|
||||||
|
// setMatrix(mvp, tile, div, false);
|
||||||
|
//
|
||||||
|
// for (Layer l = tile.layers.textureLayers; l != null;) {
|
||||||
|
// l = TextureRenderer.draw(l, 1, mProjMatrix, mvp,
|
||||||
|
// tile.layers.texOffset);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setMatrix(float[] matrix, MapTile tile,
|
||||||
|
float div, MapPosition pos) {
|
||||||
|
|
||||||
|
float x = (float) (tile.pixelX - pos.x * div);
|
||||||
|
float y = (float) (tile.pixelY - pos.y * div);
|
||||||
|
float scale = pos.scale / div;
|
||||||
|
|
||||||
|
Matrix.setIdentityM(matrix, 0);
|
||||||
|
|
||||||
|
// translate relative to map center
|
||||||
|
matrix[12] = x * scale;
|
||||||
|
matrix[13] = y * scale;
|
||||||
|
|
||||||
|
// scale to tile to world coordinates
|
||||||
|
scale /= GLRenderer.COORD_MULTIPLIER;
|
||||||
|
matrix[0] = scale;
|
||||||
|
matrix[5] = scale;
|
||||||
|
|
||||||
|
// Matrix.multiplyMM(matrix, 0, pos.viewMatrix, 0, matrix, 0);
|
||||||
|
// Matrix.multiplyMM(matrix, 0, mfProjMatrix, 0, matrix, 0);
|
||||||
|
Matrix.multiplyMM(matrix, 0, mVPMatrix, 0, matrix, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean drawProxyChild(MapTile tile, MapPosition pos) {
|
||||||
|
int drawn = 0;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if ((tile.proxies & 1 << i) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MapTile c = tile.rel.child[i].tile;
|
||||||
|
|
||||||
|
if (c.state == STATE_READY) {
|
||||||
|
drawTile(c, pos);
|
||||||
|
drawn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return drawn == 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void drawProxyTile(MapTile tile, MapPosition pos) {
|
||||||
|
int diff = pos.zoomLevel - tile.zoomLevel;
|
||||||
|
|
||||||
|
boolean drawn = false;
|
||||||
|
if (pos.scale > 1.5f || diff < 0) {
|
||||||
|
// prefer drawing children
|
||||||
|
if (!drawProxyChild(tile, pos)) {
|
||||||
|
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 {
|
||||||
|
// prefer drawing parent
|
||||||
|
MapTile t = tile.rel.parent.tile;
|
||||||
|
|
||||||
|
if (t != null && t.state == STATE_READY) {
|
||||||
|
drawTile(t, pos);
|
||||||
|
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,11 +16,9 @@ package org.oscim.renderer;
|
|||||||
|
|
||||||
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
import static android.opengl.GLES20.GL_ARRAY_BUFFER;
|
||||||
import static android.opengl.GLES20.GL_BLEND;
|
import static android.opengl.GLES20.GL_BLEND;
|
||||||
import static android.opengl.GLES20.GL_DEPTH_TEST;
|
|
||||||
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
import static android.opengl.GLES20.GL_DYNAMIC_DRAW;
|
||||||
import static android.opengl.GLES20.GL_ONE;
|
import static android.opengl.GLES20.GL_ONE;
|
||||||
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
import static android.opengl.GLES20.GL_ONE_MINUS_SRC_ALPHA;
|
||||||
import static android.opengl.GLES20.GL_POLYGON_OFFSET_FILL;
|
|
||||||
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
import static org.oscim.generator.JobTile.STATE_NEW_DATA;
|
||||||
import static org.oscim.generator.JobTile.STATE_READY;
|
import static org.oscim.generator.JobTile.STATE_READY;
|
||||||
|
|
||||||
@ -35,7 +33,6 @@ import javax.microedition.khronos.opengles.GL10;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.layer.Layer;
|
|
||||||
import org.oscim.renderer.layer.Layers;
|
import org.oscim.renderer.layer.Layers;
|
||||||
import org.oscim.renderer.overlays.RenderOverlay;
|
import org.oscim.renderer.overlays.RenderOverlay;
|
||||||
import org.oscim.theme.RenderTheme;
|
import org.oscim.theme.RenderTheme;
|
||||||
@ -81,17 +78,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
|
|
||||||
private static float[] mMVPMatrix = new float[16];
|
private static float[] mMVPMatrix = new float[16];
|
||||||
private static float[] mProjMatrix = new float[16];
|
private static float[] mProjMatrix = new float[16];
|
||||||
// 'flat' projection used for clipping by depth buffer
|
|
||||||
private static float[] mfProjMatrix = new float[16];
|
|
||||||
private static float[] mTmpMatrix = new float[16];
|
private static float[] mTmpMatrix = new float[16];
|
||||||
private static float[] mTileCoords = new float[8];
|
private static float[] mTileCoords = new float[8];
|
||||||
private static float[] mDebugCoords = new float[8];
|
private static float[] mDebugCoords = new float[8];
|
||||||
|
|
||||||
private static float[] mClearColor = null;
|
private static float[] mClearColor = null;
|
||||||
|
|
||||||
// number of tiles drawn in one frame
|
|
||||||
//private static short mDrawCount = 0;
|
|
||||||
|
|
||||||
private static boolean mUpdateColor = false;
|
private static boolean mUpdateColor = false;
|
||||||
|
|
||||||
// drawlock to synchronize Main- and GL-Thread
|
// drawlock to synchronize Main- and GL-Thread
|
||||||
@ -108,14 +99,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
/* package */static int mHolderCount;
|
/* package */static int mHolderCount;
|
||||||
/* package */static TileSet mDrawTiles;
|
/* package */static TileSet mDrawTiles;
|
||||||
|
|
||||||
static boolean[] vertexArray = { false, false };
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
final class GLState {
|
|
||||||
boolean blend = false;
|
|
||||||
boolean depth = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// scanline fill class used to check tile visibility
|
// scanline fill class used to check tile visibility
|
||||||
private static ScanBox mScanBox = new ScanBox() {
|
private static ScanBox mScanBox = new ScanBox() {
|
||||||
@Override
|
@Override
|
||||||
@ -334,32 +317,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
CACHE_TILES -= 50;
|
CACHE_TILES -= 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setMatrix(float[] matrix, MapTile tile,
|
|
||||||
float div, boolean project) {
|
|
||||||
|
|
||||||
MapPosition mapPosition = mMapPosition;
|
|
||||||
|
|
||||||
float x = (float) (tile.pixelX - mapPosition.x * div);
|
|
||||||
float y = (float) (tile.pixelY - mapPosition.y * div);
|
|
||||||
float scale = mapPosition.scale / div;
|
|
||||||
|
|
||||||
Matrix.setIdentityM(matrix, 0);
|
|
||||||
|
|
||||||
// translate relative to map center
|
|
||||||
matrix[12] = x * scale;
|
|
||||||
matrix[13] = y * scale;
|
|
||||||
|
|
||||||
// scale to tile to world coordinates
|
|
||||||
scale /= COORD_MULTIPLIER;
|
|
||||||
matrix[0] = scale;
|
|
||||||
matrix[5] = scale;
|
|
||||||
|
|
||||||
Matrix.multiplyMM(matrix, 0, mapPosition.viewMatrix, 0, matrix, 0);
|
|
||||||
|
|
||||||
if (project)
|
|
||||||
Matrix.multiplyMM(matrix, 0, mfProjMatrix, 0, matrix, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDrawFrame(GL10 glUnused) {
|
public void onDrawFrame(GL10 glUnused) {
|
||||||
|
|
||||||
@ -415,9 +372,9 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
|
|
||||||
// get current MapPosition, set mTileCoords (mapping of screen to model
|
// get current MapPosition, set mTileCoords (mapping of screen to model
|
||||||
// coordinates)
|
// coordinates)
|
||||||
MapPosition mapPosition = mMapPosition;
|
MapPosition pos = mMapPosition;
|
||||||
float[] coords = mTileCoords;
|
float[] coords = mTileCoords;
|
||||||
boolean changed = mMapViewPosition.getMapPosition(mapPosition, coords);
|
boolean changed = mMapViewPosition.getMapPosition(pos, coords);
|
||||||
|
|
||||||
int tileCnt = mDrawTiles.cnt;
|
int tileCnt = mDrawTiles.cnt;
|
||||||
MapTile[] tiles = mDrawTiles.tiles;
|
MapTile[] tiles = mDrawTiles.tiles;
|
||||||
@ -430,12 +387,12 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
// relative zoom-level, 'tiles' could not have been updated after
|
// relative zoom-level, 'tiles' could not have been updated after
|
||||||
// zoom-level changed.
|
// zoom-level changed.
|
||||||
byte z = tiles[0].zoomLevel;
|
byte z = tiles[0].zoomLevel;
|
||||||
float div = FastMath.pow(z - mapPosition.zoomLevel);
|
float div = FastMath.pow(z - pos.zoomLevel);
|
||||||
|
|
||||||
// transform screen coordinates to tile coordinates
|
// transform screen coordinates to tile coordinates
|
||||||
float scale = mapPosition.scale / div;
|
float scale = pos.scale / div;
|
||||||
float px = (float) mapPosition.x * div;
|
float px = (float) pos.x * div;
|
||||||
float py = (float) mapPosition.y * div;
|
float py = (float) pos.y * div;
|
||||||
|
|
||||||
for (int i = 0; i < 8; i += 2) {
|
for (int i = 0; i < 8; i += 2) {
|
||||||
coords[i + 0] = (px + coords[i + 0] / scale) / Tile.TILE_SIZE;
|
coords[i + 0] = (px + coords[i + 0] / scale) / Tile.TILE_SIZE;
|
||||||
@ -500,34 +457,16 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
overlays.get(i).update(mMapPosition, changed, tilesChanged);
|
overlays.get(i).update(mMapPosition, changed, tilesChanged);
|
||||||
|
|
||||||
/* draw base layer */
|
/* draw base layer */
|
||||||
GLES20.glEnable(GL_DEPTH_TEST);
|
BaseLayer.draw(tiles, tileCnt, pos);
|
||||||
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
|
|
||||||
// mDrawCount = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
// start drawing while overlays uploading textures, etc
|
||||||
MapTile t = tiles[i];
|
GLES20.glFlush();
|
||||||
if (t.isVisible && t.state == STATE_READY)
|
|
||||||
drawTile(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// proxies are clipped to the region where nothing was drawn to depth
|
|
||||||
// buffer.
|
|
||||||
// TODO draw all parent before grandparent
|
|
||||||
// TODO draw proxies for placeholder...
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
|
||||||
MapTile t = tiles[i];
|
|
||||||
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null))
|
|
||||||
drawProxyTile(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLES20.glDisable(GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glDisable(GL_DEPTH_TEST);
|
|
||||||
mDrawSerial++;
|
|
||||||
|
|
||||||
/* draw overlays */
|
/* draw overlays */
|
||||||
|
|
||||||
|
//GLState.blend(true);
|
||||||
GLES20.glEnable(GL_BLEND);
|
GLES20.glEnable(GL_BLEND);
|
||||||
|
|
||||||
// call overlay renderer
|
|
||||||
for (int i = 0, n = overlays.size(); i < n; i++) {
|
for (int i = 0, n = overlays.size(); i < n; i++) {
|
||||||
RenderOverlay renderOverlay = overlays.get(i);
|
RenderOverlay renderOverlay = overlays.get(i);
|
||||||
|
|
||||||
@ -570,10 +509,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
|
|
||||||
PolygonRenderer.debugDraw(mProjMatrix, mDebugCoords, 0);
|
PolygonRenderer.debugDraw(mProjMatrix, mDebugCoords, 0);
|
||||||
|
|
||||||
mapPosition.zoomLevel = -1;
|
pos.zoomLevel = -1;
|
||||||
mMapViewPosition.getMapPosition(mapPosition, mDebugCoords);
|
mMapViewPosition.getMapPosition(pos, mDebugCoords);
|
||||||
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0,
|
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0,
|
||||||
mapPosition.viewMatrix, 0);
|
pos.viewMatrix, 0);
|
||||||
|
|
||||||
PolygonRenderer.debugDraw(mMVPMatrix, mDebugCoords, 1);
|
PolygonRenderer.debugDraw(mMVPMatrix, mDebugCoords, 1);
|
||||||
}
|
}
|
||||||
@ -588,125 +527,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
return ((t.tileX % 4) + (t.tileY % 4 * 4) * 2) * 20;
|
return ((t.tileX % 4) + (t.tileY % 4 * 4) * 2) * 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used to not draw a tile twice per frame.
|
|
||||||
private static int mDrawSerial = 0;
|
|
||||||
|
|
||||||
private static void drawTile(MapTile tile) {
|
|
||||||
// draw parents only once
|
|
||||||
if (tile.lastDraw == mDrawSerial)
|
|
||||||
return;
|
|
||||||
|
|
||||||
float[] mvp = mMVPMatrix;
|
|
||||||
MapPosition pos = mMapPosition;
|
|
||||||
|
|
||||||
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
|
||||||
|
|
||||||
tile.lastDraw = mDrawSerial;
|
|
||||||
|
|
||||||
setMatrix(mvp, tile, div, true);
|
|
||||||
|
|
||||||
if (tile.holder != null)
|
|
||||||
tile = tile.holder;
|
|
||||||
|
|
||||||
if (tile.layers == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GLES20.glPolygonOffset(0, depthOffset(tile));
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
|
||||||
|
|
||||||
boolean clipped = false;
|
|
||||||
int simpleShader = 0; // mRotate ? 0 : 1;
|
|
||||||
|
|
||||||
for (Layer l = tile.layers.layers; l != null;) {
|
|
||||||
|
|
||||||
switch (l.type) {
|
|
||||||
case Layer.POLYGON:
|
|
||||||
|
|
||||||
GLES20.glDisable(GL_BLEND);
|
|
||||||
l = PolygonRenderer.draw(pos, l, mvp, !clipped, true);
|
|
||||||
clipped = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Layer.LINE:
|
|
||||||
if (!clipped) {
|
|
||||||
PolygonRenderer.draw(pos, null, mvp, true, true);
|
|
||||||
clipped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLES20.glEnable(GL_BLEND);
|
|
||||||
l = LineRenderer.draw(pos, l, mvp, div, simpleShader,
|
|
||||||
tile.layers.lineOffset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (tile.layers.textureLayers != null) {
|
|
||||||
// setMatrix(mvp, tile, div, false);
|
|
||||||
//
|
|
||||||
// for (Layer l = tile.layers.textureLayers; l != null;) {
|
|
||||||
// l = TextureRenderer.draw(l, 1, mProjMatrix, mvp,
|
|
||||||
// tile.layers.texOffset);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean drawProxyChild(MapTile tile) {
|
|
||||||
int drawn = 0;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if ((tile.proxies & 1 << i) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
MapTile c = tile.rel.child[i].tile;
|
|
||||||
|
|
||||||
if (c.state == STATE_READY) {
|
|
||||||
drawTile(c);
|
|
||||||
drawn++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return drawn == 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void drawProxyTile(MapTile tile) {
|
|
||||||
int diff = mMapPosition.zoomLevel - tile.zoomLevel;
|
|
||||||
|
|
||||||
boolean drawn = false;
|
|
||||||
if (mMapPosition.scale > 1.5f || diff < 0) {
|
|
||||||
// prefer drawing children
|
|
||||||
if (!drawProxyChild(tile)) {
|
|
||||||
if ((tile.proxies & MapTile.PROXY_PARENT) != 0) {
|
|
||||||
MapTile t = tile.rel.parent.tile;
|
|
||||||
if (t.state == STATE_READY) {
|
|
||||||
drawTile(t);
|
|
||||||
drawn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!drawn && (tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
|
||||||
MapTile t = tile.rel.parent.parent.tile;
|
|
||||||
if (t.state == STATE_READY)
|
|
||||||
drawTile(t);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// prefer drawing parent
|
|
||||||
MapTile t = tile.rel.parent.tile;
|
|
||||||
|
|
||||||
if (t != null && t.state == STATE_READY) {
|
|
||||||
drawTile(t);
|
|
||||||
|
|
||||||
} else if (!drawProxyChild(tile)) {
|
|
||||||
|
|
||||||
if ((tile.proxies & MapTile.PROXY_GRAMPA) != 0) {
|
|
||||||
t = tile.rel.parent.parent.tile;
|
|
||||||
if (t.state == STATE_READY)
|
|
||||||
drawTile(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
|
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
|
||||||
Log.d(TAG, "SurfaceChanged:" + mNewSurface + " " + width + " " + height);
|
Log.d(TAG, "SurfaceChanged:" + mNewSurface + " " + width + " " + height);
|
||||||
@ -738,10 +558,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
Matrix.multiplyMM(mProjMatrix, 0, mMVPMatrix, 0, mProjMatrix, 0);
|
Matrix.multiplyMM(mProjMatrix, 0, mMVPMatrix, 0, mProjMatrix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
System.arraycopy(mProjMatrix, 0, mfProjMatrix, 0, 16);
|
BaseLayer.setProjection(mProjMatrix);
|
||||||
// set to zero: we modify the z value with polygon-offset for clipping
|
|
||||||
mfProjMatrix[10] = 0;
|
|
||||||
mfProjMatrix[14] = 0;
|
|
||||||
|
|
||||||
GLES20.glViewport(0, 0, width, height);
|
GLES20.glViewport(0, 0, width, height);
|
||||||
|
|
||||||
@ -767,8 +584,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
if (mClearColor != null)
|
if (mClearColor != null)
|
||||||
mUpdateColor = true;
|
mUpdateColor = true;
|
||||||
|
|
||||||
vertexArray[0] = false;
|
GLState.init();
|
||||||
vertexArray[1] = false;
|
|
||||||
|
//vertexArray[0] = false;
|
||||||
|
//vertexArray[1] = false;
|
||||||
|
|
||||||
mMapView.redrawMap();
|
mMapView.redrawMap();
|
||||||
}
|
}
|
||||||
@ -797,33 +616,4 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
void clearBuffer() {
|
void clearBuffer() {
|
||||||
mNewSurface = true;
|
mNewSurface = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void enableVertexArrays(int va1, int va2) {
|
|
||||||
if (va1 > 1 || va2 > 1)
|
|
||||||
Log.d(TAG, "FIXME: enableVertexArrays...");
|
|
||||||
|
|
||||||
if ((va1 == 0 || va2 == 0)) {
|
|
||||||
if (!vertexArray[0]) {
|
|
||||||
GLES20.glEnableVertexAttribArray(0);
|
|
||||||
vertexArray[0] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (vertexArray[0]) {
|
|
||||||
GLES20.glDisableVertexAttribArray(0);
|
|
||||||
vertexArray[0] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((va1 == 1 || va2 == 1)) {
|
|
||||||
if (!vertexArray[1]) {
|
|
||||||
GLES20.glEnableVertexAttribArray(1);
|
|
||||||
vertexArray[1] = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (vertexArray[1]) {
|
|
||||||
GLES20.glDisableVertexAttribArray(1);
|
|
||||||
vertexArray[1] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
99
src/org/oscim/renderer/GLState.java
Normal file
99
src/org/oscim/renderer/GLState.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 OpenScienceMap
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.oscim.renderer;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public class GLState {
|
||||||
|
private final static String TAG = GLState.class.getName();
|
||||||
|
|
||||||
|
private final static boolean[] vertexArray = { false, false };
|
||||||
|
private static boolean blend = false;
|
||||||
|
private static boolean depth = false;
|
||||||
|
private static boolean stencil = false;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
vertexArray[0] = false;
|
||||||
|
vertexArray[1] = false;
|
||||||
|
blend = false;
|
||||||
|
depth = false;
|
||||||
|
stencil = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public static void blend(boolean enable) {
|
||||||
|
// if (blend == enable)
|
||||||
|
// return;
|
||||||
|
//
|
||||||
|
// if (blend)
|
||||||
|
// GLES20.glEnable(GLES20.GL_BLEND);
|
||||||
|
// else
|
||||||
|
// GLES20.glDisable(GLES20.GL_BLEND);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// public static void test(boolean depthTest, boolean stencilTest) {
|
||||||
|
// if (depth != depthTest) {
|
||||||
|
//
|
||||||
|
// if (depthTest)
|
||||||
|
// GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||||
|
// else
|
||||||
|
// GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
|
//
|
||||||
|
// depth = depthTest;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (stencil != stencilTest) {
|
||||||
|
//
|
||||||
|
// if (stencilTest)
|
||||||
|
// GLES20.glEnable(GLES20.GL_STENCIL_TEST);
|
||||||
|
// else
|
||||||
|
// GLES20.glDisable(GLES20.GL_STENCIL_TEST);
|
||||||
|
//
|
||||||
|
// stencil = stencilTest;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static void enableVertexArrays(int va1, int va2) {
|
||||||
|
if (va1 > 1 || va2 > 1)
|
||||||
|
Log.d(TAG, "FIXME: enableVertexArrays...");
|
||||||
|
|
||||||
|
if ((va1 == 0 || va2 == 0)) {
|
||||||
|
if (!vertexArray[0]) {
|
||||||
|
GLES20.glEnableVertexAttribArray(0);
|
||||||
|
vertexArray[0] = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vertexArray[0]) {
|
||||||
|
GLES20.glDisableVertexAttribArray(0);
|
||||||
|
vertexArray[0] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((va1 == 1 || va2 == 1)) {
|
||||||
|
if (!vertexArray[1]) {
|
||||||
|
GLES20.glEnableVertexAttribArray(1);
|
||||||
|
vertexArray[1] = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (vertexArray[1]) {
|
||||||
|
GLES20.glDisableVertexAttribArray(1);
|
||||||
|
vertexArray[1] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -98,7 +98,7 @@ public final class LineRenderer {
|
|||||||
int uLineColor = hLineColor[mode];
|
int uLineColor = hLineColor[mode];
|
||||||
int uLineWidth = hLineWidth[mode];
|
int uLineWidth = hLineWidth[mode];
|
||||||
|
|
||||||
GLRenderer.enableVertexArrays(hLineVertexPosition[mode], hLineTexturePosition[mode]);
|
GLState.enableVertexArrays(hLineVertexPosition[mode], hLineTexturePosition[mode]);
|
||||||
|
|
||||||
glVertexAttribPointer(hLineVertexPosition[mode], 2, GL_SHORT,
|
glVertexAttribPointer(hLineVertexPosition[mode], 2, GL_SHORT,
|
||||||
false, 8, bufferOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
false, 8, bufferOffset + LINE_VERTICES_DATA_POS_OFFSET);
|
||||||
|
@ -175,7 +175,7 @@ public final class PolygonRenderer {
|
|||||||
|
|
||||||
glUseProgram(polygonProgram);
|
glUseProgram(polygonProgram);
|
||||||
|
|
||||||
GLRenderer.enableVertexArrays(hPolygonVertexPosition, -1);
|
GLState.enableVertexArrays(hPolygonVertexPosition, -1);
|
||||||
|
|
||||||
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
|
glVertexAttribPointer(hPolygonVertexPosition, 2, GL_SHORT,
|
||||||
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
false, 0, POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||||
@ -184,6 +184,7 @@ public final class PolygonRenderer {
|
|||||||
|
|
||||||
// use stencilbuffer method for polygon drawing
|
// use stencilbuffer method for polygon drawing
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
//GLState.stencilTest(true);
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
|
@ -94,7 +94,7 @@ public final class TextureRenderer {
|
|||||||
// GlUtils.checkGlError("draw texture >");
|
// GlUtils.checkGlError("draw texture >");
|
||||||
GLES20.glUseProgram(mTextureProgram);
|
GLES20.glUseProgram(mTextureProgram);
|
||||||
|
|
||||||
GLRenderer.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) layer;
|
TextureLayer tl = (TextureLayer) layer;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import java.nio.ShortBuffer;
|
|||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.layer.VertexPool;
|
import org.oscim.renderer.layer.VertexPool;
|
||||||
import org.oscim.renderer.layer.VertexPoolItem;
|
import org.oscim.renderer.layer.VertexPoolItem;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
@ -354,7 +355,7 @@ public class BuildingOverlay extends RenderOverlay {
|
|||||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
||||||
GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
GLES20.glUniform4f(hBuildingColor, 0.5f, 0.5f, 0.5f, 0.7f);
|
||||||
|
|
||||||
GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
GLState.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||||
|
@ -20,6 +20,7 @@ import java.nio.ShortBuffer;
|
|||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.renderer.MapTile;
|
import org.oscim.renderer.MapTile;
|
||||||
import org.oscim.renderer.TileManager;
|
import org.oscim.renderer.TileManager;
|
||||||
import org.oscim.renderer.TileSet;
|
import org.oscim.renderer.TileSet;
|
||||||
@ -144,8 +145,8 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sligthly differ adjacent faces to improve contrast
|
// sligthly differ adjacent faces to improve contrast
|
||||||
float mColor[] = { 0.71872549f, 0.701960784f, 0.690196078f, 0.7f };
|
float mColor[] = { 0.76872549f, 0.751960784f, 0.740196078f, 0.8f };
|
||||||
float mColor2[] = { 0.71372549f, 0.701960784f, 0.695196078f, 0.7f };
|
float mColor2[] = { 0.76372549f, 0.751960784f, 0.745196078f, 0.8f };
|
||||||
float mRoofColor[] = { 0.895f, 0.89f, 0.88f, 0.9f };
|
float mRoofColor[] = { 0.895f, 0.89f, 0.88f, 0.9f };
|
||||||
boolean debug = false;
|
boolean debug = false;
|
||||||
|
|
||||||
@ -161,8 +162,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
GLES20.glUseProgram(extrusionProgram);
|
GLES20.glUseProgram(extrusionProgram);
|
||||||
|
|
||||||
GLRenderer
|
GLState.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
||||||
.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
|
||||||
GLES20.glUniform1i(hExtrusionMode, 0);
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
GLES20.glUniform4f(hExtrusionColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
GLES20.glUniform4f(hExtrusionColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
||||||
|
|
||||||
@ -201,7 +201,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
GLES20.glUseProgram(extrusionProgram);
|
GLES20.glUseProgram(extrusionProgram);
|
||||||
GLRenderer.enableVertexArrays(hExtrusionVertexPosition, -1);
|
GLState.enableVertexArrays(hExtrusionVertexPosition, -1);
|
||||||
|
|
||||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||||
GLES20.glCullFace(GLES20.GL_FRONT);
|
GLES20.glCullFace(GLES20.GL_FRONT);
|
||||||
@ -233,7 +233,7 @@ public class ExtrusionOverlay extends RenderOverlay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// enable color buffer, use depth mask
|
// enable color buffer, use depth mask
|
||||||
GLRenderer.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
GLState.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
||||||
GLES20.glColorMask(true, true, true, true);
|
GLES20.glColorMask(true, true, true, true);
|
||||||
GLES20.glDepthMask(false);
|
GLES20.glDepthMask(false);
|
||||||
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
|
@ -22,6 +22,7 @@ import java.nio.ShortBuffer;
|
|||||||
import org.oscim.core.MapPosition;
|
import org.oscim.core.MapPosition;
|
||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.view.MapView;
|
import org.oscim.view.MapView;
|
||||||
@ -173,7 +174,7 @@ public class ModelOverlay extends RenderOverlay {
|
|||||||
|
|
||||||
GLES20.glUseProgram(polygonProgram);
|
GLES20.glUseProgram(polygonProgram);
|
||||||
|
|
||||||
GLRenderer.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
|
GLState.enableVertexArrays(hPolygonVertexPosition, hPolygonLightPosition);
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, mIndicesBufferID);
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBufferID);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user