PageRenderTime 499ms CodeModel.GetById 80ms app.highlight 314ms RepoModel.GetById 90ms app.codeStats 1ms

/ModelRenderer/src/edu/union/android/ModelViewInterpolated.java

http://android-gl.googlecode.com/
Java | 279 lines | 226 code | 52 blank | 1 comment | 19 complexity | a639eea4378a457a4496e420d552e3bd MD5 | raw file
  1package edu.union.android;
  2
  3import java.nio.ByteBuffer;
  4import java.nio.ByteOrder;
  5import java.nio.IntBuffer;
  6import java.nio.ShortBuffer;
  7
  8import javax.microedition.khronos.opengles.GL10;
  9import javax.microedition.khronos.opengles.GL11;
 10
 11import android.content.Context;
 12import android.graphics.Bitmap;
 13import android.graphics.BitmapFactory;
 14import android.graphics.Canvas;
 15import android.graphics.OpenGLContext;
 16import android.opengl.GLU;
 17import android.view.KeyEvent;
 18import android.view.View;
 19import edu.union.graphics.Animation;
 20import edu.union.graphics.FixedPointUtils;
 21import static edu.union.graphics.FixedPointUtils.ONE;
 22import edu.union.graphics.Mesh;
 23import edu.union.graphics.Model;
 24
 25public class ModelViewInterpolated extends View {
 26	private Model m;
 27	private OpenGLContext context;
 28	ViewAnimator animator;
 29
 30	int tex;
 31	int verts;
 32	Animation cAnim;
 33	int anim_ix;
 34	int angle;
 35	
 36	int lightAmbient[] = new int[] { FixedPointUtils.toFixed(0.2f), 
 37									 FixedPointUtils.toFixed(0.3f), 
 38									 FixedPointUtils.toFixed(0.6f), ONE };
 39	int lightDiffuse[] = new int[] { ONE, ONE, ONE, ONE };
 40
 41	int matAmbient[] = new int[] { ONE, ONE, ONE, ONE };
 42	int matDiffuse[] = new int[] { ONE, ONE, ONE, ONE };
 43
 44	int[] pos = new int[] {0,20<<16,20<<16, ONE};
 45
 46	int current = 0;
 47	int next = 1;
 48	int mix = 0;
 49
 50	private IntBuffer vertices;
 51	private IntBuffer normals;
 52	private IntBuffer texCoords;
 53	private ShortBuffer indices;
 54
 55
 56	protected static int loadTexture(GL10 gl, Bitmap bmp) {
 57		ByteBuffer bb = ByteBuffer.allocateDirect(bmp.height()*bmp.width()*4);
 58		bb.order(ByteOrder.nativeOrder());
 59		IntBuffer ib = bb.asIntBuffer();
 60
 61		for (int y=0;y<bmp.height();y++)
 62			for (int x=0;x<bmp.width();x++) {
 63				ib.put(bmp.getPixel(x,y));
 64			}
 65		ib.position(0);
 66		bb.position(0);
 67
 68		int[] tmp_tex = new int[1];
 69
 70		gl.glGenTextures(1, tmp_tex, 0);
 71		int tx = tmp_tex[0];
 72		gl.glBindTexture(GL10.GL_TEXTURE_2D, tx);
 73		gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bmp.width(), bmp.height(), 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, bb);
 74		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
 75		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
 76		return tx;
 77	}
 78	
 79	protected void nextAnimation() {
 80		if (m.getAnimationCount() > 0) {
 81			anim_ix = (anim_ix+1)%m.getAnimationCount();
 82			cAnim = m.getAnimation(anim_ix);
 83			current = cAnim.getStartFrame();
 84			next = current+1;
 85		}
 86		else {
 87			cAnim = null;
 88		}
 89	}
 90		
 91	public ModelViewInterpolated(Model m, Context c) {
 92		super(c);
 93		setFocusable(true);
 94		this.m = m;
 95		anim_ix = -1;
 96		nextAnimation();
 97		
 98		context = new OpenGLContext(OpenGLContext.DEPTH_BUFFER);
 99
100		GL10 gl = (GL10)context.getGL();
101		gl.glShadeModel(GL10.GL_SMOOTH);
102		gl.glClearColor(1,1,1,1);
103
104		gl.glClearDepthf(1.0f);
105		gl.glEnable(GL10.GL_DEPTH_TEST);
106		gl.glDepthFunc(GL10.GL_LEQUAL);
107
108		gl.glEnable(GL10.GL_LIGHTING);
109		gl.glEnable(GL10.GL_LIGHT0);
110		gl.glEnable(GL10.GL_NORMALIZE);
111
112
113		gl.glLightxv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient,	0);
114		gl.glLightxv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse,	0);
115		gl.glLightxv(GL10.GL_LIGHT0, GL10.GL_POSITION, pos, 0);
116
117		gl.glMaterialxv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0);
118		gl.glMaterialxv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0);
119
120		// Pretty perspective
121		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
122		gl.glEnable(GL10.GL_CULL_FACE);
123		
124		ByteBuffer bb;
125
126		Mesh msh = m.getFrame(0).getMesh();
127
128		if (msh.getTextureFile() != null) {
129			gl.glEnable(GL10.GL_TEXTURE_2D);
130			tex = loadTexture(gl, BitmapFactory.decodeResource(c.getResources(),R.drawable.skin));
131		}
132
133		verts = msh.getFaceCount()*3;
134
135		bb = ByteBuffer.allocateDirect(verts*3*4);
136		bb.order(ByteOrder.nativeOrder());
137		vertices = bb.asIntBuffer();
138
139		bb = ByteBuffer.allocateDirect(verts*3*4);
140		bb.order(ByteOrder.nativeOrder());
141		normals = bb.asIntBuffer();
142
143		bb = ByteBuffer.allocateDirect(verts*2*4);
144		bb.order(ByteOrder.nativeOrder());
145		texCoords = bb.asIntBuffer();
146
147		bb = ByteBuffer.allocateDirect(verts*2);
148		bb.order(ByteOrder.nativeOrder());
149		indices = bb.asShortBuffer();
150
151		short ct = 0;
152		for (int i=0;i<msh.getFaceCount();i++) {
153			int[] face = msh.getFace(i);
154			int[] face_n = msh.getFaceNormals(i);
155			int[] face_tx = msh.getFaceTextures(i);
156			for (int j=0;j<3;j++) {
157				int[] n = msh.getNormalx(face_n[j]);
158				int[] v = msh.getVertexx(face[j]);
159				for (int k=0;k<3;k++) {
160					vertices.put(v[k]);
161					normals.put(n[k]);
162				}
163				int[] tx = msh.getTextureCoordinatex(face_tx[j]);
164				texCoords.put(tx[0]);
165				texCoords.put(tx[1]);				
166				indices.put(ct++);
167			}
168		}
169		vertices.position(0);
170		normals.position(0);
171		texCoords.position(0);
172		indices.position(0);
173		
174		gl.glTexCoordPointer(2,GL10.GL_FIXED,0,texCoords);
175		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
176
177		animator = new ViewAnimator(this, 30);
178	}
179
180	protected void interpolate() {
181		Mesh m1 = m.getFrame(current).getMesh();
182		Mesh m2 = m.getFrame(next).getMesh();
183		int ct = 0;
184		for (int i=0;i<m1.getFaceCount();i++) {
185			int[] face = m1.getFace(i);
186			int[] face_n = m1.getFaceNormals(i);
187			for (int j=0;j<3;j++) {
188				int[] n1 = m1.getNormalx(face_n[j]);
189				int[] v1 = m1.getVertexx(face[j]);
190				int[] n2 = m2.getNormalx(face_n[j]);
191				int[] v2 = m2.getVertexx(face[j]);
192
193				for (int k=0;k<3;k++) {
194					vertices.put(ct, v1[k]+FixedPointUtils.multiply(v2[k]-v1[k],mix));
195					normals.put(ct, n1[k]+FixedPointUtils.multiply(n2[k]-n1[k], mix));//makeFixed(n2[k]*mix+(1-mix)*n1[k]));
196					ct++;
197				}
198			}
199		}
200	}
201
202	@Override
203	protected void onAttachedToWindow() {
204		animator.start();
205		super.onAttachedToWindow();
206	}
207
208	@Override
209	protected void onDetachedFromWindow() {
210		animator.stop();
211		super.onDetachedFromWindow();
212	}
213
214	@Override
215	protected void onDraw(Canvas canvas) {
216		GL11 gl = (GL11)context.getGL();
217		int w = getWidth();
218		int h = getHeight();
219
220		context.waitNative(canvas, this);
221
222		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
223
224		gl.glMatrixMode(GL10.GL_PROJECTION);
225		gl.glLoadIdentity();
226		gl.glViewport(0,0,w,h);
227		GLU.gluPerspective(gl, 45.0f, ((float)w)/h, 1f, 100f);
228
229		gl.glMatrixMode(GL10.GL_MODELVIEW);
230		gl.glLoadIdentity();
231		GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);
232		gl.glTranslatef(0,0,-5);
233		gl.glRotatex(-(angle<<16), 0, 0x10000, 0);
234
235		interpolate();
236
237		gl.glVertexPointer(3,GL10.GL_FIXED, 0, vertices);
238		gl.glNormalPointer(GL10.GL_FIXED,0, normals);
239		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
240		gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
241		
242		gl.glBindTexture(GL10.GL_TEXTURE_2D, tex);
243		gl.glDrawElements(GL10.GL_TRIANGLES, verts, GL10.GL_UNSIGNED_SHORT, indices);
244
245		mix += 0x8000;
246		if (mix >= 0x10000) {
247			current = next;
248			next++;
249			if (cAnim != null) {
250				if (next > cAnim.getEndFrame())
251					next = cAnim.getStartFrame();
252			}
253			else {
254				if (next > m.getFrameCount())
255					next = 0;
256			}
257			mix = 0x0;
258		}
259		context.waitGL();
260	}
261	
262	@Override
263	public boolean onKeyDown(int keyCode, KeyEvent event) {
264		switch (event.getKeyCode()) {
265		case KeyEvent.KEYCODE_DPAD_RIGHT:
266			angle-=5;
267			break;
268		case KeyEvent.KEYCODE_DPAD_LEFT:
269			angle+=5;
270			break;
271		case KeyEvent.KEYCODE_DPAD_CENTER:
272			nextAnimation();
273			break;
274		}	
275		return super.onKeyDown(keyCode, event);
276	}
277	
278	
279}