Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2008 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.example.android.apis.graphics;
     18 
     19 import java.io.IOException;
     20 import java.io.InputStream;
     21 import java.nio.ByteBuffer;
     22 import java.nio.ByteOrder;
     23 import java.nio.FloatBuffer;
     24 import java.nio.ShortBuffer;
     25 
     26 import javax.microedition.khronos.egl.EGLConfig;
     27 import javax.microedition.khronos.opengles.GL10;
     28 
     29 import android.content.Context;
     30 import android.graphics.Bitmap;
     31 import android.graphics.BitmapFactory;
     32 import android.opengl.GLSurfaceView;
     33 import android.opengl.GLU;
     34 import android.opengl.GLUtils;
     35 import android.os.SystemClock;
     36 
     37 import com.example.android.apis.R;
     38 
     39 public class TriangleRenderer implements GLSurfaceView.Renderer{
     40 
     41     public TriangleRenderer(Context context) {
     42         mContext = context;
     43         mTriangle = new Triangle();
     44     }
     45 
     46     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     47         /*
     48          * By default, OpenGL enables features that improve quality
     49          * but reduce performance. One might want to tweak that
     50          * especially on software renderer.
     51          */
     52         gl.glDisable(GL10.GL_DITHER);
     53 
     54         /*
     55          * Some one-time OpenGL initialization can be made here
     56          * probably based on features of this particular context
     57          */
     58         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
     59                 GL10.GL_FASTEST);
     60 
     61         gl.glClearColor(.5f, .5f, .5f, 1);
     62         gl.glShadeModel(GL10.GL_SMOOTH);
     63         gl.glEnable(GL10.GL_DEPTH_TEST);
     64         gl.glEnable(GL10.GL_TEXTURE_2D);
     65 
     66         /*
     67          * Create our texture. This has to be done each time the
     68          * surface is created.
     69          */
     70 
     71         int[] textures = new int[1];
     72         gl.glGenTextures(1, textures, 0);
     73 
     74         mTextureID = textures[0];
     75         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
     76 
     77         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
     78                 GL10.GL_NEAREST);
     79         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
     80                 GL10.GL_TEXTURE_MAG_FILTER,
     81                 GL10.GL_LINEAR);
     82 
     83         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
     84                 GL10.GL_CLAMP_TO_EDGE);
     85         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
     86                 GL10.GL_CLAMP_TO_EDGE);
     87 
     88         gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
     89                 GL10.GL_REPLACE);
     90 
     91         InputStream is = mContext.getResources()
     92                 .openRawResource(R.raw.robot);
     93         Bitmap bitmap;
     94         try {
     95             bitmap = BitmapFactory.decodeStream(is);
     96         } finally {
     97             try {
     98                 is.close();
     99             } catch(IOException e) {
    100                 // Ignore.
    101             }
    102         }
    103 
    104         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    105         bitmap.recycle();
    106     }
    107 
    108     public void onDrawFrame(GL10 gl) {
    109         /*
    110          * By default, OpenGL enables features that improve quality
    111          * but reduce performance. One might want to tweak that
    112          * especially on software renderer.
    113          */
    114         gl.glDisable(GL10.GL_DITHER);
    115 
    116         gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
    117                 GL10.GL_MODULATE);
    118 
    119         /*
    120          * Usually, the first thing one might want to do is to clear
    121          * the screen. The most efficient way of doing this is to use
    122          * glClear().
    123          */
    124 
    125         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    126 
    127         /*
    128          * Now we're ready to draw some 3D objects
    129          */
    130 
    131         gl.glMatrixMode(GL10.GL_MODELVIEW);
    132         gl.glLoadIdentity();
    133 
    134         GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    135 
    136         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    137         gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    138 
    139         gl.glActiveTexture(GL10.GL_TEXTURE0);
    140         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
    141         gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
    142                 GL10.GL_REPEAT);
    143         gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
    144                 GL10.GL_REPEAT);
    145 
    146         long time = SystemClock.uptimeMillis() % 4000L;
    147         float angle = 0.090f * ((int) time);
    148 
    149         gl.glRotatef(angle, 0, 0, 1.0f);
    150 
    151         mTriangle.draw(gl);
    152     }
    153 
    154     public void onSurfaceChanged(GL10 gl, int w, int h) {
    155         gl.glViewport(0, 0, w, h);
    156 
    157         /*
    158         * Set our projection matrix. This doesn't have to be done
    159         * each time we draw, but usually a new projection needs to
    160         * be set when the viewport is resized.
    161         */
    162 
    163         float ratio = (float) w / h;
    164         gl.glMatrixMode(GL10.GL_PROJECTION);
    165         gl.glLoadIdentity();
    166         gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
    167 
    168     }
    169 
    170     private Context mContext;
    171     private Triangle mTriangle;
    172     private int mTextureID;
    173 }
    174 
    175 class Triangle {
    176     public Triangle() {
    177 
    178         // Buffers to be passed to gl*Pointer() functions
    179         // must be direct, i.e., they must be placed on the
    180         // native heap where the garbage collector cannot
    181         // move them.
    182         //
    183         // Buffers with multi-byte datatypes (e.g., short, int, float)
    184         // must have their byte order set to native order
    185 
    186         ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
    187         vbb.order(ByteOrder.nativeOrder());
    188         mFVertexBuffer = vbb.asFloatBuffer();
    189 
    190         ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
    191         tbb.order(ByteOrder.nativeOrder());
    192         mTexBuffer = tbb.asFloatBuffer();
    193 
    194         ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
    195         ibb.order(ByteOrder.nativeOrder());
    196         mIndexBuffer = ibb.asShortBuffer();
    197 
    198         // A unit-sided equalateral triangle centered on the origin.
    199         float[] coords = {
    200                 // X, Y, Z
    201                 -0.5f, -0.25f, 0,
    202                  0.5f, -0.25f, 0,
    203                  0.0f,  0.559016994f, 0
    204         };
    205 
    206         for (int i = 0; i < VERTS; i++) {
    207             for(int j = 0; j < 3; j++) {
    208                 mFVertexBuffer.put(coords[i*3+j] * 2.0f);
    209             }
    210         }
    211 
    212         for (int i = 0; i < VERTS; i++) {
    213             for(int j = 0; j < 2; j++) {
    214                 mTexBuffer.put(coords[i*3+j] * 2.0f + 0.5f);
    215             }
    216         }
    217 
    218         for(int i = 0; i < VERTS; i++) {
    219             mIndexBuffer.put((short) i);
    220         }
    221 
    222         mFVertexBuffer.position(0);
    223         mTexBuffer.position(0);
    224         mIndexBuffer.position(0);
    225     }
    226 
    227     public void draw(GL10 gl) {
    228         gl.glFrontFace(GL10.GL_CCW);
    229         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer);
    230         gl.glEnable(GL10.GL_TEXTURE_2D);
    231         gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer);
    232         gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS,
    233                 GL10.GL_UNSIGNED_SHORT, mIndexBuffer);
    234     }
    235 
    236     private final static int VERTS = 3;
    237 
    238     private FloatBuffer mFVertexBuffer;
    239     private FloatBuffer mTexBuffer;
    240     private ShortBuffer mIndexBuffer;
    241 }
    242