refactor and cleanup RenderElement and related classes

This commit is contained in:
Hannes Janetzek 2014-01-29 16:23:21 +01:00
parent e38c9a11ff
commit 5235e8483b
23 changed files with 317 additions and 354 deletions

View File

@ -417,7 +417,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
if (v != null)
minHeight = Integer.parseInt(v);
ExtrusionLayer l = (ExtrusionLayer) mTile.layers.extrusionLayers;
ExtrusionLayer l = mTile.layers.getExtrusionLayers();
if (l == null) {
double lat = MercatorProjection.toLatitude(mTile.y);
@ -425,7 +425,8 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
* MercatorProjection.EARTH_CIRCUMFERENCE
/ ((long) Tile.SIZE << mTile.zoomLevel));
mTile.layers.extrusionLayers = l = new ExtrusionLayer(0, groundScale, extrusion.colors);
l = new ExtrusionLayer(0, groundScale, extrusion.colors);
mTile.layers.setExtrusionLayers(l);
}
l.add(mElement, height, minHeight);
}

View File

@ -216,7 +216,7 @@ public class PathLayer extends Layer {
mMapPosition.copy(t.pos);
// compile new layers
layers.baseLayers = t.layer.baseLayers;
layers.setBaseLayers(t.layer.getBaseLayers());
compile();
}
}
@ -289,7 +289,7 @@ public class PathLayer extends Layer {
}
if (size == 0) {
if (task.layer.baseLayers != null) {
if (task.layer.getBaseLayers() != null) {
task.layer.clear();
mMap.render();
}
@ -299,8 +299,6 @@ public class PathLayer extends Layer {
ElementLayers layers = task.layer;
LineLayer ll = layers.getLineLayer(0);
ll.clear();
ll.line = mLineStyle;
ll.width = ll.line.width;

View File

@ -115,7 +115,7 @@ public abstract class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer
synchronized (lock) {
if (mItems == null) {
if (layers.textureLayers != null) {
if (layers.getTextureLayers() != null) {
layers.clear();
compile();
}
@ -183,10 +183,9 @@ public abstract class ItemizedLayer<Item extends MarkerItem> extends MarkerLayer
mSymbolLayer.addSymbol(s);
}
}
mSymbolLayer.prepare();
layers.textureLayers = mSymbolLayer;
layers.setTextureLayers(mSymbolLayer);
compile();
}

View File

@ -141,7 +141,7 @@ public class BitmapTileLayer extends TileLayer<TileLoader> {
BitmapLayer l = new BitmapLayer(false);
l.setBitmap(bitmap, Tile.SIZE, Tile.SIZE);
mTile.layers = new ElementLayers();
mTile.layers.textureLayers = l;
mTile.layers.setTextureLayers(l);
}
@Override

View File

@ -441,7 +441,7 @@ public class VectorTileLoader extends TileLoader implements IRenderTheme.Callbac
/ ((long) Tile.SIZE << mTile.zoomLevel));
l = new ExtrusionLayer(0, groundScale, extrusion.colors);
mTile.layers.add(l);
mTile.layers.setExtrusionLayers(l);
}
l.add(mElement, height, minHeight);
}

View File

@ -69,7 +69,7 @@ class TextRenderer extends ElementRenderer {
}
// set new TextLayer to be uploaded and rendered
layers.textureLayers = t.layers;
layers.setTextureLayers(t.layers);
mMapPosition = t.pos;
compile();
}
@ -85,7 +85,7 @@ class TextRenderer extends ElementRenderer {
setMatrix(pos, m, false);
for (RenderElement l = layers.textureLayers; l != null;)
for (RenderElement l = layers.getTextureLayers(); l != null;)
l = TextureLayer.Renderer.draw(l, scale, m);
}

View File

@ -62,7 +62,7 @@ public class BitmapRenderer extends ElementRenderer {
BitmapLayer l = new BitmapLayer(true);
l.setBitmap(mBitmap, mWidth, mHeight);
layers.textureLayers = l;
layers.setTextureLayers(l);
mUpdateBitmap = true;
}
@ -86,6 +86,6 @@ public class BitmapRenderer extends ElementRenderer {
@Override
protected synchronized void render(MapPosition pos, Matrices m) {
m.useScreenCoordinates(false, 8);
BitmapLayer.Renderer.draw(layers.textureLayers, m, 1, 1);
BitmapLayer.Renderer.draw(layers.getTextureLayers(), m, 1, 1);
}
}

View File

@ -16,6 +16,13 @@
*/
package org.oscim.renderer;
import static org.oscim.renderer.elements.RenderElement.BITMAP;
import static org.oscim.renderer.elements.RenderElement.LINE;
import static org.oscim.renderer.elements.RenderElement.MESH;
import static org.oscim.renderer.elements.RenderElement.POLYGON;
import static org.oscim.renderer.elements.RenderElement.SYMBOL;
import static org.oscim.renderer.elements.RenderElement.TEXLINE;
import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
@ -51,11 +58,15 @@ public abstract class ElementRenderer extends LayerRenderer {
/**
* Use mMapPosition.copy(position) to keep the position for which
* the Overlay is _compiled_. NOTE: required by setMatrix utility
* the Overlay is *compiled*. NOTE: required by setMatrix utility
* functions to draw this layer fixed to the map
*/
protected MapPosition mMapPosition;
/** Wrap around dateline */
protected boolean mFlipOnDateLine = true;
/** Layer data for rendering */
public final ElementLayers layers;
public ElementRenderer() {
@ -67,59 +78,55 @@ public abstract class ElementRenderer extends LayerRenderer {
* Render all 'layers'
*/
@Override
protected synchronized void render(MapPosition curPos, Matrices m) {
MapPosition pos = mMapPosition;
float div = (float) (curPos.scale / pos.scale);
//float div = FastMath.pow(pos.zoomLevel - curPos.zoomLevel);
protected synchronized void render(MapPosition pos, Matrices m) {
MapPosition layerPos = mMapPosition;
layers.vbo.bind();
GLState.test(false, false);
GLState.blend(true);
if (layers.baseLayers != null) {
setMatrix(curPos, m, true);
float div = (float) (pos.scale / layerPos.scale);
for (RenderElement l = layers.baseLayers; l != null;) {
switch (l.type) {
case RenderElement.POLYGON:
l = PolygonLayer.Renderer.draw(curPos, l, m, true, 1, false);
break;
RenderElement l = layers.getBaseLayers();
case RenderElement.LINE:
l = LineLayer.Renderer.draw(layers, l, curPos, m, div);
break;
if (l != null)
setMatrix(pos, m, true);
case RenderElement.TEXLINE:
l = LineTexLayer.Renderer.draw(layers, l, curPos, m, div);
break;
case RenderElement.MESH:
l = MeshLayer.Renderer.draw(pos, l, m);
break;
default:
log.debug("invalid layer");
l = l.next;
break;
}
while (l != null) {
if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(pos, l, m, true, 1, false);
continue;
}
if (l.type == LINE) {
l = LineLayer.Renderer.draw(layers, l, pos, m, div);
continue;
}
if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(layers, l, pos, m, div);
continue;
}
if (l.type == MESH) {
l = MeshLayer.Renderer.draw(pos, l, m);
continue;
}
log.debug("invalid layer {}", l.type);
break;
}
if (layers.textureLayers != null) {
setMatrix(curPos, m, false);
for (RenderElement l = layers.textureLayers; l != null;) {
switch (l.type) {
case RenderElement.BITMAP:
l = BitmapLayer.Renderer.draw(l, m, 1, 1);
break;
default:
l = TextureLayer.Renderer.draw(l, 1 / div, m);
}
l = layers.getTextureLayers();
if (l != null)
setMatrix(pos, m, false);
while (l != null) {
if (l.type == BITMAP) {
l = BitmapLayer.Renderer.draw(l, m, 1, 1);
continue;
}
if (l.type == SYMBOL) {
l = TextureLayer.Renderer.draw(l, 1 / div, m);
continue;
}
log.debug("invalid layer {}", l.type);
break;
}
}
@ -147,7 +154,7 @@ public abstract class ElementRenderer extends LayerRenderer {
public static boolean uploadLayers(ElementLayers layers, int newSize,
boolean addFill) {
// add fill coordinates
if (addFill)
newSize += 8;
@ -192,11 +199,13 @@ public abstract class ElementRenderer extends LayerRenderer {
double x = oPos.x - position.x;
double y = oPos.y - position.y;
// wrap around date-line
// while (x < -1)
// x += 1.0;
// while (x > 2)
// x -= 1.0;
if (mFlipOnDateLine) {
//wrap around date-line
while (x < 0.5)
x += 1.0;
while (x > 0.5)
x -= 1.0;
}
matrices.mvp.setTransScale((float) (x * tileScale),
(float) (y * tileScale),

View File

@ -168,9 +168,9 @@ public class ExtrusionRenderer extends LayerRenderer {
}
private static ExtrusionLayer getLayer(MapTile t) {
if (t.layers != null && t.layers.extrusionLayers != null
if (t.layers != null && t.layers.getExtrusionLayers() != null
&& t.state(MapTile.STATE_READY))
return (ExtrusionLayer) t.layers.extrusionLayers;
return (ExtrusionLayer) t.layers.getExtrusionLayers();
return null;
}
@ -200,7 +200,7 @@ public class ExtrusionRenderer extends LayerRenderer {
GLState.test(false, false);
for (int i = 0; i < mTileCnt; i++) {
ExtrusionLayer el = (ExtrusionLayer) tiles[i].layers.extrusionLayers;
ExtrusionLayer el = tiles[i].layers.getExtrusionLayers();
setMatrix(pos, m, tiles[i], 0);
m.mvp.setAsUniform(uExtMatrix);
@ -251,7 +251,7 @@ public class ExtrusionRenderer extends LayerRenderer {
// draw to depth buffer
for (int i = 0; i < mTileCnt; i++) {
MapTile t = tiles[i];
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
ExtrusionLayer el = t.layers.getExtrusionLayers();
int d = MapRenderer.depthOffset(t) * 10;
setMatrix(pos, m, t, d);
m.mvp.setAsUniform(uExtMatrix);
@ -277,7 +277,7 @@ public class ExtrusionRenderer extends LayerRenderer {
for (int i = 0; i < mTileCnt; i++) {
MapTile t = tiles[i];
ExtrusionLayer el = (ExtrusionLayer) t.layers.extrusionLayers;
ExtrusionLayer el = t.layers.getExtrusionLayers();
if (el.colors == null) {
currentColor = mColor;

View File

@ -137,7 +137,8 @@ public class GridRenderer extends ElementRenderer {
if (mText != null) {
addLabels(x, y, pos.zoomLevel);
mLineLayer.clear();
layers.setBaseLayers(mLineLayer);
mLineLayer.addLine(mLines);
}

View File

@ -106,7 +106,7 @@ public class BitmapLayer extends TextureLayer {
buf[pos++] = texMax;
buf[pos++] = texMax;
setOffset(sbuf.position() * 2);
this.offset = sbuf.position() * 2;
sbuf.put(buf);
}
@ -215,7 +215,7 @@ public class BitmapLayer extends TextureLayer {
// draw up to maxVertices in each iteration
for (int i = 0; i < t.vertices; i += maxVertices) {
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
int off = (t.offset + i) * 8 + tl.getOffset();
int off = (t.offset + i) * 8 + tl.offset;
GL.glVertexAttribPointer(hTextureVertex, 4,
GL20.GL_SHORT, false, 12, off);

View File

@ -16,15 +16,24 @@
*/
package org.oscim.renderer.elements;
import static org.oscim.renderer.elements.RenderElement.LINE;
import static org.oscim.renderer.elements.RenderElement.MESH;
import static org.oscim.renderer.elements.RenderElement.POLYGON;
import static org.oscim.renderer.elements.RenderElement.TEXLINE;
import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
import org.oscim.renderer.BufferObject;
import org.oscim.theme.styles.Line;
import org.oscim.utils.pool.Inlist;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is primarily intended for rendering the vector elements of a
* MapTile. It can be used for other purposes as well but some optimizations
* applied probably wont make sense in different contexts.
*/
public class ElementLayers {
static final Logger log = LoggerFactory.getLogger(ElementLayers.class);
@ -42,12 +51,13 @@ public class ElementLayers {
}
/** mixed Polygon- and LineLayer */
public RenderElement baseLayers;
private RenderElement baseLayers;
/** Text- and SymbolLayer */
public RenderElement textureLayers;
private RenderElement textureLayers;
private RenderElement extrusionLayers;
public RenderElement extrusionLayers;
/**
* VBO holds all vertex data to draw lines and polygons after compilation.
* Layout:
@ -62,10 +72,9 @@ public class ElementLayers {
* To not need to switch VertexAttribPointer positions all the time:
* 1. polygons are packed in VBO at offset 0
* 2. lines afterwards at lineOffset
* 3. other layers keep their byte offset in RenderElement.offset
* 3. other layers keep their byte offset in offset
*/
public int lineOffset;
public int texLineOffset;
public int[] offset = { 0, 0 };
private RenderElement mCurLayer;
@ -74,7 +83,7 @@ public class ElementLayers {
* ordered from bottom (0) to top
*/
public LineLayer addLineLayer(int level, Line style) {
LineLayer ll = (LineLayer) getLayer(level, RenderElement.LINE);
LineLayer ll = (LineLayer) getLayer(level, LINE);
if (ll == null)
return null;
@ -89,7 +98,7 @@ public class ElementLayers {
* bottom (0) to top
*/
public LineLayer getLineLayer(int level) {
return (LineLayer) getLayer(level, RenderElement.LINE);
return (LineLayer) getLayer(level, LINE);
}
/**
@ -97,7 +106,7 @@ public class ElementLayers {
* bottom (0) to top
*/
public MeshLayer getMeshLayer(int level) {
return (MeshLayer) getLayer(level, RenderElement.MESH);
return (MeshLayer) getLayer(level, MESH);
}
/**
@ -105,7 +114,7 @@ public class ElementLayers {
* bottom (0) to top
*/
public PolygonLayer getPolygonLayer(int level) {
return (PolygonLayer) getLayer(level, RenderElement.POLYGON);
return (PolygonLayer) getLayer(level, POLYGON);
}
/**
@ -113,7 +122,7 @@ public class ElementLayers {
* bottom (0) to top
*/
public LineTexLayer getLineTexLayer(int level) {
return (LineTexLayer) getLayer(level, RenderElement.TEXLINE);
return (LineTexLayer) getLayer(level, TEXLINE);
}
public TextLayer addTextLayer(TextLayer textLayer) {
@ -122,86 +131,127 @@ public class ElementLayers {
return textLayer;
}
private RenderElement getLayer(int level, byte type) {
RenderElement l = baseLayers;
RenderElement renderElement = null;
public void setBaseLayers(RenderElement layers) {
for (RenderElement l = baseLayers; l != null; l = l.next)
l.clear();
if (!(type == RenderElement.LINE
|| type == RenderElement.POLYGON
|| type == RenderElement.TEXLINE
|| type == RenderElement.MESH))
throw new IllegalArgumentException("invalid layer type");
baseLayers = layers;
}
public RenderElement getBaseLayers() {
return baseLayers;
}
public void setTextureLayers(TextureLayer tl) {
for (RenderElement l = textureLayers; l != null; l = l.next)
l.clear();
textureLayers = tl;
}
public RenderElement getTextureLayers() {
return textureLayers;
}
public void setExtrusionLayers(ExtrusionLayer el) {
for (RenderElement l = extrusionLayers; l != null; l = l.next)
l.clear();
extrusionLayers = el;
}
public ExtrusionLayer getExtrusionLayers() {
return (ExtrusionLayer) extrusionLayers;
}
/** cleanup only when layers are not used by tile or overlay anymore! */
public void clear() {
setBaseLayers(null);
setTextureLayers(null);
setExtrusionLayers(null);
mCurLayer = null;
if (vbo != null)
vbo = BufferObject.release(vbo);
}
private RenderElement getLayer(int level, int type) {
RenderElement layer = null;
if (mCurLayer != null && mCurLayer.level == level) {
renderElement = mCurLayer;
} else {
layer = mCurLayer;
if (layer.type != type) {
log.error("BUG wrong layer {} {} on layer {}",
layer.type, type, level);
if (l == null || l.level > level) {
// insert new layer at start
l = null;
} else {
while (true) {
// found layer
if (l.level == level) {
renderElement = l;
break;
}
// insert new layer between current and next layer
if (l.next == null || l.next.level > level)
break;
l = l.next;
}
throw new IllegalArgumentException();
}
return layer;
}
if (renderElement == null) {
// add a new RenderElement
if (type == RenderElement.LINE)
renderElement = new LineLayer(level);
else if (type == RenderElement.POLYGON)
renderElement = new PolygonLayer(level);
else if (type == RenderElement.TEXLINE)
renderElement = new LineTexLayer(level);
else if (type == RenderElement.MESH)
renderElement = new MeshLayer(level);
if (renderElement == null)
throw new IllegalArgumentException();
if (l == null) {
// insert at start
renderElement.next = baseLayers;
baseLayers = renderElement;
} else {
renderElement.next = l.next;
l.next = renderElement;
RenderElement l = baseLayers;
if (l == null || l.level > level) {
/** insert new layer at start */
l = null;
} else {
while (true) {
/** found layer */
if (l.level == level) {
layer = l;
break;
}
/** insert layer between current and next layer */
if (l.next == null || l.next.level > level)
break;
l = l.next;
}
}
if (renderElement.type != type) {
// check if found layer matches requested type
log.debug("BUG wrong layer " + renderElement.type + " " + type +
" on layer " + renderElement.level);
if (layer == null) {
/** add a new RenderElement */
if (type == LINE)
layer = new LineLayer(level);
else if (type == POLYGON)
layer = new PolygonLayer(level);
else if (type == TEXLINE)
layer = new LineTexLayer(level);
else if (type == MESH)
layer = new MeshLayer(level);
if (layer == null)
throw new IllegalArgumentException();
if (l == null) {
/** insert at start */
layer.next = baseLayers;
baseLayers = layer;
} else {
layer.next = l.next;
l.next = layer;
}
}
/** check if found layer matches requested type */
if (layer.type != type) {
log.error("BUG wrong layer {} {} on layer {}",
layer.type, type, level);
throw new IllegalArgumentException();
}
mCurLayer = renderElement;
mCurLayer = layer;
return renderElement;
return layer;
}
private final static int[] VERTEX_SHORT_CNT = {
4, // LINE_VERTEX_SHORTS
6, // TEXLINE_VERTEX_SHORTS
2, // POLY_VERTEX_SHORTS
2, // MESH_VERTEX_SHORTS
6, // TEXLINE_VERTEX_SHORTS
};
private final static int TEXTURE_VERTEX_SHORTS = 6;
private final static int SHORT_BYTES = 2;
public int getSize() {
@ -217,51 +267,32 @@ public class ElementLayers {
}
public void compile(ShortBuffer sbuf, boolean addFill) {
// offset from fill coordinates
int pos = 0;
int size = 0;
if (addFill) {
pos = 4;
size = 8;
}
addLayerItems(sbuf, baseLayers, POLYGON, addFill ? 4 : 0);
size += addLayerItems(sbuf, baseLayers, RenderElement.POLYGON, pos);
offset[LINE] = sbuf.position() * SHORT_BYTES;
addLayerItems(sbuf, baseLayers, LINE, 0);
lineOffset = size * SHORT_BYTES;
size += addLayerItems(sbuf, baseLayers, RenderElement.LINE, 0);
texLineOffset = size * SHORT_BYTES;
//offset[TEXLINE] = size * SHORT_BYTES;
for (RenderElement l = baseLayers; l != null; l = l.next) {
if (l.type == RenderElement.TEXLINE) {
addPoolItems(l, sbuf);
// add additional vertex for interleaving,
// see TexLineLayer.
sbuf.position(sbuf.position() + 6);
if (l.type == TEXLINE || l.type == MESH) {
l.compile(sbuf);
}
}
for (RenderElement l = baseLayers; l != null; l = l.next) {
if (l.type == RenderElement.MESH)
l.compile(sbuf);
}
for (RenderElement l = textureLayers; l != null; l = l.next) {
//TextureLayer tl = (TextureLayer) l;
l.compile(sbuf);
}
// extrusion layers are compiled by extrusion overlay
// for (RenderElement l = extrusionLayers; l != null; l = l.next) {
// ExtrusionLayer tl = (ExtrusionLayer) l;
// tl.compile(sbuf);
// }
}
// optimization for Line- and PolygonLayer:
// collect all pool items and add back in one go
private static int addLayerItems(ShortBuffer sbuf, RenderElement l, byte type, int pos) {
/**
* optimization for Line- and PolygonLayer:
* collect all pool items and add back in one go.
*/
private static int addLayerItems(ShortBuffer sbuf, RenderElement l,
int type, int pos) {
VertexItem last = null, items = null;
int size = 0;
@ -283,7 +314,7 @@ public class ElementLayers {
if (last == null)
continue;
l.setOffset(pos);
l.offset = pos;
pos += l.numVertices;
last.next = items;
@ -298,8 +329,8 @@ public class ElementLayers {
}
static void addPoolItems(RenderElement l, ShortBuffer sbuf) {
// offset of layer data in vbo
l.setOffset(sbuf.position() * SHORT_BYTES);
/** keep offset of layer data in vbo */
l.offset = sbuf.position() * SHORT_BYTES;
for (VertexItem it = l.vertexItems; it != null; it = it.next) {
if (it.next == null)
@ -310,39 +341,4 @@ public class ElementLayers {
l.vertexItems = VertexItem.pool.releaseAll(l.vertexItems);
}
// cleanup only when layers are not used by tile or overlay anymore!
public void clear() {
// clear line and polygon layers directly
for (RenderElement l = baseLayers; l != null; l = l.next) {
if (l.vertexItems != null)
l.vertexItems = VertexItem.pool.releaseAll(l.vertexItems);
l.numVertices = 0;
}
for (RenderElement l = textureLayers; l != null; l = l.next)
l.clear();
for (RenderElement l = extrusionLayers; l != null; l = l.next)
l.clear();
baseLayers = null;
textureLayers = null;
extrusionLayers = null;
mCurLayer = null;
// if (vbo != null){
// BufferObject.release(vbo);
// vbo = null;
// }
}
public void add(ExtrusionLayer l) {
extrusionLayers = Inlist.appendItem(extrusionLayers, l);
}
public ExtrusionLayer getExtrusionLayers() {
return (ExtrusionLayer) extrusionLayers;
}
}

View File

@ -16,8 +16,6 @@
*/
package org.oscim.renderer.elements;
import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
import org.oscim.backend.canvas.Paint.Cap;
@ -556,16 +554,6 @@ public final class LineLayer extends RenderElement {
si.used = opos;
}
@Override
public void clear() {
vertexItems = VertexItem.pool.releaseAll(vertexItems);
numVertices = 0;
}
@Override
protected void compile(ShortBuffer sbuf) {
}
public static final class Renderer {
// TODO: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter22.html
@ -668,7 +656,7 @@ public final class LineLayer extends RenderElement {
GLState.enableVertexArrays(hLineVertexPosition[mode], -1);
GL.glVertexAttribPointer(hLineVertexPosition[mode], 4, GL20.GL_SHORT,
false, 0, layers.lineOffset);
false, 0, layers.offset[LINE]);
m.mvp.setAsUniform(hLineMatrix[mode]);
@ -745,7 +733,7 @@ public final class LineLayer extends RenderElement {
}
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP,
l.getOffset(), l.numVertices);
l.offset, l.numVertices);
continue;
}
@ -781,7 +769,7 @@ public final class LineLayer extends RenderElement {
}
GL.glDrawArrays(GL20.GL_TRIANGLE_STRIP,
o.getOffset(), o.numVertices);
o.offset, o.numVertices);
}
}

View File

@ -246,12 +246,12 @@ public final class LineTexLayer extends RenderElement {
si.used = opos;
}
@Override
protected void clear() {
}
@Override
protected void compile(ShortBuffer sbuf) {
ElementLayers.addPoolItems(this, sbuf);
// add additional vertex for interleaving,
// see TexLineLayer.
sbuf.position(sbuf.position() + 6);
}
public final static class Renderer {
@ -369,7 +369,6 @@ public final class LineTexLayer extends RenderElement {
for (; l != null && l.type == RenderElement.TEXLINE; l = l.next) {
LineTexLayer ll = (LineTexLayer) l;
Line line = ll.line;
int lOffset = l.getOffset();
GLUtils.setColor(hTexColor, line.stippleColor, 1);
GLUtils.setColor(hBgColor, line.color, 1);
@ -396,7 +395,7 @@ public final class LineTexLayer extends RenderElement {
numIndices = maxIndices;
// i / 6 * (24 shorts per block * 2 short bytes)
int add = (lOffset + i * 8) + vOffset;
int add = (l.offset + i * 8) + vOffset;
GL.glVertexAttribPointer(hVertexPosition0,
4, GL20.GL_SHORT, false, STRIDE,
@ -425,7 +424,7 @@ public final class LineTexLayer extends RenderElement {
if (numIndices > maxIndices)
numIndices = maxIndices;
// i / 6 * (24 shorts per block * 2 short bytes)
int add = (lOffset + i * 8) + vOffset;
int add = (l.offset + i * 8) + vOffset;
GL.glVertexAttribPointer(hVertexPosition0,
4, GL20.GL_SHORT, false, STRIDE,

View File

@ -144,7 +144,7 @@ public class MeshLayer extends RenderElement {
GLUtils.setColor(hColor, ml.area.color, 1);
GL.glVertexAttribPointer(hVertexPosition, 2, GL20.GL_SHORT,
false, 0, ml.getOffset());
false, 0, ml.offset);
GL.glDrawElements(GL20.GL_TRIANGLES, ml.numIndices,
GL20.GL_UNSIGNED_SHORT, 0);

View File

@ -19,7 +19,6 @@ package org.oscim.renderer.elements;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import org.oscim.backend.GL20;
import org.oscim.backend.GLAdapter;
@ -117,14 +116,6 @@ public final class PolygonLayer extends RenderElement {
si.used = outPos;
}
@Override
protected void compile(ShortBuffer sbuf) {
}
@Override
protected void clear() {
}
public static final class Renderer {
private static final int POLYGON_VERTICES_DATA_POS_OFFSET = 0;
@ -326,7 +317,7 @@ public final class PolygonLayer extends RenderElement {
// set stencil mask to draw to
GL.glStencilMask(1 << cur++);
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.getOffset(), l.numVertices);
GL.glDrawArrays(GL20.GL_TRIANGLE_FAN, l.offset, l.numVertices);
// draw up to 7 layers into stencil buffer
if (cur == STENCIL_BITS - 1) {

View File

@ -24,45 +24,45 @@ import org.oscim.utils.pool.Inlist;
public abstract class RenderElement extends Inlist<RenderElement> {
protected static GL20 GL;
public final static byte LINE = 0;
public final static byte POLYGON = 1;
public final static byte MESH = 2;
public final static byte TEXLINE = 3;
public final static byte SYMBOL = 4;
public final static byte BITMAP = 5;
public final static byte EXTRUSION = 6;
public final static int LINE = 0;
public final static int TEXLINE = 1;
public final static int POLYGON = 2;
public final static int MESH = 3;
public final static int SYMBOL = 4;
public final static int BITMAP = 5;
public final static int EXTRUSION = 6;
protected RenderElement(byte type) {
public final int type;
/** drawing order from bottom to top. */
int level;
/** number of vertices for this layer. */
protected int numVertices;
/** temporary list of vertex data. */
protected VertexItem vertexItems;
protected RenderElement(int type) {
this.type = type;
}
public final byte type;
/** clear all resources. */
protected void clear() {
if (vertexItems != null)
vertexItems = VertexItem.pool.releaseAll(vertexItems);
numVertices = 0;
}
/** drawing order from bottom to top */
int level;
/** compile vertex data to vbo. */
protected void compile(ShortBuffer sbuf) {
/** number of vertices for this layer */
protected int numVertices;
protected VertexItem vertexItems;
abstract protected void compile(ShortBuffer sbuf);
abstract protected void clear();
}
/**
* for line and polygon layers:
* - number of VERTICES mOffset for this layertype in VBO
* otherwise:
* - offset in byte in VBO
* For line- and polygon-layers this is the offset
* of VERTICES in its layers.vbo.
* For all other types it is the byte offset in vbo.
*/
private int mOffset;
public int getOffset() {
return mOffset;
}
public void setOffset(int offset) {
mOffset = offset;
}
protected int offset;
}

View File

@ -62,7 +62,7 @@ public final class SymbolLayer extends TextureLayer {
@Override
protected void compile(ShortBuffer sbuf) {
// offset of layer data in vbo
setOffset(sbuf.position() * 2); //SHORT_BYTES;
this.offset = sbuf.position() * 2; //SHORT_BYTES;
short numIndices = 0;

View File

@ -42,7 +42,7 @@ public abstract class TextureLayer extends RenderElement {
TEXTURE_WIDTH,
TEXTURE_HEIGHT);
protected TextureLayer(byte type) {
protected TextureLayer(int type) {
super(type);
}
@ -174,7 +174,7 @@ public abstract class TextureLayer extends RenderElement {
// draw up to maxVertices in each iteration
for (int i = 0; i < t.vertices; i += maxVertices) {
// to.offset * (24(shorts) * 2(short-bytes) / 6(indices) == 8)
int off = (t.offset + i) * 8 + tl.getOffset();
int off = (t.offset + i) * 8 + tl.offset;
GL.glVertexAttribPointer(hTextureVertex, 4,
GL20.GL_SHORT, false, 12, off);

View File

@ -56,7 +56,7 @@ public class AtlasRenderLayer extends ElementRenderer {
TextLayer tl = new TextLayer();
Text t = Text.createText(20, 0, Color.BLACK, 0, false);
layers.textureLayers = tl;
layers.setTextureLayers(tl);
float[] points = new float[10];

View File

@ -28,7 +28,7 @@ public class SymbolRenderLayer extends ElementRenderer {
public SymbolRenderLayer() {
SymbolLayer l = new SymbolLayer();
layers.textureLayers = l;
layers.setTextureLayers(l);
SymbolItem it = SymbolItem.pool.get();
it.billboard = false;

View File

@ -17,7 +17,6 @@
package org.oscim.tiling;
import org.oscim.core.Tile;
import org.oscim.renderer.BufferObject;
import org.oscim.renderer.elements.ElementLayers;
import org.oscim.renderer.elements.SymbolItem;
import org.oscim.renderer.elements.TextItem;
@ -226,8 +225,6 @@ public class MapTile extends Tile {
*/
protected void clear() {
if (layers != null) {
// TODO move this to layers clear
layers.vbo = BufferObject.release(layers.vbo);
layers.clear();
layers = null;
}

View File

@ -16,6 +16,11 @@
*/
package org.oscim.tiling;
import static org.oscim.renderer.elements.RenderElement.BITMAP;
import static org.oscim.renderer.elements.RenderElement.LINE;
import static org.oscim.renderer.elements.RenderElement.MESH;
import static org.oscim.renderer.elements.RenderElement.POLYGON;
import static org.oscim.renderer.elements.RenderElement.TEXLINE;
import static org.oscim.tiling.MapTile.STATE_NEW_DATA;
import static org.oscim.tiling.MapTile.STATE_READY;
@ -178,19 +183,19 @@ public class TileRenderer extends LayerRenderer {
return 1;
int newSize = tile.layers.getSize();
if (newSize > 0) {
if (newSize <= 0)
return 1;
if (tile.layers.vbo == null)
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
if (tile.layers.vbo == null)
tile.layers.vbo = BufferObject.get(GL20.GL_ARRAY_BUFFER, newSize);
if (!ElementRenderer.uploadLayers(tile.layers, newSize, true)) {
log.debug("BUG uploadTileData " + tile + " failed!");
if (!ElementRenderer.uploadLayers(tile.layers, newSize, true)) {
log.debug("BUG uploadTileData " + tile + " failed!");
tile.layers.vbo = BufferObject.release(tile.layers.vbo);
tile.layers.clear();
tile.layers = null;
return 0;
}
tile.layers.vbo = BufferObject.release(tile.layers.vbo);
tile.layers.clear();
tile.layers = null;
return 0;
}
return 1;
@ -395,7 +400,8 @@ public class TileRenderer extends LayerRenderer {
for (int i = 0; i < tileCnt; i++) {
MapTile t = tiles[i];
if (t.isVisible && (t.state != STATE_READY) && (t.holder == null)) {
boolean preferParent = (scale > 1.5) || (pos.zoomLevel - t.zoomLevel < 0);
boolean preferParent = (scale > 1.5)
|| (pos.zoomLevel - t.zoomLevel < 0);
drawProxyTile(t, pos, true, preferParent);
}
}
@ -416,33 +422,29 @@ public class TileRenderer extends LayerRenderer {
}
private void drawTile(MapTile tile, MapPosition pos) {
// draw parents only once
/** ensure to draw parents only once */
if (tile.lastDraw == mDrawSerial)
return;
tile.lastDraw = mDrawSerial;
MapTile t = tile;
if (t.holder != null)
t = t.holder;
/** use holder proxy when it is set */
MapTile t = tile.holder == null ? tile : tile.holder;
if (t.layers == null || t.layers.vbo == null) {
//log.debug("missing data " + (t.layers == null) + " " + (t.vbo == null));
if (t.layers == null || t.layers.vbo == null)
//throw new IllegalStateException(t + "no data " + (t.layers == null));
return;
}
t.layers.vbo.bind();
// place tile relative to map position
/** place tile relative to map position */
int z = tile.zoomLevel;
float div = FastMath.pow(z - pos.zoomLevel);
double tileScale = Tile.SIZE * pos.scale;
float x = (float) ((tile.x - pos.x) * tileScale);
float y = (float) ((tile.y - pos.y) * tileScale);
// scale relative to zoom-level of this tile
/** scale relative to zoom-level of this tile */
float scale = (float) (pos.scale / (1 << z));
Matrices m = mMatrices;
@ -450,64 +452,46 @@ public class TileRenderer extends LayerRenderer {
m.mvp.multiplyLhs(m.viewproj);
boolean clipped = false;
RenderElement l = t.layers.getBaseLayers();
for (RenderElement l = t.layers.baseLayers; l != null;) {
switch (l.type) {
case RenderElement.POLYGON:
l = PolygonLayer.Renderer.draw(pos, l, m, !clipped, div, true);
clipped = true;
break;
case RenderElement.LINE:
if (!clipped) {
clipped = true;
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
}
l = LineLayer.Renderer.draw(t.layers, l, pos, m, scale);
break;
case RenderElement.TEXLINE:
if (!clipped) {
clipped = true;
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
}
l = LineTexLayer.Renderer.draw(t.layers, l, pos, m, div);
break;
case RenderElement.MESH:
if (!clipped) {
clipped = true;
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
}
l = MeshLayer.Renderer.draw(pos, l, m);
break;
default:
// just in case
l = l.next;
while (l != null) {
if (l.type == POLYGON) {
l = PolygonLayer.Renderer.draw(pos, l, m, !clipped, div, true);
clipped = true;
continue;
}
}
for (RenderElement l = t.layers.textureLayers; l != null;) {
if (!clipped) {
// draw stencil buffer clip region
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
clipped = true;
}
// if (!clipped) {
// // draw stencil buffer clip region
// PolygonRenderer.clip(m);
// clipped = true;
// }
//GLState.test(false, false);
switch (l.type) {
case RenderElement.BITMAP:
l = BitmapLayer.Renderer.draw(l, m, 1, mRenderAlpha);
break;
default:
l = l.next;
if (l.type == LINE) {
l = LineLayer.Renderer.draw(t.layers, l, pos, m, scale);
continue;
}
if (l.type == TEXLINE) {
l = LineTexLayer.Renderer.draw(t.layers, l, pos, m, div);
continue;
}
if (l.type == MESH) {
l = MeshLayer.Renderer.draw(pos, l, m);
continue;
}
// just in case
l = l.next;
}
l = t.layers.getTextureLayers();
while (l != null) {
if (!clipped) {
PolygonLayer.Renderer.draw(pos, null, m, true, div, true);
clipped = true;
}
if (l.type == BITMAP) {
l = BitmapLayer.Renderer.draw(l, m, 1, mRenderAlpha);
continue;
}
l = l.next;
}
if (t.fadeTime == 0)