Android OpenGL 画球 画圆


  

做了2个简单的类 一个是描述球的 一个是平面圆的

  1. public class Ball  
  2. {  
  3.     private int slices = 36//越大越圆滑   
  4.     private int stacks = 24//同↑   
  5.     private FloatBuffer[] normalsBuffers;  
  6.     private FloatBuffer[] slicesBuffers;  
  7.     private float yAngle;  
  8.     private float zAngle;  
  9.       
  10.       
  11.     float radius = 1.3f;  
  12.     public Ball()  
  13.     {  
  14.         slicesBuffers = new FloatBuffer[slices];  
  15.         normalsBuffers = new FloatBuffer[slices];  
  16.         for (int i = 0; i < slices; i++) {  
  17.               
  18.             float[] vertexCoords = new float[6 * (stacks + 1)];  
  19.             float[] normalCoords = new float[6 * (stacks + 1)];  
  20.   
  21.             double alpha0 = i * (2 * Math.PI) / slices;  
  22.             double alpha1 = (i + 1) * (2 * Math.PI) / slices;  
  23.               
  24.             float cosAlpha0 = (float) Math.cos(alpha0);  
  25.             float sinAlpha0 = (float) Math.sin(alpha0);  
  26.             float cosAlpha1 = (float) Math.cos(alpha1);  
  27.             float sinAlpha1 = (float) Math.sin(alpha1);  
  28.   
  29.             for (int j = 0; j <= stacks; j++)   
  30.             {     
  31.                 double beta = j * Math.PI / stacks - Math.PI / 2;  
  32.                   
  33.                 float cosBeta = (float) Math.cos(beta);  
  34.                 float sinBeta = (float) Math.sin(beta);  
  35.                   
  36.                   
  37.                 setXYZ(vertexCoords, 6 * j,  
  38.                         radius * cosBeta * cosAlpha1,  
  39.                         radius * sinBeta,  
  40.                         radius * cosBeta * sinAlpha1);  
  41.                 setXYZ(vertexCoords, 6 * j + 3,  
  42.                         radius * cosBeta * cosAlpha0,  
  43.                         radius * sinBeta,  
  44.                         radius * cosBeta * sinAlpha0);  
  45.                 setXYZ(normalCoords, 6 * j,  
  46.                         cosBeta * cosAlpha1,  
  47.                         sinBeta,  
  48.                         cosBeta * sinAlpha1);  
  49.                 setXYZ(normalCoords, 6 * j + 3,  
  50.                         cosBeta * cosAlpha0,  
  51.                         sinBeta,  
  52.                         cosBeta * sinAlpha0);  
  53.             }  
  54.             slicesBuffers[i] = FloatBuffer.wrap(vertexCoords);  
  55.             normalsBuffers[i] = FloatBuffer.wrap(normalCoords);  
  56.         }     
  57.     }  
  58.       
  59.     public void setXYZ(float[] vector, int offset, float x, float y, float z) {  
  60.         vector[offset] = x;  
  61.         vector[offset + 1] = y;  
  62.         vector[offset + 2] = z;  
  63.     }  
  64.       
  65.     public void draw(GL10 gl)  
  66.     {  
  67.         gl.glLoadIdentity();  
  68.         gl.glTranslatef(0.0f, 0.0f, -7.0f);  
  69.         gl.glColor4f(1.0f, 0.2f, 0.3f, 1.0f);  
  70.         gl.glRotatef(yAngle, 1.0f, 0.0f, 0.0f);  
  71.         gl.glRotatef(zAngle, 0.0f, 1.0f, 0.0f);  
  72.           
  73.         for (int i = 0; i < slices; i++) {  
  74.             gl.glVertexPointer(3, GL10.GL_FLOAT, 0, slicesBuffers[i]);  
  75.             gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 02 * (stacks + 1));  
  76.   
  77.         }  
  78.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  79.     }  
  80.   
  81.     public void setyAngle(float yAngle)  
  82.     {  
  83.         this.yAngle = yAngle;  
  84.     }  
  85.   
  86.     public void setzAngle(float zAngle)  
  87.     {  
  88.         this.zAngle = zAngle;  
  89.     }  
  90. }  
 
  1. public class Oval  
  2. {  
  3.     private float[] vertices = new float[720];  
  4.     private FloatBuffer verBuffer ;  
  5.     private float yAngle;  
  6.     private float zAngle;  
  7.     public Oval()  
  8.     {  
  9.         //初始化圆形数据   
  10.         for (int i = 0; i < 720; i += 2) {  
  11.             // x 坐标   
  12.             vertices[i]   =  (float) (Math.cos(DegToRad(i)) * 1);  
  13.             // y 坐标   
  14.             vertices[i+1] =  (float) (Math.sin(DegToRad(i)) * 1);  
  15.         }     
  16.         //设置圆形顶点数据   
  17.         ByteBuffer qbb = ByteBuffer.allocateDirect(vertices.length * 4);  
  18.         qbb.order(ByteOrder.nativeOrder());  
  19.         verBuffer = qbb.asFloatBuffer();  
  20.         verBuffer.put(vertices);  
  21.         verBuffer.position(0);   
  22.     }  
  23.       
  24.     public float DegToRad(float deg)  
  25.     {  
  26.         return (float) (3.14159265358979323846 * deg / 180.0);  
  27.     }  
  28.       
  29.     public void draw(GL10 gl)  
  30.     {  
  31.         //重置投影矩阵   
  32.         gl.glLoadIdentity();  
  33.         // 移动操作,移入屏幕(Z轴)5个像素, x, y , z   
  34.         gl.glTranslatef(0.0f, 0.0f, -5.0f);  
  35.           
  36.         //旋转, angle, x, y , z   
  37.         gl.glRotatef(yAngle, 0.0f, 1.0f, 0.0f);  
  38.         gl.glRotatef(zAngle, 1.0f, 0.0f, 0.0f);  
  39.           
  40.         // 设置当前色为红色, R, G, B, Alpha   
  41.         gl.glColor4f(1.0f, 0.1f, 0.1f, 1.0f);  
  42.           
  43.         //设置顶点类型为浮点坐标     
  44.         gl.glVertexPointer(2, GL10.GL_FLOAT, 0, verBuffer);  
  45.   
  46.         //打开顶点数组   
  47.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  48.           
  49.         //向OGL发送实际画图指令   
  50.         gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0360);  
  51.   
  52.         //画图结束   
  53.         gl.glFinish();  
  54.     }  
  55.   
  56.     public void setyAngle(float yAngle)  
  57.     {  
  58.         this.yAngle = yAngle;  
  59.     }  
  60.   
  61.     public void setzAngle(float zAngle)  
  62.     {  
  63.         this.zAngle = zAngle;  
  64.     }  
  65. }  

这个是renderer类 声明了Ball 和 Oval 变量

  1. public class GLRender implements Renderer{  
  2.   
  3.     Oval o = new Oval();  
  4.     Ball b = new Ball();  
  5.     //度到弧度的转换   
  6.   
  7.     @Override  
  8.     public void onDrawFrame(GL10 gl) {  
  9.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  10.         gl.glMatrixMode(GL10.GL_MODELVIEW);  
  11.         gl.glLoadIdentity();          
  12.         gl.glEnable(GL10.GL_CULL_FACE);  
  13.         gl.glLightModelx(GL10.GL_LIGHT_MODEL_TWO_SIDE, GL10.GL_FALSE);  
  14.         //o.draw(gl);                 <span style="color:#ff0000;">//------画圆</span>   
  15.          b.draw(gl);         <span style="color:#ff0000;">//------画球</span>   
  16.     }  
  17.        
  18.     public void setyAngle(float yAngle)  
  19.     {  
  20.         b.setyAngle(yAngle);  
  21.         o.setyAngle(yAngle);  
  22.     }  
  23.   
  24.     public void setzAngle(float zAngle)  
  25.     {  
  26.         b.setzAngle(zAngle);  
  27.         o.setzAngle(zAngle);  
  28.     }  
  29.   
  30.     @Override  
  31.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  32.         if (height == 0) height = 1;  
  33.         gl.glViewport(00, width, height);  
  34.         gl.glMatrixMode(GL10.GL_PROJECTION);  
  35.         gl.glLoadIdentity();  
  36.         GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 1.0f, 100.0f);  
  37.     }  
  38.   
  39.     @Override  
  40.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  41.         gl.glShadeModel(GL10.GL_SMOOTH);  
  42.         gl.glClearColor(0000);  
  43.         gl.glClearDepthf(1.0f);  
  44.         gl.glEnable(GL10.GL_DEPTH_TEST);  
  45.         gl.glDepthFunc(GL10.GL_LEQUAL);  
  46.         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);   
  47.         gl.glCullFace(GL10.GL_BACK);  
  48.         gl.glEnable(GL10.GL_LIGHT0);  
  49.     }  
  50. }  

最后是GLSurfaceView类

  1. public class MyGLSurfaceView extends GLSurfaceView  
  2. {  
  3.     GLRender myRenderer;// 自定义的渲染器  
  4.     private final float TOUCH_SCALE_FACTOR = 180.0f / 320;// 角度缩放比例  
  5.     private float mPreviousY;// 上次的触控位置Y坐标  
  6.     private float mPreviousX;// 上次的触控位置X坐标  
  7.     float yAngle = 0;// 绕y轴旋转的角度  
  8.     float zAngle = 0;// 绕z轴旋转的角度  
  9.   
  10.     public MyGLSurfaceView(Context context)  
  11.     {  
  12.         super(context);  
  13.         myRenderer = new GLRender();// 创建渲染器  
  14.         this.setRenderer(myRenderer);// 设置渲染器  
  15.         this.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);// 设置渲染模式  
  16.     }  
  17.   
  18.     @Override  
  19.     public boolean onTouchEvent(MotionEvent e)  
  20.     {   // 触摸事件的回调方法  
  21.         float x = e.getX();// 得到x坐标  
  22.         float y = e.getY();// 得到y坐标  
  23.         switch (e.getAction())  
  24.         {  
  25.         case MotionEvent.ACTION_MOVE:// 触控笔移动  
  26.             float dy = y - mPreviousY;// 计算触控笔Y位移  
  27.             float dx = x - mPreviousX;// 计算触控笔X位移  
  28.             yAngle += dx * TOUCH_SCALE_FACTOR;// 设置沿y轴旋转角度  
  29.             zAngle += dy * TOUCH_SCALE_FACTOR;// 设置沿z轴旋转角度  
  30.             myRenderer.setyAngle(yAngle);  
  31.             myRenderer.setzAngle(zAngle);     
  32.             requestRender();// 重绘画面  
  33.         }  
  34.         mPreviousY = y;// 记录触控笔位置  
  35.         mPreviousX = x;// 记录触控笔位置  
  36.         return true;// 返回true  
  37.     }  
  38. }  

重写了ontouch 事件  通过x y 计算出变化的角度 可以让图形做简单的转动 改一改就可以平动了
不过球因为没有做处理 只是用单一颜色绘制的 所以看起来和圆差不多 可以加上颜色数组 就比较明显了

相关内容