-rename BuildingOverlay -> ExtrusionOverlay,
even if there is probably nothing else to extrude - started to draw extrusion layer for proxy tiles - fixed depth offsetting..
This commit is contained in:
parent
0c023f9989
commit
99ce02a9bd
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012 Hannes Janetzek
|
* Copyright 2012, 2013 OpenScienceMap
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify it under the
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
* terms of the GNU Lesser General License as published by the Free Software
|
* terms of the GNU Lesser General License as published by the Free Software
|
||||||
@ -39,6 +39,7 @@ 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;
|
||||||
|
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;
|
||||||
import org.oscim.view.MapViewPosition;
|
import org.oscim.view.MapViewPosition;
|
||||||
@ -49,9 +50,12 @@ import android.opengl.Matrix;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
public class GLRenderer implements GLSurfaceView.Renderer {
|
public class GLRenderer implements GLSurfaceView.Renderer {
|
||||||
|
|
||||||
private static final String TAG = "SurfaceRenderer";
|
private static final String TAG = GLRenderer.class.getName();
|
||||||
|
|
||||||
private static final int MB = 1024 * 1024;
|
private static final int MB = 1024 * 1024;
|
||||||
private static final int SHORT_BYTES = 2;
|
private static final int SHORT_BYTES = 2;
|
||||||
@ -86,7 +90,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
private static float[] mClearColor = null;
|
private static float[] mClearColor = null;
|
||||||
|
|
||||||
// number of tiles drawn in one frame
|
// number of tiles drawn in one frame
|
||||||
private static short mDrawCount = 0;
|
//private static short mDrawCount = 0;
|
||||||
|
|
||||||
private static boolean mUpdateColor = false;
|
private static boolean mUpdateColor = false;
|
||||||
|
|
||||||
@ -356,16 +360,6 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
Matrix.multiplyMM(matrix, 0, mfProjMatrix, 0, matrix, 0);
|
Matrix.multiplyMM(matrix, 0, mfProjMatrix, 0, matrix, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float scaleDiv(MapTile t) {
|
|
||||||
float div = 1;
|
|
||||||
int diff = mMapPosition.zoomLevel - t.zoomLevel;
|
|
||||||
if (diff < 0)
|
|
||||||
div = (1 << -diff);
|
|
||||||
else if (diff > 0)
|
|
||||||
div = (1.0f / (1 << diff));
|
|
||||||
return div;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDrawFrame(GL10 glUnused) {
|
public void onDrawFrame(GL10 glUnused) {
|
||||||
|
|
||||||
@ -435,7 +429,8 @@ 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.
|
||||||
float div = scaleDiv(tiles[0]);
|
byte z = tiles[0].zoomLevel;
|
||||||
|
float div = FastMath.pow(z - mapPosition.zoomLevel);
|
||||||
|
|
||||||
// transform screen coordinates to tile coordinates
|
// transform screen coordinates to tile coordinates
|
||||||
float scale = mapPosition.scale / div;
|
float scale = mapPosition.scale / div;
|
||||||
@ -448,7 +443,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mHolderCount = 0;
|
mHolderCount = 0;
|
||||||
mScanBox.scan(coords, tiles[0].zoomLevel);
|
mScanBox.scan(coords, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
tileCnt += mHolderCount;
|
tileCnt += mHolderCount;
|
||||||
@ -507,7 +502,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
/* draw base layer */
|
/* draw base layer */
|
||||||
GLES20.glEnable(GL_DEPTH_TEST);
|
GLES20.glEnable(GL_DEPTH_TEST);
|
||||||
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
|
GLES20.glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
mDrawCount = 0;
|
// mDrawCount = 0;
|
||||||
|
|
||||||
for (int i = 0; i < tileCnt; i++) {
|
for (int i = 0; i < tileCnt; i++) {
|
||||||
MapTile t = tiles[i];
|
MapTile t = tiles[i];
|
||||||
@ -589,6 +584,10 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int depthOffset(MapTile t) {
|
||||||
|
return ((t.tileX % 4) + (t.tileY % 4 * 4) * 2) * 20;
|
||||||
|
}
|
||||||
|
|
||||||
// used to not draw a tile twice per frame.
|
// used to not draw a tile twice per frame.
|
||||||
private static int mDrawSerial = 0;
|
private static int mDrawSerial = 0;
|
||||||
|
|
||||||
@ -597,10 +596,11 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
if (tile.lastDraw == mDrawSerial)
|
if (tile.lastDraw == mDrawSerial)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float div = scaleDiv(tile);
|
|
||||||
float[] mvp = mMVPMatrix;
|
float[] mvp = mMVPMatrix;
|
||||||
MapPosition pos = mMapPosition;
|
MapPosition pos = mMapPosition;
|
||||||
|
|
||||||
|
float div = FastMath.pow(tile.zoomLevel - pos.zoomLevel);
|
||||||
|
|
||||||
tile.lastDraw = mDrawSerial;
|
tile.lastDraw = mDrawSerial;
|
||||||
|
|
||||||
setMatrix(mvp, tile, div, true);
|
setMatrix(mvp, tile, div, true);
|
||||||
@ -611,13 +611,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
if (tile.layers == null)
|
if (tile.layers == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GLES20.glPolygonOffset(0, mDrawCount++);
|
GLES20.glPolygonOffset(0, depthOffset(tile));
|
||||||
|
|
||||||
// seems there are not infinite offset units possible
|
|
||||||
// this should suffice for at least two rows, i.e.
|
|
||||||
// having not two neighbours with the same depth
|
|
||||||
if (mDrawCount == 20)
|
|
||||||
mDrawCount = 0;
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
GLES20.glBindBuffer(GL_ARRAY_BUFFER, tile.vbo.id);
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public final class MapTile extends JobTile {
|
|||||||
/**
|
/**
|
||||||
* pointer to access relatives in QuadTree
|
* pointer to access relatives in QuadTree
|
||||||
*/
|
*/
|
||||||
QuadTree rel;
|
public QuadTree rel;
|
||||||
|
|
||||||
int lastDraw = 0;
|
int lastDraw = 0;
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ public final class MapTile extends JobTile {
|
|||||||
final static int PROXY_GRAMPA = 1 << 5;
|
final static int PROXY_GRAMPA = 1 << 5;
|
||||||
final static int PROXY_HOLDER = 1 << 6;
|
final static int PROXY_HOLDER = 1 << 6;
|
||||||
|
|
||||||
byte proxies;
|
public byte proxies;
|
||||||
|
|
||||||
// counting the tiles that use this tile as proxy
|
// counting the tiles that use this tile as proxy
|
||||||
byte refs;
|
byte refs;
|
||||||
@ -94,9 +94,6 @@ public final class MapTile extends JobTile {
|
|||||||
if (locked > 1)
|
if (locked > 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//if (isReady || newData)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
MapTile p = rel.parent.tile;
|
MapTile p = rel.parent.tile;
|
||||||
|
|
||||||
if (p != null && (p.state != 0)) {
|
if (p != null && (p.state != 0)) {
|
||||||
|
@ -16,7 +16,7 @@ package org.oscim.renderer;
|
|||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
class QuadTree {
|
public class QuadTree {
|
||||||
private static String TAG = "QuadTree";
|
private static String TAG = "QuadTree";
|
||||||
|
|
||||||
// pointer to tile 0/0/0
|
// pointer to tile 0/0/0
|
||||||
@ -25,16 +25,16 @@ class QuadTree {
|
|||||||
// parent pointer is used to link pool items
|
// parent pointer is used to link pool items
|
||||||
private static QuadTree pool;
|
private static QuadTree pool;
|
||||||
|
|
||||||
QuadTree parent;
|
public QuadTree parent;
|
||||||
// .... x y
|
// .... x y
|
||||||
// 0 => 0 0
|
// 0 => 0 0
|
||||||
// 1 => 1 0
|
// 1 => 1 0
|
||||||
// 2 => 0 1
|
// 2 => 0 1
|
||||||
// 3 => 1 1
|
// 3 => 1 1
|
||||||
final QuadTree[] child = new QuadTree[4];
|
public final QuadTree[] child = new QuadTree[4];
|
||||||
int refs = 0;
|
int refs = 0;
|
||||||
byte id;
|
byte id;
|
||||||
MapTile tile;
|
public MapTile tile;
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
pool = null;
|
pool = null;
|
||||||
|
@ -1,351 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012 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.overlays;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
|
|
||||||
import org.oscim.core.MapPosition;
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
|
||||||
import org.oscim.renderer.MapTile;
|
|
||||||
import org.oscim.renderer.TileManager;
|
|
||||||
import org.oscim.renderer.TileSet;
|
|
||||||
import org.oscim.renderer.layer.ExtrusionLayer;
|
|
||||||
import org.oscim.utils.GlUtils;
|
|
||||||
import org.oscim.view.MapView;
|
|
||||||
|
|
||||||
import android.opengl.GLES20;
|
|
||||||
import android.opengl.Matrix;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Hannes Janetzek
|
|
||||||
*/
|
|
||||||
public class BuildingOverlay2 extends RenderOverlay {
|
|
||||||
private final static String TAG = BuildingOverlay2.class.getName();
|
|
||||||
|
|
||||||
public BuildingOverlay2(MapView mapView) {
|
|
||||||
super(mapView);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int buildingProgram;
|
|
||||||
private static int hBuildingVertexPosition;
|
|
||||||
private static int hBuildingLightPosition;
|
|
||||||
private static int hBuildingMatrix;
|
|
||||||
private static int hBuildingColor;
|
|
||||||
private static int hBuildingMode;
|
|
||||||
|
|
||||||
private boolean initialized = false;
|
|
||||||
|
|
||||||
private int BUFFERSIZE = 65536 * 2;
|
|
||||||
private TileSet mTileSet;
|
|
||||||
private ShortBuffer mShortBuffer;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
|
||||||
boolean tilesChanged) {
|
|
||||||
|
|
||||||
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
initialized = true;
|
|
||||||
|
|
||||||
// Set up the program for rendering buildings
|
|
||||||
buildingProgram = GlUtils.createProgram(buildingVertexShader,
|
|
||||||
buildingFragmentShader);
|
|
||||||
if (buildingProgram == 0) {
|
|
||||||
Log.e("blah", "Could not create building program.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
hBuildingMatrix = GLES20.glGetUniformLocation(buildingProgram, "u_mvp");
|
|
||||||
hBuildingColor = GLES20.glGetUniformLocation(buildingProgram, "u_color");
|
|
||||||
hBuildingMode = GLES20.glGetUniformLocation(buildingProgram, "u_mode");
|
|
||||||
hBuildingVertexPosition = GLES20.glGetAttribLocation(buildingProgram, "a_position");
|
|
||||||
hBuildingLightPosition = GLES20.glGetAttribLocation(buildingProgram, "a_light");
|
|
||||||
|
|
||||||
ByteBuffer buf = ByteBuffer.allocateDirect(BUFFERSIZE)
|
|
||||||
.order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
mShortBuffer = buf.asShortBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
int ready = 0;
|
|
||||||
//if (curPos.zoomLevel < 17)
|
|
||||||
mTileSet = TileManager.getActiveTiles(mTileSet);
|
|
||||||
MapTile[] tiles = mTileSet.tiles;
|
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
|
||||||
if (!tiles[i].isVisible || tiles[i].layers == null
|
|
||||||
|| tiles[i].layers.extrusionLayers == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
|
||||||
|
|
||||||
if (el.ready && !el.compiled) {
|
|
||||||
el.compile(mShortBuffer);
|
|
||||||
GlUtils.checkGlError("...");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el.compiled)
|
|
||||||
ready++;
|
|
||||||
}
|
|
||||||
|
|
||||||
isReady = ready > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// r: 0.815686275, 0.91372549
|
|
||||||
// g: 0.901960784
|
|
||||||
// b: 0.890196078
|
|
||||||
// sligthly differ adjacent faces to imrpove contrast
|
|
||||||
float mColor[] = { 0.71872549f, 0.701960784f, 0.690196078f, 0.7f };
|
|
||||||
float mColor2[] = { 0.71372549f, 0.701960784f, 0.695196078f, 0.7f };
|
|
||||||
float mRoofColor[] = { 0.895f, 0.89f, 0.88f, 0.9f };
|
|
||||||
boolean debug = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
|
||||||
|
|
||||||
boolean first = true;
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
MapTile[] tiles = mTileSet.tiles;
|
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
|
||||||
if (!tiles[i].isVisible || tiles[i].layers == null
|
|
||||||
|| tiles[i].layers.extrusionLayers == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
|
||||||
if (!el.compiled)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
GLES20.glUseProgram(buildingProgram);
|
|
||||||
GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 0);
|
|
||||||
GLES20.glUniform4f(hBuildingColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, tiles[i], 1);
|
|
||||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
|
||||||
GLES20.GL_SHORT, false, 8, 0);
|
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hBuildingLightPosition, 2,
|
|
||||||
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
|
||||||
|
|
||||||
GLES20.glUniform4f(hBuildingColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
|
|
||||||
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]),
|
|
||||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 0);
|
|
||||||
GLES20.glUniform4f(hBuildingColor, 1.0f, 0.5f, 0.5f, 0.9f);
|
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
|
||||||
GLES20.GL_UNSIGNED_SHORT,
|
|
||||||
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//int drawCount = 2;
|
|
||||||
// draw to depth buffer
|
|
||||||
MapTile[] tiles = mTileSet.tiles;
|
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
|
||||||
if (!tiles[i].isVisible || tiles[i].layers == null
|
|
||||||
|| tiles[i].layers.extrusionLayers == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
|
||||||
if (!el.compiled)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
GLES20.glUseProgram(buildingProgram);
|
|
||||||
GLRenderer.enableVertexArrays(hBuildingVertexPosition, -1);
|
|
||||||
|
|
||||||
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
|
||||||
GLES20.glCullFace(GLES20.GL_FRONT);
|
|
||||||
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LESS);
|
|
||||||
GLES20.glDepthMask(true);
|
|
||||||
GLES20.glColorMask(false, false, false, false);
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 0);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
GLES20.glPolygonOffset(1, 40);
|
|
||||||
|
|
||||||
// GLES20.glPolygonOffset(0, drawCount += 10);
|
|
||||||
// // seems there are not infinite offset units possible
|
|
||||||
// // this should suffice for at least two rows, i.e.
|
|
||||||
// // having not two neighbours with the same depth
|
|
||||||
// if (drawCount == 100)
|
|
||||||
// drawCount = 0;
|
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, tiles[i], 1);
|
|
||||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
|
||||||
GLES20.GL_SHORT, false, 8, 0);
|
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
|
|
||||||
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]),
|
|
||||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first)
|
|
||||||
return;
|
|
||||||
// enable color buffer, use depth mask
|
|
||||||
GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
|
||||||
GLES20.glColorMask(true, true, true, true);
|
|
||||||
//GLES20.glDepthMask(false);
|
|
||||||
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
|
||||||
//GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
|
||||||
|
|
||||||
int drawCount = 40;
|
|
||||||
//GLES20.glEnbable(GLES20.GL_POLYGON_);
|
|
||||||
//GLES20.glPolygonOffset(0, -2);
|
|
||||||
|
|
||||||
for (int i = 0; i < mTileSet.cnt; i++) {
|
|
||||||
if (!tiles[i].isVisible || tiles[i].layers == null
|
|
||||||
|| tiles[i].layers.extrusionLayers == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
|
||||||
if (!el.compiled)
|
|
||||||
continue;
|
|
||||||
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glPolygonOffset(1, drawCount--);
|
|
||||||
if (drawCount == 20)
|
|
||||||
drawCount = 40;
|
|
||||||
|
|
||||||
setMatrix(pos, mv, proj, tiles[i], 1);
|
|
||||||
GLES20.glUniformMatrix4fv(hBuildingMatrix, 1, false, mv, 0);
|
|
||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
|
||||||
|
|
||||||
//GLRenderer.enableVertexArrays(hBuildingVertexPosition, hBuildingLightPosition);
|
|
||||||
GLES20.glVertexAttribPointer(hBuildingVertexPosition, 3,
|
|
||||||
GLES20.GL_SHORT, false, 8, 0);
|
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hBuildingLightPosition, 2,
|
|
||||||
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
|
||||||
|
|
||||||
// draw roof
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 0);
|
|
||||||
//GLES20.glUniform4f(hBuildingColor, 0.81f, 0.8f, 0.8f, 0.9f);
|
|
||||||
GLES20.glUniform4fv(hBuildingColor, 1, mRoofColor, 0);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[2],
|
|
||||||
GLES20.GL_UNSIGNED_SHORT, (el.mIndiceCnt[0] + el.mIndiceCnt[1]) * 2);
|
|
||||||
|
|
||||||
// draw sides 1
|
|
||||||
//GLES20.glUniform4f(hBuildingColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
|
||||||
//GLES20.glUniform4f(hBuildingColor, 0.9f, 0.905f, 0.9f, 1.0f);
|
|
||||||
GLES20.glUniform4fv(hBuildingColor, 1, mColor, 0);
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 1);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[0],
|
|
||||||
GLES20.GL_UNSIGNED_SHORT, 0);
|
|
||||||
|
|
||||||
// draw sides 2
|
|
||||||
//GLES20.glUniform4f(hBuildingColor, 0.9f, 0.9f, 0.905f, 1.0f);
|
|
||||||
GLES20.glUniform4fv(hBuildingColor, 1, mColor2, 0);
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 2);
|
|
||||||
|
|
||||||
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
|
||||||
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
|
||||||
|
|
||||||
GLES20.glUniform1i(hBuildingMode, 0);
|
|
||||||
GLES20.glUniform4f(hBuildingColor, 0.75f, 0.75f, 0.75f, 1.0f);
|
|
||||||
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
|
||||||
GLES20.GL_UNSIGNED_SHORT,
|
|
||||||
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
|
||||||
|
|
||||||
// GlUtils.checkGlError(".2.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!first) {
|
|
||||||
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
|
||||||
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
|
||||||
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj,
|
|
||||||
MapTile tile, float div) {
|
|
||||||
|
|
||||||
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 /= GLRenderer.COORD_MULTIPLIER;
|
|
||||||
matrix[0] = scale;
|
|
||||||
matrix[5] = scale;
|
|
||||||
matrix[10] = scale / 1000f;
|
|
||||||
|
|
||||||
Matrix.multiplyMM(matrix, 0, mapPosition.viewMatrix, 0, matrix, 0);
|
|
||||||
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
final static String buildingVertexShader = ""
|
|
||||||
+ "precision mediump float;"
|
|
||||||
+ "uniform mat4 u_mvp;"
|
|
||||||
+ "uniform vec4 u_color;"
|
|
||||||
+ "uniform int u_mode;"
|
|
||||||
+ "uniform float u_scale;"
|
|
||||||
+ "attribute vec4 a_position;"
|
|
||||||
+ "attribute vec2 a_light;"
|
|
||||||
+ "varying vec4 color;"
|
|
||||||
+ "const float ff = 255.0;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_Position = u_mvp * a_position;"
|
|
||||||
+ " if (u_mode == 0)"
|
|
||||||
// roof / depth pass
|
|
||||||
+ " color = u_color;"
|
|
||||||
+ " else if (u_mode == 1)"
|
|
||||||
// sides 1 - use 0xff00
|
|
||||||
+ " color = vec4(u_color.rgb * (a_light.y / ff), 0.8);"
|
|
||||||
+ " else"
|
|
||||||
// sides 2 - use 0x00ff
|
|
||||||
+ " color = vec4(u_color.rgb * (a_light.x / ff), 0.8);"
|
|
||||||
+ "}";
|
|
||||||
|
|
||||||
final static String buildingFragmentShader = ""
|
|
||||||
+ "precision lowp float;"
|
|
||||||
+ "varying vec4 color;"
|
|
||||||
+ "void main() {"
|
|
||||||
+ " gl_FragColor = color;"
|
|
||||||
+ "}";
|
|
||||||
}
|
|
374
src/org/oscim/renderer/overlays/ExtrusionOverlay.java
Normal file
374
src/org/oscim/renderer/overlays/ExtrusionOverlay.java
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 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.overlays;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.core.MapPosition;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.MapTile;
|
||||||
|
import org.oscim.renderer.TileManager;
|
||||||
|
import org.oscim.renderer.TileSet;
|
||||||
|
import org.oscim.renderer.layer.ExtrusionLayer;
|
||||||
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
import android.opengl.Matrix;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public class ExtrusionOverlay extends RenderOverlay {
|
||||||
|
private final static String TAG = ExtrusionOverlay.class.getName();
|
||||||
|
|
||||||
|
public ExtrusionOverlay(MapView mapView) {
|
||||||
|
super(mapView);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int extrusionProgram;
|
||||||
|
private static int hExtrusionVertexPosition;
|
||||||
|
private static int hExtrusionLightPosition;
|
||||||
|
private static int hExtrusionMatrix;
|
||||||
|
private static int hExtrusionColor;
|
||||||
|
private static int hExtrusionMode;
|
||||||
|
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
// TODO sum up size used while filling layer only up to:
|
||||||
|
private int BUFFERSIZE = 65536 * 2;
|
||||||
|
private TileSet mTileSet;
|
||||||
|
private ShortBuffer mShortBuffer;
|
||||||
|
private MapTile[] mTiles;
|
||||||
|
private int mTileCnt;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void update(MapPosition curPos, boolean positionChanged,
|
||||||
|
boolean tilesChanged) {
|
||||||
|
|
||||||
|
mMapView.getMapViewPosition().getMapPosition(mMapPosition, null);
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
// Set up the program for rendering extrusions
|
||||||
|
extrusionProgram = GlUtils.createProgram(extrusionVertexShader,
|
||||||
|
extrusionFragmentShader);
|
||||||
|
if (extrusionProgram == 0) {
|
||||||
|
Log.e(TAG, "Could not create extrusion shader program.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hExtrusionMatrix = GLES20.glGetUniformLocation(extrusionProgram, "u_mvp");
|
||||||
|
hExtrusionColor = GLES20.glGetUniformLocation(extrusionProgram, "u_color");
|
||||||
|
hExtrusionMode = GLES20.glGetUniformLocation(extrusionProgram, "u_mode");
|
||||||
|
hExtrusionVertexPosition = GLES20.glGetAttribLocation(extrusionProgram, "a_position");
|
||||||
|
hExtrusionLightPosition = GLES20.glGetAttribLocation(extrusionProgram, "a_light");
|
||||||
|
|
||||||
|
ByteBuffer buf = ByteBuffer.allocateDirect(BUFFERSIZE)
|
||||||
|
.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
mShortBuffer = buf.asShortBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ready = 0;
|
||||||
|
//if (curPos.zoomLevel < 17)
|
||||||
|
mTileSet = TileManager.getActiveTiles(mTileSet);
|
||||||
|
MapTile[] tiles = mTileSet.tiles;
|
||||||
|
|
||||||
|
// keep a list of tiles available for rendering
|
||||||
|
if (mTiles == null || mTiles.length != tiles.length)
|
||||||
|
mTiles = new MapTile[tiles.length];
|
||||||
|
ExtrusionLayer el;
|
||||||
|
if (curPos.zoomLevel >= 17) {
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
el = getLayer(tiles[i]);
|
||||||
|
if (el == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (el.ready && !el.compiled) {
|
||||||
|
el.compile(mShortBuffer);
|
||||||
|
GlUtils.checkGlError("...");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.compiled)
|
||||||
|
mTiles[ready++] = tiles[i];
|
||||||
|
}
|
||||||
|
} else if (curPos.zoomLevel == 16) {
|
||||||
|
for (int i = 0; i < mTileSet.cnt; i++) {
|
||||||
|
if (!tiles[i].isVisible)
|
||||||
|
continue;
|
||||||
|
MapTile t = tiles[i];
|
||||||
|
|
||||||
|
for (byte j = 0; j < 4; j++) {
|
||||||
|
if ((t.proxies & (1 << j)) != 0) {
|
||||||
|
MapTile c = t.rel.child[j].tile;
|
||||||
|
el = getLayer(c);
|
||||||
|
|
||||||
|
if (el == null || !el.compiled)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// TODO check overflow, even if very unlikely...
|
||||||
|
mTiles[ready++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mTileCnt = ready;
|
||||||
|
isReady = ready > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ExtrusionLayer getLayer(MapTile t) {
|
||||||
|
if (t.layers != null && t.layers.extrusionLayers != null)
|
||||||
|
return (ExtrusionLayer) t.layers.extrusionLayers;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sligthly differ adjacent faces to improve contrast
|
||||||
|
float mColor[] = { 0.71872549f, 0.701960784f, 0.690196078f, 0.7f };
|
||||||
|
float mColor2[] = { 0.71372549f, 0.701960784f, 0.695196078f, 0.7f };
|
||||||
|
float mRoofColor[] = { 0.895f, 0.89f, 0.88f, 0.9f };
|
||||||
|
boolean debug = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void render(MapPosition pos, float[] mv, float[] proj) {
|
||||||
|
|
||||||
|
MapTile[] tiles = mTiles;
|
||||||
|
|
||||||
|
float div = FastMath.pow(tiles[0].zoomLevel - pos.zoomLevel);
|
||||||
|
|
||||||
|
int depthScale = 1;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
GLES20.glUseProgram(extrusionProgram);
|
||||||
|
|
||||||
|
GLRenderer
|
||||||
|
.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
GLES20.glUniform4f(hExtrusionColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
||||||
|
|
||||||
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], div);
|
||||||
|
GLES20.glUniformMatrix4fv(hExtrusionMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hExtrusionVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hExtrusionLightPosition, 2,
|
||||||
|
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
||||||
|
|
||||||
|
GLES20.glUniform4f(hExtrusionColor, 0.6f, 0.6f, 0.6f, 0.8f);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
|
||||||
|
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]),
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
GLES20.glUniform4f(hExtrusionColor, 1.0f, 0.5f, 0.5f, 0.9f);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT,
|
||||||
|
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
||||||
|
|
||||||
|
// just a temporary reference!
|
||||||
|
tiles[i] = null;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
GLES20.glUseProgram(extrusionProgram);
|
||||||
|
GLRenderer.enableVertexArrays(hExtrusionVertexPosition, -1);
|
||||||
|
|
||||||
|
GLES20.glEnable(GLES20.GL_CULL_FACE);
|
||||||
|
GLES20.glCullFace(GLES20.GL_FRONT);
|
||||||
|
GLES20.glEnable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_LESS);
|
||||||
|
GLES20.glDepthMask(true);
|
||||||
|
GLES20.glColorMask(false, false, false, false);
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
|
||||||
|
// draw to depth buffer
|
||||||
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
|
||||||
|
GLES20.glPolygonOffset(depthScale, GLRenderer.depthOffset(tiles[i]));
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], div);
|
||||||
|
GLES20.glUniformMatrix4fv(hExtrusionMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hExtrusionVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES,
|
||||||
|
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]),
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable color buffer, use depth mask
|
||||||
|
GLRenderer.enableVertexArrays(hExtrusionVertexPosition, hExtrusionLightPosition);
|
||||||
|
GLES20.glColorMask(true, true, true, true);
|
||||||
|
GLES20.glDepthMask(false);
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
|
|
||||||
|
for (int i = 0; i < mTileCnt; i++) {
|
||||||
|
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
|
||||||
|
|
||||||
|
GLES20.glPolygonOffset(depthScale, GLRenderer.depthOffset(tiles[i]));
|
||||||
|
|
||||||
|
setMatrix(pos, mv, proj, tiles[i], div);
|
||||||
|
GLES20.glUniformMatrix4fv(hExtrusionMatrix, 1, false, mv, 0);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, el.mIndicesBufferID);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, el.mVertexBufferID);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hExtrusionVertexPosition, 3,
|
||||||
|
GLES20.GL_SHORT, false, 8, 0);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hExtrusionLightPosition, 2,
|
||||||
|
GLES20.GL_UNSIGNED_BYTE, false, 8, 6);
|
||||||
|
|
||||||
|
// draw roof
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
//GLES20.glUniform4f(hExtrusionColor, 0.81f, 0.8f, 0.8f, 0.9f);
|
||||||
|
GLES20.glUniform4fv(hExtrusionColor, 1, mRoofColor, 0);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[2],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, (el.mIndiceCnt[0] + el.mIndiceCnt[1]) * 2);
|
||||||
|
|
||||||
|
// draw sides 1
|
||||||
|
//GLES20.glUniform4f(hExtrusionColor, 0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
//GLES20.glUniform4f(hExtrusionColor, 0.9f, 0.905f, 0.9f, 1.0f);
|
||||||
|
GLES20.glUniform4fv(hExtrusionColor, 1, mColor, 0);
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 1);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[0],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
|
// draw sides 2
|
||||||
|
//GLES20.glUniform4f(hExtrusionColor, 0.9f, 0.9f, 0.905f, 1.0f);
|
||||||
|
GLES20.glUniform4fv(hExtrusionColor, 1, mColor2, 0);
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 2);
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, el.mIndiceCnt[1],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, el.mIndiceCnt[0] * 2);
|
||||||
|
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_LEQUAL);
|
||||||
|
GLES20.glUniform1i(hExtrusionMode, 0);
|
||||||
|
GLES20.glUniform4f(hExtrusionColor, 0.65f, 0.65f, 0.65f, 0.98f);
|
||||||
|
GLES20.glDrawElements(GLES20.GL_LINES, el.mIndiceCnt[3],
|
||||||
|
GLES20.GL_UNSIGNED_SHORT,
|
||||||
|
(el.mIndiceCnt[0] + el.mIndiceCnt[1] + el.mIndiceCnt[2]) * 2);
|
||||||
|
GLES20.glDepthFunc(GLES20.GL_EQUAL);
|
||||||
|
|
||||||
|
// just a temporary reference!
|
||||||
|
tiles[i] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glDisable(GLES20.GL_CULL_FACE);
|
||||||
|
GLES20.glDisable(GLES20.GL_DEPTH_TEST);
|
||||||
|
GLES20.glDisable(GLES20.GL_POLYGON_OFFSET_FILL);
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setMatrix(MapPosition mapPosition, float[] matrix, float[] proj,
|
||||||
|
MapTile tile, float div) {
|
||||||
|
|
||||||
|
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 /= GLRenderer.COORD_MULTIPLIER;
|
||||||
|
matrix[0] = scale;
|
||||||
|
matrix[5] = scale;
|
||||||
|
matrix[10] = scale / 1000f;
|
||||||
|
|
||||||
|
Matrix.multiplyMM(matrix, 0, mapPosition.viewMatrix, 0, matrix, 0);
|
||||||
|
Matrix.multiplyMM(matrix, 0, proj, 0, matrix, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
final static String extrusionVertexShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform mat4 u_mvp;"
|
||||||
|
+ "uniform vec4 u_color;"
|
||||||
|
+ "uniform int u_mode;"
|
||||||
|
+ "attribute vec4 a_position;"
|
||||||
|
+ "attribute vec2 a_light;"
|
||||||
|
+ "varying vec4 color;"
|
||||||
|
+ "const float ff = 255.0;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mvp * a_position;"
|
||||||
|
+ " if (u_mode == 0)"
|
||||||
|
// roof / depth pass
|
||||||
|
+ " color = u_color;"
|
||||||
|
+ " else if (u_mode == 1)"
|
||||||
|
// sides 1 - use 0xff00
|
||||||
|
+ " color = vec4(u_color.rgb * (a_light.y / ff), 0.8);"
|
||||||
|
+ " else"
|
||||||
|
// sides 2 - use 0x00ff
|
||||||
|
+ " color = vec4(u_color.rgb * (a_light.x / ff), 0.8);"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
// final static String extrusionVertexAnimShader = ""
|
||||||
|
// + "precision mediump float;"
|
||||||
|
// + "uniform mat4 u_mvp;"
|
||||||
|
// + "uniform vec4 u_color;"
|
||||||
|
// + "uniform int u_mode;"
|
||||||
|
// + "uniform float u_adv;"
|
||||||
|
// + "attribute vec4 a_pos;"
|
||||||
|
// + "attribute vec2 a_light;"
|
||||||
|
// + "varying vec4 color;"
|
||||||
|
// + "const float ff = 255.0;"
|
||||||
|
// + "void main() {"
|
||||||
|
// + " gl_Position = u_mvp * vec4(a_pos.xy, a_pos.z * adv, 1.0);"
|
||||||
|
// + " if (u_mode == 0)"
|
||||||
|
// // roof / depth pass
|
||||||
|
// + " color = u_color;"
|
||||||
|
// + " else if (u_mode == 1)"
|
||||||
|
// // sides 1 - use 0xff00
|
||||||
|
// + " color = vec4(u_color.rgb * (a_light.y / ff), 0.8);"
|
||||||
|
// + " else"
|
||||||
|
// // sides 2 - use 0x00ff
|
||||||
|
// + " color = vec4(u_color.rgb * (a_light.x / ff), 0.8);"
|
||||||
|
// + "}";
|
||||||
|
|
||||||
|
final static String extrusionFragmentShader = ""
|
||||||
|
+ "precision lowp float;"
|
||||||
|
+ "varying vec4 color;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_FragColor = color;"
|
||||||
|
+ "}";
|
||||||
|
}
|
@ -45,7 +45,7 @@ import org.oscim.overlay.OverlayManager;
|
|||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLView;
|
import org.oscim.renderer.GLView;
|
||||||
import org.oscim.renderer.TileManager;
|
import org.oscim.renderer.TileManager;
|
||||||
import org.oscim.renderer.overlays.BuildingOverlay2;
|
import org.oscim.renderer.overlays.ExtrusionOverlay;
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ExternalRenderTheme;
|
||||||
import org.oscim.theme.InternalRenderTheme;
|
import org.oscim.theme.InternalRenderTheme;
|
||||||
import org.oscim.theme.RenderTheme;
|
import org.oscim.theme.RenderTheme;
|
||||||
@ -185,7 +185,7 @@ public class MapView extends RelativeLayout {
|
|||||||
enableRotation = true;
|
enableRotation = true;
|
||||||
|
|
||||||
//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
//mOverlayManager.add(new GenericOverlay(this, new GridOverlay(this)));
|
||||||
mOverlayManager.add(new GenericOverlay(this, new BuildingOverlay2(this)));
|
mOverlayManager.add(new GenericOverlay(this, new ExtrusionOverlay(this)));
|
||||||
mOverlayManager.add(new LabelingOverlay(this));
|
mOverlayManager.add(new LabelingOverlay(this));
|
||||||
|
|
||||||
// mOverlayManager.add(new GenericOverlay(this, new TestOverlay(this)));
|
// mOverlayManager.add(new GenericOverlay(this, new TestOverlay(this)));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user