201 lines
4.9 KiB
Java
201 lines
4.9 KiB
Java
/*
|
|
* 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 java.util.ArrayList;
|
|
|
|
import org.oscim.renderer.TextureRenderer;
|
|
import org.oscim.utils.pool.Inlist;
|
|
import org.oscim.utils.pool.SyncPool;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Color;
|
|
import android.opengl.GLES20;
|
|
import android.opengl.GLUtils;
|
|
import android.util.Log;
|
|
|
|
/**
|
|
* @author Hannes Janetzek
|
|
*/
|
|
public class TextureItem extends Inlist<TextureItem> {
|
|
private final static String TAG = TextureItem.class.getName();
|
|
|
|
// texture ID
|
|
public int id;
|
|
|
|
int width;
|
|
int height;
|
|
|
|
// vertex offset from which this texture is referenced
|
|
public short offset;
|
|
public short vertices;
|
|
|
|
// temporary Bitmap
|
|
public Bitmap bitmap;
|
|
|
|
TextureItem(int id) {
|
|
this.id = id;
|
|
}
|
|
|
|
public final static SyncPool<TextureItem> pool = new SyncPool<TextureItem>() {
|
|
|
|
@Override
|
|
public void init(int num) {
|
|
this.pool = null;
|
|
|
|
int[] textureIds = new int[num];
|
|
GLES20.glGenTextures(num, textureIds, 0);
|
|
|
|
for (int i = 1; i < num; i++) {
|
|
initTexture(textureIds[i]);
|
|
TextureItem to = new TextureItem(textureIds[i]);
|
|
|
|
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
|
|
protected TextureItem createItem() {
|
|
return new TextureItem(-1);
|
|
}
|
|
|
|
@Override
|
|
protected void clearItem(TextureItem it) {
|
|
TextureItem.releaseBitmap(it);
|
|
}
|
|
};
|
|
|
|
private static ArrayList<Bitmap> mBitmaps = new ArrayList<Bitmap>(10);;
|
|
|
|
public final static int TEXTURE_WIDTH = 512;
|
|
public final static int TEXTURE_HEIGHT = 256;
|
|
|
|
private static int mBitmapFormat;
|
|
private static int mBitmapType;
|
|
|
|
/**
|
|
* This function may only be used in GLRenderer Thread.
|
|
*
|
|
* @param to the TextureObjet to compile and upload
|
|
*/
|
|
public static void uploadTexture(TextureItem to) {
|
|
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "upload texture " + to.id);
|
|
|
|
if (to.id < 0) {
|
|
int[] textureIds = new int[1];
|
|
GLES20.glGenTextures(1, textureIds, 0);
|
|
to.id = textureIds[0];
|
|
initTexture(to.id);
|
|
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "new texture " + to.id);
|
|
}
|
|
|
|
uploadTexture(to, to.bitmap, mBitmapFormat, mBitmapType,
|
|
TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
|
|
|
TextureItem.releaseBitmap(to);
|
|
}
|
|
|
|
public static void uploadTexture(TextureItem to, Bitmap bitmap,
|
|
int format, int type, int w, int h) {
|
|
|
|
if (to == null) {
|
|
Log.d(TAG, "no texture!");
|
|
return;
|
|
}
|
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, to.id);
|
|
if (to.width == w && to.height == h)
|
|
GLUtils.texSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type);
|
|
else {
|
|
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, format, bitmap, type, 0);
|
|
to.width = w;
|
|
to.height = h;
|
|
}
|
|
}
|
|
|
|
static void initTexture(int id) {
|
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, id);
|
|
|
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
|
|
GLES20.GL_LINEAR);
|
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
|
|
GLES20.GL_LINEAR);
|
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
|
|
GLES20.GL_CLAMP_TO_EDGE); // Set U Wrapping
|
|
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
|
|
GLES20.GL_CLAMP_TO_EDGE); // Set V Wrapping
|
|
}
|
|
|
|
public static void init(int num) {
|
|
pool.init(num);
|
|
|
|
mBitmaps = new ArrayList<Bitmap>(10);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
Bitmap bitmap = Bitmap.createBitmap(
|
|
TEXTURE_WIDTH, TEXTURE_HEIGHT,
|
|
Bitmap.Config.ARGB_8888);
|
|
|
|
mBitmaps.add(bitmap);
|
|
}
|
|
|
|
mBitmapFormat = GLUtils.getInternalFormat(mBitmaps.get(0));
|
|
mBitmapType = GLUtils.getType(mBitmaps.get(0));
|
|
}
|
|
|
|
static Bitmap getBitmap() {
|
|
synchronized (mBitmaps) {
|
|
|
|
int size = mBitmaps.size();
|
|
if (size == 0) {
|
|
Bitmap bitmap = Bitmap.createBitmap(
|
|
TEXTURE_WIDTH, TEXTURE_HEIGHT,
|
|
Bitmap.Config.ARGB_8888);
|
|
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "alloc bitmap: " +
|
|
android.os.Debug.getNativeHeapAllocatedSize() / (1024 * 1024));
|
|
|
|
return bitmap;
|
|
}
|
|
return mBitmaps.remove(size - 1);
|
|
}
|
|
}
|
|
|
|
static void releaseBitmap(TextureItem it) {
|
|
synchronized (mBitmaps) {
|
|
|
|
if (it.bitmap != null) {
|
|
mBitmaps.add(it.bitmap);
|
|
it.bitmap = null;
|
|
}
|
|
}
|
|
}
|
|
}
|