PageRenderTime 27ms CodeModel.GetById 6ms RepoModel.GetById 0ms app.codeStats 0ms

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