《Android 应用案例开发大全(第二版)》——2.5节辅助绘制类

    xiaoxiao2024-08-21  100

    本节书摘来自异步社区《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.9f 33 }; 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, // 每个顶点的坐标数量为3 44 GL10.GL_FLOAT, // 顶点坐标的类型GL_FIXED 45 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、T 51 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,0 26 }; 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_FIXED 38 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、T 45 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, // 每个顶点的坐标数量为3 26 GL10.GL_FLOAT, // 顶点坐标值的类型为 GL_FIXED 27 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行允许使用顶点数组、为画笔指定顶点坐标数据、开启纹理、允许使用纹理数组、为画笔绑定纹理,并以三角形的方式填充。

    相关资源:敏捷开发V1.0.pptx
    最新回复(0)