android 3D系列之入门实践篇

By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处
通过之前文章--概念篇的学习,我们今天编写一个简单的入门程序,实现一个不断绕x轴,y轴旋转的彩色立方体,效果如下:

在Android中我们使用GLSurfaceView来显示OpenGL视图,GLSurfaceView:是其中很重要的一个类,此类位于 android.opengl包下,用于管理是一块可以是复合视图机器人系统的内存的特殊的曲面。管理一个使表面呈现 OpenGL 的 EGL 显示。接受一个用户提供输入Render对象进行显示。从 UI 线程实现一个专用线程渲染界面实现3D性能。支持按需要和连续的呈现。 包装、 跟踪,和检查 OpenGL 渲染器调用的错误。所以首先我们需要创建一个GLSurfaceView。

[code]

 

  • public class mainActivity extends Activity {
  •     CubeRenderer mCubeRenderer;  //我们自定义的立方体Renderer
  •     @Override
  •     public void onCreate(Bundle savedInstanceState) {
  •         super.onCreate(savedInstanceState);
  •         requestWindowFeature(Window.FEATURE_NO_TITLE); // 去掉标题
  •         GLSurfaceView GLView = new GLSurfaceView(this); //创建一个GLSurfaceView
  •            mCubeRenderer = new CubeRenderer();
  •         GLView.setRenderer(mCubeRenderer);
  •         setContentView(GLView);
  •     }
  • }
  • [/code]
    接下来我们的主要工作就是去创建一个继承Renderer接口的CubeRenderer。Renderer是一个专门用来渲染3D的接口。继承它,我们需要重载以下方法:    public void onDrawFrame(GL10 gl)

    {

    //渲染的绘图操作,重绘时调用

    }

    public void onSurfaceChanged(GL10 gl, int width, int height)

    {

    //视窗改变时调用,通常在此设置视窗范围以及透视,投影范围

    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config)

    {

    //创建时调用,通常在此进行初始化设置

    }

    以下是我们CubeRenderer的完整代码:

  • [code]
    1. public class CubeRenderer implements Renderer {
    2.     float box[] = new float[] {
    3.             // FRONT
    4.             -0.5f, -0.5f,  0.5f,
    5.              0.5f, -0.5f,  0.5f,
    6.             -0.5f,  0.5f,  0.5f,
    7.              0.5f,  0.5f,  0.5f,
    8.             // BACK
    9.             -0.5f, -0.5f, -0.5f,
    10.             -0.5f,  0.5f, -0.5f,
    11.              0.5f, -0.5f, -0.5f,
    12.              0.5f,  0.5f, -0.5f,
    13.             // LEFT
    14.             -0.5f, -0.5f,  0.5f,
    15.             -0.5f,  0.5f,  0.5f,
    16.             -0.5f, -0.5f, -0.5f,
    17.             -0.5f,  0.5f, -0.5f,
    18.             // RIGHT
    19.              0.5f, -0.5f, -0.5f,
    20.              0.5f,  0.5f, -0.5f,
    21.              0.5f, -0.5f,  0.5f,
    22.              0.5f,  0.5f,  0.5f,
    23.             // TOP
    24.             -0.5f,  0.5f,  0.5f,
    25.              0.5f,  0.5f,  0.5f,
    26.              -0.5f,  0.5f, -0.5f,
    27.              0.5f,  0.5f, -0.5f,
    28.             // BOTTOM
    29.             -0.5f, -0.5f,  0.5f,
    30.             -0.5f, -0.5f, -0.5f,
    31.              0.5f, -0.5f,  0.5f,
    32.              0.5f, -0.5f, -0.5f,
    33.         };
    34.     FloatBuffer cubeBuff;
    35.     float xrot = 0.0f;
    36.     float yrot = 0.0f;
    37.     /**
    38.      * 将float数组转换存储在字节缓冲数组
    39.      * @param arr
    40.      * @return
    41.      */
    42.     public FloatBuffer makeFloatBuffer(float[] arr) {
    43.         ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);//分配缓冲空间,一个float占4个字节
    44.         bb.order(ByteOrder.nativeOrder()); //设置字节顺序, 其中ByteOrder.nativeOrder()是获取本机字节顺序
    45.         FloatBuffer fb = bb.asFloatBuffer(); //转换为float型
    46.         fb.put(arr);        //添加数据
    47.         fb.position(0);      //设置数组的起始位置
    48.         return fb;
    49.     }
    50.     public CubeRenderer() {
    51.         // TODO Auto-generated constructor stub
    52.         cubeBuff = makeFloatBuffer(box);//转换float数组
    53.     }
    54.     protected void init(GL10 gl) {
    55.         gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清屏时背景的颜色,R,G,B,A
    56.         gl.glEnable(GL10.GL_DEPTH_TEST); //启用深度缓存
    57.         gl.glEnable(GL10.GL_CULL_FACE);  //启用背面剪裁
    58.         gl.glClearDepthf(1.0f);    // 设置深度缓存值
    59.         gl.glDepthFunc(GL10.GL_LEQUAL);  // 设置深度缓存比较函数,GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值(通过gl.glClearDepthf(1.0f)设置)时通过深度测试   
    60.         gl.glShadeModel(GL10.GL_SMOOTH);// 设置阴影模式GL_SMOOTH
    61.     }
    62.     @Override
    63.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    64.         // TODO Auto-generated method stub
    65.         init(gl);
    66.     }
    67.     @Override
    68.     public void onSurfaceChanged(GL10 gl, int w, int h) {
    69.         // TODO Auto-generated method stub
    70.         gl.glViewport(00, w, h); //设置视窗
    71.         gl.glMatrixMode(GL10.GL_PROJECTION); // 设置投影矩阵
    72.         gl.glLoadIdentity();  //设置矩阵为单位矩阵,相当于重置矩阵       
    73.         GLU.gluPerspective(gl, 45.0f, ((float) w) / h, 0.1f, 10f);//设置透视范围  
    74.     }
    75.     @Override
    76.     public void onDrawFrame(GL10 gl) {
    77.         // TODO Auto-generated method stub
    78.         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存
    79.         gl.glMatrixMode(GL10.GL_MODELVIEW);   //切换至模型观察矩阵
    80.         gl.glLoadIdentity();// 重置当前的模型观察矩阵
    81.         GLU.gluLookAt(gl, 003000010);//设置视点和模型中心位置
    82.         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);//设置顶点数据
    83.         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    84.         gl.glRotatef(xrot, 100);  //绕着(0,0,0)与(1,0,0)即x轴旋转
    85.         gl.glRotatef(yrot, 010);
    86.         gl.glColor4f(1.0f, 001.0f);   //设置颜色,红色
    87.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 04);  //绘制正方型FRONT面
    88.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 44);
    89.         gl.glColor4f(01.0f, 01.0f);
    90.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 84);
    91.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 124);
    92.         gl.glColor4f(001.0f, 1.0f);
    93.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 164);
    94.         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 204);
    95.         xrot += 1.0f;
    96.         yrot += 0.5f;
    97.     }
    98. }
    99. [/code]
    100. 源码工程,下载地址:http://download.csdn.net/source/3566635