Android高级进阶十一 Android OpenGL建立3D空间

来源:互联网 发布:南风知我意无弹窗阅读 编辑:程序博客网 时间:2024/04/30 02:08

最新版本:Android高级进阶十一 Android OpenGL建立3D空间

 这一篇文章继续写在Android上使用OpenGL,前阶段的文章一直是旨在建立一个3D的形状,这一篇文章我们就来建立一个3D的空间模型。

        老规矩先上效果图:

        这次我们使用一个文件来存储我们所有顶点及纹理定点数据,具体使用方式待会儿见分晓。

        代码如下:

        WordActivity.java

Java代码
  1. package org.ourunix.android.world;  
  2.   
  3. import android.app.Activity;  
  4. import android.opengl.GLSurfaceView;  
  5. import android.os.Bundle;  
  6. import android.view.KeyEvent;  
  7.   
  8. public class WordActivity extends Activity {  
  9.     /** Called when the activity is first created. */  
  10.     GLRenderer render;  
  11.       
  12.     @Override  
  13.     public void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         GLSurfaceView glView = new GLSurfaceView(this);  
  16.         render = new GLRenderer(this);  
  17.         glView.setRenderer(render);  
  18.         setContentView(glView);  
  19.     }  
  20.       
  21.     @Override  
  22.     public boolean onKeyUp(int keyCode, KeyEvent event) {  
  23.         // TODO Auto-generated method stub  
  24.         return render.onKeyUp(keyCode, event);  
  25.     }  
  26.       
  27. }  

        ScData.java

Java代码
  1. package org.ourunix.android.world;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class ScData {  
  7.   
  8.     public static class VERTEX{  
  9.         float x, y, z; //三角形的顶点坐标  
  10.         float u, v;//纹理坐标  
  11.           
  12.         public VERTEX(float x, float y , float z, float u, float v){  
  13.             this.x = x;  
  14.             this.y = y;  
  15.             this.z = z;  
  16.             this.u = u;  
  17.             this.v = v;  
  18.         }  
  19.     }  
  20.       
  21.     //三角形结构  
  22.     public static class TRIANGLE{  
  23.         VERTEX[] vertex = new VERTEX[3];  
  24.     }  
  25.       
  26.     //区段结构  
  27.     public static class SECTOR{  
  28.         int numTriangles;  
  29.         List<TRIANGLE> triangle = new ArrayList<TRIANGLE>();  
  30.     }  
  31. }  

        GLRenderer.java

Java代码
  1. package org.ourunix.android.world;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.nio.FloatBuffer;  
  8. import java.nio.IntBuffer;  
  9.   
  10. import javax.microedition.khronos.egl.EGLConfig;  
  11. import javax.microedition.khronos.opengles.GL10;  
  12.   
  13. import org.ourunix.android.world.ScData.SECTOR;  
  14. import org.ourunix.android.world.ScData.TRIANGLE;  
  15. import org.ourunix.android.world.ScData.VERTEX;  
  16.   
  17. import android.content.Context;  
  18. import android.content.res.AssetManager;  
  19. import android.content.res.Resources;  
  20. import android.graphics.Bitmap;  
  21. import android.graphics.BitmapFactory;  
  22. import android.opengl.GLUtils;  
  23. import android.opengl.GLSurfaceView.Renderer;  
  24. import android.view.KeyEvent;  
  25.   
  26. public class GLRenderer implements Renderer {  
  27.     private Context mContext;  
  28.     SECTOR sector1 = new SECTOR();  
  29.       
  30.     public final static float piover180 = 0.0174532925f;  
  31.     float heading;  
  32.     float xpos;  
  33.     float zpos;  
  34.   
  35.     float   yrot;               // Y Rotation  
  36.     float walkbias = 0;  
  37.     float walkbiasangle = 0;  
  38.     float lookupdown = 0.0f;  
  39.     float z=0.0f;         
  40.       
  41.     private int[] texturesID = new int[3];  
  42.       
  43.     public GLRenderer(Context ctx){  
  44.         mContext = ctx;  
  45.     }  
  46.   
  47.     @Override  
  48.     public void onDrawFrame(GL10 gl) {  
  49.         // TODO Auto-generated method stub  
  50.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    // Clear The Screen And The Depth Buffer  
  51.         gl.glLoadIdentity();                                    // Reset The View  
  52.   
  53.         float xtrans = -xpos;  
  54.         float ztrans = -zpos;  
  55.         float ytrans = -walkbias-0.25f;  
  56.         float sceneroty = 360.0f - yrot;  
  57.   
  58.         FloatBuffer vertexPointer = Utils.BufferUtil.fBuffer(new float[9]);  
  59.         FloatBuffer texCoordPointer = Utils.BufferUtil.fBuffer(new float[6]);  
  60.         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexPointer);  
  61.         gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoordPointer);  
  62.           
  63.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  64.         gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
  65.           
  66.         gl.glLoadIdentity();  
  67.   
  68.         gl.glRotatef(lookupdown, 1.0f, 0.0f, 0.0f);  
  69.         gl.glRotatef(sceneroty, 0.0f, 1.0f, 0.0f);  
  70.           
  71.         gl.glTranslatef(xtrans, ytrans, ztrans);  
  72.           
  73.         gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesID[0]);  
  74.           
  75.         for(TRIANGLE triangle : sector1.triangle)  
  76.         {  
  77.             vertexPointer.clear();  
  78.             texCoordPointer.clear();  
  79.             gl.glNormal3f(0.0f, 0.0f, 1.0f);  
  80.             for(int i=0; i<3; i++)  
  81.             {  
  82.                 VERTEX vt = triangle.vertex[i];  
  83.                 vertexPointer.put(vt.x);  
  84.                 vertexPointer.put(vt.y);  
  85.                 vertexPointer.put(vt.z);  
  86.                 texCoordPointer.put(vt.u);  
  87.                 texCoordPointer.put(vt.v);  
  88.             }  
  89.             gl.glDrawArrays(GL10.GL_TRIANGLES, 04);  
  90.         }  
  91.           
  92.         gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
  93.         gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);  
  94.           
  95.     }  
  96.   
  97.     @Override  
  98.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  99.         // TODO Auto-generated method stub  
  100.         float ratio = (float)width/height;  
  101.         gl.glViewport(00, width, height);  
  102.         gl.glMatrixMode(GL10.GL_PROJECTION);  
  103.         gl.glLoadIdentity();  
  104.         gl.glFrustumf(-ratio, ratio, -11110);  
  105.         gl.glMatrixMode(GL10.GL_MODELVIEW);  
  106.         gl.glLoadIdentity();  
  107.     }  
  108.   
  109.     @Override  
  110.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  111.         // TODO Auto-generated method stub  
  112.         //加载纹理  
  113.         gl.glEnable(GL10.GL_TEXTURE_2D);  
  114.         LoadGLTextures(gl);  
  115.           
  116.         //开启混色透明  
  117.         gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);  
  118.           
  119.         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);  
  120.         gl.glClearColor(0000);  
  121.         gl.glShadeModel(GL10.GL_SMOOTH);  
  122.           
  123.         //开启深度测试  
  124.         gl.glClearDepthf(1.0f);  
  125.         gl.glDepthFunc(GL10.GL_LESS);  
  126.         gl.glEnable(GL10.GL_DEPTH_TEST);  
  127.           
  128.         SetupWorld();  
  129.     }  
  130.   
  131.     private void LoadGLTextures(GL10 gl) {  
  132.         int[] imgArray = {R.drawable.img};  
  133.         // TODO Auto-generated method stub  
  134.         for (int i = 0; i < 3; i++){  
  135.             IntBuffer textureBuffer = IntBuffer.allocate(1);  
  136.             gl.glGenTextures(1, textureBuffer);  
  137.             texturesID[i] = textureBuffer.get();  
  138.             gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesID[i]);  
  139.             Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(), imgArray[0]);  
  140.              //生成纹理  
  141.             GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);  
  142.              // 线形滤波    
  143.             gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);    
  144.             gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);  
  145.         }  
  146.     }  
  147.       
  148.     private void SetupWorld() {  
  149.         // TODO Auto-generated method stub  
  150.         GLFile glFile = new GLFile(mContext.getResources());  
  151.         BufferedReader br = new BufferedReader(new InputStreamReader(glFile.getFile("data/world.txt")));  
  152.         TRIANGLE triangle = new TRIANGLE();  
  153.         int vertexIndex = 0;  
  154.           
  155.         try {  
  156.             String line = null;  
  157.             while((line = br.readLine()) != null){  
  158.                 if(line.trim().length() <= 0 || line.startsWith("/")){  
  159.                     continue;  
  160.                 }  
  161.                 String part[] = line.trim().split("\\s+");  
  162.                 float x = Float.valueOf(part[0]);  
  163.                 float y = Float.valueOf(part[1]);  
  164.                 float z = Float.valueOf(part[2]);  
  165.                 float u = Float.valueOf(part[3]);  
  166.                 float v = Float.valueOf(part[4]);  
  167.                 VERTEX vertex = new VERTEX(x, y, z, u, v);  
  168.                 triangle.vertex[vertexIndex] = vertex;  
  169.                   
  170.                 vertexIndex ++;  
  171.                 if(vertexIndex == 3){  
  172.                     vertexIndex = 0;  
  173.                     sector1.triangle.add(triangle);  
  174.                     triangle = new TRIANGLE();  
  175.                 }  
  176.             }  
  177.         } catch (IOException e) {  
  178.             e.printStackTrace();  
  179.         }  
  180.     }  
  181.       
  182.     public boolean onKeyUp(int keyCode, KeyEvent event)  
  183.     {  
  184.         switch ( keyCode )  
  185.         {  
  186.             case KeyEvent.KEYCODE_DPAD_LEFT:  
  187.                 yrot -= 1.5f;  
  188.                 break;  
  189.             case KeyEvent.KEYCODE_DPAD_RIGHT:  
  190.                 yrot += 1.5f;  
  191.                 break;  
  192.             case KeyEvent.KEYCODE_DPAD_UP:  
  193.                 // 沿游戏者所在的X平面移动  
  194.                 xpos -= (float)Math.sin(heading*piover180) * 0.05f;   
  195.                 // 沿游戏者所在的Z平面移动  
  196.                 zpos -= (float)Math.cos(heading*piover180) * 0.05f;           
  197.                 if (walkbiasangle >= 359.0f)// 如果walkbiasangle大于359度  
  198.                 {  
  199.                     walkbiasangle = 0.0f;// 将 walkbiasangle 设为0  
  200.                 }  
  201.                 else                                  
  202.                 {  
  203.                      walkbiasangle+= 10;// 如果 walkbiasangle < 359 ,则增加 10  
  204.                 }  
  205.                 // 使游戏者产生跳跃感  
  206.                 walkbias = (float)Math.sin(walkbiasangle * piover180)/20.0f;          
  207.                 break;  
  208.             case KeyEvent.KEYCODE_DPAD_DOWN:  
  209.                 // 沿游戏者所在的X平面移动  
  210.                 xpos += (float)Math.sin(heading*piover180) * 0.05f;       
  211.                 // 沿游戏者所在的Z平面移动  
  212.                 zpos += (float)Math.cos(heading*piover180) * 0.05f;   
  213.                 // 如果walkbiasangle小于1度  
  214.                 if (walkbiasangle <= 1.0f)                    
  215.                 {  
  216.                     walkbiasangle = 359.0f;// 使 walkbiasangle 等于 359                      
  217.                 }  
  218.                 else                              
  219.                 {  
  220.                     walkbiasangle-= 10;// 如果 walkbiasangle > 1 减去 10  
  221.                 }  
  222.                 // 使游戏者产生跳跃感  
  223.                 walkbias = (float)Math.sin(walkbiasangle * piover180)/20.0f;          
  224.                 break;  
  225.         }  
  226.         return false;  
  227.     }  
  228.   
  229.     public  class GLFile  
  230.     {  
  231.         public Resources resources;  
  232.         public GLFile(Resources r)  
  233.         {  
  234.             resources = r;  
  235.         }  
  236.         public InputStream getFile(String name){  
  237.             AssetManager am = resources.getAssets();  
  238.             try {  
  239.                 return am.open(name);  
  240.             } catch (IOException e) {  
  241.                 e.printStackTrace();  
  242.                 return null;  
  243.             }  
  244.         }  
  245.     }  
  246. }  

        Utils.java

Java代码
  1. package org.ourunix.android.world;  
  2.   
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6. import java.nio.IntBuffer;  
  7. import java.nio.ShortBuffer;  
  8.   
  9. public class Utils {  
  10.      public static class BufferUtil {    
  11.             public static IntBuffer intBuffer;  
  12.             public static FloatBuffer floatBuffer;  
  13.             public static ShortBuffer shortBuffer;  
  14.         
  15.             public static IntBuffer iBuffer(int[] a) {    
  16.                 // 先初始化buffer,数组的长度*4,因为一个float占4个字节    
  17.                 ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);    
  18.                 // 数组排列用nativeOrder    
  19.                 mbb.order(ByteOrder.nativeOrder());    
  20.                 intBuffer = mbb.asIntBuffer();    
  21.                 intBuffer.put(a);    
  22.                 intBuffer.position(0);    
  23.                 return intBuffer;    
  24.             }    
  25.               
  26.             public static FloatBuffer fBuffer(float[] a) {    
  27.                 // 先初始化buffer,数组的长度*4,因为一个float占4个字节    
  28.                 ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);    
  29.                 // 数组排列用nativeOrder    
  30.                 mbb.order(ByteOrder.nativeOrder());    
  31.                 floatBuffer = mbb.asFloatBuffer();    
  32.                 floatBuffer.put(a);    
  33.                 floatBuffer.position(0);    
  34.                 return floatBuffer;    
  35.             }  
  36.               
  37.             public static ShortBuffer sBuffer(short[] a) {    
  38.                 // 先初始化buffer,数组的长度*4,因为一个float占4个字节    
  39.                 ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 2);    
  40.                 // 数组排列用nativeOrder    
  41.                 mbb.order(ByteOrder.nativeOrder());    
  42.                 shortBuffer = mbb.asShortBuffer();    
  43.                 shortBuffer.put(a);    
  44.                 shortBuffer.position(0);    
  45.                 return shortBuffer;    
  46.             }  
  47.         }  
  48. }  

        源码下载:Android高级进阶十一 Android OpenGL建立3D空间源码

原创粉丝点击