Android examples for android.opengl:OpenGL Texture
Method that loads a texture from a file for OpenGL.
/*/*from www . j ava2 s . c om*/ * Copyright (C) 2014 Jorge Ruesga * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Rect; import android.media.effect.Effect; import android.opengl.GLES20; import android.opengl.GLUtils; import android.util.Log; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; public class Main{ private static final String TAG = "GLESUtil"; private static final boolean DEBUG = false; public static final boolean DEBUG_GL_MEMOBJS = false; public static final String DEBUG_GL_MEMOBJS_NEW_TAG = "MEMOBJS_NEW"; public static final String DEBUG_GL_MEMOBJS_DEL_TAG = "MEMOBJS_DEL"; private static final Object SYNC = new Object(); /** * Method that loads a texture from a file. * * @param file The image file * @param dimensions The desired dimensions * @param effect The effect to apply to the image or null if no effect is needed * @param dimen The new dimensions * @param recycle If the bitmap should be recycled * @return GLESTextureInfo The texture info */ public static GLESTextureInfo loadTexture(File file, Rect dimensions, Effect effect, Rect dimen, boolean recycle) { Bitmap bitmap = null; try { // Decode and associate the bitmap (invert the desired dimensions) bitmap = BitmapUtils.decodeBitmap(file, dimensions.height(), dimensions.width()); if (bitmap == null) { Log.e(TAG, "Failed to decode the file bitmap"); return new GLESTextureInfo(); } if (DEBUG) Log.d(TAG, "image: " + file.getAbsolutePath()); GLESTextureInfo ti = loadTexture(bitmap, effect, dimen); ti.path = file; return ti; } catch (Exception e) { if (DEBUG) { String msg = "Failed to generate a valid texture from file: " + file.getAbsolutePath(); Log.e(TAG, msg, e); } return new GLESTextureInfo(); } finally { // Recycle the bitmap if (bitmap != null && recycle) { bitmap.recycle(); bitmap = null; } } } /** * Method that loads a texture from a resource context. * * @param ctx The current context * @param resourceId The resource identifier * @param effect The effect to apply to the image or null if no effect is needed * @param dimen The new dimensions * @param recycle If the bitmap should be recycled * @return GLESTextureInfo The texture info */ public static GLESTextureInfo loadTexture(Context ctx, int resourceId, Effect effect, Rect dimen, boolean recycle) { Bitmap bitmap = null; InputStream raw = null; try { // Decode and associate the bitmap raw = ctx.getResources().openRawResource(resourceId); bitmap = BitmapUtils.decodeBitmap(raw); if (bitmap == null) { String msg = "Failed to decode the resource bitmap"; Log.e(TAG, msg); return new GLESTextureInfo(); } if (DEBUG) Log.d(TAG, "resourceId: " + resourceId); GLESTextureInfo ti = loadTexture(bitmap, effect, dimen); return ti; } catch (Exception e) { String msg = "Failed to generate a valid texture from resource: " + resourceId; Log.e(TAG, msg, e); return new GLESTextureInfo(); } finally { // Close the buffer try { if (raw != null) { raw.close(); } } catch (IOException e) { // Ignore. } // Recycle the bitmap if (bitmap != null && recycle) { bitmap.recycle(); bitmap = null; } } } /** * Method that loads texture from a bitmap reference. * * @param bitmap The bitmap reference * @param effect The effect to apply to the image or null if no effect is needed * @param dimen The new dimensions * @return GLESTextureInfo The texture info */ public static GLESTextureInfo loadTexture(Bitmap bitmap, Effect effect, Rect dimen) { // Check that we have a valid image name reference if (bitmap == null) { return new GLESTextureInfo(); } int num = effect == null ? 1 : 2; int[] textureHandles = new int[num]; GLES20.glGenTextures(num, textureHandles, 0); GLESUtil.glesCheckError("glGenTextures"); for (int i = 0; i < num; i++) { if (GLESUtil.DEBUG_GL_MEMOBJS) { Log.d(GLESUtil.DEBUG_GL_MEMOBJS_NEW_TAG, "glGenTextures: " + textureHandles[i]); } } if (textureHandles[0] <= 0 || (effect != null && textureHandles[1] <= 0)) { Log.e(TAG, "Failed to generate a valid texture"); return new GLESTextureInfo(); } // Bind the texture to the name GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandles[0]); GLESUtil.glesCheckError("glBindTexture"); // Set the texture properties GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLESUtil.glesCheckError("glTexParameteri"); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLESUtil.glesCheckError("glTexParameteri"); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLESUtil.glesCheckError("glTexParameteri"); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLESUtil.glesCheckError("glTexParameteri"); // Load the texture GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); if (!GLES20.glIsTexture(textureHandles[0])) { Log.e(TAG, "Failed to load a valid texture"); return new GLESTextureInfo(); } // Has a effect? int handle = textureHandles[0]; if (effect != null) { // Apply the effect (we need a thread-safe call here) synchronized (SYNC) { // No more than 1024 (the minimum supported by all the gles20 devices) int w = Math.min(dimen.width(), 1024); int h = Math.min(dimen.width(), 1024); effect.apply(textureHandles[0], w, h, textureHandles[1]); } handle = textureHandles[1]; // Delete the unused texture int[] textures = { textureHandles[0] }; if (GLESUtil.DEBUG_GL_MEMOBJS) { Log.d(GLESUtil.DEBUG_GL_MEMOBJS_DEL_TAG, "glDeleteTextures: [" + textureHandles[0] + "]"); } GLES20.glDeleteTextures(1, textures, 0); GLESUtil.glesCheckError("glDeleteTextures"); } // Return the texture handle identifier and the associated info GLESTextureInfo ti = new GLESTextureInfo(); ti.handle = handle; ti.bitmap = bitmap; ti.path = null; return ti; } /** * Method that checks if an GLES error is present * * @param func The GLES function to check * @return boolean If there was an error */ public static boolean glesCheckError(String func) { int error = GLES20.glGetError(); if (error != 0) { Log.e(TAG, "GLES20 Error (" + glesGetErrorModule() + ") (" + func + "): " + GLUtils.getEGLErrorString(error)); return true; } return false; } /** * Method that returns the line and module that generates the current error * * @return String The line and module */ private static String glesGetErrorModule() { try { return String .valueOf(Thread.currentThread().getStackTrace()[4]); } catch (IndexOutOfBoundsException ioobEx) { // Ignore } return ""; } }