加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

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   
}  

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读