本文共 8171 字,大约阅读时间需要 27 分钟。
本节书摘来自异步社区《Android 应用案例开发大全(第二版)》一书中的第2章,第2.5节辅助绘制类,作者 吴亚峰 , 于复兴 , 杜化美,更多章节内容可以访问云栖社区“异步社区”公众号查看
2.5 辅助绘制类
Android 应用案例开发大全(第二版)上一节介绍了壁纸实现的开发,本节将开始对辅助绘制类的开发进行详细介绍。在绘制3D水族馆动态壁纸中的各个物体之前,必须要做好准备工作,而这些准备工作就包括辅助绘制类的开发。辅助绘制类包括背景图辅助绘制类BackGround,气泡辅助绘制类Bubble和模型辅助绘制类LoadedObjectVertexNormalTexture,下面就对这些类的开发进行详细介绍。2.5.1 背景图辅助绘制类——BackGround
本小节将对本案例的背景图辅助绘制类进行详细介绍,这个类的作用是绘制水族馆的馆体,所有的鱼、水草和石头都包含在水族馆的馆体内。具体代码如下所示。1 package com.bn.ld.draw;2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码3 public class BackGround {4 private FloatBuffer mVertexBuffer; // 顶点坐标数据缓冲5 private FloatBuffer mTextureBuffer; // 顶点纹理数据缓冲6 int vCount;7 public BackGround() {8 vCount=12; // 顶点的数量9 float vertices[]=new float[] { // 顶点坐标数据数组10 -23*Constant.SCREEN_SCALEX,20*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,11 -23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,12 23*Constant.SCREEN_SCALEX,20*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,13 -23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,14 23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,15 23*Constant.SCREEN_SCALEX,20*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,16 -23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,17 -23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,30*Constant.SCREEN_SCALEZ,18 23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ,19 -23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,30*Constant.SCREEN_SCALEZ,20 23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,30*Constant.SCREEN_SCALEZ,21 23*Constant.SCREEN_SCALEX,-10*Constant.SCREEN_SCALEY,-30*Constant.SCREEN_SCALEZ, 22 };23 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); // 创建顶点坐标数据缓冲24 vbb.order(ByteOrder.nativeOrder()); // 设置字节顺序25 mVertexBuffer = vbb.asFloatBuffer(); // 转换为int型缓冲26 mVertexBuffer.put(vertices); // 向缓冲区中放入顶点坐标数据27 mVertexBuffer.position(0); // 设置缓冲区起始位置28 float textureCoors[]=new float[]{ // 顶点纹理S、T坐标值数组29 0,0,0,0.85f,1,0,30 0,0.85f,1,0.85f,1,0,31 0,0.9f,0,1,1,0.9f,32 0,1,1,1,1,0.9f33 }; 34 ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4); // 创建顶点纹理数据缓冲35 cbb.order(ByteOrder.nativeOrder()); // 设置字节顺序36 mTextureBuffer = cbb.asFloatBuffer(); // 转换为int型缓冲37 mTextureBuffer.put(textureCoors); // 向缓冲区中放入顶点纹理数据38 mTextureBuffer.position(0); // 设置缓冲区起始位置39 }40 public void drawSelf(GL10 gl,int texld){41 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 允许使用顶点数组42 gl.glVertexPointer( // 为画笔指定顶点坐标数据43 3, // 每个顶点的坐标数量为344 GL10.GL_FLOAT, // 顶点坐标的类型GL_FIXED45 0, // 连续顶点坐标数据之间的间隔46 mVertexBuffer ); // 顶点坐标数据47 gl.glEnable(GL10.GL_TEXTURE_2D); // 开启纹理48 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 允许使用纹理数组49 gl.glTexCoordPointer( // 为画笔指定纹理u、v坐标数据50 2, // 每个顶点两个纹理坐标数据 S、T51 GL10.GL_FLOAT, // 数据类型52 0, // 连续纹理坐标数据之间的间隔53 mTextureBuffer ); // 纹理坐标数据54 gl.glBindTexture(GL10.GL_TEXTURE_2D, texld); // 为画笔绑定指定名称ID纹理55 gl.glDrawArrays( // 绘制图形56 GL10.GL_TRIANGLES, // 以三角形的方式绘制57 0, // 开始点编号58 vCount // 顶点坐标的个数59 );}}
第4~22行为创建顶点坐标缓冲和顶点纹理坐标缓冲,设置背景图片的顶点坐标。
第23~39行为初始化顶点坐标缓冲和顶点纹理数据缓冲并且设置了字节顺序,同时将数据放入了缓冲区,设置缓冲区的起始位置。第40~59行为设置允许使用顶点数组,为画笔指定顶点坐标数据,开启纹理,允许使用纹理数组,为画笔绑定纹理,并且以三角形的方式绘制图形。2.5.2 气泡辅助绘制类——Bubble
本小节将对案例中的气泡辅助绘制类进行详细介绍,在本案例的运行界面中,屏幕前面不断从下方冒出透明的气泡,这些气泡有大有小而且位置各不相同,上升的最大高度也不同,要绘制出这些气泡,就必须对气泡辅助绘制类进行很好地设计,具体代码如下所示。1 package com.bn.ld.draw;2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码3 public class Bubble {4 private FloatBuffer mVertexBuffer; // 顶点坐标数据缓冲5 private FloatBuffer mTextureBuffer; // 顶点纹理数据缓6 int vCount=0; // 顶点数量7 public Bubble() {8 float UNIT_SIZE=1.0f;9 vCount=6; // 顶点的数量 10 float vertices[]=new float[]{ //顶点坐标数据数组11 -0.15f*UNIT_SIZE,0.15f*UNIT_SIZE,0,12 -0.15f*UNIT_SIZE,-0.15f*UNIT_SIZE,0,13 0.15f*UNIT_SIZE,0.15f*UNIT_SIZE,0,14 -0.15f*UNIT_SIZE,-0.15f*UNIT_SIZE,0,15 0.15f*UNIT_SIZE,-0.15f*UNIT_SIZE,0,16 0.15f*UNIT_SIZE,0.15f*UNIT_SIZE,0,17 };18 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); // 创建顶点坐标数据缓冲19 vbb.order(ByteOrder.nativeOrder()); // 设置字节顺序20 mVertexBuffer = vbb.asFloatBuffer(); // 转换为int型缓冲21 mVertexBuffer.put(vertices); // 向缓冲区中放入顶点坐标数据22 mVertexBuffer.position(0); // 设置缓冲区起始位置23 float textureCoors[]=new float[]{ // 顶点纹理S、T坐标值数组24 0,0,0,1,1,0,25 0,1,1,1,1,026 }; 27 ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4); // 创建顶点纹理数据缓冲28 cbb.order(ByteOrder.nativeOrder()); // 设置字节顺序29 mTextureBuffer = cbb.asFloatBuffer(); // 转换为int型缓冲30 mTextureBuffer.put(textureCoors); // 向缓冲区中放入顶点着色数据31 mTextureBuffer.position(0); // 设置缓冲区起始位置32 }33 public void drawSelf(GL10 gl,int texld){34 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 允许使用顶点数组35 gl.glVertexPointer ( // 为画笔指定顶点坐标数据36 3, // 每个顶点的坐标数量为3 37 GL10.GL_FLOAT, // 顶点坐标值的类型为GL_FIXED38 0, // 连续顶点坐标数据之间的间隔39 mVertexBuffer // 顶点坐标数据40 );41 gl.glEnable(GL10.GL_TEXTURE_2D); // 开启纹理42 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 允许使用纹理数组43 gl.glTexCoordPointer ( // 为画笔指定纹理u、v坐标数据44 2, // 每个顶点两个纹理坐标数据 S、T45 GL10.GL_FLOAT, // 数据类型46 0, // 连续纹理坐标数据之间的间隔47 mTextureBuffer ); // 纹理坐标数据48 gl.glBindTexture(GL10.GL_TEXTURE_2D, texld); // 为画笔绑定指定名称ID纹理49 gl.glDrawArrays ( // 绘制图形50 GL10.GL_TRIANGLES, // 三角形方式填充51 0, // 开始点编号52 vCount // 顶点坐标的个数53 ); }}
第4~17行定义了顶点坐标缓冲和顶点纹理坐标缓冲,设置气泡的顶点坐标。
第18~32行为初始化顶点坐标缓冲和顶点纹理数据缓冲并且设置了字节顺序,同时将数据放入缓冲区,设置缓冲区的起始位置为0。第33~53行为设置允许使用顶点数组,为画笔指定顶点坐标数据、开启纹理、允许使用纹理数组、为画笔绑定纹理,并且以三角形的方式进行绘制。2.5.3 3D模型辅助绘制类——LoadedObjectVertexNormalTexture
因为水族馆中必不可少的是鱼,所以要向壁纸中加入鱼元素。本案例中的鱼为3D模型,下面就对加载3D模型并进行3D模型相关处理的辅助绘制类进行详细介绍,具体代码如下所示。1 package com.bn.ld.draw;2 ……//此处省略部分类和包的引入代码,读者可自行查阅光盘中的源代码3 public class LoadedObjectVertexNormalTexture{4 private FloatBuffer mVertexBuffer; // 顶点坐标数据缓冲5 private FloatBuffer mTexBuffer; // 顶点纹理数据缓冲6 int vCount=0; // 顶点数量7 public LoadedObjectVertexNormalTexture(float[] vertices,float[] normals,float texCoors[]) {8 vCount=vertices.length/3; // 计算顶点个数9 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); // 创建顶点坐标数据缓冲10 vbb.order(ByteOrder.nativeOrder()); // 设置字节顺序11 mVertexBuffer = vbb.asFloatBuffer(); // 转换为float型缓冲12 mVertexBuffer.put(vertices); // 向缓冲区中放入顶点坐标数据13 mVertexBuffer.position(0); // 设置缓冲区起始位置14 ByteBuffer vbt = ByteBuffer.allocateDirect(texCoors.length*4); // 创建纹理坐标数据缓冲15 vbt.order(ByteOrder.nativeOrder()); // 设置字节顺序16 mTexBuffer = vbt.asFloatBuffer(); // 转换为float型缓冲17 mTexBuffer.put(texCoors); // 向缓冲区中放入顶点坐标数据18 mTexBuffer.position(0); // 设置缓冲区起始位置19 }20 public void drawSelf(GL10 gl,int texId) { 21 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 启用顶点坐标数组 22 gl.glEnable(GL10.GL_TEXTURE_2D); // 开启纹理 23 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 允许使用纹理S、T坐标缓冲24 gl.glVertexPointer( // 为画笔指定顶点坐标数据25 3, // 每个顶点的坐标数量为326 GL10.GL_FLOAT, // 顶点坐标值的类型为 GL_FIXED27 0, // 连续顶点坐标数据之间的间隔28 mVertexBuffer); // 顶点坐标数据29 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTexBuffer); // 为画笔指定纹理S、T坐标缓冲30 gl.glBindTexture(GL10.GL_TEXTURE_2D, texId); // 绑定当前纹理31 gl.glDrawArrays ( // 绘制图形32 GL10.GL_TRIANGLES, // 以三角形方式填充33 0, // 开始点编号34 vCount ); // 顶点的数量35 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // 禁用顶点坐标数组36 gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 禁用纹理S、T坐标缓冲37 gl.glDisable(GL10.GL_TEXTURE_2D); // 禁用纹理38 }}
第4~19行创建了顶点坐标缓冲和顶点纹理坐标缓冲,并且初始化顶点坐标缓冲和顶点纹理数据缓冲、设置了字节顺序、将数据放入了缓冲区,设置缓冲区起始位置为0。
第20~38行允许使用顶点数组、为画笔指定顶点坐标数据、开启纹理、允许使用纹理数组、为画笔绑定纹理,并以三角形的方式填充。转载地址:http://ggmdl.baihongyu.com/