refactor: TextureItem:
- use different pools for TextLayer and bitmap tiles to always get the correct (matching) texture from pool. - the common TextureItem pool is only used to provide the same api, it does not keep images or textures
This commit is contained in:
parent
fa2d3dd7a4
commit
eff5935068
@ -20,9 +20,14 @@ import org.oscim.backend.CanvasAdapter;
|
|||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
import org.oscim.renderer.atlas.TextureAtlas.Rect;
|
||||||
import org.oscim.renderer.elements.TextureItem;
|
import org.oscim.renderer.elements.TextureItem;
|
||||||
|
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
||||||
import org.oscim.utils.pool.Inlist;
|
import org.oscim.utils.pool.Inlist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UNUSED
|
||||||
|
* */
|
||||||
public abstract class SpriteManager<T> {
|
public abstract class SpriteManager<T> {
|
||||||
|
TexturePool pool;
|
||||||
|
|
||||||
public class Sprite extends Inlist<Sprite> {
|
public class Sprite extends Inlist<Sprite> {
|
||||||
|
|
||||||
@ -46,14 +51,11 @@ public abstract class SpriteManager<T> {
|
|||||||
protected TextureItem mTexture;
|
protected TextureItem mTexture;
|
||||||
|
|
||||||
public SpriteManager() {
|
public SpriteManager() {
|
||||||
mTexture = TextureItem.get();
|
mTexture = pool.get();
|
||||||
|
|
||||||
//mTexture.ownBitmap = true;
|
//mTexture.ownBitmap = true;
|
||||||
|
|
||||||
mAtlas = new TextureAtlas(
|
mAtlas = new TextureAtlas(256, 256, 32);
|
||||||
TextureItem.TEXTURE_WIDTH,
|
|
||||||
TextureItem.TEXTURE_HEIGHT,
|
|
||||||
32);
|
|
||||||
|
|
||||||
mCanvas.setBitmap(mTexture.bitmap);
|
mCanvas.setBitmap(mTexture.bitmap);
|
||||||
}
|
}
|
||||||
@ -68,12 +70,12 @@ public abstract class SpriteManager<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
mTexture = TextureItem.pool.releaseAll(mTexture);
|
for (TextureItem t = mTexture; t != null; t = t.dispose());
|
||||||
mAtlas.clear();
|
mAtlas.clear();
|
||||||
items = null;
|
items = null;
|
||||||
|
|
||||||
//mTexture.bitmap.eraseColor(Color.TRANSPARENT);
|
//mTexture.bitmap.eraseColor(Color.TRANSPARENT);
|
||||||
mTexture = TextureItem.get();
|
mTexture = pool.get();
|
||||||
mCanvas.setBitmap(mTexture.bitmap);
|
mCanvas.setBitmap(mTexture.bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,15 +29,17 @@ import org.oscim.renderer.MapRenderer.Matrices;
|
|||||||
* Renderer for a single bitmap, width and height must be power of 2.
|
* Renderer for a single bitmap, width and height must be power of 2.
|
||||||
*/
|
*/
|
||||||
public class BitmapLayer extends TextureLayer {
|
public class BitmapLayer extends TextureLayer {
|
||||||
|
// TODO share layers.vbo() between BitmapTileLayers
|
||||||
|
|
||||||
// static final Logger log = LoggerFactory.getLogger(BitmapLayer.class);
|
// static final Logger log = LoggerFactory.getLogger(BitmapLayer.class);
|
||||||
private Bitmap mBitmap;
|
private Bitmap mBitmap;
|
||||||
private final boolean mReuseBitmap;
|
private final boolean mReuseBitmap;
|
||||||
private final short[] mVertices;
|
private final short[] mVertices;
|
||||||
|
private int mWidth, mHeight;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param reuseBitmap false if the Bitmap should be recycled after
|
* @param reuseBitmap false if the Bitmap should be disposed
|
||||||
* it is compiled to texture.
|
* after loading to texture.
|
||||||
*/
|
*/
|
||||||
public BitmapLayer(boolean reuseBitmap) {
|
public BitmapLayer(boolean reuseBitmap) {
|
||||||
super(RenderElement.BITMAP);
|
super(RenderElement.BITMAP);
|
||||||
@ -49,26 +51,19 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
verticesCnt = 4;
|
verticesCnt = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* w/h sets also target dimension to render the bitmap.
|
||||||
|
*/
|
||||||
public void setBitmap(Bitmap bitmap, int w, int h) {
|
public void setBitmap(Bitmap bitmap, int w, int h) {
|
||||||
mWidth = w;
|
mWidth = w;
|
||||||
mHeight = h;
|
mHeight = h;
|
||||||
|
|
||||||
mBitmap = bitmap;
|
mBitmap = bitmap;
|
||||||
if (this.textures == null)
|
if (textures == null)
|
||||||
this.textures = new TextureItem(mBitmap);
|
textures = new TextureItem(mBitmap);
|
||||||
|
|
||||||
TextureItem ti = this.textures;
|
TextureItem t = textures;
|
||||||
ti.vertices = TextureLayer.Renderer.INDICES_PER_SPRITE;
|
t.vertices = TextureLayer.INDICES_PER_SPRITE;
|
||||||
}
|
|
||||||
|
|
||||||
private int mWidth, mHeight;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set target dimension to renderthe bitmap
|
|
||||||
*/
|
|
||||||
public void setSize(int w, int h) {
|
|
||||||
mWidth = w;
|
|
||||||
mHeight = h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setVertices(ShortBuffer sbuf) {
|
private void setVertices(ShortBuffer sbuf) {
|
||||||
@ -76,37 +71,40 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
short w = (short) (mWidth * MapRenderer.COORD_SCALE);
|
short w = (short) (mWidth * MapRenderer.COORD_SCALE);
|
||||||
short h = (short) (mHeight * MapRenderer.COORD_SCALE);
|
short h = (short) (mHeight * MapRenderer.COORD_SCALE);
|
||||||
|
|
||||||
short t = 1;
|
short texMin = 0;
|
||||||
|
short texMax = 1;
|
||||||
|
|
||||||
|
// putSprite(buf, pos, tx, ty, x1, y1, x2, y2, u1, v1, u2, v2);
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
// top-left
|
// top-left
|
||||||
buf[pos++] = 0;
|
buf[pos++] = 0;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = 0;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = texMin;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = texMin;
|
||||||
// bot-left
|
// bot-left
|
||||||
buf[pos++] = 0;
|
buf[pos++] = 0;
|
||||||
buf[pos++] = h;
|
buf[pos++] = h;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = texMin;
|
||||||
buf[pos++] = t;
|
buf[pos++] = texMax;
|
||||||
// top-right
|
// top-right
|
||||||
buf[pos++] = w;
|
buf[pos++] = w;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = 0;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = t;
|
buf[pos++] = texMax;
|
||||||
buf[pos++] = 0;
|
buf[pos++] = texMin;
|
||||||
// bot-right
|
// bot-right
|
||||||
buf[pos++] = w;
|
buf[pos++] = w;
|
||||||
buf[pos++] = h;
|
buf[pos++] = h;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = -1;
|
buf[pos++] = -1;
|
||||||
buf[pos++] = t;
|
buf[pos++] = texMax;
|
||||||
buf[pos++] = t;
|
buf[pos++] = texMax;
|
||||||
|
|
||||||
this.offset = sbuf.position() * 2; // bytes
|
this.offset = sbuf.position() * 2; // bytes
|
||||||
sbuf.put(buf);
|
sbuf.put(buf);
|
||||||
@ -137,26 +135,25 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
@Override
|
@Override
|
||||||
protected void clear() {
|
protected void clear() {
|
||||||
|
|
||||||
if (mBitmap != null) {
|
// release textures and vertexItems
|
||||||
if (!mReuseBitmap)
|
super.clear();
|
||||||
mBitmap.recycle();
|
|
||||||
|
|
||||||
mBitmap = null;
|
if (mBitmap == null)
|
||||||
textures.bitmap = null;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
TextureItem.releaseTexture(textures);
|
if (!mReuseBitmap)
|
||||||
textures = null;
|
mBitmap.recycle();
|
||||||
|
|
||||||
vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
mBitmap = null;
|
||||||
|
|
||||||
|
//textures.bitmap = null;
|
||||||
|
//textures.dispose();
|
||||||
|
//TextureItem.pool.releaseTexture(textures);
|
||||||
|
//textures = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class Renderer {
|
public static final class Renderer {
|
||||||
|
|
||||||
//static final Logger log = LoggerFactory.getLogger(BitmapRenderer.class);
|
|
||||||
|
|
||||||
public final static boolean debug = true;
|
|
||||||
|
|
||||||
private static int mTextureProgram;
|
private static int mTextureProgram;
|
||||||
private static int hTextureMVMatrix;
|
private static int hTextureMVMatrix;
|
||||||
private static int hTextureProjMatrix;
|
private static int hTextureProjMatrix;
|
||||||
@ -209,16 +206,16 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(true);
|
MapRenderer.bindQuadIndicesVBO(true);
|
||||||
|
|
||||||
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
for (TextureItem t = tl.textures; t != null; t = t.next) {
|
||||||
|
|
||||||
ti.bind();
|
t.bind();
|
||||||
|
|
||||||
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
// draw up to maxVertices in each iteration
|
// draw up to maxVertices in each iteration
|
||||||
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
for (int i = 0; i < t.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 = (ti.offset + i) * 8 + tl.offset;
|
int off = (t.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
GL20.GL_SHORT, false, 12, off);
|
GL20.GL_SHORT, false, 12, off);
|
||||||
@ -226,7 +223,7 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
int numVertices = ti.vertices - i;
|
int numVertices = t.vertices - i;
|
||||||
if (numVertices > maxVertices)
|
if (numVertices > maxVertices)
|
||||||
numVertices = maxVertices;
|
numVertices = maxVertices;
|
||||||
|
|
||||||
@ -245,9 +242,6 @@ public class BitmapLayer extends TextureLayer {
|
|||||||
+ "attribute vec4 vertex;"
|
+ "attribute vec4 vertex;"
|
||||||
+ "attribute vec2 tex_coord;"
|
+ "attribute vec2 tex_coord;"
|
||||||
+ "uniform mat4 u_mv;"
|
+ "uniform mat4 u_mv;"
|
||||||
+ "uniform mat4 u_proj;"
|
|
||||||
+ "uniform float u_scale;"
|
|
||||||
+ "uniform float u_swidth;"
|
|
||||||
+ "varying vec2 tex_c;"
|
+ "varying vec2 tex_c;"
|
||||||
+ "void main() {"
|
+ "void main() {"
|
||||||
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
+ " gl_Position = u_mv * vec4(vertex.xy, 0.0, 1.0);"
|
||||||
|
|||||||
@ -38,7 +38,7 @@ public class ElementLayers {
|
|||||||
BitmapLayer.Renderer.init();
|
BitmapLayer.Renderer.init();
|
||||||
MeshLayer.Renderer.init();
|
MeshLayer.Renderer.init();
|
||||||
|
|
||||||
TextureItem.init(gl, 0);
|
TextureItem.init(gl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** mixed Polygon- and LineLayer */
|
/** mixed Polygon- and LineLayer */
|
||||||
|
|||||||
@ -73,7 +73,7 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
|
|
||||||
prevTextures = textures;
|
prevTextures = textures;
|
||||||
textures = null;
|
textures = null;
|
||||||
TextureItem to = null;
|
TextureItem t = null;
|
||||||
|
|
||||||
for (SymbolItem it = symbols; it != null;) {
|
for (SymbolItem it = symbols; it != null;) {
|
||||||
int width = 0, height = 0;
|
int width = 0, height = 0;
|
||||||
@ -82,14 +82,13 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
|
|
||||||
if (it.texRegion != null) {
|
if (it.texRegion != null) {
|
||||||
|
|
||||||
// FIXME this work only with one TextureAtlas per
|
// FIXME this work only with one TextureAtlas per SymbolLayer.
|
||||||
// SymbolLayer.
|
|
||||||
if (textures == null) {
|
if (textures == null) {
|
||||||
to = it.texRegion.atlas.loadTexture();
|
t = it.texRegion.atlas.loadTexture();
|
||||||
// clone TextureItem to use same texID with
|
// clone TextureItem to use same texID with
|
||||||
// multiple TextureItem
|
// multiple TextureItem
|
||||||
to = TextureItem.clone(to);
|
t = TextureItem.clone(t);
|
||||||
textures = Inlist.appendItem(textures, to);
|
textures = Inlist.appendItem(textures, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureAtlas.Rect r = it.texRegion.rect;
|
TextureAtlas.Rect r = it.texRegion.rect;
|
||||||
@ -99,20 +98,20 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
height = r.h;
|
height = r.h;
|
||||||
|
|
||||||
} else if (it.bitmap != null) {
|
} else if (it.bitmap != null) {
|
||||||
width = it.bitmap.getWidth();
|
t = getTexture(it.bitmap);
|
||||||
height = it.bitmap.getHeight();
|
|
||||||
to = getTexture(it.bitmap);
|
|
||||||
if (to == null) {
|
|
||||||
to = new TextureItem(it.bitmap);
|
|
||||||
textures = Inlist.appendItem(textures, to);
|
|
||||||
|
|
||||||
to.upload();
|
if (t == null) {
|
||||||
|
t = new TextureItem(it.bitmap);
|
||||||
|
textures = Inlist.appendItem(textures, t);
|
||||||
|
t.upload();
|
||||||
|
|
||||||
|
t.offset = numIndices;
|
||||||
|
t.vertices = 0;
|
||||||
}
|
}
|
||||||
to.offset = numIndices;
|
width = t.width;
|
||||||
to.vertices = 0;
|
height = t.height;
|
||||||
}
|
|
||||||
|
|
||||||
if (to == null) {
|
} else { //if (to == null) {
|
||||||
log.debug("Bad SymbolItem");
|
log.debug("Bad SymbolItem");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -126,9 +125,15 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
short x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
short x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||||
|
|
||||||
// add symbol items referencing the same bitmap /
|
// add symbol items referencing the same bitmap /
|
||||||
for (SymbolItem it2 = it;; it2 = it2.next) {
|
for (SymbolItem prev = it; it != null; it = it.next) {
|
||||||
|
|
||||||
if (it == it2 || it.offset != prevOffset) {
|
if (prev.bitmap != null && prev.bitmap != it.bitmap)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (prev.texRegion != null && prev.texRegion != it.texRegion)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (it == prev || it.offset != prevOffset) {
|
||||||
prevOffset = it.offset;
|
prevOffset = it.offset;
|
||||||
if (it.offset == null) {
|
if (it.offset == null) {
|
||||||
float hw = width / 2f;
|
float hw = width / 2f;
|
||||||
@ -147,18 +152,12 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
y2 = (short) (SCALE * (-hh));
|
y2 = (short) (SCALE * (-hh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (it2 == null
|
|
||||||
|| (it.bitmap != null && it2.bitmap != it.bitmap)
|
|
||||||
|| (it.texRegion != null && it2.texRegion != it.texRegion)) {
|
|
||||||
it = it2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add vertices
|
// add vertices
|
||||||
short tx = (short) ((int) (SCALE * it2.x) & LBIT_MASK
|
short tx = (short) ((int) (SCALE * it.x) & LBIT_MASK
|
||||||
| (it2.billboard ? 1 : 0));
|
| (it.billboard ? 1 : 0));
|
||||||
|
|
||||||
short ty = (short) (SCALE * it2.y);
|
short ty = (short) (SCALE * it.y);
|
||||||
|
|
||||||
if (pos == VertexItem.SIZE) {
|
if (pos == VertexItem.SIZE) {
|
||||||
sbuf.put(buf, 0, VertexItem.SIZE);
|
sbuf.put(buf, 0, VertexItem.SIZE);
|
||||||
@ -168,14 +167,12 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
TextureLayer.putSprite(buf, pos, tx, ty,
|
TextureLayer.putSprite(buf, pos, tx, ty,
|
||||||
x1, y1, x2, y2, u1, v1, u2, v2);
|
x1, y1, x2, y2, u1, v1, u2, v2);
|
||||||
|
|
||||||
// TextureRenderer.VERTICES_PER_SPRITE
|
pos += TextLayer.VERTICES_PER_SPRITE * 6;
|
||||||
// * TextureRenderer.SHORTS_PER_VERTICE;
|
|
||||||
pos += 24;
|
|
||||||
|
|
||||||
// six elements used to draw the four vertices
|
// six elements used to draw the four vertices
|
||||||
to.vertices += TextureLayer.Renderer.INDICES_PER_SPRITE;
|
t.vertices += TextureLayer.INDICES_PER_SPRITE;
|
||||||
}
|
}
|
||||||
numIndices += to.vertices;
|
numIndices += t.vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos > 0)
|
if (pos > 0)
|
||||||
@ -183,35 +180,40 @@ public final class SymbolLayer extends TextureLayer {
|
|||||||
|
|
||||||
si = VertexItem.pool.release(si);
|
si = VertexItem.pool.release(si);
|
||||||
|
|
||||||
prevTextures = TextureItem.pool.releaseAll(prevTextures);
|
for (t = prevTextures; t != null; t = t.dispose());
|
||||||
|
prevTextures = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextureItem getTexture(Bitmap bitmap) {
|
private TextureItem getTexture(Bitmap bitmap) {
|
||||||
TextureItem to;
|
TextureItem t;
|
||||||
|
|
||||||
for (to = prevTextures; to != null; to = to.next) {
|
for (t = prevTextures; t != null; t = t.next) {
|
||||||
if (to.bitmap == bitmap) {
|
if (t.bitmap == bitmap) {
|
||||||
prevTextures = Inlist.remove(prevTextures, to);
|
prevTextures = Inlist.remove(prevTextures, t);
|
||||||
textures = Inlist.appendItem(textures, to);
|
textures = Inlist.appendItem(textures, t);
|
||||||
break;
|
|
||||||
|
t.offset = 0;
|
||||||
|
t.vertices = 0;
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
return to;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearItems() {
|
public void clearItems() {
|
||||||
symbols = SymbolItem.pool.releaseAll(symbols);
|
symbols = SymbolItem.pool.releaseAll(symbols);
|
||||||
verticesCnt = 0;
|
//verticesCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
textures = TextureItem.pool.releaseAll(textures);
|
// release textures
|
||||||
symbols = SymbolItem.pool.releaseAll(symbols);
|
super.clear();
|
||||||
vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
clearItems();
|
||||||
|
|
||||||
verticesCnt = 0;
|
//symbols = SymbolItem.pool.releaseAll(symbols);
|
||||||
|
//vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
//verticesCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -17,14 +17,11 @@
|
|||||||
package org.oscim.renderer.elements;
|
package org.oscim.renderer.elements;
|
||||||
|
|
||||||
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
import static org.oscim.renderer.MapRenderer.COORD_SCALE;
|
||||||
import static org.oscim.renderer.elements.TextureItem.TEXTURE_HEIGHT;
|
|
||||||
import static org.oscim.renderer.elements.TextureItem.TEXTURE_WIDTH;
|
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
|
|
||||||
public final class TextLayer extends TextureLayer {
|
public final class TextLayer extends TextureLayer {
|
||||||
|
|
||||||
//static final Logger log = LoggerFactory.getLogger(TextureLayer.class);
|
//static final Logger log = LoggerFactory.getLogger(TextureLayer.class);
|
||||||
|
|
||||||
private final static int LBIT_MASK = 0xfffffffe;
|
private final static int LBIT_MASK = 0xfffffffe;
|
||||||
@ -94,15 +91,18 @@ public final class TextLayer extends TextureLayer {
|
|||||||
float y = 0;
|
float y = 0;
|
||||||
float yy;
|
float yy;
|
||||||
|
|
||||||
TextureItem to = TextureItem.get();
|
TextureItem t = pool.get();
|
||||||
textures = to;
|
textures = t;
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(t.bitmap);
|
||||||
|
|
||||||
for (TextItem it = labels; it != null;) {
|
for (TextItem it = labels; it != null;) {
|
||||||
|
|
||||||
float width = it.width + 2 * mFontPadX;
|
float width = it.width + 2 * mFontPadX;
|
||||||
float height = (int) (it.text.fontHeight) + 0.5f;
|
float height = (int) (it.text.fontHeight) + 0.5f;
|
||||||
|
|
||||||
|
if (height > TEXTURE_HEIGHT)
|
||||||
|
height = TEXTURE_HEIGHT;
|
||||||
|
|
||||||
if (height > advanceY)
|
if (height > advanceY)
|
||||||
advanceY = (int) height;
|
advanceY = (int) height;
|
||||||
|
|
||||||
@ -112,14 +112,14 @@ public final class TextLayer extends TextureLayer {
|
|||||||
advanceY = (int) (height + 0.5f);
|
advanceY = (int) (height + 0.5f);
|
||||||
|
|
||||||
if (y + height > TEXTURE_HEIGHT) {
|
if (y + height > TEXTURE_HEIGHT) {
|
||||||
to.offset = offsetIndices;
|
t.offset = offsetIndices;
|
||||||
to.vertices = (short) (numIndices - offsetIndices);
|
t.vertices = (short) (numIndices - offsetIndices);
|
||||||
offsetIndices = numIndices;
|
offsetIndices = numIndices;
|
||||||
|
|
||||||
to.next = TextureItem.get();
|
t.next = pool.get();
|
||||||
to = to.next;
|
t = t.next;
|
||||||
|
|
||||||
mCanvas.setBitmap(to.bitmap);
|
mCanvas.setBitmap(t.bitmap);
|
||||||
|
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
@ -246,8 +246,8 @@ public final class TextLayer extends TextureLayer {
|
|||||||
buf[pos++] = v1;
|
buf[pos++] = v1;
|
||||||
|
|
||||||
// six indices to draw the four vertices
|
// six indices to draw the four vertices
|
||||||
numIndices += TextureLayer.Renderer.INDICES_PER_SPRITE;
|
|
||||||
verticesCnt += 4;
|
verticesCnt += 4;
|
||||||
|
numIndices += TextureLayer.INDICES_PER_SPRITE;
|
||||||
|
|
||||||
if (it.next == null || (it.next.text != it.text)
|
if (it.next == null || (it.next.text != it.text)
|
||||||
|| (it.next.string != it.string)) {
|
|| (it.next.string != it.string)) {
|
||||||
@ -262,18 +262,21 @@ public final class TextLayer extends TextureLayer {
|
|||||||
|
|
||||||
vi.used = pos;
|
vi.used = pos;
|
||||||
|
|
||||||
to.offset = offsetIndices;
|
t.offset = offsetIndices;
|
||||||
to.vertices = (short) (numIndices - offsetIndices);
|
t.vertices = (short) (numIndices - offsetIndices);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
textures = TextureItem.pool.releaseAll(textures);
|
// release textures
|
||||||
labels = TextItem.pool.releaseAll(labels);
|
super.clear();
|
||||||
vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
|
||||||
verticesCnt = 0;
|
clearLabels();
|
||||||
|
//labels = TextItem.pool.releaseAll(labels);
|
||||||
|
//vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
//verticesCnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearLabels() {
|
public void clearLabels() {
|
||||||
|
|||||||
@ -18,6 +18,8 @@ package org.oscim.renderer.elements;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import javax.annotation.CheckReturnValue;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.GL20;
|
import org.oscim.backend.GL20;
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
@ -29,19 +31,16 @@ import org.oscim.utils.pool.SyncPool;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
// TODO use separate pools for different bitmap types and dimensions
|
|
||||||
|
|
||||||
public class TextureItem extends Inlist<TextureItem> {
|
public class TextureItem extends Inlist<TextureItem> {
|
||||||
static final Logger log = LoggerFactory.getLogger(TextureItem.class);
|
static final Logger log = LoggerFactory.getLogger(TextureItem.class);
|
||||||
|
|
||||||
private static GL20 GL;
|
|
||||||
|
|
||||||
/** texture ID */
|
/** texture ID */
|
||||||
public int id;
|
public int id;
|
||||||
|
|
||||||
public int width;
|
/** current settings */
|
||||||
public int height;
|
public final int width;
|
||||||
public boolean repeat;
|
public final int height;
|
||||||
|
public final boolean repeat;
|
||||||
|
|
||||||
/** vertex offset from which this texture is referenced */
|
/** vertex offset from which this texture is referenced */
|
||||||
public short offset;
|
public short offset;
|
||||||
@ -50,272 +49,290 @@ public class TextureItem extends Inlist<TextureItem> {
|
|||||||
/** temporary Bitmap */
|
/** temporary Bitmap */
|
||||||
public Bitmap bitmap;
|
public Bitmap bitmap;
|
||||||
|
|
||||||
/** external bitmap (not from pool) */
|
|
||||||
private boolean ownBitmap;
|
|
||||||
|
|
||||||
/** do not release the texture when TextureItem is released. */
|
/** do not release the texture when TextureItem is released. */
|
||||||
private boolean isClone;
|
private boolean ref;
|
||||||
|
|
||||||
/** texture data is ready */
|
/** texture data is ready */
|
||||||
private boolean isReady;
|
private boolean ready;
|
||||||
|
|
||||||
private TextureItem(int id) {
|
final TexturePool pool;
|
||||||
|
|
||||||
|
private TextureItem(TexturePool pool, int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
this.width = pool.mWidth;
|
||||||
|
this.height = pool.mHeight;
|
||||||
public static TextureItem clone(TextureItem ti) {
|
this.pool = pool;
|
||||||
TextureItem clone = new TextureItem(ti.id);
|
this.repeat = false;
|
||||||
clone.id = ti.id;
|
|
||||||
clone.width = ti.width;
|
|
||||||
clone.height = ti.height;
|
|
||||||
clone.isClone = true;
|
|
||||||
// original texture needs to be loaded
|
|
||||||
clone.isReady = true;
|
|
||||||
return clone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureItem(Bitmap bitmap) {
|
public TextureItem(Bitmap bitmap) {
|
||||||
this.bitmap = bitmap;
|
this.bitmap = bitmap;
|
||||||
this.id = -1;
|
this.id = -1;
|
||||||
this.ownBitmap = true;
|
|
||||||
this.width = bitmap.getWidth();
|
this.width = bitmap.getWidth();
|
||||||
this.height = bitmap.getHeight();
|
this.height = bitmap.getHeight();
|
||||||
|
this.pool = NOPOOL;
|
||||||
|
this.repeat = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureItem(Bitmap bitmap, boolean repeat) {
|
public TextureItem(Bitmap bitmap, boolean repeat) {
|
||||||
this.bitmap = bitmap;
|
this.bitmap = bitmap;
|
||||||
this.id = -1;
|
this.id = -1;
|
||||||
this.ownBitmap = true;
|
|
||||||
this.width = bitmap.getWidth();
|
this.width = bitmap.getWidth();
|
||||||
this.height = bitmap.getHeight();
|
this.height = bitmap.getHeight();
|
||||||
this.repeat = repeat;
|
this.repeat = repeat;
|
||||||
|
this.pool = NOPOOL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TextureItem(TexturePool pool, int id, int width, int height) {
|
||||||
|
this.id = id;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.pool = pool;
|
||||||
|
this.repeat = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TextureItem clone(TextureItem ti) {
|
||||||
|
// original texture needs to be loaded
|
||||||
|
if (!ti.ready)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
|
||||||
|
TextureItem clone = new TextureItem(ti.pool, ti.id, ti.width, ti.height);
|
||||||
|
clone.id = ti.id;
|
||||||
|
clone.ref = true;
|
||||||
|
clone.ready = true;
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload Image to Texture
|
||||||
|
* [on GL-Thread]
|
||||||
|
*/
|
||||||
public void upload() {
|
public void upload() {
|
||||||
if (!isReady) {
|
if (!ready) {
|
||||||
TextureItem.uploadTexture(this);
|
pool.uploadTexture(this);
|
||||||
isReady = true;
|
ready = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind Texture for rendering
|
||||||
|
* [on GL-Thread]
|
||||||
|
*/
|
||||||
public void bind() {
|
public void bind() {
|
||||||
if (!isReady) {
|
if (!ready) {
|
||||||
TextureItem.uploadTexture(this);
|
pool.uploadTexture(this);
|
||||||
isReady = true;
|
ready = true;
|
||||||
} else {
|
} else {
|
||||||
GLState.bindTex2D(id);
|
GLState.bindTex2D(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a TextureItem from pool with default Bitmap with dimension
|
* Dispose TextureItem
|
||||||
* TextureRenderer.TEXTURE_WIDTH/HEIGHT.
|
* [Threadsafe]
|
||||||
|
*
|
||||||
|
* @return this.next
|
||||||
*/
|
*/
|
||||||
public synchronized static TextureItem get() {
|
@CheckReturnValue
|
||||||
TextureItem ti = pool.get();
|
public TextureItem dispose() {
|
||||||
ti.bitmap = getBitmap();
|
TextureItem n = this.next;
|
||||||
ti.bitmap.eraseColor(Color.TRANSPARENT);
|
this.next = null;
|
||||||
|
pool.release(this);
|
||||||
return ti;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TextureItemPool extends SyncPool<TextureItem> {
|
public static class TexturePool extends SyncPool<TextureItem> {
|
||||||
|
|
||||||
public TextureItemPool() {
|
private final ArrayList<Integer> mTexDisposed = new ArrayList<Integer>();
|
||||||
super(10);
|
private final ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
|
||||||
|
|
||||||
|
private final int mHeight;
|
||||||
|
private final int mWidth;
|
||||||
|
//private final int mBitmapFormat;
|
||||||
|
//private final int mBitmapType;
|
||||||
|
|
||||||
|
protected int mTexCnt = 0;
|
||||||
|
|
||||||
|
public TexturePool(int maxFill, int width, int height) {
|
||||||
|
super(maxFill);
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(int num) {
|
public TextureItem releaseAll(TextureItem t) {
|
||||||
if (pool != null) {
|
throw new RuntimeException("use TextureItem.dispose()");
|
||||||
log.debug("still textures in pool! " + fill);
|
}
|
||||||
pool = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num > 0) {
|
/**
|
||||||
int[] textureIds = GLUtils.glGenTextures(num);
|
* Retrieve a TextureItem from pool.
|
||||||
for (int i = 0; i < num; i++) {
|
*/
|
||||||
TextureItem to = new TextureItem(textureIds[i]);
|
public synchronized TextureItem get() {
|
||||||
initTexture(to);
|
TextureItem t = super.get();
|
||||||
pool = Inlist.push(pool, to);
|
|
||||||
|
synchronized (mBitmaps) {
|
||||||
|
int size = mBitmaps.size();
|
||||||
|
if (size == 0)
|
||||||
|
t.bitmap = CanvasAdapter.g.getBitmap(mWidth, mHeight, 0);
|
||||||
|
else {
|
||||||
|
t.bitmap = mBitmaps.remove(size - 1);
|
||||||
|
t.bitmap.eraseColor(Color.TRANSPARENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fill = num;
|
return t;
|
||||||
}
|
|
||||||
|
|
||||||
public TextureItem get(int width, int height) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TextureItem createItem() {
|
protected TextureItem createItem() {
|
||||||
return new TextureItem(-1);
|
return new TextureItem(this, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** called when item is added back to pool */
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean clearItem(TextureItem t) {
|
protected boolean clearItem(TextureItem t) {
|
||||||
|
|
||||||
if (t.ownBitmap) {
|
//if (t.ownBitmap) {
|
||||||
t.bitmap = null;
|
// t.bitmap = null;
|
||||||
t.ownBitmap = false;
|
// t.ownBitmap = false;
|
||||||
releaseTexture(t);
|
// releaseTexture(t);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (t.ref)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (t.isClone) {
|
|
||||||
t.isClone = false;
|
|
||||||
t.id = -1;
|
|
||||||
t.width = -1;
|
|
||||||
t.height = -1;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
t.isReady = false;
|
|
||||||
|
|
||||||
|
t.ready = false;
|
||||||
releaseBitmap(t);
|
releaseBitmap(t);
|
||||||
|
|
||||||
return true;
|
// only add back to pool when a texture
|
||||||
|
// is already assigned
|
||||||
|
return t.id >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void freeItem(TextureItem t) {
|
protected void freeItem(TextureItem t) {
|
||||||
t.width = -1;
|
|
||||||
t.height = -1;
|
|
||||||
|
|
||||||
if (!t.isClone)
|
if (!t.ref) {
|
||||||
releaseTexture(t);
|
synchronized (mTexDisposed) {
|
||||||
|
if (t.id >= 0) {
|
||||||
|
mTexDisposed.add(Integer.valueOf(t.id));
|
||||||
|
t.id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void releaseBitmap(TextureItem t) {
|
||||||
|
|
||||||
|
if (t.bitmap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
synchronized (mBitmaps) {
|
||||||
|
mBitmaps.add(t.bitmap);
|
||||||
|
t.bitmap = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadTexture(TextureItem t) {
|
||||||
|
|
||||||
|
if (t.bitmap == null)
|
||||||
|
throw new RuntimeException("Missing bitmap for texture");
|
||||||
|
|
||||||
|
synchronized (mTexDisposed) {
|
||||||
|
int size = mTexDisposed.size();
|
||||||
|
if (size > 0) {
|
||||||
|
int[] tmp = new int[size];
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
tmp[i] = mTexDisposed.get(i).intValue();
|
||||||
|
|
||||||
|
mTexDisposed.clear();
|
||||||
|
GLUtils.glDeleteTextures(size, tmp);
|
||||||
|
mTexCnt -= size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.id < 0) {
|
||||||
|
int[] textureIds = GLUtils.glGenTextures(1);
|
||||||
|
t.id = textureIds[0];
|
||||||
|
|
||||||
|
initTexture(t);
|
||||||
|
|
||||||
|
if (TextureLayer.Renderer.debug)
|
||||||
|
log.debug("fill:" + getFill()
|
||||||
|
+ " count:" + mTexCnt
|
||||||
|
+ " new texture " + t.id);
|
||||||
|
|
||||||
|
mTexCnt++;
|
||||||
|
|
||||||
|
t.bitmap.uploadToTexture(false);
|
||||||
|
} else {
|
||||||
|
GLState.bindTex2D(t.id);
|
||||||
|
// use faster subimage upload
|
||||||
|
t.bitmap.uploadToTexture(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (t.ownBitmap) {
|
||||||
|
// t.bitmap.uploadToTexture(false);
|
||||||
|
//} else
|
||||||
|
|
||||||
|
//if (t.width == mWidth && t.height == mHeight) {
|
||||||
|
// // use faster subimage upload
|
||||||
|
// t.bitmap.uploadToTexture(true);
|
||||||
|
//} else {
|
||||||
|
// t.bitmap.uploadToTexture(false);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (TextureLayer.Renderer.debug)
|
||||||
|
GLUtils.checkGlError(TextureItem.class.getName());
|
||||||
|
|
||||||
|
releaseBitmap(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initTexture(TextureItem t) {
|
||||||
|
GLState.bindTex2D(t.id);
|
||||||
|
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER,
|
||||||
|
GL20.GL_LINEAR);
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER,
|
||||||
|
GL20.GL_LINEAR);
|
||||||
|
|
||||||
|
if (t.repeat) {
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
|
||||||
|
GL20.GL_REPEAT);
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
|
||||||
|
GL20.GL_REPEAT);
|
||||||
|
} else {
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
|
||||||
|
GL20.GL_CLAMP_TO_EDGE);
|
||||||
|
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
|
||||||
|
GL20.GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public final static SyncPool<TextureItem> pool = new TextureItemPool();
|
// Pool for not-pooled textures. Disposed items will only be released
|
||||||
|
// on the GL-Thread and will not be put back in any pool.
|
||||||
|
final static TexturePool NOPOOL = new TexturePool(0, 0, 0) {
|
||||||
|
protected void releaseBitmap(TextureItem t) {
|
||||||
|
// TODO
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
private final static ArrayList<Integer> mTextures = new ArrayList<Integer>();
|
// public final static TexturePool nopool(){
|
||||||
private final static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);
|
// return NOPOOL;
|
||||||
|
// }
|
||||||
|
|
||||||
public final static int TEXTURE_WIDTH = 512;
|
private static GL20 GL;
|
||||||
public final static int TEXTURE_HEIGHT = 256;
|
|
||||||
|
|
||||||
//private static int mBitmapFormat;
|
static void init(GL20 gl) {
|
||||||
//private static int mBitmapType;
|
|
||||||
private static int mTexCnt = 0;
|
|
||||||
|
|
||||||
static void releaseTexture(TextureItem it) {
|
|
||||||
|
|
||||||
synchronized (mTextures) {
|
|
||||||
if (it.id >= 0) {
|
|
||||||
mTextures.add(Integer.valueOf(it.id));
|
|
||||||
it.id = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function may only be used in GLRenderer Thread.
|
|
||||||
*
|
|
||||||
* @param t
|
|
||||||
* the TextureObjet to compile and upload
|
|
||||||
*/
|
|
||||||
private static void uploadTexture(TextureItem t) {
|
|
||||||
GL.glBindTexture(GL20.GL_TEXTURE_2D, 0);
|
|
||||||
if (t.bitmap == null) {
|
|
||||||
throw new RuntimeException("Missing bitmap for texture");
|
|
||||||
}
|
|
||||||
|
|
||||||
// free unused textures -> TODO find a better place for this
|
|
||||||
synchronized (mTextures) {
|
|
||||||
int size = mTextures.size();
|
|
||||||
if (size > 0) {
|
|
||||||
int[] tmp = new int[size];
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
tmp[i] = mTextures.get(i).intValue();
|
|
||||||
}
|
|
||||||
mTextures.clear();
|
|
||||||
GLUtils.glDeleteTextures(size, tmp);
|
|
||||||
|
|
||||||
mTexCnt -= size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t.id < 0) {
|
|
||||||
mTexCnt++;
|
|
||||||
int[] textureIds = GLUtils.glGenTextures(1);
|
|
||||||
t.id = textureIds[0];
|
|
||||||
initTexture(t);
|
|
||||||
if (TextureLayer.Renderer.debug)
|
|
||||||
log.debug("fill:" + pool.getFill()
|
|
||||||
+ " count:" + mTexCnt
|
|
||||||
+ " new texture " + t.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLState.bindTex2D(t.id);
|
|
||||||
|
|
||||||
if (t.ownBitmap) {
|
|
||||||
t.bitmap.uploadToTexture(false);
|
|
||||||
} else if (t.width == TEXTURE_WIDTH && t.height == TEXTURE_HEIGHT) {
|
|
||||||
t.bitmap.uploadToTexture(true);
|
|
||||||
} else {
|
|
||||||
t.bitmap.uploadToTexture(false);
|
|
||||||
t.width = TEXTURE_WIDTH;
|
|
||||||
t.height = TEXTURE_HEIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TextureLayer.Renderer.debug)
|
|
||||||
GLUtils.checkGlError(TextureItem.class.getName());
|
|
||||||
|
|
||||||
if (!t.ownBitmap)
|
|
||||||
TextureItem.releaseBitmap(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initTexture(TextureItem t) {
|
|
||||||
GLState.bindTex2D(t.id);
|
|
||||||
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER,
|
|
||||||
GL20.GL_LINEAR);
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER,
|
|
||||||
GL20.GL_LINEAR);
|
|
||||||
|
|
||||||
if (t.repeat) {
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
|
|
||||||
GL20.GL_REPEAT);
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
|
|
||||||
GL20.GL_REPEAT);
|
|
||||||
} else {
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_S,
|
|
||||||
GL20.GL_CLAMP_TO_EDGE);
|
|
||||||
GL.glTexParameterf(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_WRAP_T,
|
|
||||||
GL20.GL_CLAMP_TO_EDGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init(GL20 gl, int num) {
|
|
||||||
GL = gl;
|
GL = gl;
|
||||||
|
|
||||||
mTexCnt = num;
|
// mTexCnt = num;
|
||||||
pool.init(num);
|
// NOPOOL.init(num);
|
||||||
|
//
|
||||||
mBitmaps.clear();
|
// mBitmaps.clear();
|
||||||
mTextures.clear();
|
// mTexDisposed.clear();
|
||||||
}
|
|
||||||
|
|
||||||
static Bitmap getBitmap() {
|
|
||||||
synchronized (mBitmaps) {
|
|
||||||
int size = mBitmaps.size();
|
|
||||||
if (size == 0) {
|
|
||||||
return CanvasAdapter.g.getBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return mBitmaps.remove(size - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void releaseBitmap(TextureItem it) {
|
|
||||||
synchronized (mBitmaps) {
|
|
||||||
if (it.bitmap != null) {
|
|
||||||
mBitmaps.add(it.bitmap);
|
|
||||||
it.bitmap = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,28 +25,38 @@ import org.oscim.renderer.GLState;
|
|||||||
import org.oscim.renderer.GLUtils;
|
import org.oscim.renderer.GLUtils;
|
||||||
import org.oscim.renderer.MapRenderer;
|
import org.oscim.renderer.MapRenderer;
|
||||||
import org.oscim.renderer.MapRenderer.Matrices;
|
import org.oscim.renderer.MapRenderer.Matrices;
|
||||||
|
import org.oscim.renderer.elements.TextureItem.TexturePool;
|
||||||
|
|
||||||
public abstract class TextureLayer extends RenderElement {
|
public abstract class TextureLayer extends RenderElement {
|
||||||
|
|
||||||
|
public final static int INDICES_PER_SPRITE = 6;
|
||||||
|
final static int VERTICES_PER_SPRITE = 4;
|
||||||
|
final static int SHORTS_PER_VERTICE = 6;
|
||||||
|
|
||||||
|
final static int TEXTURE_HEIGHT = 128;
|
||||||
|
final static int TEXTURE_WIDTH = 512;
|
||||||
|
final static int POOL_FILL = 10;
|
||||||
|
|
||||||
|
/** pool shared by TextLayers */
|
||||||
|
final static TexturePool pool = new TexturePool(POOL_FILL,
|
||||||
|
TEXTURE_WIDTH,
|
||||||
|
TEXTURE_HEIGHT);
|
||||||
|
|
||||||
protected TextureLayer(byte type) {
|
protected TextureLayer(byte type) {
|
||||||
super(type);
|
super(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// holds textures and offset in vbo
|
/** holds textures and offset in vbo */
|
||||||
public TextureItem textures;
|
public TextureItem textures;
|
||||||
|
|
||||||
// scale mode
|
/** scale mode */
|
||||||
public boolean fixed;
|
public boolean fixed;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sbuf
|
|
||||||
* buffer to add vertices
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected void compile(ShortBuffer sbuf) {
|
protected void compile(ShortBuffer sbuf) {
|
||||||
|
|
||||||
for (TextureItem to = textures; to != null; to = to.next)
|
for (TextureItem t = textures; t != null; t = t.next)
|
||||||
to.upload();
|
t.upload();
|
||||||
|
|
||||||
// add vertices to vbo
|
// add vertices to vbo
|
||||||
ElementLayers.addPoolItems(this, sbuf);
|
ElementLayers.addPoolItems(this, sbuf);
|
||||||
@ -54,6 +64,14 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
|
|
||||||
abstract public boolean prepare();
|
abstract public boolean prepare();
|
||||||
|
|
||||||
|
protected void clear() {
|
||||||
|
while (textures != null)
|
||||||
|
textures = textures.dispose();
|
||||||
|
|
||||||
|
vertexItems = VertexItem.pool.releaseAll(vertexItems);
|
||||||
|
verticesCnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void putSprite(short buf[], int pos,
|
static void putSprite(short buf[], int pos,
|
||||||
short tx, short ty,
|
short tx, short ty,
|
||||||
short x1, short y1,
|
short x1, short y1,
|
||||||
@ -105,10 +123,6 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
private static int hTextureTexCoord;
|
private static int hTextureTexCoord;
|
||||||
private static int hTextureSize;
|
private static int hTextureSize;
|
||||||
|
|
||||||
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() {
|
static void init() {
|
||||||
|
|
||||||
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
mTextureProgram = GLUtils.createProgram(textVertexShader,
|
||||||
@ -121,9 +135,12 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
|
hTextureScreenScale = GL.glGetUniformLocation(mTextureProgram, "u_swidth");
|
||||||
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
hTextureVertex = GL.glGetAttribLocation(mTextureProgram, "vertex");
|
||||||
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
hTextureTexCoord = GL.glGetAttribLocation(mTextureProgram, "tex_coord");
|
||||||
|
|
||||||
|
// FIXME pool should be disposed on exit...
|
||||||
|
pool.init(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RenderElement draw(RenderElement renderElement, float scale, Matrices m) {
|
public static RenderElement draw(RenderElement l, float scale, Matrices m) {
|
||||||
|
|
||||||
GLState.test(false, false);
|
GLState.test(false, false);
|
||||||
GLState.blend(true);
|
GLState.blend(true);
|
||||||
@ -132,7 +149,7 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
|
|
||||||
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
GLState.enableVertexArrays(hTextureTexCoord, hTextureVertex);
|
||||||
|
|
||||||
TextureLayer tl = (TextureLayer) renderElement;
|
TextureLayer tl = (TextureLayer) l;
|
||||||
|
|
||||||
if (tl.fixed)
|
if (tl.fixed)
|
||||||
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
GL.glUniform1f(hTextureScale, (float) Math.sqrt(scale));
|
||||||
@ -146,20 +163,18 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(true);
|
MapRenderer.bindQuadIndicesVBO(true);
|
||||||
|
|
||||||
for (TextureItem ti = tl.textures; ti != null; ti = ti.next) {
|
for (TextureItem t = tl.textures; t != null; t = t.next) {
|
||||||
|
GL.glUniform2f(hTextureSize,
|
||||||
ti.bind();
|
1f / (t.width * COORD_SCALE),
|
||||||
|
1f / (t.height * COORD_SCALE));
|
||||||
|
t.bind();
|
||||||
|
|
||||||
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
int maxVertices = MapRenderer.maxQuads * INDICES_PER_SPRITE;
|
||||||
|
|
||||||
GL.glUniform2f(hTextureSize,
|
|
||||||
1f / (ti.width * COORD_SCALE),
|
|
||||||
1f / (ti.height * COORD_SCALE));
|
|
||||||
|
|
||||||
// draw up to maxVertices in each iteration
|
// draw up to maxVertices in each iteration
|
||||||
for (int i = 0; i < ti.vertices; i += maxVertices) {
|
for (int i = 0; i < t.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 = (ti.offset + i) * 8 + tl.offset;
|
int off = (t.offset + i) * 8 + tl.offset;
|
||||||
|
|
||||||
GL.glVertexAttribPointer(hTextureVertex, 4,
|
GL.glVertexAttribPointer(hTextureVertex, 4,
|
||||||
GL20.GL_SHORT, false, 12, off);
|
GL20.GL_SHORT, false, 12, off);
|
||||||
@ -167,7 +182,7 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
GL.glVertexAttribPointer(hTextureTexCoord, 2,
|
||||||
GL20.GL_SHORT, false, 12, off + 8);
|
GL20.GL_SHORT, false, 12, off + 8);
|
||||||
|
|
||||||
int numVertices = ti.vertices - i;
|
int numVertices = t.vertices - i;
|
||||||
if (numVertices > maxVertices)
|
if (numVertices > maxVertices)
|
||||||
numVertices = maxVertices;
|
numVertices = maxVertices;
|
||||||
|
|
||||||
@ -178,7 +193,7 @@ public abstract class TextureLayer extends RenderElement {
|
|||||||
|
|
||||||
MapRenderer.bindQuadIndicesVBO(false);
|
MapRenderer.bindQuadIndicesVBO(false);
|
||||||
|
|
||||||
return renderElement.next;
|
return l.next;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static double COORD_DIV = 1.0 / MapRenderer.COORD_SCALE;
|
private final static double COORD_DIV = 1.0 / MapRenderer.COORD_SCALE;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user