现在的位置: 首页 > 综合 > 正文

Android的OpenGL学习笔记(2)

2013年10月02日 ⁄ 综合 ⁄ 共 7105字 ⁄ 字号 评论关闭

                                                                              Android的OpenGL学习笔记(2)

上篇主要目的是介绍OpenGL的基本框架,这里就用基本的框架绘画出一个三角形,绘制三角形在OpenGL中比较重要,因为在OpenGL(Android)中的图形都是用三角形拼凑起来的!

画三角形有两种,主要是调用的方法不同而已:

第一种,调用glDrawElements()方法绘画:

看代码,主要看继承GLSurfaceView的代码部分,其他的和上篇基本一样:

VortexRenderer.java

Code:
  1. package com.droidnova.android.games.vortex;  
  2.   
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6. import java.nio.ShortBuffer;  
  7.   
  8. import javax.microedition.khronos.egl.EGLConfig;  
  9. import javax.microedition.khronos.opengles.GL10;  
  10.   
  11. import android.opengl.GLSurfaceView;  
  12.   
  13. public class VortexRenderer implements GLSurfaceView.Renderer {  
  14.     //private static final String LOG_TAG = VortexRenderer.class.getSimpleName();  
  15.       
  16.     private float _red = 0f;  
  17.     private float _green = 0f;  
  18.     private float _blue = 0f;  
  19.   
  20.     // a raw buffer to hold indices allowing a reuse of points.  
  21.     private ShortBuffer _indexBuffer;  
  22.       
  23.     // a raw buffer to hold the vertices  
  24.     private FloatBuffer _vertexBuffer;  
  25.       
  26.     private short[] _indicesArray = {012};//关于索引的理解:即三角形三个顶点的索引,这里暂时画了一个平面二维的三角形,  
  27.     //看不出它的作用,当画三维的时候,就会清楚了,这里大概提一下,索引组合可以构成一个面!相当于三个点可以构成一个面,这里用索引代替了三个点而已!  
  28.     private int _nrOfVertices = 3;  
  29.   
  30.     private float _angle;  
  31.       
  32.     @Override  
  33.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  34.         // preparation  
  35.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  36.         initTriangle();  
  37.     }  
  38.   
  39.     @Override  
  40.     public void onSurfaceChanged(GL10 gl, int w, int h) {  
  41.         gl.glViewport(00, w, h);  
  42.     }  
  43.   
  44.     @Override  
  45.     public void onDrawFrame(GL10 gl) {  
  46.         // define the color we want to be displayed as the "clipping wall"  
  47.         gl.glClearColor(_red, _green, _blue, 1.0f);  
  48.           
  49.         gl.glLoadIdentity();//还原场景,还原矩阵。假如你旋转一个三角形之后,调用这个方法,  
  50.                             //可以让该三角形还原到初始位置,这里的主要作用是为了防止三角形不停的旋转。  
  51.         // clear the color buffer to show the ClearColor we called above...  
  52.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  53.           
  54.         // set rotation  
  55.         gl.glRotatef(_angle, 0f, 1f, 0f);//旋转时需要进行3D图像到2D的转换,需要进行浮点运算,  
  56.                         //会有偏差,所以随着时间的延长,三角形的顶点有偏移现象,暂时就这么理解着!  
  57.       
  58.         gl.glColor4f(0.5f, 0f, 0f, 0.5f);//对三角形进行着色!  
  59.         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);//第三个参数表示在数组元素中,两个有意义的数据单元之间相隔的字节数。  
  60.         //当值为0时,表示该数组数据是紧密排列的,没有间隔  
  61.         gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);  
  62.     }  
  63.       
  64.     private void initTriangle() {  
  65.         // float has 4 bytes  
  66.         ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4);  
  67.         vbb.order(ByteOrder.nativeOrder());  
  68.         _vertexBuffer = vbb.asFloatBuffer();//将字节Buffer转换为FloatBuffer,暂时这么理解的!  
  69.           
  70.         // short has 2 bytes  
  71.         ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2);//申请空间  
  72.         ibb.order(ByteOrder.nativeOrder());//必须设置为原生字节序!  
  73.         _indexBuffer = ibb.asShortBuffer();  
  74.           
  75.         float[] coords = {  
  76.             -0.5f, -0.5f, 0f, // (x1, y1, z1)  
  77.             0.5f, -0.5f, 0f, // (x2, y2, z2)  
  78.             0f, 0.5f, 0f // (x3, y3, z3)  
  79.         };  
  80.           
  81.         _vertexBuffer.put(coords);  
  82.           
  83.         _indexBuffer.put(_indicesArray);  
  84.           
  85.         _vertexBuffer.position(0);  
  86.         _indexBuffer.position(0);  
  87.     }  
  88.       
  89.     public void setColor(float r, float g, float b) {  
  90.         _red = r;  
  91.         _green = g;  
  92.         _blue = b;  
  93.     }  
  94.       
  95.     public void setAngle(float angle) {  
  96.         _angle = angle;  
  97.     }  
  98. }  

VortexView.java

Code:
  1. package com.droidnova.android.games.vortex;  
  2.   
  3. import android.content.Context;  
  4. import android.opengl.GLSurfaceView;  
  5. import android.view.MotionEvent;  
  6.   
  7. public class VortexView extends GLSurfaceView {  
  8.     // private static final String LOG_TAG = VortexView.class.getSimpleName();  
  9.     private VortexRenderer _renderer;  
  10.   
  11.     public VortexView(Context context) {  
  12.         super(context);  
  13.         _renderer = new VortexRenderer();  
  14.         setRenderer(_renderer);  
  15.     }  
  16.   
  17.     public boolean onTouchEvent(final MotionEvent event) {  
  18.         queueEvent(new Runnable() {  
  19.             public void run() {  
  20.                 _renderer.setColor(event.getX() / getWidth(), event.getY()  
  21.                         / getHeight(), 1.0f);  
  22.                 _renderer.setAngle(event.getX());  
  23.             }  
  24.         });  
  25.         return true;  
  26.     }  
  27. }  

第二种,调用glDrawArrays()绘画三角形:

GLRender.java代码:

Code:
  1. package com.android.myOpenGL;  
  2.   
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6.   
  7. import javax.microedition.khronos.egl.EGLConfig;  
  8. import javax.microedition.khronos.opengles.GL10;  
  9.   
  10. import android.opengl.GLSurfaceView.Renderer;  
  11.   
  12. public class GLRender implements Renderer {  
  13.     private float _red = 0.9f;  
  14.     private float _green = 0.2f;  
  15.     private float _blue = 0.2f;  
  16.     private float _angle;  
  17.   
  18.     private FloatBuffer _vertexBuffer;  
  19.     private int _nrOfVertices = 3;  
  20.   
  21.     @Override  
  22.     public void onDrawFrame(GL10 gl) {  
  23.         // TODO Auto-generated method stub  
  24.         gl.glClearColor(_red, _green, _blue, 1.0f);  
  25.           
  26.         gl.glLoadIdentity();//如果注释掉这句,效果将如同地球绕太阳旋转一样,自身旋转,也绕太阳公转,注意三角形分正反面  
  27.           
  28.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  29.   
  30.         gl.glTranslatef(0.5f, 0f, 0f);  
  31.         gl.glRotatef(_angle, 0f, 1f, 0f);//绕Y轴旋转,Y轴正方向单位1处,X,Y,Z三个参数共同决定讯转轴的方向。  
  32.         _angle++;//为了测试旋转平移的先后顺序会对结果造成何种影响添加上的,这样也可以让三角形不停的旋转,一般我喜欢这么做!  
  33.         /* 
  34.          * 先旋转还是先平移,顺序不同,效果也会不同的,具体怎么样的效果,自己运行一下程序,并改变次序,就会得到结果! 
  35.          */  
  36.           
  37.           
  38.         gl.glColor4f(0.5f, 0f, 0f, 0.5f);  
  39.         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);  
  40.         gl.glDrawArrays(GL10.GL_TRIANGLES, 03);  
  41.   
  42.         //gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//取消顶点设置,如果在这里添加这句,三角形会一闪而过。为了显示三角形,我们注释掉这句话。  
  43.     }  
  44.   
  45.     @Override  
  46.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  47.         // TODO Auto-generated method stub  
  48.         gl.glViewport(00, width, height);  
  49.     }  
  50.   
  51.     @Override  
  52.     public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {  
  53.         // TODO Auto-generated method stub  
  54.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  55.         initTriangle();  
  56.     }  
  57.   
  58.     private void initTriangle() {  
  59.         // float has 4 bytes  
  60.         ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4);  
  61.         vbb.order(ByteOrder.nativeOrder());  
  62.         _vertexBuffer = vbb.asFloatBuffer();  
  63.           
  64.           
  65.         float[] coords = {  
  66.             -0.5f, -0.5f, 0f, // (x1, y1, z1)  
  67.             0.5f, -0.5f, 0f, // (x2, y2, z2)  
  68.             0f, 0.5f, 0f // (x3, y3, z3)  
  69.         };  
  70.           
  71.         _vertexBuffer.put(coords);  
  72.           
  73.           
  74.         _vertexBuffer.position(0);  
  75.     }  
  76.       
  77.     public void setColor(float r, float g, float b) {  
  78.         _red = r;  
  79.         _green = g;  
  80.         _blue = b;  
  81.     }  
  82.       
  83.     public void setAngle(float angle) {  
  84.         _angle = angle;  
  85.     }  
  86. }  

最终效果图都是一样的,如图:

必要的解释都在代码注释中,如有问题,请留言提出,如有错误,也同样请留言指出,小弟感激不尽……

抱歉!评论已关闭.