OpenGL达成的烟花粒子系统
发布时间:2021-11-24 20:57:31 所属栏目:教程 来源:互联网
导读:最近在学习OpenGL,看到一个网友写的烟花系统非常漂亮,自己也实现一下,作为学习的练习。代码分别在VC和Android上实现。 基本原理: 物理上,粒子首先向上做匀减速直线运动,s = v * t,v = a * t;x、z方向速度是0。到最高点之后,360度均匀炸开成24束小粒
最近在学习OpenGL,看到一个网友写的烟花系统非常漂亮,自己也实现一下,作为学习的练习。代码分别在VC和Android上实现。 基本原理: 物理上,粒子首先向上做匀减速直线运动,s = v * t,v = a * t;x、z方向速度是0。到最高点之后,360度均匀炸开成24束小粒子,x、z方向做匀速直线运动,vx = r * sin(radian),vz = r * cos(radian);y方向做匀加速直线运动。拖尾的实现原理是每个粒子后面跟一串粒子,就像一只鸡妈妈后面领了大小一队鸡娃娃,粒子娃娃的位置依次是粒子妈妈最近N次运动经过的位置(N表示后面跟的粒子娃娃个数),粒子娃娃的大小分别为:size_baby = size_mother * (1 - (float)n/N);类似地,粒子娃娃的透明效果:alpha_baby = alpha_mother * (1 - (float)n/N),很简单,但是实现的尾迹效果不错呢,如果追求更好的效果,可以试试一些递减的非线性函数,比如1 - sin(3.141593f/2*n/N)。 数据结构: const int MAX_FIRE = 5; // 最多5个烟花 const int MAX_PARTICLES = 24; // 每个烟花升空散开的小烟花个数 const int MAX_TAIL = 30; // 烟花尾迹数 typedef struct { float r, g, b; /* color */ float x, y, z; /* position */ float xs, ys, zs; /* speed */ float xg, yg, zg; /* gravity */ boolean up; /* up or down */ } Particle; typedef struct { Particle particle[MAX_PARTICLES][MAX_TAIL]; // 烟花系统数组 float life, fade, rad; // 生命,衰减速度,x-z平面上的运动速度 } Fire; Fire fire[MAX_FIRE]; 初始化: for(int loop = 0; loop < MAX_FIRE; loop++) { resetFire(loop); }//for loop end void resetFire(int loop) { // init position float xtemp = rand()%30 - 15.f; float ytemp = -1*rand()%5 - 15.f;//8.f; float ztemp = -1*rand()%5 - 15.f;//100.f; float speed = rand()%5 + 15.f; fire[loop].life = 1.5f;//1.0f; fire[loop].fade = (float) ((rand()%100)/20000 + 0.002); fire[loop].rad = rand()%3 + 4.0f; for (int loop1 = 0; loop1 < MAX_PARTICLES; loop1++) { Particle* pat = &fire[loop].particle[loop1][0]; //初始颜色 pat->r = 1.0f; pat->g = 1.0f; pat->b = 1.0f; //初始位置 pat->x = xtemp; pat->y = ytemp; pat->z = ztemp; //初始速度 pat->xs = 0.0f; pat->ys = speed; pat->zs = 0.0f; //初始加速度 pat->xg = 0.0f; pat->yg = -5.f; pat->zg = 0.0f; pat->up = true; //尾部初始化 for(int loop2 = 1; loop2 < MAX_TAIL; loop2++) { pat = &fire[loop].particle[loop1][loop2]; pat->x = fire[loop].particle[loop1][0].x; pat->y = fire[loop].particle[loop1][0].y; pat->z = fire[loop].particle[loop1][0].z; } //for loop2 end }//for loop1 end } (编辑:常州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |