粒子系统原理_第1页
粒子系统原理_第2页
粒子系统原理_第3页
粒子系统原理_第4页
粒子系统原理_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、粒子系统原理粒子系统几乎是每个引擎中比不可少的部分,它主要用来解决由大量按一定规则运动(变化)的微小物质组成的大物质,在计算机上的生成与显示的问题。经常使用粒子系统模拟的现象有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。如图8-1,8-2他们都是由粒子系统来完成的。图8-1SimplePhysicsParticlesl中的截图图8-2由粒子系统完成的爆炸等效果通过上面的两幅图我们可以看出,其实粒子系统是一种特效发生器,它可以制造大量的小粒子来达到某种特殊的效果,比如烟雾、火焰或者爆炸。好的粒子效果甚至比渲染好的动画都出色,正因为如此,当前几乎所

2、有的游戏中都使用了粒子系统。为了制造真实的粒子效果,粒子发生器必须在不影响帧率的情况下控制成千上万的粒子运动。简单的粒子系统只允许设置粒子的一些属性,比如生存时间、重力或者颜色;复杂的粒子系统允许为每个粒子的运动函数编写代码。一些粒子系统也包含了光线生成器来创建光线或者轨迹。粒子系统基本原理粒子系统是采用大量的、具有一定生命和属性的微小粒子图元作为基本元素来描述不规则的模糊物体。在粒子系统中,每一个粒子图元均具有:形状、大小、颜色、透明度、运动速度和运动方向、生命周期等属性。而一个粒子究竟有什么样的属性,主要取决于粒子系统用来模拟什么。粒子系统是动态变化的,粒子系统的所有属性都是时间t的函数,

3、随着时间的推移,系统中不断有新粒子的加入,旧的粒子死亡,系统中“存活”的粒子其位置及生命值亦随时间变化而变化。随着虚拟世界时间的流逝,每个粒子都要在虚拟世界经历“产生”、“活动”和“消亡”三个阶段。一般而言,粒子系统的绘制基本可按照以下步骤进行。产生新的粒子加入系统中;赋予每个粒子一定的属性;删除超过生命值上限的粒子;根据粒子属性的动态变化对粒子进行移动和变换;绘制并显示由有生命的粒子组成的图形。其中第、步循环形成了物体的动态变化过程。粒子系统的组成通过前面的学习,我们知道了粒子系统中每一颗粒子他都具有自己的各种属性,因此这每一颗粒子就是一个粒子对象,所以我们的例子系统首先需要一个代表粒子的类

4、Particle。由于我们每一种特效都需要很多粒子来实现,这些粒子的运动方式以及发射的频率都是我们能够控制的,所以我们还需要一个用于控制粒子特效的类ParticleSystem。综上所诉,粒子系统将由粒子(Particle)和发射器(ParticleSystem)组成。粒子(Particle)这里我们的粒子类Particle主要就用于表示粒子特效中的每一颗粒子,他将包括每一颗粒子的各种属性,如代码清单8-1是我们用于表示粒子对象的类Particle的实现。代码清单8-1:Particleviewplaincopytoclipboardprint?/粒子类publicclassParticle3

5、./位置YFSPointpos=YFSPoint.makeZero();5./开始位置6.YFSPointstartPos=YFSPoint.makeZero();7./颜色8.YFSColor4Fcolor=newYFSColor4F();/辅助颜色变化YFSColor4FdeltaColor=newYFSColor4F();/尺寸和辅助尺寸变化floatsize;13.floatdeltaSize;14./自转速度,辅助自转速度viewplaincopytoclipboardprint?viewplaincopytoclipboardprint?15.floatrotation;16.fl

6、oatdeltaRotation;17./生命周期18.floattimeToLive;19./方向20.YFSPointdirection=YFSPoint.makeZero();21./径向加速度,逃离发射原点的速度22.floatradialAccel;23./切线加速度,围绕发射原点旋转速度24.floattangentialAccel;25./弧度.26.floatradian;27.floatradianPerSecond;28./半径.29.floatradius;30.floatdeltaRadius;31.从代码清单8-1我们可以看出,这些成员变量实际上都是每一颗粒子所共同拥

7、有的一些通用的属性,其中我们给每一个变量都加入了注解,这里所要说明的就是,粒子特效都是需要运动的,所以大多数数据需要一个初始值,然后还需要指定一个该值的变化范围,比如上面的radius表示粒子的半径,而deltaRadius则表示该半径可以在一个什么样的范围之内变化。timeToLive则表示该粒子的生命周期,即粒子从激活之后到消亡这段时间,因为我们的每颗粒子都会消亡,这里我们说一下,通常一个粒子消亡之后,我们不会去释放他,而是将其标记为为激活状态,用来作为下一个将要产生的例子(去修改其属性值即可),这样就避免了重复的分配内存空间。当然如果你确实需要释放也是可以的。发射器(ParticleSy

8、stem)上面我们介绍了单独的一刻粒子对象,这里我们来分析一下如何实现一个发射器,来控制每一颗粒子的发射情况,在分析这个发射器之前,我们首先看一下粒子系统一般包括哪几种?粒子系统一般可以按照其特性分为两类:模拟重力效果以半径来进行扩散重力效果相信不用过多的介绍了,就是通过程序来模拟物理重力效果,那么另外一种是以一个中心点,来根据所设定的半径进行扩散的粒子,因此我们首先将这两种不同的粒子通过一个enum分区开来,起定义如代码清单8-2所示。代码清单8-2:Mode1./粒子系统模式2.publicstaticenumModeGRAVITY,/模拟重力RADIUS;以半径来扩散稍后我们会在程序中实

9、现这样两种粒子效果,现在大家可以思考一个问题,在我们的粒子系统中,这些微粒他们应该如何运动呢?实际上运动就是改变这些微粒的坐标位置,那么我们可以按照坐标的位置来将粒子系统分为两种,他们分别是:自由运动,成组运动。每一颗粒子他可以按照自己的属性来自由的运动,当然在某些特殊需求时,我们可以将粒子分成很多组,然后对这每一组的所有粒子采用一种运动方式,那么就是我们所说的成组运动的方式,我们同样也先通过一个enum将其分别定义出来,如代码清单8-3所示。代码青岛那8-3:PositionTypeviewplaincopytoclipboardprint?1./位置类型publicstaticenumPo

10、sitionTypeFREE,自由GROUPED;/组其中FREE代表自由运动,GROUPED代表成组的运动。好的,我们已经对粒子系统,也就是发射器进行了分类,下面我们来分析如何实现这个发射器呢?这里我们将以一个通用的发射器来作为基类进行实现,具体的特殊的特效,我们可以继承自该发射器来完善,首先看一下我们这个发射器他需要包括哪些属性呢?如代码清单8-4所示。代码清单8-4:ParticleSystem成员viewplaincopytoclipboardprint?1./粒子系统基类2.publicclassParticleSystemextendsNodeimplementsNode.IBle

11、ndableTextureOwner3.publicstaticfinalintPARTICLE_DURATION_INFINITY=-1;4.publicstaticfinalintPARTICLE_START_SIZE_EQUAL_TO_END_SIZE5.=-1;publicstaticfinalintPARTICLE_START_RADIUS_EQUAL_TO_END_RADIUS=-1;6./是否要更新7.privatebooleanmUpdating;8./是否激活9.privatebooleanmActive;10./运行时间viewplaincopytoclipboardpri

12、nt?viewplaincopytoclipboardprint?0.51.52.protectedfloatmDuration;/流失的时间privatefloatmElapsed;/所有粒子重心,(变化范围)protectedYFSPointmCenterOfGravity;protectedYFSPointmCenterOfGravityVar;/角度,(

13、变化范围)protectedfloatmAngle;protectedfloatmAngleVar;/开始结束尺寸,(变化范围)protectedfloatmStartSize;protectedfloatmStartSizeVar;protectedfloatmEndSize;protectedfloatmEndSizeVar;/生命,(变化范围)protectedfloatmLife;protectedfloatmLifeVar;/开始结束颜色,(变化范围)protectedYFSColor4FmStartColor;protectedYFSColor4FmStartColorVar;pr

14、otectedYFSColor4FmEndColor;protectedYFSColor4FmEndColorVar;/开始结束自旋角度,(变化范围)protectedfloatmStartSpin;protectedfloatmStartSpinVar;protectedfloatmEndSpin;protectedfloatmEndSpinVar;/所有粒子列表protectedListmParticles;/最大粒子数目protectedintmMaxParticles;/粒子计数protectedintmParticleCount;/粒子排放速率protectedfloatmEmiss

15、ionRate;/粒子排放计数器protectedfloatmEmitCounter;/纹理贴图protectedTexture2DmTexture;/混合方式protectedYFSBlendFuncmBlendFunc;/位置类型,运动方式53.protectedPositionTypemPositionType;54./完成之后是否自动释放55.protectedbooleanmAutoRemoveOnFinish;56./索引57.protectedintmParticleIdx;58./排放模式59.protectedModemEmitterMode;60./重心61.protect

16、edYFSPointmGravity;62./速度,(变化范围)63.protectedfloatmSpeed;64.protectedfloatmSpeedVar;65./切向加速度,(变化范围)66.protectedfloatmTangentialAccel;67.protectedfloatmTangentialAccelVar;68./径向加速度,(变化范围)69.protectedfloatmRadialAccel;70.protectedfloatmRadialAccelVar;71./开始结束的半径,(变化范围)72.protectedfloatmStartRadius;73.

17、protectedfloatmStartRadiusVar;74.protectedfloatmEndRadius;75.protectedfloatmEndRadiusVar;76./旋转角度,(变化范围)77.publicfloatmRotationDegree;78.publicfloatmRotationDegreeVar;79./之前的位置80.privatebooleanmPendingPosition;81./之前的x,y82.privatefloatmPendingX;83.privatefloatmPendingY;84./.85.代码清单8-4中“/.表”示我们省略了不分具

18、体的操作内容,后面再分析,首先我们可以看到该类继承自Node,而同时实现了Node.IBIendableTextureOwner接口,说明我们的粒子系统也是一个节点node,这里就方便我们统一使用引擎来管理场景中的所有节点,及其操作。由于我们的发射器是由很多个小的微粒组成的,所以我们使用了mParticIes来存放这些所有的微粒,其中mAutoRemoveOnFinish就用于判断当一个粒子消亡之后是否需要释放其空间,其他的都是粒子所需要一些基本特性的定义,这里我们就不多说了,整个类的实现也是非常简单,还包括一些set/get函数来对这些属性进行设置,很简单,所以我们就不一一贴出代码了,下面我

19、们看看几个具体的操作,比如:粒子系统的初始化,更新,等,如代码清单8-5所示。代码清单8-5:ParticleSystem实现viewplaincopytoclipboardprint?1.publicParticleSystem(intnumberOfParticles)2./最大粒子数量3.this.mMaxParticles=numberOfParticles;4.5.this.mParticles=newArrayList(this.mMaxParticles);6.7.this.mActive=true;8./设置默认混合方式9.this.mBlendFunc=newYFSBlend

20、Func(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);10./类型默认为自由运动方式11.this.mPositionType=PositionType.FREE;12./重力模式13.this.mEmitterMode=Mode.GRAVITY;14./完成之后不自动释放15.this.mAutoRemoveOnFinish=false;16.this.mCenterOfGravity=YFSPoint.makeZero();this.mGravity=YFSPoint.makeZero();this.mCenterOfGravityVar=

21、YFSPoint.makeZero();this.mStartColor=newYFSColor4F();this.mStartColorVar=newYFSColor4F();this.mEndColor=newYFSColor4F();this.mEndColorVar=newYFSColor4F();24./更新函数回调25.schedule(update);26.27./添加粒子28.privatebooleanaddParticle()29.if(isFull()30.returnfalse;31.32.Particleparticle=newParticle();33./初始化一个

22、粒子initParticle(particle);/添加,计数+1this.mParticles.add(particle);this.mParticleCount+=1;4.75.76.returntrue;/设置,得到时间publicvoidsetDuration(floatduration)this.mDuration=duration;publicfloatgetDura

23、tion()returnthis.mDuration;publicYFSPointgetCenterOfGravity()returnthis.mCenterOfGravity;/设置粒子重心位置publicvoidsetParticlePositionVariance(YFSPointbase,YFSPointvariance)if(base!=null)this.mCenterOfGravity=base;if(variance!=null)this.mCenterOfGravityVar=variance;/初始化粒子privatevoidinitParticle(Particlepar

24、ticle)particle.timeToLive=Math.max(0.0F,this.mLife+this.mLifeVar*Utilities.randMinusOneToOne();particle.pos.x=(this.mCenterOfGravity.x+this.mCenterOfGravityVar.x*Utilities.randMinusOneToOne();particle.pos.y=(this.mCenterOfGravity.y+this.mCenterOfGravityVar.y*Utilities.randMinusOneToOne();YFSColor4Fs

25、tart=newYFSColor4F();start.r=Math.min(1.0F,Math.max(0.0F,this.mStartColor.r+this.mStartColorVar.r*Utilities.randMinusOneToOne();start.g=Math.min(1.0F,Math.max(0.0F,this.mStartColor.g+this.mStartColorVar.g*Utilities.randMinusOneToOne();6

26、.00009.110.ar17.1.0F,Math.max(0.0F,this.mStartColor.b+this.mStartColorVar.b*Utilities.randMinusOneToOne();start.a=Math.min(1.0F,Math.max(0.0F,this.mStartColor.a+this.mStartColorVar.a*Utilities.randMinusOneToOne();YFSColor4Fend=newYF

27、SColor4F();end.r=Math.min(1.0F,Math.max(0.0F,this.mEndColor.r+this.mEndColorVar.r*Utilities.randMinusOneToOne();end.g=Math.min(1.0F,Math.max(0.0F,this.mEndColor.g+this.mEndColorVar.g*Utilities.randMinusOneToOne();end.b=Math.min(1.0F,Math.max(0.0F,this.mEndColor.b+this.mEndColorVar.b*Utilities.randMi

28、nusOneToOne();end.a=Math.min(1.0F,Math.max(0.0F,this.mEndColor.a+this.mEndColorVar.a*Utilities.randMinusOneToOne();particle.color=start;particle.deltaColor.r=(end.r-start.r)/particle.timeToLive);particle.deltaColor.g=(end.g-start.g)/particle.timeToLive);particle.deltaColor.b=(end.b-start.b)/particle

29、.timeToLive);particle.deltaColor.a=(end.a-start.a)/particle.timeToLive);floatstartS=Math.max(0.0F,this.mStartSize+this.mStartSizeV*Utilities.randMinusOneToOne();particle.size=startS;if(this.mEndSize=-1.0F)particle.deltaSize=0.0F;elsefloatendS=this.mEndSize+this.mEndSizeVar24

30、.46.*Utilities.randMinusOneToOne();endS=Math.max(0.0F,endS);particle.deltaSize=(endS-startS)/particle.timeToLive);floatstartA=this.mStartSpin+this.mStartSpinVar*Utilities.randMinusOneToOne();floatendA=this.mEndSpin+

31、this.mEndSpinVar*Utilities.randMinusOneToOne();particle.rotation=startA;particle.deltaRotation=(endA-startA)/particle.timeToLive);if(this.mPositionType=PositionType.FREE)particle.startPos=convertToWorldSpace(0.0F,0.0F);floata=Utilities.d2r(this.mAngle+this.mAngleVar*Utilities.randMinusOneToOne();if(

32、this.mEmitterMode=Mode.GRAVITY)YFSPointv=YFSPoint.makeZero();v.y=(float)Math.sin(a);v.x=(float)Math.cos(a);floats=this.mSpeed+this.mSpeedVar*Utilities.randMinusOneToOne();particle.direction=YFSPoint.mul(v,s);particle.radialAccel=(this.mRadialAccel+this.mRadialAccelVar147.148.149.*Utilities.randMinus

33、OneToOne();particle.tangentialAccel=(this.mTangentialAccel+this.mTangentialAccelVar56.157.*Utilities.randMinusOneToOne();elsefloatsRadius=this.mStartRadius+this.mStartRadiusVar*Utilities.randMinusOneToOne();floateRadius=this.mEndRadius+this.mEndRadiusVar*Utilities.randMinusO

34、neToOne();particle.radius=sRadius;158.159.if(this.mEndRadius=-1.0F)160.particle.deltaRadius=0.0F;161.elseparticle.deltaRadius=(eRadius-sRadius)/particle.timeToLive);particle.radian=a;particle.radianPerSecond=Utilities.d2r(this.mRotationDegree+this.mRotationDegreeVar*Utilities.randMinusOneToOne();169

35、./停止粒子系统170.publicvoidstopSystem()171.this.mActive=false;this.mElapsed=this.mDuration;this.mEmitCounter=0.0F;this.mPendingPosition=false;176./重置粒子系统177.publicvoidresetSystem()this.mActive=true;this.mPendingPosition=false;this.mElapsed=0.0F;for(this.mParticleIdx=0;this.mParticleIdxthis.mParticleCount

36、;this.mParticleIdx+=1)Particlep=(Particle)this.mParticles.get(this.mParticleIdx);p.timeToLive=0.0F;186./更新粒子187.publicvoidupdate(floatdt)this.mUpdating=true;if(this.mPendingPosition)this.mPosition.x=this.mPendingX;this.mPosition.y=this.mPendingY;this.mTransformDirty=(this.mInverseDirty=true);this.mP

37、endingPosition=false;195.196.if(this.mActive)&(this.mEmissionRate!=0.0F)236.236.this.mGravity);236.236.this.mGravity);0002.203.204.while(this.mParticleCountrate)addParticle();this.mEmitCounter-=rate;this.mElapsed+=dt;if(this.mDuration!=-1.0F)&(this.mDur

38、ationthis.mElapsed)stopSystem();this.mParticleIdx=0;211.YFSPointcurrentPosition=YFSPoint.makeZero();if(this.mPositionType=PositionType.FREE)currentPosition=convertToWorldSpace(0.0F,0.0F);while(this.mParticleIdx0.0F)if(this.mEmitterMode=Mode.GRAVITY)YFSPointradial=YFSPoint.makeZero();27.

39、34.235.al),radial=YFSPoint.normalize(p.pos);YFSPointtangential=radial;radial=YFSPoint.mul(radial,p.radialAccel);floatneYFS=tangential.x;tangential.x=(-tangential.y);tangential.y=neYFS;tangential=YFSPoint.mul(tangential,p.tangentialAccel);YFSPointtmp=YFSPoint.add(

40、YFSPoint.add(radial,tangentitmp=YFSPoint.mul(tmp,dt);55.256.257.258.259.260.261.262.263.264.265.266.267.268.269.270.271.272.273.274.275.276.277.p.direction=YFSPoint.add(p.direction,tmp);tmp=YFSPoint.mul(p.direction,dt);p.pos=YF

41、SPoint.add(p.pos,tmp);elsep.radian+=p.radianPerSecond*dt;p.radius+=p.deltaRadius*dt;p.pos.x=(float)(-Math.cos(p.radian)*p.radius);p.pos.y=(float)(-Math.sin(p.radian)*p.radius);p.color.r+=p.deltaColor.r*dt;p.color.g+=p.deltaColor.g*dt;p.color.b+=p.deltaColor.b*dt;p.color.a+=p.deltaColor.a*dt;p.size+=

42、p.deltaSize*dt;p.size=Math.max(0.0F,p.size);p.rotation+=p.deltaRotation*dt;YFSPointnewPos;if(this.mPositionType=PositionType.FREE)YFSPointdiff=YFSPoint.sub(currentPosition,p.startPos);newPos=YFSPoint.sub(p.pos,diff);elsenewPos=p.pos;updateQuadWithParticle(p,newPos);this.mParticleIdx+=1;elseif(this.m

43、ParticleIdx!=this.mParticleCount-1)Particleparticle=(Particle)this.mParticles.remove(this.mParticleCount-1);this.mParticles.remove(this.mParticleIdx);this.mParticles.add(this.mParticleIdx,particle);this.mParticleCount-=1;if(this.mParticleCount=0)&(this.mAutoRemoveOnFinish)278.279.280.281.278.279.280

44、.281.282.283.284.285.286.287.288.unschedule(update);getParent().removeChild(this,true);return;postStep();this.mUpdating=false;289./其中主要包括了构造函数、用来初始化粒子系统,然后提供一个可以向发射器中添加一刻粒子的方法(addParticle),还提供了对每一颗粒子的初始化操作,位于initParticle函数中,当然我们既然初始化了一个粒子系统,那么我们就需要实现一个停止粒子系统的方法(stopSystem)和重置系统方法(resetSystem),这里我们需要

45、解释一下构造函数中使用sceduleupdate一句用来更新该粒子系统,很想我们C+中的回调函数。所以对于粒子系统的更新都会进入update方法进行,另外,在初始化粒子时(initParticle)其中包含了一些数学计算,这部分内容的计算也不叫简单,我们就不多说了,大家也可以查找一下相关的资料即可。当然代码中的“/.同.样.表.示.省.略”了一部分内容。他们分别用于系统的属性设置。到这里我们基本上就完成了一个粒子系统的框架,但是这并不是我们需要的效果,我们并没有实现出粒子效果,那么下面就是我们分析粒子系统实现的部分了。粒子系统实现要实现粒子系统,我们首先需要对粒子系统进行一个简单的划分,它可以

46、简单的氛围两种:点粒子和四边形粒子。点粒子就是说粒子系统中的所有粒子都是由一个点构成的,因此这个点通常就需要不同的颜色来展示,四边形粒子实际上就是将一个粒子纹理给映射到一个四边形上,作为一个粒子对象,当然我们可以看出点粒子的实现肯定比四边形粒子的实现简单很多,下面我们分析分析这两种类型的粒子的实现。点粒子系统(PointParticleSystem)前面我们有说过,所有的具体的粒子的实现,可以根据继承自上一小节所实现的粒子系统基类来完成,这样问题将变得更加简单,点粒子就是一个点,所以我们也只需要顶点坐标,颜色数组即可,具体实现入代码清单8-6所示。代码清单8-6:PointParticleSy

47、stemviewplaincopytoclipboardprint?/点粒子系统publicclassPointParticleSystemextendsParticleSystem236.236.this.mGravity);.3./顶点privateFloatBuffermVertices;/颜色privateFloatBuffermColors;/尺寸private

48、FloatBuffermSizes;publicPointParticleSystem(intnumberOfParticles)super(numberOfParticles);ByteBufferbb=ByteBuffer.allocateDirect(numberOfParticles*2*4);bb.order(ByteOrder.nativeOrder();this.mVertices=bb.asFloatBuffer();bb=ByteBuffer.allocateDirect(numberOfParticles*4*4);bb.order(ByteOrder.nativeOrde

49、r();this.mColors=bb.asFloatBuffer();bb=ByteBuffer.allocateDirect(numberOfParticles*4);bb.order(ByteOrder.nativeOrder();this.mSizes=bb.asFloatBuffer();privatevoidposition(intindex)this.mVertices.position(index*2);this.mColors.position(index*4);this.mSizes.position(index);protectedvoidupdateQuadWithPa

50、rticle(Particleparticle,YFSPointnewPosition)position(this.mParticleIdx);this.mVertices.put(newPosition.x);this.mVertices.put(newPosition.y);this.mColors.put(particle.color.r);this.mColors.put(particle.color.g);this.mColors.put(particle.color.b);this.mColors.put(particle.color.a);this.mSizes.put(part

51、icle.size);position(0);44.45./渲染46.publicvoiddraw(GL10gl)47.if(this.mParticleIdx=0)48.return;49.50.51.GL11gl11=Director.getInstance().gl11;52.53.if(this.mTexture!=null)this.mTexture.loadTexture(gl);gl.glEnable(GL10.GL_TEXTURE_2D);gl.glBindTexture(GL10.GL_TEXTURE_2D,this.mTexture.getName();58.59.gl.g

52、lEnable(GL11.GL_POINT_SPRITE_OES);60.gl11.glTexEnvi(GL11.GL_POINT_SPRITE_OES,GL11.GL_COORD_REPLACE_OES,1);61.62.gl.glVertexPointer(2,GL10.GL_FLOAT,0,this.mVertices);63.gl.glColorPointer(4,GL10.GL_FLOAT,0,this.mColors);64.65.gl.glEnableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);66.gl11.glPointSizePoin

53、terOES(GL10.GL_FLOAT,0,this.mSizes);67.68.booleannewBlend=false;if(this.mBlendFunc.src!=GL10.GL_SRC_ALPHA)|(this.mBlendFunc.dst!=GL10.GL_ONE_MINUS_SRC_ALPHA)newBlend=true;gl.glBlendFunc(this.mBlendFunc.src,this.mBlendFunc.dst);73.74.gl.glDrawArrays(GL10.GL_POINTS,0,this.mParticleIdx);75.if(newBlend)

54、gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);TOC o 1-5 h z79.if(this.mTexture!=null)80.gl.glDisable(GL10.GL_TEXTURE_2D);81.82.gl.glDisableClientState(GL11.GL_POINT_SIZE_ARRAY_OES);gl.glDisable(GL11.GL_POINT_SPRITE_OES);可以看出该类继承自PointParticleSystem并且包含了一个顶点缓冲,一个颜色缓冲,还有一个尺寸大小的缓冲。这里在构造

55、的时候就需要指定由多少个粒子(numberOfParticles),然后就为每一个粒子申请相应的缓冲区,这里面比较核心的内容会是draw函数,它负责该粒子系统的渲染,渲染时要根据需要来设置混合的方式,然后通过丨丨rawrraysPOS来绘制这些点即可Cle具d体的更新也将有updata函数来操作。四边形粒子系统(QuadParticleSystem)相对于点粒子系统,四边形的粒子系统相对复杂了很多,因为他至少一个纹理来进行映射,但是整个框架还是使用了之前的发射器基类(ParticleSystem),所以实现的原理将和点粒子系统一样,首先看一些具体的实现入代码清单8-7所示。代码清单8-7:Qu

56、adParticleSystemviewplaincopytoclipboardprint?/四边形粒子系统publicclassQuadParticleSystemextendsParticleSystemprivateFloatBuffermVertices;privateFloatBuffermColors;/纹理privateFloatBuffermTexCoords;7./索引8.privateShortBuffermIndices;9.publicQuadParticleSystem(intnumberOfParticles)super(numberOfParticles);12.

57、ByteBufferbb=ByteBuffer.allocateDirect(numberOfParticles*2*4*4);bb.order(ByteOrder.nativeOrder();this.mVertices=bb.asFloatBuffer();17.bb=ByteBuffer.allocateDirect(numberOfParticles*4*4*4);bb.order(ByteOrder.nativeOrder();this.mColors=bb.asFloatBuffer();6

58、.1.62.63.bb=ByteBuffer.allocateDirect(numberOfParticles*2*4*4);bb.order(ByteOrder.nativeOrder();this.mTexCoords=bb.asFloatBuffer();bb=ByteBuffer.allocateDirect(numberOfParticles*6*4);bb.order(ByteOrder.nativeOrder();this.mIndic

59、es=bb.asShortBuffer();initIndices();initTexCoordsWithRect(YFSRect.make(0.0F,0.0F,1.0F,1.0F);publicvoidsetTexture(Texture2Dtexture,YFSRectrect)super.setTexture(texture);floatwide=texture.getPixelWidth();floathigh=texture.getPixelHeight();rect.origin.x/=wide;rect.origin.y/=high;rect.size.width/=wide;r

60、ect.size.height/=high;initTexCoordsWithRect(rect);publicvoidsetTexture(Texture2Dtexture)setTexture(texture,YFSRect.make(0.0F,0.0F,texture.getWidth(),texture.getHeight();privatevoidposition(intindex)this.mVertices.position(index*2*4);this.mColors.position(index*4*4);this.mTexCoords.position(index*2*4

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论