天天看点

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

本节书摘来自异步社区《android 应用案例开发大全(第3版)》一书中的第2章,第2.5节 辅助绘制类,作者 吴亚峰 , 苏亚光 , 于复兴,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.5 辅助绘制类

上一节介绍了实现壁纸的开发,本节将对辅助绘制类的开发进行详细介绍。在绘制百纳水族馆动态壁纸中各个物体之前,必须要做好准备工作,而这些准备工作就包括辅助绘制类的开发。其中包括背景图辅助绘制类background,气泡辅助绘制类bubble,鱼类辅助绘制类ms3dmodel以及模型辅助绘制类loadedobjectvertexnormaltexture,下面就对这些类的开发进行详细的介绍。

2.5.1 背景辅助绘制类——background

本小节将对本案例的背景辅助绘制类进行详细介绍,这个类的作用是绘制百纳水族馆的背景模型,在此逼真的深海背景下,所有的鱼、珍珠贝以及气泡都在此背景前呈现,使整个百纳水族馆更加地活灵活现。

(1)首先来看本类的框架结构,本类中包括对背景图的顶点坐标及纹理坐标的初始化方法,以及对着色器初始化的initshader()方法和drawself()方法。仔细学习本类的结构,有助于读者更快地掌握本类所讲的知识,对读者有很大的帮助。其具体代码如下。

第6~9行是这个类的构造方法,此方法调用初始化顶点坐标与着色数据的initvertexdata()方法和初始化着色器的initshader(mv)方法。

第13~32行是对顶点坐标数据的初始化,用三角形卷绕方式创建一个背景模型,将顶点数据存到float类型的顶点数组中,并创建顶点坐标缓冲,同时对顶点字节进行设置,然后放入顶点坐标缓冲区,设置缓冲区的起始位置。

第33~41行是对创建好的背景模型进行纹理创建,对顶点纹理s、t坐标进行初始化,将顶点纹理坐标数据存入float类型的纹理数组中,并创建纹理坐标缓冲,对纹理坐标进行设置然后送入缓冲区并设置起始位置。

(2)读者对本类的框架掌握后,下面将为读者介绍本类中对着色器初始化的方法initshader()方法以及绘制矩形的drawself()方法。drawself()方法最后为画笔指定顶点位置数据和画笔指定顶点纹理坐标数据,绘制纹理矩形。其具体代码如下。

第1~14行是本类中对着色器的初始化,将着色器脚本内容加载并基于其顶点与片元着色器来创建程序供显卡使用,并从程序中获取顶点位置属性、顶点纹理坐标属性、总变换矩阵属性的id引用来使用。

第15~28行是本类中的drawslef()方法,其作用是绘制矩形,根据数据画出需要的矩形。首先制定某套shader程序,将一些数据传入shader程序,最后为画笔指定顶点位置数据和为画笔指定顶点纹理坐标数据,绘制纹理矩形。

2.5.2 气泡辅助绘制类——bubble

本小节将对案例中的气泡辅助绘制类进行详细的介绍,在该壁纸的场景中,有三处气泡位置在不断地冒出透明的气泡,这些气泡上升的高度不同,并且这些气泡随着高度的不断增加,大小也在不断变大,要绘制这些气泡,首先需要构造气泡模型,其具体代码如下所示。

第6~9行是这个类的构造方法,调用initvertexdata()方法对顶点坐标数据与顶点纹理坐标数据进行初始化,并调用initshader(mv)方法对着色器进行初始化。

第11~25行是对气泡模型的顶点坐标数据的初始化,首先以三角形卷绕的方式组装顶点数据并将数据存放到float类型的数组中,并创建顶点坐标数据缓冲,对顶点数据进行设置并放入缓冲区,设置缓冲区的起始位置。

第26~32行是对气泡模型的顶点纹理坐标s、t进行初始化,其坐标的组装需要与顶点卷绕方式、方向一致,并将顶点纹理坐标数据存入float类型的数组中,创建顶点纹理坐标缓冲,设置顶点纹理坐标,放入缓冲区,并设置缓冲区的起始位置。

说明

因其模型辅助绘制类loadedobjectvertexnormaltexture与背景图辅助绘制类background,气泡辅助绘制类bubble中的代码类似,所以只对以上两个小节的辅助绘制类做详细介绍,其模型辅助绘制类loadedobjectvertexnormaltexture读者可查看随书光盘中的源代码。

2.5.3 鱼类辅助绘制类——ms3dmodel

本小节将对鱼类辅助绘制类ms3dmodel进行详细的介绍,在该壁纸中的鱼不但可以游来游去,而且鱼的本身也是有动作的,含有动画的模型就是骨骼动画。本小节将介绍如何对有骨骼动画的ms3d文件类型进行加载,并存储其动画的相关数据,以及执行模型绘制的ms3dmodel类。

(1)下面将详细介绍的是ms3dmodel类的框架结构,这个类的主要作用是用于存储从ms3d文件中加载的动画相关数据,以及执行模型绘制。读者理解其代码框架,有助于更好地对本案例中鱼类的加载有更加深刻的理解。其代码框架如下。

第4~18行定义了一些本类中需要的一些成员变量,其中最为重要的是第8~17行的成员变量,这些成员变量分别对应于ms3d文件头信息、顶点信息、三角形索引、组信息等重要数据,读者了解后有助于更好地理解本类。

第23~30行为更新关节、顶点数据到动画中指定时刻及绘制模型的animate方法,若需要更新到的动画时刻与当前不同,则首先需要更新关节数据,再更新顶点数据,再执行模型的绘制,否则直接绘制模型。

第31~37行为更新关节数据的updatejoint方法,首先判断新的当前时间是否大于总的动画时间,若大于总的动画时间则将其设置为0,表示一轮动画播放完毕后从头开始。接着对每个关节进行遍历,调用每个关节信息对象的update方法更新每个关节。

第38~50行为省略掉的一些重要的功能方法,将在后面的步骤中详细介绍。

(2)下面介绍的是步骤(1)中省略的ms3dmodel类中用于绘制模型的draw方法,此方法是将加载ms3d文件中的各种数据进行组装送入缓冲区,然后进行绘制的重要功能方法,读者理解其功能,有助于读者更好地理解本类。其具体代码如下。

第2~10行是首先指定某套shader程序,然后将矩阵复制。本案例中因为给鱼类加上了灯光,所以就需要把总变换矩阵、变换矩阵、摄像机位置、灯光位置传入以进行操作。这样就可以在着色器中根据灯光位置、摄像机位置来给鱼类添加灯光特效。

第18~28行是对纹理坐标数据的操作,用一轮遍历来遍历获取当前组信息对象、组内三角形的索引数组及组内三角形的数量。并根据一个标志位来判断是否有材质,来断定是否需要纹理贴图,然后将纹理坐标缓冲送入渲染管线,启用纹理坐标数组。

第29~39行是动态的计算有动画的模型的顶点数据,所以在顶点数据有更新的情况下,根据三角形组装信息(组成三角形的3个顶点的索引)重新填充模型顶点坐标数据缓冲,以便绘制出最新姿态的模型,并将顶点坐标缓冲送入渲染管线。

第41~49行首先将顶点法向量数据送入渲染管线,然后开启顶点坐标数据、顶点法向量数组,并将纹理绑定。因为本案例中鱼类本身有逼真的深水明暗条纹,所以需要将明暗采样纹理传入着色器以进行操作,最后用定点法进行绘制。

(3)接下来介绍的是ms3dmodel类中省略的用于更新顶点数据的updatevectexs方法,以及用于更新指定索引顶点数据updatevectex方法,具体代码如下。

第1~5行为更新顶点数据的updatevectexs方法,其中对每一个顶点进行遍历,调用updatevectex方法更新每一个顶点的数据。

第6~16行为更新指定索引顶点数据的updatevectex方法,其中对有关关节控制的顶点根据关节的实时变换情况计算出定点经关节影响后的位置。

(4)接下来介绍步骤(1)中的用于从指定ms3d模型文件的输入流中加载ms3d模型的load方法。该方法并不复杂,它按照ms3d文件数据组织格式依次加载了各部分的数据。读者理解这部分有助于提高对ms3d文件的认知。其具体代码如下。

第3~4行首先拿到ms3d模型的引用,然后再拿到特殊输入流对象smallendianinputstream的引用,为后面的模型导入做准备。

第6~32行是按照ms3d文件数据组织格式依次加载了各部分的数据,依次加载的数据为文件头、顶点、三角形组装、组、材质、帧速率、当前播放时间,关键帧数量关节信息,进行异常检查,保证加载的正确性,并返回模型。

本节中用于从输入流加载ms3d模型的load方法并不复杂,它按照ms3d文件格式依次加载各部分的数据。各部分数据的具体加载并不是在此方法中实现的,而是在各部分数据对应的类中实现的,读者可查看随书光盘中的源代码。另外,此方法中包含的一个输入流类——smallendianinputstream,并不复杂,读者可查看随书光盘中的源代码。

继续阅读