1c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich/*
2c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * Copyright (C) 2008 The Android Open Source Project
3c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich *
4c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * Licensed under the Apache License, Version 2.0 (the "License");
5c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * you may not use this file except in compliance with the License.
6c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * You may obtain a copy of the License at
7c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich *
8c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich *      http://www.apache.org/licenses/LICENSE-2.0
9c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich *
10c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * Unless required by applicable law or agreed to in writing, software
11c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * distributed under the License is distributed on an "AS IS" BASIS,
12c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * See the License for the specific language governing permissions and
14c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * limitations under the License.
15c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich */
16c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
17c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichpackage com.example.android.apis.graphics;
18c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
19c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.io.ByteArrayInputStream;
20c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.io.ByteArrayOutputStream;
21c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.io.IOException;
22c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.io.InputStream;
23c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.nio.Buffer;
24c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.nio.ByteBuffer;
25c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport java.nio.ByteOrder;
26c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
27c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport javax.microedition.khronos.opengles.GL10;
28c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
29c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.app.Activity;
30c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.opengl.ETC1Util;
31c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.opengl.GLES10;
32c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.opengl.GLSurfaceView;
33c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.os.Bundle;
34c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport android.util.Log;
35c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
36c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichimport com.example.android.apis.R;
37c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
38c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich/**
39c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * Demonstrate how to use ETC1 format compressed textures.
40c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * This sample can be recompiled to use either resource-based
41c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * textures (compressed offline using the etc1tool), or
42c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich * textures created on the fly by compressing images.
43c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich *
44c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich */
45c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevichpublic class CompressedTextureActivity extends Activity {
46c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private final static String TAG = "CompressedTextureActivity";
47c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    /**
48c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * Choose between creating a compressed texture on the fly or
49c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * loading a compressed texture from a resource.
50c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     */
51c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private final static boolean TEST_CREATE_TEXTURE = false;
52c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    /**
53c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * When creating a compressed texture on the fly, choose
54c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * whether or not to use the i/o stream APIs.
55c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     */
56c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private final static boolean USE_STREAM_IO = false;
57c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
58c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    @Override
59c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    protected void onCreate(Bundle savedInstanceState) {
60c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        super.onCreate(savedInstanceState);
61c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        mGLView = new GLSurfaceView(this);
62c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        mGLView.setEGLConfigChooser(false);
63c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        StaticTriangleRenderer.TextureLoader loader;
64c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        if (TEST_CREATE_TEXTURE) {
65c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            loader = new SyntheticCompressedTextureLoader();
66c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        } else {
67c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            loader = new CompressedTextureLoader();
68c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        }
69c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        mGLView.setRenderer(new StaticTriangleRenderer(this, loader));
70c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        setContentView(mGLView);
71c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    }
72c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
73c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    @Override
74c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    protected void onPause() {
75c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        super.onPause();
76c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        mGLView.onPause();
77c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    }
78c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
79c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    @Override
80c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    protected void onResume() {
81c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        super.onResume();
82c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        mGLView.onResume();
83c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    }
84c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
85c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    /**
86c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * Demonstrate how to load a compressed texture from an APK resource.
87c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     *
88c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     */
89c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private class CompressedTextureLoader implements StaticTriangleRenderer.TextureLoader {
90c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        public void load(GL10 gl) {
91c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            Log.w(TAG, "ETC1 texture support: " + ETC1Util.isETC1Supported());
92c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            InputStream input = getResources().openRawResource(R.raw.androids);
93c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            try {
94c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                ETC1Util.loadTexture(GLES10.GL_TEXTURE_2D, 0, 0,
95c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                        GLES10.GL_RGB, GLES10.GL_UNSIGNED_SHORT_5_6_5, input);
96c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            } catch (IOException e) {
97c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                Log.w(TAG, "Could not load texture: " + e);
98c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            } finally {
99c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                try {
100c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    input.close();
101c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                } catch (IOException e) {
102c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    // ignore exception thrown from close.
103c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                }
104c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            }
105c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        }
106c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    }
107c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
108c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    /**
109c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     * Demonstrate how to create a compressed texture on the fly.
110c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich     */
111c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private class SyntheticCompressedTextureLoader implements StaticTriangleRenderer.TextureLoader {
112c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        public void load(GL10 gl) {
113c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            int width = 128;
114c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            int height = 128;
115c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            Buffer image = createImage(width, height);
116c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            ETC1Util.ETC1Texture etc1Texture = ETC1Util.compressTexture(image, width, height, 3, 3 * width);
117c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            if (USE_STREAM_IO) {
118c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                // Test the ETC1Util APIs for reading and writing compressed textures to I/O streams.
119c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                try {
120c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
121c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    ETC1Util.writeTexture(etc1Texture, bos);
122c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
123c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    ETC1Util.loadTexture(GLES10.GL_TEXTURE_2D, 0, 0,
124c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                            GLES10.GL_RGB, GLES10.GL_UNSIGNED_SHORT_5_6_5, bis);
125c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                } catch (IOException e) {
126c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    Log.w(TAG, "Could not load texture: " + e);
127c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                }
128c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            } else {
129c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                ETC1Util.loadTexture(GLES10.GL_TEXTURE_2D, 0, 0,
130c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                        GLES10.GL_RGB, GLES10.GL_UNSIGNED_SHORT_5_6_5, etc1Texture);
131c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            }
132c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        }
133c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
134c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        private Buffer createImage(int width, int height) {
135c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            int stride = 3 * width;
136c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            ByteBuffer image = ByteBuffer.allocateDirect(height * stride)
137c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                .order(ByteOrder.nativeOrder());
138c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich
139c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            // Fill with a pretty "munching squares" pattern:
140c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            for (int t = 0; t < height; t++) {
141c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                byte red = (byte)(255-2*t);
142c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                byte green = (byte)(2*t);
143c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                byte blue = 0;
144c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                for (int x = 0; x < width; x++) {
145c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    int y = x ^ t;
146c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    image.position(stride*y+x*3);
147c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    image.put(red);
148c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    image.put(green);
149c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                    image.put(blue);
150c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich                }
151c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            }
152c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            image.position(0);
153c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich            return image;
154c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich        }
155c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    }
156c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich    private GLSurfaceView mGLView;
157c1645153e799c488fc66eb0d481a3a3b21c94323Jack Palevich}
158