Method that loads a texture from a file for OpenGL. - Android android.opengl

Android examples for android.opengl:OpenGL Texture

Description

Method that loads a texture from a file for OpenGL.

Demo Code

/*/*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 "";
    }
}

Related Tutorials