switch to ShortBuffer for half-float, shader tweaks,..
This commit is contained in:
@@ -125,7 +125,8 @@ public class MapView extends GLSurfaceView {
|
||||
super(context, attributeSet);
|
||||
|
||||
if (!(context instanceof MapActivity)) {
|
||||
throw new IllegalArgumentException("context is not an instance of MapActivity");
|
||||
throw new IllegalArgumentException(
|
||||
"context is not an instance of MapActivity");
|
||||
}
|
||||
setWillNotDraw(true);
|
||||
setWillNotCacheDrawing(true);
|
||||
@@ -138,7 +139,8 @@ public class MapView extends GLSurfaceView {
|
||||
mMapController = new MapController(this);
|
||||
|
||||
// mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.POSTGIS_READER);
|
||||
mMapDatabase = MapDatabaseFactory.createMapDatabase(MapDatabaseInternal.MAP_READER);
|
||||
mMapDatabase = MapDatabaseFactory
|
||||
.createMapDatabase(MapDatabaseInternal.MAP_READER);
|
||||
|
||||
mMapViewPosition = new MapViewPosition(this);
|
||||
mMapScaleBar = new MapScaleBar(this);
|
||||
@@ -327,7 +329,8 @@ public class MapView extends GLSurfaceView {
|
||||
* the new center point of the map.
|
||||
*/
|
||||
public void setCenter(GeoPoint geoPoint) {
|
||||
MapPosition mapPosition = new MapPosition(geoPoint, mMapViewPosition.getZoomLevel(), 1);
|
||||
MapPosition mapPosition = new MapPosition(geoPoint,
|
||||
mMapViewPosition.getZoomLevel(), 1);
|
||||
setCenterAndZoom(mapPosition);
|
||||
}
|
||||
|
||||
@@ -566,16 +569,22 @@ public class MapView extends GLSurfaceView {
|
||||
protected final void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// find out how big the zoom controls should be
|
||||
mMapZoomControls.measure(
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST),
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST));
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec),
|
||||
MeasureSpec.AT_MOST),
|
||||
MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
|
||||
MeasureSpec.AT_MOST));
|
||||
|
||||
// make sure that MapView is big enough to display the zoom controls
|
||||
setMeasuredDimension(Math.max(MeasureSpec.getSize(widthMeasureSpec), mMapZoomControls.getMeasuredWidth()),
|
||||
Math.max(MeasureSpec.getSize(heightMeasureSpec), mMapZoomControls.getMeasuredHeight()));
|
||||
setMeasuredDimension(
|
||||
Math.max(MeasureSpec.getSize(widthMeasureSpec),
|
||||
mMapZoomControls.getMeasuredWidth()),
|
||||
Math.max(MeasureSpec.getSize(heightMeasureSpec),
|
||||
mMapZoomControls.getMeasuredHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
|
||||
protected synchronized void onSizeChanged(int width, int height, int oldWidth,
|
||||
int oldHeight) {
|
||||
mMapWorker.pause();
|
||||
mMapWorker.awaitPausing();
|
||||
super.onSizeChanged(width, height, oldWidth, oldHeight);
|
||||
@@ -605,7 +614,8 @@ public class MapView extends GLSurfaceView {
|
||||
* @return the maximum possible zoom level.
|
||||
*/
|
||||
byte getMaximumPossibleZoomLevel() {
|
||||
return (byte) Math.min(mMapZoomControls.getZoomLevelMax(), mMapGenerator.getZoomLevelMax());
|
||||
return (byte) Math.min(mMapZoomControls.getZoomLevelMax(),
|
||||
mMapGenerator.getZoomLevelMax());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -615,8 +625,9 @@ public class MapView extends GLSurfaceView {
|
||||
if (!mMapViewPosition.isValid()) {
|
||||
return false;
|
||||
} else if (!mMapGenerator.requiresInternetConnection()
|
||||
&& (!mMapDatabase.hasOpenFile() || !mMapDatabase.getMapFileInfo().boundingBox.contains(getMapPosition()
|
||||
.getMapCenter()))) {
|
||||
&& (!mMapDatabase.hasOpenFile() || !mMapDatabase.getMapFileInfo().boundingBox
|
||||
.contains(getMapPosition()
|
||||
.getMapCenter()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -624,7 +635,8 @@ public class MapView extends GLSurfaceView {
|
||||
}
|
||||
|
||||
byte limitZoomLevel(byte zoom) {
|
||||
return (byte) Math.max(Math.min(zoom, getMaximumPossibleZoomLevel()), mMapZoomControls.getZoomLevelMin());
|
||||
return (byte) Math.max(Math.min(zoom, getMaximumPossibleZoomLevel()),
|
||||
mMapZoomControls.getZoomLevelMin());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -222,11 +222,13 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
mWays = wayLength;
|
||||
|
||||
if (!firstMatch && prevClosed == closed && !changed) {
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags, mCurrentTile.zoomLevel,
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, false);
|
||||
} else {
|
||||
prevClosed = closed;
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags, mCurrentTile.zoomLevel,
|
||||
DatabaseRenderer.renderTheme.matchWay(this, tags,
|
||||
(byte) (mCurrentTile.zoomLevel + 0),
|
||||
closed, true);
|
||||
}
|
||||
|
||||
@@ -268,6 +270,9 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
@Override
|
||||
public void renderWay(Line line) {
|
||||
|
||||
// if (prevClosed && !mProjected)
|
||||
// return;
|
||||
|
||||
projectToTile(false);
|
||||
|
||||
LineLayer outlineLayer = null;
|
||||
@@ -304,7 +309,7 @@ public class DatabaseRenderer implements MapGenerator, RenderCallback,
|
||||
if (!mDebugDrawPolygons)
|
||||
return;
|
||||
|
||||
// if (!projectToTile(mCurrentTile.zoomLevel < 13))
|
||||
// if (!projectToTile(mCurrentTile.zoomLevel < 14))
|
||||
if (!projectToTile(false))
|
||||
return;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.mapsforge.android.glrenderer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import android.util.SparseArray;
|
||||
|
||||
@@ -56,7 +57,8 @@ class LineLayers {
|
||||
}
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder());
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
|
||||
ByteOrder.nativeOrder());
|
||||
fbuf = bbuf.asFloatBuffer();
|
||||
} else {
|
||||
fbuf.position(0);
|
||||
@@ -87,8 +89,8 @@ class LineLayers {
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ByteBuffer compileLayerData(ByteBuffer buf) {
|
||||
ByteBuffer sbuf = buf;
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
ShortBuffer sbuf = buf;
|
||||
|
||||
array = new LineLayer[layers.size()];
|
||||
|
||||
@@ -98,14 +100,16 @@ class LineLayers {
|
||||
size += l.verticesCnt * NUM_VERTEX_FLOATS;
|
||||
}
|
||||
|
||||
if (buf == null || buf.capacity() < size * 2) {
|
||||
sbuf = ByteBuffer.allocateDirect(size * 2).order(ByteOrder.nativeOrder());
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
|
||||
ByteOrder.nativeOrder());
|
||||
sbuf = bbuf.asShortBuffer();
|
||||
} else {
|
||||
sbuf.position(0);
|
||||
}
|
||||
int pos = 0;
|
||||
|
||||
byte[] data = new byte[PoolItem.SIZE * 2];
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
LineLayer l = array[i];
|
||||
@@ -115,7 +119,7 @@ class LineLayers {
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
sbuf.put(data, 0, item.used * 2);
|
||||
sbuf.put(data, 0, item.used);
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
*/
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@@ -88,7 +88,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
private long mTileX, mTileY;
|
||||
|
||||
private FloatBuffer floatBuffer = null;
|
||||
private ByteBuffer byteBuffer = null;
|
||||
// private ByteBuffer byteBuffer = null;
|
||||
private ShortBuffer shortBuffer = null;
|
||||
|
||||
boolean useHalfFloat = false;
|
||||
|
||||
@@ -125,7 +126,6 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
private int gLineTexturePositionHandle;
|
||||
private int gLineColorHandle;
|
||||
private int gLineMatrixHandle;
|
||||
private int gLineWidthHandle;
|
||||
private int gLineModeHandle;
|
||||
|
||||
private int gPolygonProgram;
|
||||
@@ -325,7 +325,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
newTiles.tiles[tiles++] = tile;
|
||||
|
||||
if (!tile.isDrawn && !tile.isLoading) {
|
||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator, mJobParameter, mDebugSettings);
|
||||
MapGeneratorJob job = new MapGeneratorJob(tile, mapGenerator,
|
||||
mJobParameter, mDebugSettings);
|
||||
mJobList.add(job);
|
||||
}
|
||||
}
|
||||
@@ -395,8 +396,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
byte zoomLevel = mMapPosition.zoomLevel;
|
||||
float scale = mMapPosition.scale;
|
||||
|
||||
double x = MercatorProjection.longitudeToPixelX(mMapPosition.geoPoint.getLongitude(), zoomLevel);
|
||||
double y = MercatorProjection.latitudeToPixelY(mMapPosition.geoPoint.getLatitude(), zoomLevel);
|
||||
double x = MercatorProjection.longitudeToPixelX(
|
||||
mMapPosition.geoPoint.getLongitude(), zoomLevel);
|
||||
double y = MercatorProjection.latitudeToPixelY(
|
||||
mMapPosition.geoPoint.getLatitude(), zoomLevel);
|
||||
|
||||
long tileX = MercatorProjection.pixelXToTileX(x, zoomLevel);
|
||||
long tileY = MercatorProjection.pixelYToTileY(y, zoomLevel);
|
||||
@@ -459,8 +462,10 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
blend = false;
|
||||
}
|
||||
|
||||
GLES20.glUniform4f(gPolygonColorHandle, (color >> 16 & 0xff) / 255f * alpha, (color >> 8 & 0xff) / 255f
|
||||
* alpha, (color & 0xff) / 255f * alpha, alpha);
|
||||
GLES20.glUniform4f(gPolygonColorHandle,
|
||||
(color >> 16 & 0xff) / 255f * alpha,
|
||||
(color >> 8 & 0xff) / 255f * alpha,
|
||||
(color & 0xff) / 255f * alpha, alpha);
|
||||
|
||||
// set stencil buffer mask used to draw this layer
|
||||
GLES20.glStencilFunc(GLES20.GL_EQUAL, 0xff, 1 << c);
|
||||
@@ -486,10 +491,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2, OES_HALF_FLOAT, false, 0,
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
OES_HALF_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
} else {
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2, GLES20.GL_FLOAT, false, 0,
|
||||
GLES20.glVertexAttribPointer(gPolygonVertexPositionHandle, 2,
|
||||
GLES20.GL_FLOAT, false, 0,
|
||||
POLYGON_VERTICES_DATA_POS_OFFSET);
|
||||
}
|
||||
|
||||
@@ -531,11 +538,11 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
else {
|
||||
// clear stencilbuffer
|
||||
GLES20.glStencilMask(0xFF);
|
||||
GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
// GLES20.glClear(GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
// clear stencilbuffer (tile region)
|
||||
// GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
|
||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
GLES20.glStencilOp(GLES20.GL_ZERO, GLES20.GL_ZERO, GLES20.GL_ZERO);
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
// stencil op for stencil method polygon drawing
|
||||
@@ -554,7 +561,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
// modify alpha channel
|
||||
float s = (mDrawScale < 1.3f ? 1.3f : mDrawScale);
|
||||
colors[cnt] = (colors[cnt] & 0xffffff) | (byte) ((s - 1) * 0xff) << 24;
|
||||
colors[cnt] = (colors[cnt] & 0xffffff)
|
||||
| (byte) ((s - 1) * 0xff) << 24;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,16 +596,20 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.id);
|
||||
|
||||
if (useHalfFloat) {
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT, false, 8,
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, OES_HALF_FLOAT,
|
||||
false, 8,
|
||||
LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT, false, 8,
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, OES_HALF_FLOAT,
|
||||
false, 8,
|
||||
LINE_VERTICES_DATA_TEX_OFFSET >> 1);
|
||||
} else {
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT, false, 16,
|
||||
GLES20.glVertexAttribPointer(gLineVertexPositionHandle, 2, GLES20.GL_FLOAT,
|
||||
false, 16,
|
||||
LINE_VERTICES_DATA_POS_OFFSET);
|
||||
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT, false, 16,
|
||||
GLES20.glVertexAttribPointer(gLineTexturePositionHandle, 2, GLES20.GL_FLOAT,
|
||||
false, 16,
|
||||
LINE_VERTICES_DATA_TEX_OFFSET);
|
||||
}
|
||||
|
||||
@@ -629,6 +641,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
// linear scale for fixed lines
|
||||
float fdiv = 0.9f / (mDrawScale / z);
|
||||
|
||||
// int cnt = 0;
|
||||
for (int i = 0, n = layers.length; i < n; i++) {
|
||||
LineLayer l = layers[i];
|
||||
|
||||
@@ -637,14 +650,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
drawOutlines = l.isOutline;
|
||||
drawFixed = l.isFixed;
|
||||
if (drawFixed) {
|
||||
GLES20.glUniform1i(gLineModeHandle, 2);
|
||||
GLES20.glUniform1f(gLineWidthHandle, fdiv);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0.4f, fdiv);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, fdiv);
|
||||
} else if (drawOutlines) {
|
||||
GLES20.glUniform1i(gLineModeHandle, 1);
|
||||
GLES20.glUniform1f(gLineWidthHandle, wdiv);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
||||
// GLES20.glUniform1i(gLineModeHandle, 1);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, wdiv);
|
||||
} else {
|
||||
GLES20.glUniform1i(gLineModeHandle, 0);
|
||||
GLES20.glUniform1f(gLineWidthHandle, wdiv * 0.95f);
|
||||
GLES20.glUniform2f(gLineModeHandle, 0, wdiv * 0.95f);
|
||||
// GLES20.glUniform1i(gLineModeHandle, 0);
|
||||
// GLES20.glUniform1f(gLineWidthHandle, wdiv * 0.95f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,7 +674,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
} else {
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, l.offset, l.verticesCnt);
|
||||
}
|
||||
// cnt += l.verticesCnt;
|
||||
}
|
||||
// GLES20.glUniform2f(gLineModeHandle, 0, wdiv);
|
||||
// float[] c = { 1, 0, 0, 1 };
|
||||
// GLES20.glUniform4fv(gLineColorHandle, 1, c, 0);
|
||||
// GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, cnt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -754,7 +774,15 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private int uploadCnt;
|
||||
|
||||
private boolean uploadTileData(GLMapTile tile) {
|
||||
// not sure about this, but seems it fixes some flickering when
|
||||
// multiple tiles are uploaded in one go. but if this is really
|
||||
// the issue tiles should stay corrupted..
|
||||
if (uploadCnt++ > 0)
|
||||
GLES20.glFinish();
|
||||
|
||||
if (tile.lineVBO == null) {
|
||||
// Upload line data to vertex buffer object
|
||||
synchronized (mVBOs) {
|
||||
@@ -766,7 +794,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
if (useHalfFloat)
|
||||
byteBuffer = tile.lineLayers.compileLayerData(byteBuffer);
|
||||
shortBuffer = tile.lineLayers.compileLayerData(shortBuffer);
|
||||
else
|
||||
floatBuffer = tile.lineLayers.compileLayerData(floatBuffer);
|
||||
|
||||
@@ -778,10 +806,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.lineVBO.size = tile.lineLayers.size * SHORT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size, byteBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
||||
} else {
|
||||
tile.lineVBO.size = tile.lineLayers.size * FLOAT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size, floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.lineVBO.size,
|
||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
mBufferMemoryUsage += tile.lineVBO.size;
|
||||
@@ -791,7 +821,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
|
||||
if (useHalfFloat)
|
||||
byteBuffer = tile.polygonLayers.compileLayerData(byteBuffer);
|
||||
shortBuffer = tile.polygonLayers.compileLayerData(shortBuffer);
|
||||
else
|
||||
floatBuffer = tile.polygonLayers.compileLayerData(floatBuffer);
|
||||
|
||||
@@ -804,10 +834,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
|
||||
if (useHalfFloat) {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * SHORT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size, byteBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
shortBuffer, GLES20.GL_STATIC_DRAW);
|
||||
} else {
|
||||
tile.polygonVBO.size = tile.polygonLayers.size * FLOAT_BYTES;
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size, floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, tile.polygonVBO.size,
|
||||
floatBuffer, GLES20.GL_STATIC_DRAW);
|
||||
}
|
||||
mBufferMemoryUsage += tile.polygonVBO.size;
|
||||
|
||||
@@ -835,7 +867,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glStencilMask(0xFF);
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
GLES20.glFlush();
|
||||
synchronized (this) {
|
||||
mDrawX = mCurX;
|
||||
mDrawY = mCurY;
|
||||
@@ -854,14 +886,16 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLMapTile[] tiles = curTiles.tiles;
|
||||
|
||||
if (mBufferMemoryUsage > LIMIT_BUFFERS) {
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024) + "MB");
|
||||
Log.d(TAG, "buffer object usage: " + mBufferMemoryUsage / (1024 * 1024)
|
||||
+ "MB");
|
||||
synchronized (mVBOs) {
|
||||
for (VertexBufferObject vbo : mVBOs) {
|
||||
if (vbo.size == 0)
|
||||
continue;
|
||||
mBufferMemoryUsage -= vbo.size;
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo.id);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null, GLES20.GL_STATIC_DRAW);
|
||||
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, 0, null,
|
||||
GLES20.GL_STATIC_DRAW);
|
||||
vbo.size = 0;
|
||||
|
||||
}
|
||||
@@ -869,6 +903,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
Log.d(TAG, " > " + mBufferMemoryUsage / (1024 * 1024) + "MB");
|
||||
}
|
||||
|
||||
uploadCnt = 0;
|
||||
|
||||
// check visible tiles, set tile clip scissors, upload new vertex data
|
||||
for (int i = 0; i < tileCnt; i++) {
|
||||
GLMapTile tile = tiles[i];
|
||||
@@ -880,7 +916,8 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
uploadTileData(tile);
|
||||
|
||||
if (timing)
|
||||
Log.d(TAG, "buffer upload took: " + (SystemClock.uptimeMillis() - start));
|
||||
Log.d(TAG, "buffer upload took: "
|
||||
+ (SystemClock.uptimeMillis() - start));
|
||||
|
||||
continue;
|
||||
}
|
||||
@@ -901,6 +938,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
// GLES20.glFinish();
|
||||
|
||||
if (timing)
|
||||
clear_time = (SystemClock.uptimeMillis() - start);
|
||||
@@ -930,7 +968,7 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
GLES20.glFinish();
|
||||
poly_time = (SystemClock.uptimeMillis() - start);
|
||||
}
|
||||
|
||||
// GLES20.glFlush();
|
||||
// Draw lines
|
||||
GLES20.glEnable(GLES20.GL_BLEND);
|
||||
GLES20.glUseProgram(gLineProgram);
|
||||
@@ -946,11 +984,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
|
||||
|
||||
if (timing) {
|
||||
GLES20.glFinish();
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " " + clear_time + " " + poly_time);
|
||||
Log.d(TAG, "draw took " + (SystemClock.uptimeMillis() - start) + " "
|
||||
+ clear_time + " " + poly_time);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1002,10 +1041,12 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
|
||||
// Set up the program for rendering lines
|
||||
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader, Shaders.gLineFragmentShader);
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShader);
|
||||
if (gLineProgram == 0) {
|
||||
Log.e(TAG, "trying simple line program.");
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader, Shaders.gLineFragmentShaderSimple);
|
||||
gLineProgram = GlUtils.createProgram(Shaders.gLineVertexShader,
|
||||
Shaders.gLineFragmentShaderSimple);
|
||||
if (gLineProgram == 0) {
|
||||
Log.e(TAG, "Could not create line program.");
|
||||
return;
|
||||
@@ -1020,20 +1061,22 @@ public class MapRenderer implements org.mapsforge.android.MapRenderer {
|
||||
Log.d(TAG, "Extensions: " + ext);
|
||||
|
||||
gLineMatrixHandle = GLES20.glGetUniformLocation(gLineProgram, "u_center");
|
||||
gLineWidthHandle = GLES20.glGetUniformLocation(gLineProgram, "u_width");
|
||||
gLineModeHandle = GLES20.glGetUniformLocation(gLineProgram, "u_mode");
|
||||
gLineColorHandle = GLES20.glGetUniformLocation(gLineProgram, "u_color");
|
||||
gLineVertexPositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_position");
|
||||
gLineVertexPositionHandle = GLES20
|
||||
.glGetAttribLocation(gLineProgram, "a_position");
|
||||
gLineTexturePositionHandle = GLES20.glGetAttribLocation(gLineProgram, "a_st");
|
||||
|
||||
// Set up the program for rendering polygons
|
||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader, Shaders.gPolygonFragmentShader);
|
||||
gPolygonProgram = GlUtils.createProgram(Shaders.gPolygonVertexShader,
|
||||
Shaders.gPolygonFragmentShader);
|
||||
if (gPolygonProgram == 0) {
|
||||
Log.e(TAG, "Could not create polygon program.");
|
||||
return;
|
||||
}
|
||||
gPolygonMatrixHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_center");
|
||||
gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram, "a_position");
|
||||
gPolygonVertexPositionHandle = GLES20.glGetAttribLocation(gPolygonProgram,
|
||||
"a_position");
|
||||
gPolygonColorHandle = GLES20.glGetUniformLocation(gPolygonProgram, "u_color");
|
||||
|
||||
GLES20.glUseProgram(gPolygonProgram);
|
||||
|
||||
@@ -16,11 +16,14 @@ package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.mapsforge.core.Tile;
|
||||
|
||||
class PolygonLayer extends Layer {
|
||||
int fadeLevel;
|
||||
private boolean first = true;
|
||||
private float originX;
|
||||
private float originY;
|
||||
|
||||
// private boolean first = true;
|
||||
// private float originX;
|
||||
// private float originY;
|
||||
|
||||
PolygonLayer(int layer, int color, int fade) {
|
||||
super(layer, color);
|
||||
@@ -34,11 +37,11 @@ class PolygonLayer extends Layer {
|
||||
|
||||
verticesCnt += length / 2 + 2;
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
originX = points[pos];
|
||||
originY = points[pos + 1];
|
||||
}
|
||||
// if (first) {
|
||||
// first = false;
|
||||
// originX = points[pos];
|
||||
// originY = points[pos + 1];
|
||||
// }
|
||||
|
||||
float[] curVertices = curItem.vertices;
|
||||
int outPos = curItem.used;
|
||||
@@ -48,8 +51,8 @@ class PolygonLayer extends Layer {
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
curVertices[outPos++] = originX;
|
||||
curVertices[outPos++] = originY;
|
||||
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
|
||||
curVertices[outPos++] = Tile.TILE_SIZE >> 1;
|
||||
|
||||
int remaining = length;
|
||||
int inPos = pos;
|
||||
@@ -74,7 +77,7 @@ class PolygonLayer extends Layer {
|
||||
curVertices = getNextItem();
|
||||
outPos = 0;
|
||||
}
|
||||
|
||||
// Float.intBitsToFloat(bits)
|
||||
curVertices[outPos++] = points[pos + 0];
|
||||
curVertices[outPos++] = points[pos + 1];
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ package org.mapsforge.android.glrenderer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import org.mapsforge.android.utils.FastMath;
|
||||
import org.mapsforge.core.Tile;
|
||||
@@ -25,10 +26,11 @@ import android.util.SparseArray;
|
||||
|
||||
class PolygonLayers {
|
||||
private static final int NUM_VERTEX_FLOATS = 2;
|
||||
private static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
|
||||
private static final float[] mFillCoords = { -2, Tile.TILE_SIZE + 1,
|
||||
Tile.TILE_SIZE + 1, Tile.TILE_SIZE + 1, -2,
|
||||
-2, Tile.TILE_SIZE + 1, -2 };
|
||||
|
||||
private static byte[] mByteFillCoords = null;
|
||||
private static short[] mByteFillCoords = null;
|
||||
|
||||
private SparseArray<PolygonLayer> layers;
|
||||
|
||||
@@ -68,7 +70,8 @@ class PolygonLayers {
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(ByteOrder.nativeOrder());
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 4).order(
|
||||
ByteOrder.nativeOrder());
|
||||
// Log.d("GLMap", "allocate buffer " + size);
|
||||
fbuf = bbuf.asFloatBuffer();
|
||||
} else {
|
||||
@@ -100,8 +103,8 @@ class PolygonLayers {
|
||||
return fbuf;
|
||||
}
|
||||
|
||||
ByteBuffer compileLayerData(ByteBuffer buf) {
|
||||
ByteBuffer bbuf = buf;
|
||||
ShortBuffer compileLayerData(ShortBuffer buf) {
|
||||
ShortBuffer sbuf = buf;
|
||||
|
||||
array = new PolygonLayer[layers.size()];
|
||||
|
||||
@@ -113,27 +116,29 @@ class PolygonLayers {
|
||||
|
||||
size *= NUM_VERTEX_FLOATS;
|
||||
|
||||
if (buf == null || buf.capacity() < size * 2) {
|
||||
bbuf = ByteBuffer.allocateDirect(size * 2).order(ByteOrder.nativeOrder());
|
||||
if (buf == null || buf.capacity() < size) {
|
||||
ByteBuffer bbuf = ByteBuffer.allocateDirect(size * 2).order(
|
||||
ByteOrder.nativeOrder());
|
||||
sbuf = bbuf.asShortBuffer();
|
||||
} else {
|
||||
bbuf.position(0);
|
||||
sbuf.position(0);
|
||||
}
|
||||
|
||||
byte[] data = new byte[PoolItem.SIZE * 2];
|
||||
short[] data = new short[PoolItem.SIZE];
|
||||
|
||||
if (mByteFillCoords == null) {
|
||||
mByteFillCoords = new byte[16];
|
||||
mByteFillCoords = new short[8];
|
||||
FastMath.convertFloatToHalf(mFillCoords[0], mByteFillCoords, 0);
|
||||
FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 2);
|
||||
FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 4);
|
||||
FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 6);
|
||||
FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 8);
|
||||
FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 10);
|
||||
FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 12);
|
||||
FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 14);
|
||||
FastMath.convertFloatToHalf(mFillCoords[1], mByteFillCoords, 1);
|
||||
FastMath.convertFloatToHalf(mFillCoords[2], mByteFillCoords, 2);
|
||||
FastMath.convertFloatToHalf(mFillCoords[3], mByteFillCoords, 3);
|
||||
FastMath.convertFloatToHalf(mFillCoords[4], mByteFillCoords, 4);
|
||||
FastMath.convertFloatToHalf(mFillCoords[5], mByteFillCoords, 5);
|
||||
FastMath.convertFloatToHalf(mFillCoords[6], mByteFillCoords, 6);
|
||||
FastMath.convertFloatToHalf(mFillCoords[7], mByteFillCoords, 7);
|
||||
}
|
||||
|
||||
bbuf.put(mByteFillCoords, 0, 16);
|
||||
sbuf.put(mByteFillCoords, 0, 8);
|
||||
int pos = 4;
|
||||
|
||||
for (int i = 0, n = array.length; i < n; i++) {
|
||||
@@ -142,7 +147,7 @@ class PolygonLayers {
|
||||
for (int k = 0, m = l.pool.size(); k < m; k++) {
|
||||
PoolItem item = l.pool.get(k);
|
||||
PoolItem.toHalfFloat(item, data);
|
||||
bbuf.put(data, 0, item.used * 2);
|
||||
sbuf.put(data, 0, item.used);
|
||||
}
|
||||
|
||||
l.offset = pos;
|
||||
@@ -152,11 +157,11 @@ class PolygonLayers {
|
||||
l.pool = null;
|
||||
}
|
||||
|
||||
bbuf.position(0);
|
||||
sbuf.position(0);
|
||||
|
||||
// not needed for drawing
|
||||
layers = null;
|
||||
|
||||
return bbuf;
|
||||
return sbuf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,74 +15,79 @@
|
||||
|
||||
package org.mapsforge.android.glrenderer;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
// TODO use byte[] for half-float, not converting on compilation (in glThread)
|
||||
|
||||
class PoolItem {
|
||||
final float[] vertices;
|
||||
// final byte[] vertices;
|
||||
int used;
|
||||
|
||||
PoolItem() {
|
||||
vertices = new float[SIZE];
|
||||
// vertices = new byte[SIZE];
|
||||
used = 0;
|
||||
}
|
||||
|
||||
static int SIZE = 256;
|
||||
|
||||
private static final byte b0x7c = (byte) 0x7c;
|
||||
private static final byte b0x00 = (byte) 0x00;
|
||||
private static final byte b0x01 = (byte) 0x01;
|
||||
private static final byte b0xfc = (byte) 0xfc;
|
||||
private static final byte b0x80 = (byte) 0x80;
|
||||
private static final byte b0x7b = (byte) 0x7b;
|
||||
private static final byte b0xff = (byte) 0xff;
|
||||
private static final byte b0xfb = (byte) 0xfb;
|
||||
private static final float FLOAT_HALF_PREC = 5.96046E-8f;
|
||||
private static final float FLOAT_HALF_MAX = 65504f;
|
||||
|
||||
static void toHalfFloat(PoolItem item, byte[] data) {
|
||||
private static ByteBuffer byteBuffer = ByteBuffer.allocate(SIZE * 4);
|
||||
private static IntBuffer intBuffer = byteBuffer.asIntBuffer();
|
||||
private static FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
|
||||
private static int[] intArray = new int[SIZE];
|
||||
|
||||
static void toHalfFloat(PoolItem item, short[] data) {
|
||||
floatBuffer.position(0);
|
||||
floatBuffer.put(item.vertices, 0, item.used);
|
||||
intBuffer.position(0);
|
||||
intBuffer.get(intArray, 0, item.used);
|
||||
|
||||
int out = 0;
|
||||
for (int j = 0; j < item.used; j++) {
|
||||
float flt = item.vertices[j];
|
||||
int f = intArray[j];
|
||||
|
||||
if (flt == 0f) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x00;
|
||||
} else if (flt == -0f) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x80;
|
||||
if (f == 0x0000000) {
|
||||
// == 0
|
||||
data[out++] = (short) 0x0000;
|
||||
} else if (f == 0x80000000) {
|
||||
// == -0
|
||||
data[out++] = (short) 0x8000;
|
||||
} else if (f == 0x3f800000) {
|
||||
// == 1
|
||||
data[out++] = (short) 0x3c00;
|
||||
} else if (f == 0xbf800000) {
|
||||
// == -1
|
||||
data[out++] = (short) 0xbc00;
|
||||
} else if (flt > FLOAT_HALF_MAX) {
|
||||
if (flt == Float.POSITIVE_INFINITY) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0x7c;
|
||||
data[out++] = (short) 0x7c00;
|
||||
} else {
|
||||
data[out++] = b0xff;
|
||||
data[out++] = b0x7b;
|
||||
data[out++] = (short) 0x7bff;
|
||||
}
|
||||
} else if (flt < -FLOAT_HALF_MAX) {
|
||||
if (flt == Float.NEGATIVE_INFINITY) {
|
||||
data[out++] = b0x00;
|
||||
data[out++] = b0xfc;
|
||||
data[out++] = (short) 0xfc00;
|
||||
} else {
|
||||
data[out++] = b0xff;
|
||||
data[out++] = b0xfb;
|
||||
data[out++] = (short) 0xfbff;
|
||||
}
|
||||
} else if (flt > 0f && flt < FLOAT_HALF_PREC) {
|
||||
data[out++] = b0x01;
|
||||
data[out++] = b0x00;
|
||||
data[out++] = (short) 0x0001;
|
||||
} else if (flt < 0f && flt > -FLOAT_HALF_PREC) {
|
||||
data[out++] = b0x01;
|
||||
data[out++] = b0x80;
|
||||
data[out++] = (short) 0x8001;
|
||||
} else {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
// maybe just ignore and set 0? -- we'll see. when this happens
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException("NaN to half conversion not supported!");
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[out++] = (byte) ((f >> 13) & 0xff);
|
||||
|
||||
data[out++] = (byte) (((f >> 24) & 0x80) | ((((f & 0x7f800000) - 0x38000000) >> 21) & 0x7c) | ((f >> 21) & 0x03));
|
||||
data[out++] = (short) (((f >> 16) & 0x8000)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||
| ((f >> 13) & 0x03ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,60 +17,78 @@ package org.mapsforge.android.glrenderer;
|
||||
|
||||
class Shaders {
|
||||
final static String gLineVertexShader = ""
|
||||
+ "precision highp float; \n"
|
||||
+ "precision mediump float; \n"
|
||||
+ "uniform mat4 u_center;"
|
||||
+ "uniform float u_width;"
|
||||
// + "uniform float u_width;"
|
||||
+ "attribute vec4 a_position;"
|
||||
+ "attribute vec2 a_st;"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " gl_Position = u_center * a_position;"
|
||||
+ " v_st = a_st;" + "}";
|
||||
+ " v_st = a_st;"
|
||||
+ "}";
|
||||
|
||||
final static String gLineFragmentShader = ""
|
||||
+ "#extension GL_OES_standard_derivatives : enable\n"
|
||||
+ "precision mediump float;"
|
||||
+ "uniform float u_width;"
|
||||
+ "uniform int u_mode;"
|
||||
+ "uniform vec2 u_mode;"
|
||||
+ "uniform vec4 u_color;"
|
||||
+ "const float zero = 0.0;"
|
||||
+ "const int standard = 0;"
|
||||
+ "const int fixed_width = 2;"
|
||||
+ "const vec4 blank = vec4(1.0, 0.0, 0.0, 1.0);"
|
||||
+ "const vec4 blank2 = vec4(0.0, 1.0, 0.0, 1.0);"
|
||||
+ "varying vec2 v_st;"
|
||||
+ "void main() {"
|
||||
+ " if (u_mode != fixed_width) {"
|
||||
// + " gl_FragColor = u_color;"
|
||||
// + " float fuzz;"
|
||||
// + " float len;"
|
||||
+ " if (v_st.t == zero){ "
|
||||
// + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s));"
|
||||
+ " float fuzz = -fwidth(v_st.s) * 1.5;"
|
||||
+ " float len = abs(v_st.s) - u_width;"
|
||||
// + " if (len < fuzz)"
|
||||
+ " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
+ " } else {"
|
||||
+ " float fuzz = -max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
+ " float len = length(v_st) - u_width;"
|
||||
// + " if (len < fuzz)"
|
||||
+ " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
+ " } "
|
||||
// + " if (len > zero)"
|
||||
// + " gl_FragColor = blank;"
|
||||
// + " discard;"
|
||||
// + " gl_FragColor = u_color;"
|
||||
// + " else if (len < fuzz)"
|
||||
// + " gl_FragColor = blank2;"
|
||||
// + " else "
|
||||
+ " } else { "
|
||||
+ " float fuzz = fwidth(v_st.s);"
|
||||
// + " gl_FragColor = u_color * smoothstep(fuzz, zero, abs(v_st.s) - u_width + fuzz);"
|
||||
// + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s)) * 1.5;"
|
||||
+ " gl_FragColor = u_color * smoothstep(fuzz*0.5, -fuzz, abs(v_st.s) - u_width);"
|
||||
+ " }"
|
||||
+ "float width = u_mode[1];"
|
||||
// + " if (v_st.t == zero){ "
|
||||
// + " float fuzz = fwidth(v_st.s) * 1.5;"
|
||||
// + " gl_FragColor = u_color * smoothstep(-fuzz * u_mode[0], fuzz, width - abs(v_st.s));"
|
||||
// + " } else {"
|
||||
+ " float fuzz = max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
+ " gl_FragColor = u_color * smoothstep(-fuzz * u_mode[0], fuzz, width - length(v_st));"
|
||||
// + " } "
|
||||
+ "}";
|
||||
|
||||
// final static String gLineFragmentShader = ""
|
||||
// + "#extension GL_OES_standard_derivatives : enable\n"
|
||||
// + "precision mediump float;"
|
||||
// + "uniform float u_width;"
|
||||
// + "uniform vec2 u_mode;"
|
||||
// + "uniform vec4 u_color;"
|
||||
// + "const float zero = 0.0;"
|
||||
// // + "const vec4 blank = vec4(1.0, 0.0, 0.0, 1.0);"
|
||||
// + "varying vec2 v_st;"
|
||||
// + "void main() {"
|
||||
// + "float width = u_mode[1];"
|
||||
// // + "float alpha = 1.0;"
|
||||
// + " if (u_mode[0] == zero) {"
|
||||
// // + " gl_FragColor = u_color;"
|
||||
// // + " float fuzz;"
|
||||
// // + " float len;"
|
||||
// + " if (v_st.t == zero){ "
|
||||
// // + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s));"
|
||||
// + " float fuzz = -fwidth(v_st.s) * 1.5;"
|
||||
// + " float len = abs(v_st.s) - width;"
|
||||
// // + " if (len < fuzz)"
|
||||
// + " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
// + " } else {"
|
||||
// + " float fuzz = -max(fwidth(v_st.s), fwidth(v_st.t)) * 1.5;"
|
||||
// + " float len = length(v_st) - width;"
|
||||
// // + " if (len < fuzz)"
|
||||
// + " gl_FragColor = u_color * smoothstep(zero, fuzz, len);"
|
||||
// + " } "
|
||||
// // + " if (len > zero)"
|
||||
// // + " gl_FragColor = blank;"
|
||||
// // + " discard;"
|
||||
// // + " gl_FragColor = u_color;"
|
||||
// // + " else if (len < fuzz)"
|
||||
// // + " gl_FragColor = blank2;"
|
||||
// // + " else "
|
||||
// + " } else { "
|
||||
// + " float fuzz = fwidth(v_st.s);"
|
||||
// // + " gl_FragColor = u_color * smoothstep(fuzz, zero, abs(v_st.s) - u_width + fuzz);"
|
||||
// // + " fuzz = - sqrt(dFdx(v_st.s) * dFdx(v_st.s) + dFdy(v_st.s) * dFdy(v_st.s)) * 1.5;"
|
||||
// + " gl_FragColor = u_color * smoothstep(fuzz*0.5, -fuzz, abs(v_st.s) - width);"
|
||||
// + " }"
|
||||
// + "}";
|
||||
|
||||
// final static String gLineFragmentShader = "" +
|
||||
// "#extension GL_OES_standard_derivatives : enable\n" +
|
||||
// "precision mediump float;" +
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
<rule e="way" k="waterway" v="*">
|
||||
|
||||
<rule e="way" k="waterway" v="ditch|drain" zoom-min="14">
|
||||
<line stroke="#b4cbdc" stroke-width="0.5" stroke-linecap="butt"
|
||||
<line stroke="#b4cbdc" stroke-width="0.7" stroke-linecap="butt"
|
||||
fixed="true" />
|
||||
</rule>
|
||||
|
||||
@@ -332,7 +332,7 @@
|
||||
|
||||
<rule e="way" k="outline" v="*">
|
||||
<rule e="way" k="*" v="1">
|
||||
<outline stroke="#909090" />
|
||||
<outline stroke="#bb909090" />
|
||||
</rule>
|
||||
<rule e="way" k="*" v="2">
|
||||
<outline stroke="#c0c0c0" />
|
||||
@@ -401,14 +401,10 @@
|
||||
<line stroke="#d3cb98" stroke-width="0.4" outline="2" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="service|byway">
|
||||
<rule e="way" k="*" v="service|byway|pedestrian">
|
||||
<line stroke="#ffffff" stroke-width="0.8" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="pedestrian">
|
||||
<line stroke="#f1f0f4" stroke-width="0.8" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="construction">
|
||||
<line stroke="#d0d0d0" stroke-width="1.3" outline="1" />
|
||||
</rule>
|
||||
@@ -418,9 +414,7 @@
|
||||
|
||||
<rule e="way" k="*" v="residential|road|unclassified|living_street">
|
||||
<rule e="way" k="bridge" v="yes|true">
|
||||
<line stroke="#ffffff" stroke-width="1.3" stroke-linecap="butt"
|
||||
outline="2" />
|
||||
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="2" stroke-linecap="butt" />
|
||||
</rule>
|
||||
<rule e="way" k="bridge" v="~|no|false">
|
||||
<line stroke="#ffffff" stroke-width="1.3" outline="1" />
|
||||
@@ -434,19 +428,17 @@
|
||||
<rule e="way" k="*" v="*" zoom-min="11">
|
||||
|
||||
<rule e="way" k="*" v="tertiary|secondary_link">
|
||||
<line stroke="#ffff9a" stroke-width="1.5" outline="3" />
|
||||
<line stroke="#ffffff" stroke-width="1.5" outline="1" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk_link|motorway_link">
|
||||
<line stroke="#fed6a3" stroke-width="1.6" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#fed6a3" stroke-width="1.5" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="secondary|primary_link">
|
||||
|
||||
<rule e="way" k="bridge" v="yes|true">
|
||||
<line stroke="#fefe8a" stroke-width="1.6" outline="1"
|
||||
stroke-linecap="butt" />
|
||||
<line stroke="#fefe8a" stroke-width="1.6" outline="1" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="bridge" v="~|no|false">
|
||||
@@ -455,18 +447,15 @@
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="primary">
|
||||
<line stroke="#fefe8a" stroke-width="1.7" stroke-linecap="butt"
|
||||
outline="3" />
|
||||
<line stroke="#fefe8a" stroke-width="1.7" outline="3" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="trunk">
|
||||
<line stroke="#fed6a3" stroke-width="1.8" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#fed6a3" stroke-width="1.8" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
|
||||
<rule e="way" k="*" v="motorway">
|
||||
<line stroke="#eec693" stroke-width="1.9" stroke-linecap="butt"
|
||||
outline="4" />
|
||||
<line stroke="#eec693" stroke-width="1.9" outline="4" stroke-linecap="butt" />
|
||||
</rule>
|
||||
</rule>
|
||||
</rule>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.mapsforge.android.utils;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2009-2010 jMonkeyEngine
|
||||
* All rights reserved. FastMath.java
|
||||
* Copyright (c) 2009-2010 jMonkeyEngine All rights reserved. FastMath.java
|
||||
*/
|
||||
public class FastMath {
|
||||
|
||||
@@ -58,7 +57,8 @@ public class FastMath {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException("NaN to half conversion not supported!");
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[pos + 1] = (byte) (((f >> 24) & 0x80)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 21) & 0x7c)
|
||||
@@ -67,4 +67,50 @@ public class FastMath {
|
||||
data[pos + 0] = (byte) ((f >> 13) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param flt
|
||||
* ...
|
||||
* @param data
|
||||
* ...
|
||||
* @param pos
|
||||
* ..
|
||||
*/
|
||||
public static void convertFloatToHalf(float flt, short[] data, int pos) {
|
||||
if (flt == 0f) {
|
||||
data[pos] = (short) 0x0000;
|
||||
} else if (flt == -0f) {
|
||||
data[pos] = (short) 0x8000;
|
||||
} else if (flt == 1f) {
|
||||
data[pos] = (short) 0x3c00;
|
||||
} else if (flt == -1f) {
|
||||
data[pos] = (short) 0xbc00;
|
||||
} else if (flt > FLOAT_HALF_MAX) {
|
||||
if (flt == Float.POSITIVE_INFINITY) {
|
||||
data[pos] = (short) 0x7c00;
|
||||
} else {
|
||||
data[pos] = (short) 0x7bff;
|
||||
}
|
||||
} else if (flt < -FLOAT_HALF_MAX) {
|
||||
if (flt == Float.NEGATIVE_INFINITY) {
|
||||
data[pos] = (short) 0xfc00;
|
||||
} else {
|
||||
data[pos] = (short) 0xfbff;
|
||||
}
|
||||
} else if (flt > 0f && flt < FLOAT_HALF_PREC) {
|
||||
data[pos] = (short) 0x0001;
|
||||
} else if (flt < 0f && flt > -FLOAT_HALF_PREC) {
|
||||
data[pos] = (short) 0x8001;
|
||||
} else {
|
||||
int f = Float.floatToIntBits(flt);
|
||||
|
||||
if (f == 0x7fc00000)
|
||||
throw new UnsupportedOperationException(
|
||||
"NaN to half conversion not supported!");
|
||||
|
||||
data[pos] = (short) (((f >> 16) & 0x8000)
|
||||
| ((((f & 0x7f800000) - 0x38000000) >> 13) & 0x7c00)
|
||||
| ((f >> 13) & 0x03ff));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user