152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project/* 252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * you may not use this file except in compliance with the License. 652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * You may obtain a copy of the License at 752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * 1052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * See the License for the specific language governing permissions and 1452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project * limitations under the License. 1552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project */ 1652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectpackage com.android.objviewer; 1852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 1952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.app.Activity; 2052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.content.AssetManager; 2152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.content.Context; 2252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.Canvas; 2352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.OpenGLContext; 2452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.Paint; 2552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.glutils.GLView; 2652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.graphics.glutils.Object3D; 2752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.Bundle; 2852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.Handler; 2952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.Message; 3052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.os.SystemClock; 3152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.KeyEvent; 3252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.View; 3352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport android.view.Window; 3452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 3552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.io.IOException; 3652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.io.InputStream; 3752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.ArrayList; 3852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport java.util.List; 3952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectimport javax.microedition.khronos.opengles.GL10; 4152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectclass OBJView extends View { 4352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Mathematical constants 4552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static final float PI = (float)Math.PI; 4652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static final float TWO_PI = (float)(2.0*Math.PI); 4752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static final float PI_OVER_TWO = (float)(Math.PI/2.0); 4852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 4952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Ambient light to apply 5052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // private float[] lightModelAmbient = { 0.0f, 0.0f, 0.0f, 1.0f }; 5152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float[] lightModelAmbient = { 0.2f, 0.2f, 0.2f, 1.0f }; 5252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Paint object for drawing the FPS display 5452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private Paint paint = new Paint(); 5552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // GLView object to manage drawing 5752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private GLView glView = new GLView(); 5852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 5952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private boolean initialized = false; 6052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 6152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private OpenGLContext mGLContext; 6252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 6352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Next time to draw 6452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private long mNextTime; 6552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 6652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // View transformation controlled by UI 6752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mRotAngle = 0.0f; 6852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mRotVelocity = 1.0f; 6952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mTiltAngle = 0.0f; 7052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Object bounds 7252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mCenterX = 0.0f; 7352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mCenterY = 0.0f; 7452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mCenterZ = 0.0f; 7552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float mScale = 1.0f; 7652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 7752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Light direction 7852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private float[] mLightDir = { 0.0f, 0.0f, 1.0f, 0.0f }; 7952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public OBJView(Context context) { 8152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super(context); 8252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mGLContext = new OpenGLContext(OpenGLContext.DEPTH_BUFFER); 8452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project Message msg = mHandler.obtainMessage(INVALIDATE); 8652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mNextTime = SystemClock.uptimeMillis() + 100; 8752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mHandler.sendMessageAtTime(msg, mNextTime); 8852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 8952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project requestFocus(); 9052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 9152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void reset() { 9352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project initialized = false; 9452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotAngle = 0.0f; 9652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotVelocity = 1.0f; 9752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mTiltAngle = 0.0f; 9852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 9952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterX = 0.0f; 10052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterY = 0.0f; 10152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterZ = 0.0f; 10252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mScale = 1.0f; 10352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 10452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 10552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 10652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Hand the key to the GLView object first 10752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (glView.processKey(keyCode)) { 10852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return true; 10952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 11052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 11152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project switch (keyCode) { 11252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_DPAD_LEFT: 11352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotVelocity -= 1.0f; 11452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 11552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 11652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_DPAD_RIGHT: 11752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotVelocity += 1.0f; 11852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 11952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 12052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_DPAD_CENTER: 12152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotVelocity = 0.0f; 12252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 12352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 12452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_DPAD_UP: 12552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mTiltAngle -= 360.0f/24.0f; 12652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 12752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 12852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_DPAD_DOWN: 12952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mTiltAngle += 360.0f/24.0f; 13052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 13152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 13252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project case KeyEvent.KEYCODE_U: 13352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project OBJViewer.nextObject(); 13452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project reset(); 13552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project break; 13652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 13752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project default: 13852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return super.onKeyDown(keyCode, event); 13952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 14052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return true; 14252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 14352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private void init(GL10 gl) { 14552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.reset(); 14652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project paint.setColor(0xffffffff); 14852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 14952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glEnable(gl.GL_DEPTH_TEST); 15052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glDisable(gl.GL_SCISSOR_TEST); 15252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Some quality settings... 15452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glEnable(gl.GL_DITHER); 15552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glShadeModel(gl.GL_SMOOTH); 15752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 15852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glEnable(gl.GL_CULL_FACE); 15952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glFrontFace(gl.GL_CCW); 16052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 16152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glClearColor(0, 0, 0, 1); 16252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 16352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glLightModelf(gl.GL_LIGHT_MODEL_TWO_SIDE, 0); 16452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glLightModelfv(gl.GL_LIGHT_MODEL_AMBIENT, lightModelAmbient, 0); 16552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 16652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 16752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override 16852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project protected void onDraw(Canvas canvas) { 16952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project GL10 gl = (GL10)mGLContext.getGL(); 17052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mGLContext.makeCurrent(this); 17152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (!initialized) { 17352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project init(gl); 17452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project initialized = true; 17552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Load the object 17752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project Object3D obj = OBJViewer.getObject(); 17852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 17952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Compute a scale factor and translation to bring it 18052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // into view 18152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterX = (obj.getBoundsMinX() + obj.getBoundsMaxX())/2.0f; 18252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterY = (obj.getBoundsMinY() + obj.getBoundsMaxY())/2.0f; 18352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mCenterZ = (obj.getBoundsMinZ() + obj.getBoundsMaxZ())/2.0f; 18452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float spanX = obj.getBoundsMaxX() - obj.getBoundsMinX(); 18552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float spanY = obj.getBoundsMaxY() - obj.getBoundsMinY(); 18652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float spanZ = obj.getBoundsMaxZ() - obj.getBoundsMinZ(); 18752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float maxSpan = Math.max(spanX, spanY); 18852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project maxSpan = Math.max(maxSpan, spanZ); 18952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mScale = 2.0f/maxSpan; 19052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 19152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 19252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int w = getWidth(); 19352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project int h = getHeight(); 19452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glViewport(0, 0, w, h); 19552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 19652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project float ratio = (float)w/h; 19752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.setAspectRatio(ratio); 19852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 19952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Clear buffers 20052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT); 20152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 20252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Set up the projection and view 20352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.setProjection(gl); 20452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.setView(gl); 20552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 20652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Set up lighting 20752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glMatrixMode(gl.GL_MODELVIEW); 20852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glEnable(gl.GL_LIGHTING); 20952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glEnable(gl.GL_LIGHT0); 21052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, mLightDir, 0); 21152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.setLights(gl, gl.GL_LIGHT0); 21252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 21352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Rotate the viewpoint around the model 21452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glRotatef(mTiltAngle, 1, 0, 0); 21552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glRotatef(mRotAngle, 0, 1, 0); 21652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 21752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Scale object to fit in [-1, 1] 21852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glScalef(mScale, mScale, mScale); 21952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 22052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Center the object at the origin 22152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project gl.glTranslatef(-mCenterX, -mCenterY, -mCenterZ); 22252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 22352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Increment the rotation angle 22452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotAngle += mRotVelocity; 22552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (mRotAngle < 0.0f) { 22652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotAngle += 360.0f; 22752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 22852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (mRotAngle > 360.0f) { 22952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mRotAngle -= 360.0f; 23052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 23152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 23252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Draw the object 23352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project Object3D object = OBJViewer.getObject(); 23452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project object.draw(gl); 23552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 23652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Allow GL to complete 23752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mGLContext.post(); 23852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 23952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Draw GLView messages and/or FPS 24052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.showMessages(canvas); 24152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.setNumTriangles(object.getNumTriangles()); 24252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project glView.showStatistics(canvas, w); 24352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 24452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 24552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static final int INVALIDATE = 1; 24652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 24752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private final Handler mHandler = new Handler() { 24852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public void handleMessage(Message msg) { 24952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (msg.what == INVALIDATE) { 25052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project invalidate(); 25152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project msg = obtainMessage(INVALIDATE); 25252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project long current = SystemClock.uptimeMillis(); 25352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (mNextTime < current) { 25452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mNextTime = current + 20; 25552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 25652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project sendMessageAtTime(msg, mNextTime); 25752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project mNextTime += 20; 25852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 25952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 26052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project }; 26152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project} 26252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 26352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 26452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Projectpublic class OBJViewer extends Activity { 26552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 26652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static Object3D object = null; 26752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 26852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static List<String> objectFiles = new ArrayList<String>(); 26952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private static int objectIndex = 0; 27052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 27152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project static { 27252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("world.gles"); 27352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("al.gles"); 27452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("apple.gles"); 27552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("dolphins.gles"); 27652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("f16.gles"); 27752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("flowers.gles"); 27852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("porsche.gles"); 27952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("rosevase.gles"); 28052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("shuttle.gles"); 28152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectFiles.add("soccerball.gles"); 28252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 28352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 28452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project private int readInt16(InputStream is) throws Exception { 28552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return is.read() | (is.read() << 8); 28652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 28752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 28852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public static Object3D getObject() { 28952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return object; 29052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 29152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 29252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public static void nextObject() { 29352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project try { 29452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project objectIndex = (objectIndex + 1) % objectFiles.size(); 29552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project object.load(objectFiles.get(objectIndex)); 29652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } catch (IOException e) { 29752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new RuntimeException(e); 29852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 29952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 30052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 30152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override protected void onCreate(Bundle icicle) { 30252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.onCreate(icicle); 30352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 30452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Get rid of the title 30552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project requestWindowFeature(Window.FEATURE_NO_TITLE); 30652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project // Make sure we're not drawing a background 30752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project setTheme(R.style.Theme); 30852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project setContentView(new OBJView((Context)getApplication())); 30952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 31052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project if (object == null) { 31152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project try { 31252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project final AssetManager am = getAssets(); 31352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project this.object = new Object3D() { 31452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project public InputStream readFile(String filename) 31552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throws IOException { 31652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project return am.open(filename); 31752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 31852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 31952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project }; 32052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project object.load(objectFiles.get(0)); 32152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } catch (Exception e) { 32252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project throw new RuntimeException(e); 32352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 32452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 32552d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 32652d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 32752d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override protected void onResume() { 32852d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.onResume(); 32952d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 33052d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project 33152d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project @Override protected void onStop() { 33252d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project super.onStop(); 33352d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project } 33452d4c30ca52320ec92d1d1ddc8db3f07f69c4f98The Android Open Source Project} 335