Convenience method to load an ETC1 texture whether or not the active OpenGL context supports the ETC1 texture compression format. - Android android.opengl

Android examples for android.opengl:OpenGL Texture

Description

Convenience method to load an ETC1 texture whether or not the active OpenGL context supports the ETC1 texture compression format.

Demo Code


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import nicastel.renderscripttexturecompressor.etc1.rs.ScriptC_etc1compressor;
import android.opengl.ETC1;
import android.opengl.GLES10;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;

public class Main{
    /**/* w ww .  j a  va  2s .  c  o m*/
     * Convenience method to load an ETC1 texture whether or not the active OpenGL context
     * supports the ETC1 texture compression format.
     * @param target the texture target.
     * @param level the texture level
     * @param border the border size. Typically 0.
     * @param fallbackFormat the format to use if ETC1 texture compression is not supported.
     * Must be GL_RGB.
     * @param fallbackType the type to use if ETC1 texture compression is not supported.
     * Can be either GL_UNSIGNED_SHORT_5_6_5, which implies 16-bits-per-pixel,
     * or GL_UNSIGNED_BYTE, which implies 24-bits-per-pixel.
     * @param input the input stream containing an ETC1 texture in PKM format.
     * @throws IOException
     */
    public static void loadTexture(int target, int level, int border,
            int fallbackFormat, int fallbackType, InputStream input)
            throws IOException {
        loadTexture(target, level, border, fallbackFormat, fallbackType,
                createTexture(input));
    }
    /**
     * Convenience method to load an ETC1 texture whether or not the active OpenGL context
     * supports the ETC1 texture compression format.
     * @param target the texture target.
     * @param level the texture level
     * @param border the border size. Typically 0.
     * @param fallbackFormat the format to use if ETC1 texture compression is not supported.
     * Must be GL_RGB.
     * @param fallbackType the type to use if ETC1 texture compression is not supported.
     * Can be either GL_UNSIGNED_SHORT_5_6_5, which implies 16-bits-per-pixel,
     * or GL_UNSIGNED_BYTE, which implies 24-bits-per-pixel.
     * @param texture the ETC1 to load.
     */
    public static void loadTexture(int target, int level, int border,
            int fallbackFormat, int fallbackType, ETC1Texture texture) {
        if (fallbackFormat != GLES10.GL_RGB) {
            throw new IllegalArgumentException(
                    "fallbackFormat must be GL_RGB");
        }
        if (!(fallbackType == GLES10.GL_UNSIGNED_SHORT_5_6_5 || fallbackType == GLES10.GL_UNSIGNED_BYTE)) {
            throw new IllegalArgumentException("Unsupported fallbackType");
        }

        int width = texture.getWidth();
        int height = texture.getHeight();
        Buffer data = texture.getData();
        if (isETC1Supported()) {
            int imageSize = data.remaining();
            GLES10.glCompressedTexImage2D(target, level,
                    RsETC1.ETC1_RGB8_OES, width, height, border, imageSize,
                    data);
        } else {
            boolean useShorts = fallbackType != GLES10.GL_UNSIGNED_BYTE;
            int pixelSize = useShorts ? 2 : 3;
            int stride = pixelSize * width;
            ByteBuffer decodedData = ByteBuffer.allocateDirect(
                    stride * height).order(ByteOrder.nativeOrder());
            ETC1.decodeImage((ByteBuffer) data, decodedData, width, height,
                    pixelSize, stride);
            GLES10.glTexImage2D(target, level, fallbackFormat, width,
                    height, border, fallbackFormat, fallbackType,
                    decodedData);
        }
    }
    /**
     * Create a new ETC1Texture from an input stream containing a PKM formatted compressed texture.
     * @param input an input stream containing a PKM formatted compressed texture.
     * @return an ETC1Texture read from the input stream.
     * @throws IOException
     */
    public static ETC1Texture createTexture(InputStream input)
            throws IOException {
        int width = 0;
        int height = 0;
        byte[] ioBuffer = new byte[4096];
        {
            if (input.read(ioBuffer, 0, ETC1.ETC_PKM_HEADER_SIZE) != ETC1.ETC_PKM_HEADER_SIZE) {
                throw new IOException("Unable to read PKM file header.");
            }
            ByteBuffer headerBuffer = ByteBuffer.allocateDirect(
                    ETC1.ETC_PKM_HEADER_SIZE)
                    .order(ByteOrder.nativeOrder());
            headerBuffer.put(ioBuffer, 0, ETC1.ETC_PKM_HEADER_SIZE)
                    .position(0);
            if (!ETC1.isValid(headerBuffer)) {
                throw new IOException("Not a PKM file.");
            }
            width = ETC1.getWidth(headerBuffer);
            height = ETC1.getHeight(headerBuffer);
        }
        int encodedSize = ETC1.getEncodedDataSize(width, height);
        ByteBuffer dataBuffer = ByteBuffer.allocateDirect(encodedSize)
                .order(ByteOrder.nativeOrder());
        for (int i = 0; i < encodedSize;) {
            int chunkSize = Math.min(ioBuffer.length, encodedSize - i);
            if (input.read(ioBuffer, 0, chunkSize) != chunkSize) {
                throw new IOException("Unable to read PKM file data.");
            }
            dataBuffer.put(ioBuffer, 0, chunkSize);
            i += chunkSize;
        }
        dataBuffer.position(0);
        return new ETC1Texture(width, height, dataBuffer);
    }
    /**
     * Check if ETC1 texture compression is supported by the active OpenGL ES context.
     * @return true if the active OpenGL ES context supports ETC1 texture compression.
     */
    public static boolean isETC1Supported() {
        int[] results = new int[20];
        GLES10.glGetIntegerv(GLES10.GL_NUM_COMPRESSED_TEXTURE_FORMATS,
                results, 0);
        int numFormats = results[0];
        if (numFormats > results.length) {
            results = new int[numFormats];
        }
        GLES10.glGetIntegerv(GLES10.GL_COMPRESSED_TEXTURE_FORMATS, results,
                0);
        for (int i = 0; i < numFormats; i++) {
            if (results[i] == RsETC1.ETC1_RGB8_OES) {
                return true;
            }
        }
        return false;
    }
}

Related Tutorials