android 3D系列之入门实践篇

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

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


 
<ul>
	<li class="alt"><span class="keyword">public</span> <span class="keyword">class</span> mainActivity <span class="keyword">extends</span> Activity {</li>
	<li class="">    CubeRenderer mCubeRenderer;  <span class="comment">//我们自定义的立方体Renderer</span></li>
	<li class="alt">    <span class="annotation">@Override</span></li>
	<li class="">    <span class="keyword">public</span> <span class="keyword">void</span> onCreate(Bundle savedInstanceState) {</li>
	<li class="alt">        <span class="keyword">super</span>.onCreate(savedInstanceState);</li>
	<li class="">        requestWindowFeature(Window.FEATURE_NO_TITLE); <span class="comment">// 去掉标题</span></li>
	<li class="alt">        GLSurfaceView GLView = <span class="keyword">new</span> GLSurfaceView(<span class="keyword">this</span>); <span class="comment">//创建一个GLSurfaceView</span></li>
	<li class="">           mCubeRenderer = <span class="keyword">new</span> CubeRenderer();</li>
	<li class="alt">        GLView.setRenderer(mCubeRenderer);</li>
	<li class="">        setContentView(GLView);</li>
	<li class="alt"></li>
	<li class="">    }</li>
	<li class="alt">}</li>
	<li class="alt">

接下来我们的主要工作就是去创建一个继承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的完整代码:

  • </li>
    	<li class="alt">
    <ol class="dp-j" start="1">
    	<li class="alt"><span class="keyword">public</span> <span class="keyword">class</span> CubeRenderer <span class="keyword">implements</span> Renderer {</li>
    	<li class=""></li>
    	<li class="alt">    <span class="keyword">float</span> box[] = <span class="keyword">new</span> <span class="keyword">float</span>[] {</li>
    	<li class="">            <span class="comment">// FRONT</span></li>
    	<li class="alt">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">            -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">            <span class="comment">// BACK</span></li>
    	<li class="">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="alt">            -<span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="alt">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">            <span class="comment">// LEFT</span></li>
    	<li class="alt">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="">            -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">            -<span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="alt">            <span class="comment">// RIGHT</span></li>
    	<li class="">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="alt">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="">            <span class="comment">// TOP</span></li>
    	<li class="alt">            -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">             -<span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f,  <span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="alt">            <span class="comment">// BOTTOM</span></li>
    	<li class="">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">            -<span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f,  <span class="number">0</span>.5f,</li>
    	<li class="alt">             <span class="number">0</span>.5f, -<span class="number">0</span>.5f, -<span class="number">0</span>.5f,</li>
    	<li class="">        };</li>
    	<li class="alt"></li>
    	<li class="">    FloatBuffer cubeBuff;</li>
    	<li class="alt"></li>
    	<li class="">    <span class="keyword">float</span> xrot = <span class="number">0</span>.0f;</li>
    	<li class="alt">    <span class="keyword">float</span> yrot = <span class="number">0</span>.0f;</li>
    	<li class=""></li>
    	<li class="alt">    <span class="comment">/**</span></li>
    	<li class=""><span class="comment">     * 将float数组转换存储在字节缓冲数组</span></li>
    	<li class="alt"><span class="comment">     * @param arr</span></li>
    	<li class=""><span class="comment">     * @return</span></li>
    	<li class="alt"><span class="comment">     */</span></li>
    	<li class="">    <span class="keyword">public</span> FloatBuffer makeFloatBuffer(<span class="keyword">float</span>[] arr) {</li>
    	<li class="alt">        ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * <span class="number">4</span>);<span class="comment">//分配缓冲空间,一个float占4个字节</span></li>
    	<li class="">        bb.order(ByteOrder.nativeOrder()); <span class="comment">//设置字节顺序, 其中ByteOrder.nativeOrder()是获取本机字节顺序</span></li>
    	<li class="alt">        FloatBuffer fb = bb.asFloatBuffer(); <span class="comment">//转换为float型</span></li>
    	<li class="">        fb.put(arr);        <span class="comment">//添加数据</span></li>
    	<li class="alt">        fb.position(<span class="number">0</span>);      <span class="comment">//设置数组的起始位置</span></li>
    	<li class="">        <span class="keyword">return</span> fb;</li>
    	<li class="alt">    }</li>
    	<li class=""></li>
    	<li class="alt">    <span class="keyword">public</span> CubeRenderer() {</li>
    	<li class="">        <span class="comment">// TODO Auto-generated constructor stub</span></li>
    	<li class="alt">        cubeBuff = makeFloatBuffer(box);<span class="comment">//转换float数组</span></li>
    	<li class="">    }</li>
    	<li class="alt"></li>
    	<li class=""></li>
    	<li class="alt">    <span class="keyword">protected</span> <span class="keyword">void</span> init(GL10 gl) {</li>
    	<li class="">        gl.glClearColor(<span class="number">0</span>.0f, <span class="number">0</span>.0f, <span class="number">0</span>.0f, <span class="number">1</span>.0f);<span class="comment">//设置清屏时背景的颜色,R,G,B,A</span></li>
    	<li class="alt"></li>
    	<li class="">        gl.glEnable(GL10.GL_DEPTH_TEST); <span class="comment">//启用深度缓存</span></li>
    	<li class="alt">        gl.glEnable(GL10.GL_CULL_FACE);  <span class="comment">//启用背面剪裁</span></li>
    	<li class="">        gl.glClearDepthf(<span class="number">1</span>.0f);    <span class="comment">// 设置深度缓存值</span></li>
    	<li class="alt">        gl.glDepthFunc(GL10.GL_LEQUAL);  <span class="comment">// 设置深度缓存比较函数,GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值(通过gl.glClearDepthf(1.0f)设置)时通过深度测试   </span></li>
    	<li class="">        gl.glShadeModel(GL10.GL_SMOOTH);<span class="comment">// 设置阴影模式GL_SMOOTH</span></li>
    	<li class="alt">    }</li>
    	<li class=""></li>
    	<li class="alt">    <span class="annotation">@Override</span></li>
    	<li class="">    <span class="keyword">public</span> <span class="keyword">void</span> onSurfaceCreated(GL10 gl, EGLConfig config) {</li>
    	<li class="alt">        <span class="comment">// TODO Auto-generated method stub</span></li>
    	<li class="">        init(gl);</li>
    	<li class="alt">    }</li>
    	<li class=""></li>
    	<li class="alt">    <span class="annotation">@Override</span></li>
    	<li class="">    <span class="keyword">public</span> <span class="keyword">void</span> onSurfaceChanged(GL10 gl, <span class="keyword">int</span> w, <span class="keyword">int</span> h) {</li>
    	<li class="alt">        <span class="comment">// TODO Auto-generated method stub</span></li>
    	<li class="">        gl.glViewport(<span class="number">0</span>, <span class="number">0</span>, w, h); <span class="comment">//设置视窗</span></li>
    	<li class="alt">        gl.glMatrixMode(GL10.GL_PROJECTION); <span class="comment">// 设置投影矩阵</span></li>
    	<li class="">        gl.glLoadIdentity();  <span class="comment">//设置矩阵为单位矩阵,相当于重置矩阵       </span></li>
    	<li class="alt">        GLU.gluPerspective(gl, <span class="number">45</span>.0f, ((<span class="keyword">float</span>) w) / h, <span class="number">0</span>.1f, 10f);<span class="comment">//设置透视范围  </span></li>
    	<li class="">    }</li>
    	<li class="alt"></li>
    	<li class="">    <span class="annotation">@Override</span></li>
    	<li class="alt">    <span class="keyword">public</span> <span class="keyword">void</span> onDrawFrame(GL10 gl) {</li>
    	<li class="">        <span class="comment">// TODO Auto-generated method stub</span></li>
    	<li class="alt">        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);<span class="comment">// 清除屏幕和深度缓存</span></li>
    	<li class=""></li>
    	<li class="alt">        gl.glMatrixMode(GL10.GL_MODELVIEW);   <span class="comment">//切换至模型观察矩阵</span></li>
    	<li class="">        gl.glLoadIdentity();<span class="comment">// 重置当前的模型观察矩阵</span></li>
    	<li class="alt">        GLU.gluLookAt(gl, <span class="number">0</span>, <span class="number">0</span>, <span class="number">3</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);<span class="comment">//设置视点和模型中心位置</span></li>
    	<li class=""></li>
    	<li class="alt">        gl.glVertexPointer(<span class="number">3</span>, GL10.GL_FLOAT, <span class="number">0</span>, cubeBuff);<span class="comment">//设置顶点数据</span></li>
    	<li class="">        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);</li>
    	<li class="alt"></li>
    	<li class="">        gl.glRotatef(xrot, <span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>);  <span class="comment">//绕着(0,0,0)与(1,0,0)即x轴旋转</span></li>
    	<li class="alt">        gl.glRotatef(yrot, <span class="number">0</span>, <span class="number">1</span>, <span class="number">0</span>);</li>
    	<li class=""></li>
    	<li class="alt">        gl.glColor4f(<span class="number">1</span>.0f, <span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>.0f);   <span class="comment">//设置颜色,红色</span></li>
    	<li class="">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">0</span>, <span class="number">4</span>);  <span class="comment">//绘制正方型FRONT面</span></li>
    	<li class="alt">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">4</span>, <span class="number">4</span>);</li>
    	<li class=""></li>
    	<li class="alt">        gl.glColor4f(<span class="number">0</span>, <span class="number">1</span>.0f, <span class="number">0</span>, <span class="number">1</span>.0f);</li>
    	<li class="">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">8</span>, <span class="number">4</span>);</li>
    	<li class="alt">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">12</span>, <span class="number">4</span>);</li>
    	<li class=""></li>
    	<li class="alt">        gl.glColor4f(<span class="number">0</span>, <span class="number">0</span>, <span class="number">1</span>.0f, <span class="number">1</span>.0f);</li>
    	<li class="">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">16</span>, <span class="number">4</span>);</li>
    	<li class="alt">        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, <span class="number">20</span>, <span class="number">4</span>);</li>
    	<li class=""></li>
    	<li class="alt">        xrot += <span class="number">1</span>.0f;</li>
    	<li class="">        yrot += <span class="number">0</span>.5f;</li>
    	<li class="alt">    }</li>
    	<li class=""></li>
    	<li class="alt">}</li>
    	<li class="alt">
  • 源码工程,下载地址:http://download.csdn.net/source/3566635
  •  

    赞(0) 打赏
    分享到: 更多 (0)

    觉得文章有用就打赏一下文章作者

    支付宝扫一扫打赏

    微信扫一扫打赏