歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenGL實現的煙花粒子系統

OpenGL實現的煙花粒子系統

日期:2017/3/1 11:09:22   编辑:Linux編程

最近在學習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)。

數據結構:

  1. const int MAX_FIRE = 5; // 最多5個煙花
  2. const int MAX_PARTICLES = 24; // 每個煙花升空散開的小煙花個數
  3. const int MAX_TAIL = 30; // 煙花尾跡數
  4. typedef struct {
  5. float r, g, b; /* color */
  6. float x, y, z; /* position */
  7. float xs, ys, zs; /* speed */
  8. float xg, yg, zg; /* gravity */
  9. boolean up; /* up or down */
  10. } Particle;
  11. typedef struct {
  12. Particle particle[MAX_PARTICLES][MAX_TAIL]; // 煙花系統數組
  13. float life, fade, rad; // 生命,衰減速度,x-z平面上的運動速度
  14. } Fire;
  15. Fire fire[MAX_FIRE];

初始化:

  1. for(int loop = 0; loop < MAX_FIRE; loop++) {
  2. resetFire(loop);
  3. }//for loop end
  4. void resetFire(int loop) {
  5. // init position
  6. float xtemp = rand()%30 - 15.f;
  7. float ytemp = -1*rand()%5 - 15.f;//8.f;
  8. float ztemp = -1*rand()%5 - 15.f;//100.f;
  9. float speed = rand()%5 + 15.f;
  10. fire[loop].life = 1.5f;//1.0f;
  11. fire[loop].fade = (float) ((rand()%100)/20000 + 0.002);
  12. fire[loop].rad = rand()%3 + 4.0f;
  13. for (int loop1 = 0; loop1 < MAX_PARTICLES; loop1++) {
  14. Particle* pat = &fire[loop].particle[loop1][0];
  15. //初始顏色
  16. pat->r = 1.0f; pat->g = 1.0f; pat->b = 1.0f;
  17. //初始位置
  18. pat->x = xtemp; pat->y = ytemp; pat->z = ztemp;
  19. //初始速度
  20. pat->xs = 0.0f; pat->ys = speed; pat->zs = 0.0f;
  21. //初始加速度
  22. pat->xg = 0.0f; pat->yg = -5.f; pat->zg = 0.0f;
  23. pat->up = true;
  24. //尾部初始化
  25. for(int loop2 = 1; loop2 < MAX_TAIL; loop2++) {
  26. pat = &fire[loop].particle[loop1][loop2];
  27. pat->x = fire[loop].particle[loop1][0].x;
  28. pat->y = fire[loop].particle[loop1][0].y;
  29. pat->z = fire[loop].particle[loop1][0].z;
  30. } //for loop2 end
  31. }//for loop1 end
  32. }
Copyright © Linux教程網 All Rights Reserved