Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.test;
     18 /*
     19  * Copyright (C) 2008 The Android Open Source Project
     20  *
     21  * Licensed under the Apache License, Version 2.0 (the "License");
     22  * you may not use this file except in compliance with the License.
     23  * You may obtain a copy of the License at
     24  *
     25  *      http://www.apache.org/licenses/LICENSE-2.0
     26  *
     27  * Unless required by applicable law or agreed to in writing, software
     28  * distributed under the License is distributed on an "AS IS" BASIS,
     29  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     30  * See the License for the specific language governing permissions and
     31  * limitations under the License.
     32  */
     33 
     34 import java.nio.ByteBuffer;
     35 import java.nio.ByteOrder;
     36 import java.nio.CharBuffer;
     37 import java.nio.FloatBuffer;
     38 
     39 import android.content.Context;
     40 import android.opengl.GLSurfaceView;
     41 import android.util.AttributeSet;
     42 import android.util.Log;
     43 import android.view.KeyEvent;
     44 import android.view.MotionEvent;
     45 
     46 import javax.microedition.khronos.egl.EGL10;
     47 import javax.microedition.khronos.egl.EGLConfig;
     48 import javax.microedition.khronos.opengles.GL;
     49 import javax.microedition.khronos.opengles.GL10;
     50 import javax.microedition.khronos.opengles.GL11;
     51 /**
     52  * An implementation of SurfaceView that uses the dedicated surface for
     53  * displaying an OpenGL animation.  This allows the animation to run in a
     54  * separate thread, without requiring that it be driven by the update mechanism
     55  * of the view hierarchy.
     56  *
     57  * The application-specific rendering code is delegated to a GLView.Renderer
     58  * instance.
     59  */
     60 class TestView extends GLSurfaceView {
     61     TestView(Context context) {
     62         super(context);
     63         init();
     64     }
     65 
     66     public TestView(Context context, AttributeSet attrs) {
     67         super(context, attrs);
     68         init();
     69     }
     70 
     71     private void init() {
     72         setRenderer(new Renderer());
     73         setRenderMode(RENDERMODE_WHEN_DIRTY);
     74     }
     75 
     76         /** A grid is a topologically rectangular array of vertices.
     77     *
     78     * The vertex and index data are held in VBO objects because on most
     79     * GPUs VBO objects are the fastest way of rendering static vertex
     80     * and index data.
     81     *
     82     */
     83 
     84    private static class Grid {
     85        // Size of vertex data elements in bytes:
     86        final static int FLOAT_SIZE = 4;
     87        final static int CHAR_SIZE = 2;
     88 
     89        // Vertex structure:
     90        // float x, y, z;
     91 
     92        final static int VERTEX_SIZE = 3 * FLOAT_SIZE;
     93 
     94        private int mVertexBufferObjectId;
     95        private int mElementBufferObjectId;
     96 
     97        // These buffers are used to hold the vertex and index data while
     98        // constructing the grid. Once createBufferObjects() is called
     99        // the buffers are nulled out to save memory.
    100 
    101        private ByteBuffer mVertexByteBuffer;
    102        private FloatBuffer mVertexBuffer;
    103        private CharBuffer mIndexBuffer;
    104 
    105        private int mW;
    106        private int mH;
    107        private int mIndexCount;
    108 
    109        public Grid(int w, int h) {
    110            if (w < 0 || w >= 65536) {
    111                throw new IllegalArgumentException("w");
    112            }
    113            if (h < 0 || h >= 65536) {
    114                throw new IllegalArgumentException("h");
    115            }
    116            if (w * h >= 65536) {
    117                throw new IllegalArgumentException("w * h >= 65536");
    118            }
    119 
    120            mW = w;
    121            mH = h;
    122            int size = w * h;
    123 
    124            mVertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * size)
    125                .order(ByteOrder.nativeOrder());
    126            mVertexBuffer = mVertexByteBuffer.asFloatBuffer();
    127 
    128            int quadW = mW - 1;
    129            int quadH = mH - 1;
    130            int quadCount = quadW * quadH;
    131            int indexCount = quadCount * 6;
    132            mIndexCount = indexCount;
    133            mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount)
    134                .order(ByteOrder.nativeOrder()).asCharBuffer();
    135 
    136            /*
    137             * Initialize triangle list mesh.
    138             *
    139             *     [0]-----[  1] ...
    140             *      |    /   |
    141             *      |   /    |
    142             *      |  /     |
    143             *     [w]-----[w+1] ...
    144             *      |       |
    145             *
    146             */
    147 
    148            {
    149                int i = 0;
    150                for (int y = 0; y < quadH; y++) {
    151                    for (int x = 0; x < quadW; x++) {
    152                        char a = (char) (y * mW + x);
    153                        char b = (char) (y * mW + x + 1);
    154                        char c = (char) ((y + 1) * mW + x);
    155                        char d = (char) ((y + 1) * mW + x + 1);
    156 
    157                        mIndexBuffer.put(i++, a);
    158                        mIndexBuffer.put(i++, c);
    159                        mIndexBuffer.put(i++, b);
    160 
    161                        mIndexBuffer.put(i++, b);
    162                        mIndexBuffer.put(i++, c);
    163                        mIndexBuffer.put(i++, d);
    164                    }
    165                }
    166            }
    167 
    168        }
    169 
    170        public void set(int i, int j, float x, float y, float z) {
    171            if (i < 0 || i >= mW) {
    172                throw new IllegalArgumentException("i");
    173            }
    174            if (j < 0 || j >= mH) {
    175                throw new IllegalArgumentException("j");
    176            }
    177 
    178            int index = mW * j + i;
    179 
    180            mVertexBuffer.position(index * VERTEX_SIZE / FLOAT_SIZE);
    181            mVertexBuffer.put(x);
    182            mVertexBuffer.put(y);
    183            mVertexBuffer.put(z);
    184        }
    185 
    186        public void createBufferObjects(GL gl) {
    187            // Generate a the vertex and element buffer IDs
    188            int[] vboIds = new int[2];
    189            GL11 gl11 = (GL11) gl;
    190            gl11.glGenBuffers(2, vboIds, 0);
    191            mVertexBufferObjectId = vboIds[0];
    192            mElementBufferObjectId = vboIds[1];
    193 
    194            // Upload the vertex data
    195            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
    196            mVertexByteBuffer.position(0);
    197            gl11.glBufferData(GL11.GL_ARRAY_BUFFER, mVertexByteBuffer.capacity(), mVertexByteBuffer, GL11.GL_STATIC_DRAW);
    198 
    199            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
    200            mIndexBuffer.position(0);
    201            gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity() * CHAR_SIZE, mIndexBuffer, GL11.GL_STATIC_DRAW);
    202 
    203            // We don't need the in-memory data any more
    204            mVertexBuffer = null;
    205            mVertexByteBuffer = null;
    206            mIndexBuffer = null;
    207        }
    208 
    209        public void draw(GL10 gl) {
    210            GL11 gl11 = (GL11) gl;
    211 
    212            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    213 
    214            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
    215            gl11.glVertexPointer(3, GL10.GL_FLOAT, VERTEX_SIZE, 0);
    216 
    217            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
    218            gl11.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, 0);
    219            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    220            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
    221            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
    222        }
    223    }
    224 
    225 
    226     private class Renderer implements GLSurfaceView.Renderer {
    227         private static final String TAG = "Renderer";
    228         private Grid mGrid;
    229 
    230         public void onDrawFrame(GL10 gl) {
    231 			gl.glClearColor(0,0,1,1);
    232 			gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    233             mGrid.draw(gl);
    234         }
    235 
    236         public void onSurfaceChanged(GL10 gl, int width, int height) {
    237             gl.glViewport(0, 0, width, height);
    238 			gl.glMatrixMode(GL11.GL_PROJECTION);
    239 			gl.glLoadIdentity();
    240 			gl.glOrthof(0, width, height, 0, -1, 1);
    241 			gl.glMatrixMode(GL11.GL_MODELVIEW);
    242             createGrid(gl, width, height);
    243         }
    244 
    245         public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    246         }
    247 
    248         private void createGrid(GL10 gl, float w, float h) {
    249         mGrid = new Grid(2, 2);
    250 			for (int j = 0; j < 2; j++) {
    251 				for (int i = 0; i < 2; i++) {
    252 					float x = w * i;
    253 					float y = h * j;
    254 					float z = 0.0f;
    255 					mGrid.set(i,j, x, y, z);
    256 				}
    257 			}
    258 			mGrid.createBufferObjects(gl);
    259 		}
    260     }
    261 }
    262 
    263