OpenGL粒子系統詳解及程式設計實現

2021-07-17 04:15:21 字數 4645 閱讀 2843

粒子系統的基本思想是:採用許多形狀簡單的微小粒子作為基本元素,用它們來表示不規則模糊物體。這些粒子都有各自的生命週期,在系統中都要經歷「產生」 、 「運動和生長」及「消亡」三個階段。粒子系統是乙個有「生命」的系統,因此不象傳統方法那樣只能生成瞬時靜態的景物畫面,而是可以產生一系列運動進化的畫面,這使得模擬動態的自然景物成為可能。

這篇文章講解不用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...