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