added BitmapTileLayer, and TileSource interface from mapsforge
This commit is contained in:
parent
34065efb93
commit
ae993eccce
87
src/org/oscim/layers/tile/BitmapTileLayer.java
Normal file
87
src/org/oscim/layers/tile/BitmapTileLayer.java
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* 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.layers.tile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
import org.oscim.layers.tile.bitmap.TileSource;
|
||||||
|
import org.oscim.renderer.layer.BitmapLayer;
|
||||||
|
import org.oscim.renderer.layer.Layers;
|
||||||
|
import org.oscim.view.MapView;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
|
||||||
|
public class BitmapTileLayer extends TileLayer<TileLoader> {
|
||||||
|
private static final int TIMEOUT_CONNECT = 5000;
|
||||||
|
private static final int TIMEOUT_READ = 10000;
|
||||||
|
|
||||||
|
final TileSource mTileSource;
|
||||||
|
|
||||||
|
public BitmapTileLayer(MapView mapView, TileSource tileSource) {
|
||||||
|
super(mapView);
|
||||||
|
mTileSource = tileSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TileLoader createLoader(JobQueue q, TileManager tm) {
|
||||||
|
return new TileLoader(q, tm) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean executeJob(MapTile tile) {
|
||||||
|
URL url;
|
||||||
|
try {
|
||||||
|
url = mTileSource.getTileUrl(tile);
|
||||||
|
URLConnection urlConnection = getURLConnection(url);
|
||||||
|
InputStream inputStream = getInputStream(urlConnection);
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
|
||||||
|
|
||||||
|
tile.layers = new Layers();
|
||||||
|
BitmapLayer l = new BitmapLayer();
|
||||||
|
l.setBitmap(bitmap);
|
||||||
|
|
||||||
|
tile.layers.textureLayers = l;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getInputStream(URLConnection urlConnection) throws IOException {
|
||||||
|
if ("gzip".equals(urlConnection.getContentEncoding())) {
|
||||||
|
return new GZIPInputStream(urlConnection.getInputStream());
|
||||||
|
}
|
||||||
|
return urlConnection.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private URLConnection getURLConnection(URL url) throws IOException {
|
||||||
|
URLConnection urlConnection = url.openConnection();
|
||||||
|
urlConnection.setConnectTimeout(TIMEOUT_CONNECT);
|
||||||
|
urlConnection.setReadTimeout(TIMEOUT_READ);
|
||||||
|
return urlConnection;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -19,9 +19,6 @@ import org.oscim.utils.PausableThread;
|
|||||||
public abstract class TileLoader extends PausableThread {
|
public abstract class TileLoader extends PausableThread {
|
||||||
private static int id;
|
private static int id;
|
||||||
|
|
||||||
public interface Factory<T extends TileLoader>{
|
|
||||||
T create(JobQueue jobQueue, TileManager tileManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String THREAD_NAME;
|
private final String THREAD_NAME;
|
||||||
private final JobQueue mJobQueue;
|
private final JobQueue mJobQueue;
|
||||||
|
|||||||
@ -22,6 +22,7 @@ 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.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.layer.BitmapRenderer;
|
||||||
import org.oscim.renderer.layer.Layer;
|
import org.oscim.renderer.layer.Layer;
|
||||||
import org.oscim.renderer.layer.LineRenderer;
|
import org.oscim.renderer.layer.LineRenderer;
|
||||||
import org.oscim.renderer.layer.LineTexRenderer;
|
import org.oscim.renderer.layer.LineTexRenderer;
|
||||||
@ -185,6 +186,17 @@ public class TileRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Layer l = t.layers.textureLayers; l != null;) {
|
||||||
|
switch (l.type) {
|
||||||
|
case Layer.BITMAP:
|
||||||
|
l = BitmapRenderer.draw(l, 1, m);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
l = l.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// clear clip-region and could also draw 'fade-effect'
|
// clear clip-region and could also draw 'fade-effect'
|
||||||
if (mFaded)
|
if (mFaded)
|
||||||
PolygonRenderer.drawOver(m, true, 0x22000000);
|
PolygonRenderer.drawOver(m, true, 0x22000000);
|
||||||
|
|||||||
56
src/org/oscim/layers/tile/bitmap/AbstractTileSource.java
Normal file
56
src/org/oscim/layers/tile/bitmap/AbstractTileSource.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
*
|
||||||
|
* 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.layers.tile.bitmap;
|
||||||
|
|
||||||
|
public abstract class AbstractTileSource implements TileSource {
|
||||||
|
protected final String hostName;
|
||||||
|
protected final int port;
|
||||||
|
|
||||||
|
protected AbstractTileSource(String hostName, int port) {
|
||||||
|
if (hostName == null || hostName.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("no host name specified");
|
||||||
|
} else if (port < 0 || port > 65535) {
|
||||||
|
throw new IllegalArgumentException("invalid port number: " + port);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hostName = hostName;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
} else if (!(obj instanceof AbstractTileSource)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AbstractTileSource other = (AbstractTileSource) obj;
|
||||||
|
if (!this.hostName.equals(other.hostName)) {
|
||||||
|
return false;
|
||||||
|
} else if (this.port != other.port) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + this.hostName.hashCode();
|
||||||
|
result = prime * result + this.port;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/org/oscim/layers/tile/bitmap/MapQuestAerial.java
Normal file
62
src/org/oscim/layers/tile/bitmap/MapQuestAerial.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
*
|
||||||
|
* 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.layers.tile.bitmap;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
|
public class MapQuestAerial extends AbstractTileSource {
|
||||||
|
public static final MapQuestAerial INSTANCE = new MapQuestAerial("otile1.mqcdn.com", 80);
|
||||||
|
private static final int PARALLEL_REQUESTS_LIMIT = 8;
|
||||||
|
private static final String PROTOCOL = "http";
|
||||||
|
private static final int ZOOM_LEVEL_MAX = 18;
|
||||||
|
private static final int ZOOM_LEVEL_MIN = 0;
|
||||||
|
|
||||||
|
public MapQuestAerial(String hostName, int port) {
|
||||||
|
super(hostName, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getParallelRequestsLimit() {
|
||||||
|
return PARALLEL_REQUESTS_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getTileUrl(Tile tile) throws MalformedURLException {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder(32);
|
||||||
|
|
||||||
|
stringBuilder.append("/tiles/1.0.0/sat/");
|
||||||
|
stringBuilder.append(tile.zoomLevel);
|
||||||
|
stringBuilder.append('/');
|
||||||
|
stringBuilder.append(tile.tileX);
|
||||||
|
stringBuilder.append('/');
|
||||||
|
stringBuilder.append(tile.tileY);
|
||||||
|
stringBuilder.append(".jpg");
|
||||||
|
|
||||||
|
return new URL(PROTOCOL, this.hostName, this.port, stringBuilder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getZoomLevelMax() {
|
||||||
|
return ZOOM_LEVEL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getZoomLevelMin() {
|
||||||
|
return ZOOM_LEVEL_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/org/oscim/layers/tile/bitmap/OpenStreetMapMapnik.java
Normal file
62
src/org/oscim/layers/tile/bitmap/OpenStreetMapMapnik.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
*
|
||||||
|
* 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.layers.tile.bitmap;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
|
public class OpenStreetMapMapnik extends AbstractTileSource {
|
||||||
|
public static final OpenStreetMapMapnik INSTANCE = new OpenStreetMapMapnik("tile.openstreetmap.org", 80);
|
||||||
|
private static final int PARALLEL_REQUESTS_LIMIT = 8;
|
||||||
|
private static final String PROTOCOL = "http";
|
||||||
|
private static final int ZOOM_LEVEL_MAX = 18;
|
||||||
|
private static final int ZOOM_LEVEL_MIN = 0;
|
||||||
|
|
||||||
|
public OpenStreetMapMapnik(String hostName, int port) {
|
||||||
|
super(hostName, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getParallelRequestsLimit() {
|
||||||
|
return PARALLEL_REQUESTS_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL getTileUrl(Tile tile) throws MalformedURLException {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder(32);
|
||||||
|
|
||||||
|
stringBuilder.append('/');
|
||||||
|
stringBuilder.append(tile.zoomLevel);
|
||||||
|
stringBuilder.append('/');
|
||||||
|
stringBuilder.append(tile.tileX);
|
||||||
|
stringBuilder.append('/');
|
||||||
|
stringBuilder.append(tile.tileY);
|
||||||
|
stringBuilder.append(".png");
|
||||||
|
|
||||||
|
return new URL(PROTOCOL, this.hostName, this.port, stringBuilder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getZoomLevelMax() {
|
||||||
|
return ZOOM_LEVEL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte getZoomLevelMin() {
|
||||||
|
return ZOOM_LEVEL_MIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
42
src/org/oscim/layers/tile/bitmap/TileSource.java
Normal file
42
src/org/oscim/layers/tile/bitmap/TileSource.java
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
*
|
||||||
|
* 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.layers.tile.bitmap;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
|
||||||
|
public interface TileSource {
|
||||||
|
/**
|
||||||
|
* @return the maximum number of parallel requests which this {@code TileSource} supports.
|
||||||
|
*/
|
||||||
|
int getParallelRequestsLimit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the download URL for the given {@code Tile}.
|
||||||
|
*/
|
||||||
|
URL getTileUrl(Tile tile) throws MalformedURLException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maximum zoom level which this {@code TileSource} supports.
|
||||||
|
*/
|
||||||
|
byte getZoomLevelMax();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the minimum zoom level which this {@code TileSource} supports.
|
||||||
|
*/
|
||||||
|
byte getZoomLevelMin();
|
||||||
|
}
|
||||||
@ -243,8 +243,8 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
| GLES20.GL_DEPTH_BUFFER_BIT
|
| GLES20.GL_DEPTH_BUFFER_BIT
|
||||||
| GLES20.GL_STENCIL_BUFFER_BIT);
|
| GLES20.GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
boolean tilesChanged = true;
|
boolean tilesChanged = false;
|
||||||
boolean positionChanged = true;
|
boolean positionChanged = false;
|
||||||
|
|
||||||
// get current MapPosition, set mBoxCoords (mapping of screen to model
|
// get current MapPosition, set mBoxCoords (mapping of screen to model
|
||||||
// coordinates)
|
// coordinates)
|
||||||
@ -253,7 +253,7 @@ public class GLRenderer implements GLSurfaceView.Renderer {
|
|||||||
synchronized (mMapViewPosition) {
|
synchronized (mMapViewPosition) {
|
||||||
mMapViewPosition.updateAnimation();
|
mMapViewPosition.updateAnimation();
|
||||||
|
|
||||||
positionChanged |= mMapViewPosition.getMapPosition(pos);
|
positionChanged = mMapViewPosition.getMapPosition(pos);
|
||||||
|
|
||||||
if (positionChanged)
|
if (positionChanged)
|
||||||
mMapViewPosition.getMapViewProjection(mBoxCoords);
|
mMapViewPosition.getMapViewProjection(mBoxCoords);
|
||||||
|
|||||||
117
src/org/oscim/renderer/layer/BitmapLayer.java
Normal file
117
src/org/oscim/renderer/layer/BitmapLayer.java
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* 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.layer;
|
||||||
|
|
||||||
|
import java.nio.ShortBuffer;
|
||||||
|
|
||||||
|
import org.oscim.core.Tile;
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
public class BitmapLayer extends TextureLayer {
|
||||||
|
// private final static String TAG = BitmapLayer.class.getName();
|
||||||
|
private Bitmap mBitmap;
|
||||||
|
|
||||||
|
public BitmapLayer() {
|
||||||
|
type = Layer.BITMAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBitmap(Bitmap bitmap) {
|
||||||
|
mBitmap = bitmap;
|
||||||
|
|
||||||
|
vertexItems = VertexItem.pool.get();
|
||||||
|
short[] buf = vertexItems.vertices;
|
||||||
|
short size = (short) (Tile.SIZE * GLRenderer.COORD_SCALE);
|
||||||
|
short center = (short) (size >> 1);
|
||||||
|
short m = (short) (-(size >> 1));
|
||||||
|
short p = center;
|
||||||
|
short t = (8 * 256);
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
// top-left
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = m;
|
||||||
|
buf[pos++] = m;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
// bot-left
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = size;
|
||||||
|
buf[pos++] = m;
|
||||||
|
buf[pos++] = p;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = t;
|
||||||
|
// top-right
|
||||||
|
buf[pos++] = size;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
buf[pos++] = p;
|
||||||
|
buf[pos++] = m;
|
||||||
|
buf[pos++] = t;
|
||||||
|
buf[pos++] = 0;
|
||||||
|
// bot-right
|
||||||
|
buf[pos++] = size;
|
||||||
|
buf[pos++] = size;
|
||||||
|
buf[pos++] = p;
|
||||||
|
buf[pos++] = p;
|
||||||
|
buf[pos++] = t;
|
||||||
|
buf[pos++] = t;
|
||||||
|
|
||||||
|
vertexItems.used = 24;
|
||||||
|
|
||||||
|
TextureItem ti = this.textures = new TextureItem(-1);
|
||||||
|
ti.ownBitmap = true;
|
||||||
|
ti.width = mBitmap.getWidth();
|
||||||
|
ti.height = mBitmap.getHeight();
|
||||||
|
ti.bitmap = mBitmap;
|
||||||
|
ti.vertices = TextureRenderer.INDICES_PER_SPRITE;
|
||||||
|
|
||||||
|
verticesCnt = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean prepare() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
if (mBitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
super.compile(sbuf);
|
||||||
|
|
||||||
|
mBitmap.recycle();
|
||||||
|
mBitmap = null;
|
||||||
|
textures.bitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void clear() {
|
||||||
|
|
||||||
|
if (mBitmap != null) {
|
||||||
|
mBitmap.recycle();
|
||||||
|
mBitmap = null;
|
||||||
|
textures.bitmap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureItem.releaseTexture(textures);
|
||||||
|
textures = null;
|
||||||
|
|
||||||
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
vertexItems = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
141
src/org/oscim/renderer/layer/BitmapRenderer.java
Normal file
141
src/org/oscim/renderer/layer/BitmapRenderer.java
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, 2013 Hannes Janetzek
|
||||||
|
*
|
||||||
|
* 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.layer;
|
||||||
|
|
||||||
|
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
||||||
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_HEIGHT;
|
||||||
|
|
||||||
|
import org.oscim.renderer.GLRenderer;
|
||||||
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
|
import android.opengl.GLES20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hannes Janetzek
|
||||||
|
*/
|
||||||
|
public final class BitmapRenderer {
|
||||||
|
private final static String TAG = BitmapRenderer.class.getName();
|
||||||
|
public final static boolean debug = true;
|
||||||
|
|
||||||
|
private static int mTextureProgram;
|
||||||
|
private static int hTextureMVMatrix;
|
||||||
|
private static int hTextureProjMatrix;
|
||||||
|
private static int hTextureVertex;
|
||||||
|
private static int hTextureScale;
|
||||||
|
private static int hTextureScreenScale;
|
||||||
|
private static int hTextureTexCoord;
|
||||||
|
|
||||||
|
public final static int INDICES_PER_SPRITE = 6;
|
||||||
|
final static int VERTICES_PER_SPRITE = 4;
|
||||||
|
final static int SHORTS_PER_VERTICE = 6;
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
mTextureProgram = GlUtils.createProgram(textVertexShader,
|
||||||
|
textFragmentShader);
|
||||||
|
|
||||||
|
hTextureMVMatrix = GLES20.glGetUniformLocation(mTextureProgram, "u_mv");
|
||||||
|
hTextureProjMatrix = GLES20.glGetUniformLocation(mTextureProgram, "u_proj");
|
||||||
|
hTextureScale = GLES20.glGetUniformLocation(mTextureProgram, "u_scale");
|
||||||
|
hTextureScreenScale = GLES20.glGetUniformLocation(mTextureProgram, "u_swidth");
|
||||||
|
hTextureVertex = GLES20.glGetAttribLocation(mTextureProgram, "vertex");
|
||||||
|
hTextureTexCoord = GLES20.glGetAttribLocation(mTextureProgram, "tex_coord");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Layer draw(Layer layer, float scale, Matrices m) {
|
||||||
|
GLState.test(false, false);
|
||||||
|
GLState.blend(true);
|
||||||
|
|
||||||
|
GLState.useProgram(mTextureProgram);
|
||||||
|
|
||||||
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
|
TextureLayer tl = (TextureLayer) layer;
|
||||||
|
|
||||||
|
if (tl.fixed)
|
||||||
|
GLES20.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
||||||
|
else
|
||||||
|
GLES20.glUniform1f(hTextureScale, 1);
|
||||||
|
|
||||||
|
GLES20.glUniform1f(hTextureScreenScale, 1f / GLRenderer.screenWidth);
|
||||||
|
|
||||||
|
m.proj.setAsUniform(hTextureProjMatrix);
|
||||||
|
|
||||||
|
m.mvp.setAsUniform(hTextureMVMatrix);
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID);
|
||||||
|
|
||||||
|
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
||||||
|
//Log.d(TAG, "render texture " + ti.id);
|
||||||
|
|
||||||
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ti.id);
|
||||||
|
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
|
// draw up to maxVertices in each iteration
|
||||||
|
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
||||||
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
|
int off = (ti.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
|
GLES20.GL_SHORT, false, 12, off);
|
||||||
|
|
||||||
|
GLES20.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
|
GLES20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
|
int numVertices = ti.vertices - i;
|
||||||
|
if (numVertices > maxVertices)
|
||||||
|
numVertices = maxVertices;
|
||||||
|
|
||||||
|
GLES20.glDrawElements(GLES20.GL_TRIANGLES, numVertices,
|
||||||
|
GLES20.GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
return layer.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//private final static double TEX_COORD_DIV_X = 1.0 / (TEXTURE_WIDTH * COORD_SCALE);
|
||||||
|
private final static double TEX_COORD_DIV_X = 1.0 / (TEXTURE_HEIGHT* COORD_SCALE);
|
||||||
|
private final static double TEX_COORD_DIV_Y = 1.0 / (TEXTURE_HEIGHT * COORD_SCALE);
|
||||||
|
private final static double COORD_DIV = 1.0 / GLRenderer.COORD_SCALE;
|
||||||
|
|
||||||
|
private final static String textVertexShader = ""
|
||||||
|
+ "precision mediump float; "
|
||||||
|
+ "attribute vec4 vertex;"
|
||||||
|
+ "attribute vec2 tex_coord;"
|
||||||
|
+ "uniform mat4 u_mv;"
|
||||||
|
+ "uniform mat4 u_proj;"
|
||||||
|
+ "uniform float u_scale;"
|
||||||
|
+ "uniform float u_swidth;"
|
||||||
|
+ "varying vec2 tex_c;"
|
||||||
|
+ "const vec2 div = vec2(" + TEX_COORD_DIV_X + "," + TEX_COORD_DIV_Y + ");"
|
||||||
|
+ "const float coord_scale = " + COORD_DIV + ";"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||||
|
+ " tex_c = tex_coord * div;"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
private final static String textFragmentShader = ""
|
||||||
|
+ "precision mediump float;"
|
||||||
|
+ "uniform sampler2D tex;"
|
||||||
|
+ "varying vec2 tex_c;"
|
||||||
|
+ "void main() {"
|
||||||
|
+ " gl_FragColor = texture2D(tex, tex_c.xy);"
|
||||||
|
+ "}";
|
||||||
|
}
|
||||||
@ -28,6 +28,7 @@ public class Layers {
|
|||||||
LineTexRenderer.init();
|
LineTexRenderer.init();
|
||||||
PolygonRenderer.init();
|
PolygonRenderer.init();
|
||||||
TextureRenderer.init();
|
TextureRenderer.init();
|
||||||
|
BitmapRenderer.init();
|
||||||
|
|
||||||
TextureItem.init(10);
|
TextureItem.init(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -102,7 +102,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
float x = 0;
|
float x = 0;
|
||||||
float y = 0;
|
float y = 0;
|
||||||
|
|
||||||
TextureItem to = TextureItem.pool.get();
|
TextureItem to = TextureItem.get(true);
|
||||||
textures = to;
|
textures = to;
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(to.bitmap);
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
offsetIndices = numIndices;
|
offsetIndices = numIndices;
|
||||||
curIndices = 0;
|
curIndices = 0;
|
||||||
|
|
||||||
to.next = TextureItem.pool.get();
|
to.next = TextureItem.get(true);
|
||||||
to = to.next;
|
to = to.next;
|
||||||
|
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(to.bitmap);
|
||||||
@ -247,7 +247,8 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void clear() {
|
protected void clear() {
|
||||||
TextureItem.pool.releaseAll(textures);
|
TextureItem.releaseAll(textures);
|
||||||
|
|
||||||
SymbolItem.pool.releaseAll(symbols);
|
SymbolItem.pool.releaseAll(symbols);
|
||||||
VertexItem.pool.releaseAll(vertexItems);
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
textures = null;
|
textures = null;
|
||||||
|
|||||||
@ -17,8 +17,6 @@ package org.oscim.renderer.layer;
|
|||||||
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
||||||
import static org.oscim.renderer.layer.TextureItem.TEXTURE_HEIGHT;
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_HEIGHT;
|
||||||
import static org.oscim.renderer.layer.TextureItem.TEXTURE_WIDTH;
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_WIDTH;
|
||||||
|
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
public final class TextLayer extends TextureLayer {
|
public final class TextLayer extends TextureLayer {
|
||||||
|
|
||||||
@ -91,7 +89,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
float y = 0;
|
float y = 0;
|
||||||
float yy;
|
float yy;
|
||||||
|
|
||||||
TextureItem to = TextureItem.pool.get();
|
TextureItem to = TextureItem.get(true);
|
||||||
textures = to;
|
textures = to;
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(to.bitmap);
|
||||||
|
|
||||||
@ -113,7 +111,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
to.vertices = (short) (numIndices - offsetIndices);
|
to.vertices = (short) (numIndices - offsetIndices);
|
||||||
offsetIndices = numIndices;
|
offsetIndices = numIndices;
|
||||||
|
|
||||||
to.next = TextureItem.pool.get();
|
to.next = TextureItem.get(true);
|
||||||
to = to.next;
|
to = to.next;
|
||||||
|
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(to.bitmap);
|
||||||
@ -266,7 +264,7 @@ public final class TextLayer extends TextureLayer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void clear() {
|
protected void clear() {
|
||||||
TextureItem.pool.releaseAll(textures);
|
TextureItem.releaseAll(textures);
|
||||||
TextItem.pool.releaseAll(labels);
|
TextItem.pool.releaseAll(labels);
|
||||||
VertexItem.pool.releaseAll(vertexItems);
|
VertexItem.pool.releaseAll(vertexItems);
|
||||||
textures = null;
|
textures = null;
|
||||||
|
|||||||
@ -16,6 +16,7 @@ package org.oscim.renderer.layer;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.oscim.utils.GlUtils;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
import org.oscim.utils.pool.SyncPool;
|
import org.oscim.utils.pool.SyncPool;
|
||||||
|
|
||||||
@ -44,15 +45,30 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
// temporary Bitmap
|
// temporary Bitmap
|
||||||
public Bitmap bitmap;
|
public Bitmap bitmap;
|
||||||
|
|
||||||
|
boolean ownBitmap;
|
||||||
|
|
||||||
TextureItem(int id) {
|
TextureItem(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static SyncPool<TextureItem> pool = new SyncPool<TextureItem>() {
|
public synchronized static void releaseAll(TextureItem ti) {
|
||||||
|
pool.releaseAll(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized static TextureItem get(boolean initBitmap) {
|
||||||
|
TextureItem ti = pool.get();
|
||||||
|
if (initBitmap) {
|
||||||
|
ti.bitmap = getBitmap();
|
||||||
|
ti.bitmap.eraseColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static SyncPool<TextureItem> pool = new SyncPool<TextureItem>(20) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(int num) {
|
public void init(int num) {
|
||||||
this.pool = null;
|
super.init(num);
|
||||||
|
|
||||||
int[] textureIds = new int[num];
|
int[] textureIds = new int[num];
|
||||||
GLES20.glGenTextures(num, textureIds, 0);
|
GLES20.glGenTextures(num, textureIds, 0);
|
||||||
@ -60,22 +76,10 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
for (int i = 1; i < num; i++) {
|
for (int i = 1; i < num; i++) {
|
||||||
initTexture(textureIds[i]);
|
initTexture(textureIds[i]);
|
||||||
TextureItem to = new TextureItem(textureIds[i]);
|
TextureItem to = new TextureItem(textureIds[i]);
|
||||||
|
pool = Inlist.push(pool, to);
|
||||||
to.next = this.pool;
|
|
||||||
this.pool = to;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextureItem get() {
|
|
||||||
TextureItem it = super.get();
|
|
||||||
|
|
||||||
it.bitmap = TextureItem.getBitmap();
|
|
||||||
it.bitmap.eraseColor(Color.TRANSPARENT);
|
|
||||||
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TextureItem createItem() {
|
protected TextureItem createItem() {
|
||||||
return new TextureItem(-1);
|
return new TextureItem(-1);
|
||||||
@ -83,10 +87,22 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void clearItem(TextureItem it) {
|
protected void clearItem(TextureItem it) {
|
||||||
TextureItem.releaseBitmap(it);
|
//Log.d(TAG, it.ownBitmap + " " + (it.bitmap == null));
|
||||||
|
if (it.ownBitmap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
releaseBitmap(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void freeItem(TextureItem it) {
|
||||||
|
it.width = -1;
|
||||||
|
it.height = -1;
|
||||||
|
releaseTexture(it);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static ArrayList<Integer> mFreeTextures = new ArrayList<Integer>();
|
||||||
private static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
|
private static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
|
||||||
|
|
||||||
public final static int TEXTURE_WIDTH = 512;
|
public final static int TEXTURE_WIDTH = 512;
|
||||||
@ -94,6 +110,27 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
|
|
||||||
private static int mBitmapFormat;
|
private static int mBitmapFormat;
|
||||||
private static int mBitmapType;
|
private static int mBitmapType;
|
||||||
|
private static int mTexCnt = 0;
|
||||||
|
|
||||||
|
static void releaseTexture(TextureItem it) {
|
||||||
|
synchronized (mFreeTextures) {
|
||||||
|
if (it.id >= 0) {
|
||||||
|
mFreeTextures.add(Integer.valueOf(it.id));
|
||||||
|
it.id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void releaseBitmap(TextureItem it) {
|
||||||
|
synchronized (mBitmaps) {
|
||||||
|
if (it.bitmap != null) {
|
||||||
|
mBitmaps.add(it.bitmap);
|
||||||
|
it.bitmap = null;
|
||||||
|
}
|
||||||
|
it.ownBitmap = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function may only be used in GLRenderer Thread.
|
* This function may only be used in GLRenderer Thread.
|
||||||
@ -102,23 +139,32 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
*/
|
*/
|
||||||
public static void uploadTexture(TextureItem to) {
|
public static void uploadTexture(TextureItem to) {
|
||||||
|
|
||||||
if (TextureRenderer.debug)
|
// free unused textures, find a better place for this TODO
|
||||||
Log.d(TAG, "upload texture " + to.id);
|
synchronized (mFreeTextures) {
|
||||||
|
int size = mFreeTextures.size();
|
||||||
|
int[] tmp = new int[size];
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
tmp[i] = mFreeTextures.get(i).intValue();
|
||||||
|
mFreeTextures.clear();
|
||||||
|
GLES20.glDeleteTextures(size, tmp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (to.id < 0) {
|
if (to.id < 0) {
|
||||||
|
mTexCnt++;
|
||||||
int[] textureIds = new int[1];
|
int[] textureIds = new int[1];
|
||||||
GLES20.glGenTextures(1, textureIds, 0);
|
GLES20.glGenTextures(1, textureIds, 0);
|
||||||
to.id = textureIds[0];
|
to.id = textureIds[0];
|
||||||
initTexture(to.id);
|
initTexture(to.id);
|
||||||
|
|
||||||
if (TextureRenderer.debug)
|
if (TextureRenderer.debug)
|
||||||
Log.d(TAG, "new texture " + to.id);
|
Log.d(TAG, pool.getCount() + " " + pool.getFill()
|
||||||
|
+ " " + mTexCnt + " new texture " + to.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType,
|
uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType,
|
||||||
TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||||
|
|
||||||
TextureItem.releaseBitmap(to);
|
if (!to.ownBitmap)
|
||||||
|
TextureItem.releaseBitmap(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void uploadTexture(TextureItem to, Bitmap bitmap,
|
public static void uploadTexture(TextureItem to, Bitmap bitmap,
|
||||||
@ -129,13 +175,21 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
|
||||||
if (to.width == w && to.height == h)
|
|
||||||
|
if (to.ownBitmap) {
|
||||||
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
|
||||||
|
|
||||||
|
} else if (to.width == w && to.height == h) {
|
||||||
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type);
|
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type);
|
||||||
else {
|
|
||||||
|
} else {
|
||||||
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, format, bitmap, type, 0);
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, format, bitmap, type, 0);
|
||||||
to.width = w;
|
to.width = w;
|
||||||
to.height = h;
|
to.height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TextureRenderer.debug)
|
||||||
|
GlUtils.checkGlError(TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initTexture(int id) {
|
static void initTexture(int id) {
|
||||||
@ -166,6 +220,8 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
|
|
||||||
mBitmapFormat = GLUtils.getInternalFormat(mBitmaps.get(0));
|
mBitmapFormat = GLUtils.getInternalFormat(mBitmaps.get(0));
|
||||||
mBitmapType = GLUtils.getType(mBitmaps.get(0));
|
mBitmapType = GLUtils.getType(mBitmaps.get(0));
|
||||||
|
|
||||||
|
mTexCnt = num;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitmap getBitmap() {
|
static Bitmap getBitmap() {
|
||||||
@ -186,14 +242,4 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
return mBitmaps.remove(size - 1);
|
return mBitmaps.remove(size - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseBitmap(TextureItem it) {
|
|
||||||
synchronized (mBitmaps) {
|
|
||||||
|
|
||||||
if (it.bitmap != null) {
|
|
||||||
mBitmaps.add(it.bitmap);
|
|
||||||
it.bitmap = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,8 +20,8 @@ import static org.oscim.renderer.layer.TextureItem.TEXTURE_HEIGHT;
|
|||||||
import static org.oscim.renderer.layer.TextureItem.TEXTURE_WIDTH;
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_WIDTH;
|
||||||
|
|
||||||
import org.oscim.renderer.GLRenderer;
|
import org.oscim.renderer.GLRenderer;
|
||||||
import org.oscim.renderer.GLState;
|
|
||||||
import org.oscim.renderer.GLRenderer.Matrices;
|
import org.oscim.renderer.GLRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.GLState;
|
||||||
import org.oscim.utils.GlUtils;
|
import org.oscim.utils.GlUtils;
|
||||||
|
|
||||||
import android.opengl.GLES20;
|
import android.opengl.GLES20;
|
||||||
@ -30,6 +30,7 @@ import android.opengl.GLES20;
|
|||||||
* @author Hannes Janetzek
|
* @author Hannes Janetzek
|
||||||
*/
|
*/
|
||||||
public final class TextureRenderer {
|
public final class TextureRenderer {
|
||||||
|
//private final static String TAG = TextureRenderer.class.getName();
|
||||||
public final static boolean debug = false;
|
public final static boolean debug = false;
|
||||||
|
|
||||||
private static int mTextureProgram;
|
private static int mTextureProgram;
|
||||||
@ -78,15 +79,15 @@ public final class TextureRenderer {
|
|||||||
|
|
||||||
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID);
|
GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, GLRenderer.mQuadIndicesID);
|
||||||
|
|
||||||
for (TextureItem to = tl.textures; to != null; to = to.next) {
|
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
||||||
|
|
||||||
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, ti.id);
|
||||||
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
|
int maxVertices = GLRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
// draw up to maxVertices in each iteration
|
// draw up to maxVertices in each iteration
|
||||||
for (int i = 0; i < to.vertices; i += maxVertices) {
|
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
||||||
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
|
||||||
int off = (to.offset + i) * 8 + tl.offset;
|
int off = (ti.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GLES20.glVertexAttribPointer(hTextureVertex, 4,
|
GLES20.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
GLES20.GL_SHORT, false, 12, off);
|
GLES20.GL_SHORT, false, 12, off);
|
||||||
@ -94,7 +95,7 @@ public final class TextureRenderer {
|
|||||||
GLES20.glVertexAttribPointer(hTextureTexCoord, 2,
|
GLES20.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
GLES20.GL_SHORT, false, 12, off + 8);
|
GLES20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
int numVertices = to.vertices - i;
|
int numVertices = ti.vertices - i;
|
||||||
if (numVertices > maxVertices)
|
if (numVertices > maxVertices)
|
||||||
numVertices = maxVertices;
|
numVertices = maxVertices;
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,6 @@ import org.oscim.core.Tile;
|
|||||||
import org.oscim.graphics.Color;
|
import org.oscim.graphics.Color;
|
||||||
import org.oscim.graphics.Paint.Cap;
|
import org.oscim.graphics.Paint.Cap;
|
||||||
import org.oscim.layers.tile.MapTile;
|
import org.oscim.layers.tile.MapTile;
|
||||||
import org.oscim.layers.tile.MapTile;
|
|
||||||
import org.oscim.layers.tile.TileRenderLayer;
|
import org.oscim.layers.tile.TileRenderLayer;
|
||||||
import org.oscim.layers.tile.TileSet;
|
import org.oscim.layers.tile.TileSet;
|
||||||
import org.oscim.renderer.BufferObject;
|
import org.oscim.renderer.BufferObject;
|
||||||
@ -61,7 +60,7 @@ import android.opengl.GLES20;
|
|||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
public class TextOverlay extends BasicOverlay {
|
public class TextOverlay extends BasicOverlay {
|
||||||
//private final static String TAG = TextOverlay.class.getName();
|
private final static String TAG = TextOverlay.class.getName();
|
||||||
private final static float MIN_CAPTION_DIST = 5;
|
private final static float MIN_CAPTION_DIST = 5;
|
||||||
private final static float MIN_WAY_DIST = 3;
|
private final static float MIN_WAY_DIST = 3;
|
||||||
|
|
||||||
@ -179,7 +178,7 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
mRun = false;
|
mRun = false;
|
||||||
|
|
||||||
if (updateLabels()) {
|
if (updateLabels()) {
|
||||||
mMapView.redrawMap(true);
|
mMapView.render();
|
||||||
} else {
|
} else {
|
||||||
mRun = true;
|
mRun = true;
|
||||||
}
|
}
|
||||||
@ -695,14 +694,15 @@ public class TextOverlay extends BasicOverlay {
|
|||||||
|
|
||||||
// set new TextLayer to be uploaded and rendered
|
// set new TextLayer to be uploaded and rendered
|
||||||
layers.textureLayers = mNextLayer;
|
layers.textureLayers = mNextLayer;
|
||||||
|
mNextLayer = null;
|
||||||
|
|
||||||
// make the 'labeled' MapPosition current
|
// make the 'labeled' MapPosition current
|
||||||
MapPosition tmp = mMapPosition;
|
MapPosition tmp = mMapPosition;
|
||||||
mMapPosition = mTmpPos;
|
mMapPosition = mTmpPos;
|
||||||
mTmpPos = tmp;
|
mTmpPos = tmp;
|
||||||
|
|
||||||
newData = true;
|
this.newData = true;
|
||||||
mNextLayer = null;
|
|
||||||
if (!(positionChanged || tilesChanged))
|
if (!(positionChanged || tilesChanged))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
48
src/org/oscim/utils/IOUtils.java
Normal file
48
src/org/oscim/utils/IOUtils.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
|
*
|
||||||
|
* 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.utils;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class with IO-specific helper methods.
|
||||||
|
*/
|
||||||
|
public final class IOUtils {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(IOUtils.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes the {@link Closeable#close()} method on the given object. If an {@link IOException} occurs during the
|
||||||
|
* method call, it will be caught and logged on level {@link Level#WARNING}.
|
||||||
|
*
|
||||||
|
* @param closeable
|
||||||
|
* the data source which should be closed (may be null).
|
||||||
|
*/
|
||||||
|
public static void closeQuietly(Closeable closeable) {
|
||||||
|
try {
|
||||||
|
if (closeable != null) {
|
||||||
|
closeable.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOGGER.log(Level.FINE, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IOUtils() {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,26 +21,45 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
|
|
||||||
protected T pool;
|
protected T pool;
|
||||||
|
|
||||||
public SyncPool(){
|
public SyncPool() {
|
||||||
maxFill = 100;
|
maxFill = 100;
|
||||||
|
fill = 0;
|
||||||
|
count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SyncPool(int maxItemsInPool) {
|
public SyncPool(int maxItemsInPool) {
|
||||||
maxFill = maxItemsInPool;
|
maxFill = maxItemsInPool;
|
||||||
fill = 0;
|
fill = 0;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFill() {
|
||||||
|
return fill;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param items number of initial items
|
* @param items number of initial items
|
||||||
*/
|
*/
|
||||||
public void init(int items){
|
public void init(int items) {
|
||||||
|
count = items;
|
||||||
|
fill = items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param item set initial state
|
||||||
|
*/
|
||||||
|
protected void clearItem(T item) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param item release resources
|
* @param item release resources
|
||||||
*/
|
*/
|
||||||
protected void clearItem(T item) {
|
protected void freeItem(T item) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +78,8 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
item.next = pool;
|
item.next = pool;
|
||||||
pool = item;
|
pool = item;
|
||||||
}
|
}
|
||||||
} else{
|
} else {
|
||||||
|
freeItem(item);
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,69 +88,36 @@ public abstract class SyncPool<T extends Inlist<T>> {
|
|||||||
if (item == null)
|
if (item == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fill > maxFill)
|
if (fill > maxFill) {
|
||||||
while (item != null) {
|
while (item != null) {
|
||||||
clearItem(item);
|
clearItem(item);
|
||||||
|
freeItem(item);
|
||||||
|
count--;
|
||||||
|
|
||||||
item = item.next;
|
item = item.next;
|
||||||
count--;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (item == null)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
while (item != null) {
|
while (item != null) {
|
||||||
T next = item.next;
|
T next = item.next;
|
||||||
|
|
||||||
clearItem(item);
|
clearItem(item);
|
||||||
|
fill++;
|
||||||
|
|
||||||
item.next = pool;
|
item.next = pool;
|
||||||
pool = item;
|
pool = item;
|
||||||
fill++;
|
|
||||||
|
|
||||||
item = next;
|
item = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove 'item' from 'list' and add back to pool
|
|
||||||
public T release(T list, T item) {
|
|
||||||
if (item == null)
|
|
||||||
return list;
|
|
||||||
|
|
||||||
T ret = list;
|
|
||||||
|
|
||||||
clearItem(item);
|
|
||||||
|
|
||||||
if (item == list) {
|
|
||||||
ret = item.next;
|
|
||||||
} else {
|
|
||||||
for (T prev = list, it = list.next; it != null; it = it.next) {
|
|
||||||
if (it == item) {
|
|
||||||
prev.next = it.next;
|
|
||||||
}
|
|
||||||
prev = it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fill < maxFill) {
|
|
||||||
synchronized (this) {
|
|
||||||
fill++;
|
|
||||||
|
|
||||||
item.next = pool;
|
|
||||||
pool = item;
|
|
||||||
}
|
|
||||||
} else{
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T get() {
|
public T get() {
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (pool == null){
|
if (pool == null) {
|
||||||
count++;
|
count++;
|
||||||
return createItem();
|
return createItem();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import org.oscim.core.MapPosition;
|
|||||||
import org.oscim.core.Tile;
|
import org.oscim.core.Tile;
|
||||||
import org.oscim.database.MapOptions;
|
import org.oscim.database.MapOptions;
|
||||||
import org.oscim.layers.Layer;
|
import org.oscim.layers.Layer;
|
||||||
|
import org.oscim.layers.tile.BitmapTileLayer;
|
||||||
import org.oscim.layers.tile.MapTileLayer;
|
import org.oscim.layers.tile.MapTileLayer;
|
||||||
import org.oscim.layers.tile.MapTileLoader;
|
import org.oscim.layers.tile.MapTileLoader;
|
||||||
import org.oscim.overlay.BuildingOverlay;
|
import org.oscim.overlay.BuildingOverlay;
|
||||||
@ -152,6 +153,18 @@ public class MapView extends RelativeLayout {
|
|||||||
return baseLayer;
|
return baseLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setBackgroundMap(BitmapTileLayer tileLayer) {
|
||||||
|
mLayerManager.add(0, tileLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapTileLayer setBaseMap(BitmapTileLayer tileLayer) {
|
||||||
|
mLayerManager.add(0, new MapEventLayer(this));
|
||||||
|
mLayerManager.add(1, tileLayer);
|
||||||
|
|
||||||
|
//mRotationEnabled = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
mLayerManager.destroy();
|
mLayerManager.destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user