粒子系統的基本思想是:採用許多形狀簡單的微小粒子作為基本元素,用它們來表示不規則模糊物體。這些粒子都有各自的生命週期,在系統中都要經歷「產生」 、 「運動和生長」及「消亡」三個階段。粒子系統是乙個有「生命」的系統,因此不象傳統方法那樣只能生成瞬時靜態的景物畫面,而是可以產生一系列運動進化的畫面,這使得模擬動態的自然景物成為可能。
這篇文章講解不用gpu加速的乙個粒子系統例項。
利用粒子系統生成畫面的基本步驟:
1、產生新的粒子;
2、賦予每一新粒子一定的屬性;
3、刪去那些已經超過生存期的粒子;
4、根據粒子的動態屬性對粒子進行移動和變換;
5、顯示由有生命的粒子組成的影象。
粒子系統採用隨機過程來控制粒子的產生數量,確定新產生粒子的一些初始隨機屬性,如初始運動方向、初始大小、初始顏色、初始透明度、初始形狀以及生存期等,並在粒子的運動和生長過程中隨機地改變這些屬性。粒子系統的隨機性使模擬不規則模糊物體變得十分簡便。
粒子系統應用的關鍵在於如何描述粒子的運動軌跡,也就是構造粒子的運動函式。函式選擇的恰當與否,決定效果的逼真程度。其次,座標系的選定(即視角)也有一定的關係,視角不同,看到的效果自然不一樣了。
我們需要定義乙個資料結構來描述粒子。這裡定義乙個struct型別,包含一些描述粒子特性的資料成員:
typedef
struct
//structrue for particle
particles;
其資料成員的意義:
active:粒子是否啟用,沒有啟用的粒子將不會顯示在螢幕上;
life:粒子的生命時間,也就是持續顯示的時間。後面會被用在粒子的顏色的a值上。當它為0時,粒子完全透明,也就看不見了。所以其值應該不大於1.0f。
fade;描述life的衰減程度;
r、g、b:粒子的顏色
xi、yi、zi描述粒子的運動方向;
xg、yg、zg:描述粒子運動受到的阻力的方向。
接著我們要定義乙個粒子集合,包含很多個粒子:
#define max_particles 1000對粒子系統進行初始化:particles paticle[max_particles];
for (loop = 0;loop < max_particles;++loop)
colors是預定義的以供使用的顏色陣列:
static glfloat colors[12][3]= // rainbow of colors
,,,,
,,,,
,,,
};
粒子系統的繪製:
我們把每個粒子看成單獨的乙個物件來看待。在這裡用由兩個三角形組成的序列來表示,採用
gl_********_strip
方法繪製。
glbegin(gl_********_strip);
gltexcoord2d(1,1); glvertex3f(x+0.5f,y+0.5f,z); // top right
gltexcoord2d(0,1); glvertex3f(x-0.5f,y+0.5f,z); // top left
gltexcoord2d(1,0); glvertex3f(x+0.5f,y-0.5f,z); // bottom right
gltexcoord2d(0,0); glvertex3f(x-0.5f,y-0.5f,z); // bottom left
glend();
這裡不用繪製四邊形的方法是因為繪製三角形速度要快很多,而且大多數圖形卡本來就是把繪製i四邊形的工作轉化成為三角形實現。但是並不是所以的圖形卡都這麼做,所以我們手動實現。
gl_********_strip
的運作原理可以參考這裡:
gl_********_strip
在本程式中,我們啟用了混合。我們開啟了混合功能,既為頂點繪製指定了顏色值,也使用了紋理貼圖。
我們從硬碟上讀取bmp影象,載入紋理。採用了glaux庫實現。可以參考: glaux
程式完整**:
#pragma comment(lib,"glaux.lib")
#include
#include
#include
using
namespace
std;
#define max_particles 1000
typedef
struct
//structrue for particle
particles;
bool rainbow = true;
bool sp,rp;//space button and return button pressed or not?
float slowdown = 2.0f;
float xspeed,yspeed;
float zoom = -40.0f;
bool gkeys[256];
gluint loop,col,delay,texture[1];
particles paticle[max_particles];
static glfloat colors[12][3]= // rainbow of colors
,,,,
,,,,
,,,
}; aux_rgbimagerec *loadbmp(char *filename) // loads a bitmap image
file=fopen(filename,"r"); // check to see if the file exists
if (file) // does the file exist?
return null; // if load failed return null
} int loadgltextures() // load bitmaps and convert to textures
if (textureimage[0]) // if texture exists
free(textureimage[0]); // free the image structure
} return status; // return the status
} void reshape(int w,int h)
int init()
glshademodel(gl_smooth);
glclearcolor(0.0f,0.0f,0.0f,0.0f);
glcleardepth(1.0f);
gldisable(gl_depth_test);
glenable(gl_blend);
glblendfunc(gl_src_alpha,gl_one);
//really nice perspective calculations
glhint(gl_perspective_correction_hint,gl_nicest);
glhint(gl_point_smooth_hint,gl_nicest);
glenable(gl_texture_2d);
glbindtexture(gl_texture_2d,texture[0]);
for (loop = 0;loop < max_particles;++loop)
return
true;
}void display()}}
glutswapbuffers();
}void keyboard(unsigned
char key,int x,int y)
glutpostredisplay();
break;
case
'l':
slowdown += 0.3;
glutpostredisplay();
break;
case
'h':
slowdown += 0.3;
glutpostredisplay();
break;
default:
break;}}
int main(int argc,char** argv)
{glutinit(&argc,argv);
glutinitdisplaymode(glut_double | glut_rgb | glut_depth);
glutinitwindowsize(400,400);
glutinitwindowposition(100,100);
glutcreatewindow("particle");
init();
glutdisplayfunc(display);
glutidlefunc(display);
glutreshapefunc(reshape);
glutkeyboardfunc(keyboard);
glutmainloop();
return
0;
CCParticleSystem粒子系統
第一次接觸粒子系統,以前遊戲裡面的一些小特效,像製作動畫一樣,是採用一幀一幀的切出來的,由於這種特效,變化無常,切出來的幀,都非常的大,也很耗記憶體,一下就記憶體溢位了.呵呵 主要是以前都沒有接觸過.現在接觸了,以後遊戲就可以用到了.開心 建立乙個ccparticlesystem粒子系統 ccpar...
Unity粒子系統
首次接觸unity的粒子系統,內容太多,搞得都不好寫筆記,所以就記錄下unity的粒子系統做出來的東西以及經常用的一些引數。火焰效果製作 這個相對簡單 建立粒子系統物件 1 調duration 1 開啟loop start size 1 start lifetime 1 start speed 1 ...
Unity粒子系統
rateoverdistance 隨著移動距離產生的粒子數量。只有當粒子系統移動時,才發射粒子。bursts sprite 通過相同尺寸的sprite實現粒子動畫。tiles 網格的行列數。animation startframe 開始的幀是哪一幀。flipu 翻轉u。flipv 翻轉v。enabl...