2.3 壁纸的基本框架
对百纳水族馆案例中每个类进行详细介绍之前,首先对本案例的基本框架进行简单的介绍。本节将要介绍的是本案例的基本框架、案例中各个类的作用以及类与类之间的关系,从而使读者对百纳水族馆有一个全面的了解,可以更好地理解本案例的详细开发过程。
2.3.1 壁纸项目的框架结构
下面将对百纳水族馆动态壁纸的整体框架进行简单介绍,使读者结合壁纸项目的框架结构图对本案例的开发过程有一个全面清晰的认识,对动态壁纸的制作流程有一个初步了解。本项目主要包含5大类,其框架如图2-17所示。
说明
图2-17是本案例的框架图,从中可以看出,本项目主要包含壁纸实现类、绘制类、线程类、工具常量类以及辅助绘制类等。这里简单了解一下即可,后面将进一步进行较为详细的介绍。
2.3.2 各个类的简要介绍
前面介绍了5大类的基本框架,为了使读者更为详细地了解各个类的作用以及各个类之间的联系,下面将对本项目中的所有类一一进行简要介绍,使读者对3D动态壁纸——百纳水族馆的制作流程有一个深刻的认识,具体内容如下。
1.壁纸实现类
壁纸服务类OpenGLES2WallpaperService。
GLWallpaperService类是动态壁纸类的基础类,此类为壁纸项目的开发提供了服务接口,OpenGLES2WallpaperService是百纳水族馆的基础类,通过继承GLWallpaperService类,重写onCreateEngine方法等来实现壁纸功能。
自定义场景渲染器类MySurfaceView。
MySurfaceView是百纳水族馆的核心类,在本类中首先设置使用OPENGL ES2.0渲染技术,然后创建了本案例中需要绘制的所有对象,设置各个对象的绘制方式,加载各类物体模型及所需纹理,设置摄像机位置,使用投影矩阵,初始化光源位置等。
2.绘制类
群鱼控制类FishControl。
FishControl类是群鱼控制类(群鱼是指不包括鱼群的所有单条鱼、乌龟的集合)。在该类中定义了群鱼列表,列表中存放着所有的单条鱼对象和乌龟对象,创建并启动鱼的移动线程,最后遍历群鱼列表对单条鱼、乌龟进行绘制。
单条鱼类SingleFish。
SingleFish类绘制单条鱼类(包括乌龟)。在此类中定义了单条鱼的所有属性,包括鱼的位置、速度、外力、鱼食对鱼的吸引力、鱼的质量(力的缩放比)、鱼的旋转角度等。该类中的fishMove方法计算了鱼的旋转角度、鱼所受的外力和鱼食对鱼的吸引力。
鱼群控制类FishSchoolControl。
FishSchoolControl类是鱼群的控制类。在此类中定义了鱼群中的每条鱼,这些鱼组成了可以一起游动的鱼群,鱼群中的第一条鱼不受到其他任何鱼的外力,只受到墙壁的作用力;然后创建并启动鱼群的游动线程,遍历鱼群列表实现对鱼群的绘制。
单个鱼群类SingleFishSchool。
SingleFishSchool类是绘制鱼群里单条鱼的类。此类中定义了鱼群中每条鱼的所有相关属性,具体包括鱼的位置、速度、外力、鱼偏离相对位置(以鱼群中第一条鱼所在位置为球心,以定长半径确定球面上的一个点)后受到的向心力、鱼的质量、鱼的旋转角度等。
喂食类FeedFish。
FeedFish类是食物的控制类。此类中startFeed方法的作用是由摄像机与触控点确定一条与场景地面高度交叉的拾取射线并计算出交点的坐标,如果是第一次调用此方法,此方法还会调用SingleFood的startFeed方法来启动SingleFood中创建的两个线程。
鱼食类SingleFood。
SingleFood类是绘制鱼食的类。该类的作用是创建并启动线程,绘制鱼食。在此类中定义了食物的移动线程,计算鱼食对鱼的吸引力线程,给出了食物的Y坐标,并创建了启动以上两个线程的startFeed方法,最后再进行鱼食的绘制。
气泡控制类BubbleControl。
BubbleControl类是本案例中所有气泡的控制类。在本类中首先根据气泡的数量创建气泡对象并将气泡对象添加到气泡列表中,然后创建并启动气泡移动线程,根据气泡的位置对气泡进行排序,最后遍历气泡列表并且绘制气泡。
单个气泡类SingleBubble。
SingleBubble类用于绘制场景中的单个气泡类,在本类中定义了气泡的所有属性,如气泡的位置、纹理ID、最大高度等。每调用一次此类中的bubbleMove方法,气泡就会移动一小段距离,如果气泡的Y坐标位置大于气泡高度的最大值,就会调用newPosition方法重新设置气泡的位置和气泡的最大高度。
3.线程类
群鱼游动线程类FishGoThread。
FishGoThread类是群鱼游动的线程类。在此类中遍历群鱼列表判断两条鱼之间的距离,若距离小于阈值,则两条鱼之间产生力的作用。对鱼进行碰撞检测,当鱼与墙壁的距离小于阈值时鱼会受到与墙壁垂直的力,然后修改鱼所受到的外力、鱼的速度和位置。
鱼群游动线程类FishschoolThread。
FishschoolThread类是鱼群游动的线程类。在此类中遍历鱼群列表并判断鱼群中的鱼(不包括第一条鱼)与相对位置的距离,若距离大于阈值就会对该鱼产生向心力;然后对鱼群进行碰撞检测,碰壁时鱼群受到一个与墙壁垂直的力;最后修改鱼所受到的外力、鱼群的速度和位置。
鱼食对鱼产生吸引力的线程类AttractThread。
AttractThread类是鱼食对鱼产生吸引力的线程类。在此类中不断遍历群鱼列表判断鱼是否能看到鱼食,如果鱼能看到鱼食,则该鱼受到鱼食的吸引力作用使鱼向鱼食游动,当鱼与鱼食之间的距离小于阈值后鱼食消失,认定鱼食已经被吃掉。本案例中鱼食对鱼群中的鱼不产生吸引力作用。
鱼食移动线程类FoodThread。
FoodThread类是鱼食移动的线程类。在此类中只要喂食线程中的标志位没有被置成false就会不断地修改鱼食的X方向和Z方向的位置使鱼食产生晃动的效果,然后不断地修改鱼食的Y位置。
气泡移动线程类BubbleThread。
BubbleThread类是气泡的移动线程。在此类中首先遍历气泡列表,将气泡分为3份(因为在本案例中有3处气泡,读者可根据自身需要进行更改),进行标志用来判断气泡向左还是向右上升;然后调用气泡对象中的bubbleMove方法,从而实现气泡的移动。
4.工具常量类
常量类Constant。
Constant类是整个壁纸中用到的所有静态常量的集合。其中包括屏幕的长宽比、摄像机的位置、背景图的缩放比、地面高度等一系列静态常量。将这些常用的静态常量定义到常量类Constant中,会降低程序的维护成本,同时会增强程序的可读性。
向量类Vector。
Vector类是本案例中用到的三维向量的类。包含了案例中所有需要的向量算法,具体包括求向量的模、向量的减法、向量的加法、向量的归一化等。此外还有获取力的大小,求指定半径的向量,获取从一个向量指向另一个向量的向量等方法。
屏幕拾取类IntersectantUtil。
IntersectantUtil类是和屏幕拾取相关的工具类(主要是在对鱼进行喂食的时候会用到该类中包含的相关算法),通过拾取计算获得触控点在摄像机坐标系中的坐标,再乘以摄像机矩阵的逆矩阵即可得到该点在世界坐标系中的坐标。
着色器加载类ShaderUtil。
ShaderUtil类是着色器加载的工具类。该类的作用是将着色器(shader)的脚本加载进显卡并且编译,其中loadFromAssetsFile方法用来从着色器sh脚本中加载着色器的内容,checkGIError方法用来检查每一步操作是否有错误,createProgram方法用来创建着色器程序,loadShader方法用来加载着色器编码进GPU并且进行编译。
存储矩阵状态类MatrixState。
MatrixState类是用于封装Matrix类各项功能的类。MatrixState是一个非常重要的类,其中包括摄像机矩阵、投影矩阵、当前物体总变换矩阵等。它还包括获取当前矩阵逆矩阵的方法,获取摄像机矩阵,获取保护矩阵以及恢复矩阵的方法。
5.辅助绘制类
背景图辅助绘制类Background。
Background类是百纳水族馆背景及地板的辅助绘制类。其中地板是虚拟的,在程序中只是给出了地面高度用来喂鱼。该类中给出了背景图的顶点坐标以及纹理坐标,并形成顶点缓冲和纹理缓冲送进渲染管线,用来绘制背景图。
气泡辅助绘制类Bubble。
Bubble类是百纳水族馆中气泡的辅助绘制类。该类主要是构造一个纹理矩形并贴上气泡纹理,开启混合之后,用户就可以看到气泡了。此类中给出了纹理矩形的顶点坐标以及纹理坐标,并形成顶点缓冲和纹理缓冲送进渲染管线,从而用于气泡的绘制。
模型辅助绘制类LoadedObjectVertexNormalTexture。
LoadedObjectVertexNormalTexture类是百纳水族馆中鱼食的辅助绘制类。该类的主要作用是对加载的obj模型信息进行处理,形成顶点缓冲、纹理缓冲以及法向量缓冲,并将相关的缓冲送入渲染管线,用于对于鱼食的绘制。
模型辅助绘制类MS3DModel。
MS3DModel类是百纳水族馆中鱼类、乌龟以及珍珠贝的辅助绘制类。该类的主要作用是加载ms3d骨骼动画模型并对加载完的模型信息进行处理,形成顶点缓冲、纹理缓冲、法向量缓冲等,并将相关缓冲送入渲染管线,用于百纳水族馆中鱼类、乌龟以及珍珠贝的绘制。