213 lines
5.1 KiB
Java
213 lines
5.1 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;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
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 TextureObject {
|
|
private final static String TAG = TextureObject.class.getName();
|
|
|
|
private static TextureObject pool;
|
|
private static int poolCount;
|
|
|
|
private static ArrayList<Bitmap> mBitmaps;
|
|
|
|
public final static int TEXTURE_WIDTH = 256;
|
|
public final static int TEXTURE_HEIGHT = 256;
|
|
|
|
private static int mBitmapFormat;
|
|
private static int mBitmapType;
|
|
|
|
/**
|
|
* Get a TextureObject with Bitmap to draw to.
|
|
* 'uploadTexture()' uploads the Bitmap as texture.
|
|
*
|
|
* @return obtained TextureObject
|
|
*/
|
|
public static synchronized TextureObject get() {
|
|
TextureObject to;
|
|
|
|
if (pool == null) {
|
|
poolCount += 1;
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "textures: " + poolCount);
|
|
pool = new TextureObject(-1);
|
|
}
|
|
|
|
to = pool;
|
|
pool = pool.next;
|
|
|
|
to.next = null;
|
|
|
|
to.bitmap = getBitmap();
|
|
to.bitmap.eraseColor(Color.TRANSPARENT);
|
|
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "get texture " + to.id + " " + to.bitmap);
|
|
|
|
return to;
|
|
}
|
|
|
|
public static synchronized void release(TextureObject to) {
|
|
while (to != null) {
|
|
if (TextureRenderer.debug)
|
|
Log.d(TAG, "release texture " + to.id);
|
|
|
|
TextureObject next = to.next;
|
|
|
|
if (to.bitmap != null) {
|
|
mBitmaps.add(to.bitmap);
|
|
to.bitmap = null;
|
|
}
|
|
|
|
to.next = pool;
|
|
pool = to;
|
|
|
|
to = next;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function may only be used in GLRenderer Thread.
|
|
*
|
|
* @param to the TextureObjet to compile and upload
|
|
*/
|
|
public static synchronized void uploadTexture(TextureObject to) {
|
|
// FIXME what needs synchronized ?
|
|
|
|
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);
|
|
|
|
mBitmaps.add(to.bitmap);
|
|
to.bitmap = null;
|
|
}
|
|
|
|
public static void uploadTexture(TextureObject 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
|
|
}
|
|
|
|
static void init(int num) {
|
|
pool = null;
|
|
poolCount = num;
|
|
|
|
int[] textureIds = new int[num];
|
|
GLES20.glGenTextures(num, textureIds, 0);
|
|
|
|
for (int i = 1; i < num; i++) {
|
|
initTexture(textureIds[i]);
|
|
TextureObject to = new TextureObject(textureIds[i]);
|
|
|
|
to.next = pool;
|
|
pool = to;
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
private static Bitmap getBitmap() {
|
|
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);
|
|
}
|
|
|
|
// -----------------------
|
|
public TextureObject next;
|
|
|
|
// texture ID
|
|
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;
|
|
|
|
TextureObject(int id) {
|
|
this.id = id;
|
|
}
|
|
}
|