/* * Copyright 2012 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 . */ 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; public class TextureObject { private static TextureObject pool; private static ArrayList mBitmaps; // shared bitmap and canvas for default texture size public final static int TEXTURE_WIDTH = 256; public final static int TEXTURE_HEIGHT = 256; private static int mBitmapFormat; private static int mBitmapType; private static int objectCount = 10; public static synchronized TextureObject get() { TextureObject to; if (pool == null) { objectCount += 1; if (TextureRenderer.debug) Log.d("...", "textures: " + objectCount); 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("...", "get texture " + to.id + " " + to.bitmap); return to; } public static synchronized void release(TextureObject to) { while (to != null) { if (TextureRenderer.debug) Log.d("...", "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; } } public static synchronized void uploadTexture(TextureObject to) { if (TextureRenderer.debug) Log.d("...", "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("...", "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("...", "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; TextureObject to; int[] textureIds = new int[num]; GLES20.glGenTextures(num, textureIds, 0); for (int i = 1; i < num; i++) { initTexture(textureIds[i]); to = new TextureObject(textureIds[i]); to.next = pool; pool = to; } mBitmaps = new ArrayList(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) { for (int i = 0; i < 4; i++) { Bitmap bitmap = Bitmap.createBitmap(TEXTURE_WIDTH, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888); mBitmaps.add(bitmap); } size = 4; } return mBitmaps.remove(size - 1); } public TextureObject next; public Bitmap bitmap; int id; int width; int height; // vertex offset from which this texture is referenced // or store texture id with vertex? public short offset; public short vertices; TextureObject(int id) { this.id = id; } }