計算機圖形學opengl教程第19課粒子系統(tǒng)_第1頁
計算機圖形學opengl教程第19課粒子系統(tǒng)_第2頁
計算機圖形學opengl教程第19課粒子系統(tǒng)_第3頁
計算機圖形學opengl教程第19課粒子系統(tǒng)_第4頁
計算機圖形學opengl教程第19課粒子系統(tǒng)_第5頁
已閱讀5頁,還剩8頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第 19 20 課源碼第 19 課 粒子系統(tǒng):你是否希望創(chuàng)建噴射的效果。,噴泉,流星之類的效果。這一課將告訴你如何創(chuàng)建一個簡單的例子系統(tǒng),并用它來創(chuàng)建一種歡迎來到第十九課.你已經學習了很多知識,并且現在想自己來實踐.我將在這講解一個新命令. 三角形帶(我的理解就是畫很多三角形來組要的形狀),它非常容易使用,當畫很多三角形的時候能加快你程序的運行速度.在本課中,我將會教你該如何做一個半復雜的微粒程序.一旦您了解微粒程序的原理后,在創(chuàng)建例如:火,煙,噴泉等效果將是很輕松的事情.我必須警告你!直到今天我從未寫一個真正的粒子程序.寫一個出名的復雜的粒子程序.我嘗試過,但在我了解我不能控制所有點變瘋狂之

2、后我放棄了!你也許不相信我要告訴你的,但這個課程從頭到尾都是的想法.開始我沒有一點想法,并且沒有任何技術數據放在面前.我開始考慮粒子,突然腦袋裝滿想法(腦袋開啟了?):給予每個粒子生命,任意變化顏色,速度,重力影響等等.來適應環(huán)境的變化,把每個粒子看成單一的從這個點運動到另一個點的顆粒.很快我完成了這個項目.我看看時鐘然后有個想法突然出現.四個小時過去了!我偶爾記得已經停止喝咖啡,眨眼,但是 4 個小時.?盡管這個程序我覺得很棒,并象的運行,但它不可能是最好的粒子引擎,這個我不關心,只要他運行好就可以.并且我能把它運行在象的那么嚴密項目中.如果你是那種想了解透徹的人,那么你要花費很多時間在網絡

3、上查找資料并弄明白它.在程序中有很多小的代碼會看起來很模糊:)本課(使它更容易了解).所用的部分代碼來自于Lesson1.但有很多新的代碼,因此我將重寫一些發(fā)生代碼變化的部分下面用到的代碼來自于Lesson6,我將會增加5 行新的代碼在程序的前面.第一行stdio.h允許讀文件中的數據.它和以前用在紋理當中是一樣的.第二行定義了一些要在屏幕上顯示的粒子的數目.告訴程序 MAX_PARTICLES 在這里的數值為 1000.第三條行將不斷分離的彩色的粒子栓牢在一起,并設置為默認情況.sp 和 rp 用來確定空格鍵和返回鍵是否有按住.#define MAX_PARTICLES 1000/ 定義最大

4、的粒子數bool boolboolrainbow=true;/ 是否為彩虹模式空格鍵是否被按下回車鍵是否被按下sp;rp;/下面四行是復雜的變量.變量 slowdown 控制粒子移動的快慢.數值愈高,移動越慢.數值越底,移動越快.如果數值降低,粒子將快速的移動!粒子的速度影響它們在熒屏中移動的距離.記住速度慢的粒子不會射很遠的.變量xspeed和 yspeed 控制尾部的方向.xspeed 將會增加粒子在x 軸上速度.如果 xspeed 是正值粒子將會向右邊移動多.如果 xspeed 負價值,粒子將會向左邊移動多.那個值越高,就向那個方向移動比較多.yspeed 工作相同的方法,但是在y 軸上

5、.因為有其它的影響粒子的運動,所以我多.xspeed 和 yspeed 有助于在想要的方向上移動粒子.最的圖象,而且當接近你時很后是變量 zoom,酷用該變量移入或移出的屏幕.在粒子引擎里,有時可看見float float floatfloatslowdown=2.0f; xspeed; yspeed;zoom=-40.0f;/粒子/X 方向的速度/ Y 方向的速度/ 沿Z 軸縮放定義了一個復雜的循環(huán)變量叫做Loop.用這變量預先定義粒子并在屏幕中畫粒子.col 用來給予粒子不同的顏色.delay 用來控制在彩虹模式中圓的顏色變化.最后,設定一個空間(粒子紋理).我用紋理而不用點的重要原因是,

6、點的速度慢,而且挺麻煩的.其次紋理很酷:)你用一個正方形的粒子,一張你臉的小片等等.很好控制!,一張星星的圖GLu GLuGLuloop; col;delay;/ 循環(huán)變量/ 當前的顏色/ 彩虹效果延遲好!現在是有趣的東西.下描述單一粒子結構,這是給予粒子的屬性.用型變量 active 開始,如果為 true,的粒子為活躍的.如果為 false 則粒子為死的,此時就刪除它.在程序中我沒有使用活躍的,因為它很好的實現.變量 life 和fade 來控制粒子顯示多久以及顯示時候的亮度.隨著 life 數值的降低fade 的數值也相應降低.這將導致一些粒子比其他粒子燃燒的時間長.typedef st

7、ructbool active;/ 創(chuàng)建粒子數據結構/ 是否激活/ 粒子生命floife;float fade;/ 衰度變量 r,g 和b 用來表示粒子的紅色強度,綠色強度和藍色強度.當r 的值變成 1.0f 時粒子將會很紅,當三個變量全為 1.0f 時則粒子將變成白色.floatfloat floatr;g;b;/紅色值綠色值藍色值變量x.y 和z 控制粒子在屏幕上顯示的位置.x 表示粒子在x 軸上的位置.y 表示y 軸上的位置.z 表示粒子z 軸上的位置float floatfloatx;y;z;/X YZ位置位置位置下面三個變量很重要.這三個變量控制粒子在每個軸上移動的快慢和方向.如果

8、xi 是負價粒子將會向左移動,正值將會向右移動.如果 yi 是負值粒子將會向下移動,正值將向上.最后,如果 zi 負值粒子將會向熒屏移向觀察者.移動,正植將float floatfloatxi;yi;zi;/X YZ方向方向方向最后,另外 3 個變量!每一個變量可被看成加速度.如果 xg 正值時,粒子將會被拉倒右邊,負值將拉向左邊.所以如果粒子向左移動(負的)而上.zg 拉進或拉出屏幕.給它一個正的加速度,粒子速度將變慢.最后將向反方向移動(高中物理).yg 拉下或拉float floatfloatxg;yg;zg;/X YZ方向重力加速度方向重力加速度方向重力加速度結構的名字為particl

9、es.particles;/ 粒子數據結構下面粒子,創(chuàng)建一個數組叫 particle.數組空間為每個粒子提供相應的信息MAX_PARTICLES 個元素.也就是說創(chuàng)建 1000(MAX_PARTICLES)個particles particleMAX_PARTICLES;/ 保存 1000 個粒子的數組在顏色數組上減少一些代碼來12 中不同的顏色.對每一個顏色從 0 到 11亮紅,亮綠,和亮藍.下面的顏色表里包含 12 個漸變顏色從紅色到紫羅蘭色sic GLfloat colors123=/ 彩虹顏色1.0f,0.5f,0.5f,1.0f,0.75f,0.5f,1.0f,1.0f,0.5f,0

10、.75f,1.0f,0.5f,0.5f,1.0f,0.5f,0.5f,1.0f,0.75f,0.5f,1.0f,1.0f,0.5f,0.75f,1.0f,0.5f,0.5f,1.0f,0.75f,0.5f,1.0f,1.0f,0.5f,1.0f,1.0f,0.5f,0.75f;這段代碼調用前面的代碼載入位圖,與前面的代碼相同,只是位圖的名稱不同。載入一符名為Partic位圖mp 的if (TextureImage0=LoadBMP(Data/Particmp) / 載入粒子紋理窗口改變大小的代碼和前面一樣,不需要改變使用光滑的陰影,清除背景為黑色,關閉深度測試,綁定并的改變就是禁用深度測試和初

11、始化粒子紋理.啟用位圖后選擇粒子紋理。唯一glDisable(GL_DEPTH_TEST);/深度測試下面代碼初始化每個粒子.從活躍的粒子開始.如果粒子不活躍,它在熒屏上將不出現,無論它有多少life.當使粒子活躍之後,給它 life.我懷疑給粒子生命和顏色漸變的是否是最好的方法,但當它運行一次后,效果很好!life 滿值是 1.0f.這也給粒子完整的光亮.for (loop=0;loopMAX_PARTICLES;loop+)/初始化所有的粒子particleloop.active=true;particleloop.life=1.0f;/ 使所有的粒子為激活狀態(tài)/ 所有的粒子生命值為最大通

12、過給定的值來設定粒子退色快慢.每次粒子被拉的時候 life 隨著 fade 而減小.結束的數值將是 099 中的任意一個,然后平分 1000 份來得到一個很小的浮點數.最后把結果加上 0.003f 來使 fade 速度值不為 0particleloop.fade=float(rand()%100)/1000.0f+0.003f;/ 隨機生成衰率既然粒子是活躍的,而且又給它生命,下面將給它顏色數值.一開始,就想每個粒子有不同的顏色.我怎么做才能使每個粒子與前面顏色箱里的顏色一一對應那?數學很簡單,用 loop 變量乘以箱子中顏色的數目與粒子最大值(MAX_PARTICLES)的余數.這樣防止最后

13、的顏色數值大于最大的顏色數值(12).舉例:900*(12/900)=12.1000*(12/1000)=12,等等particleloop.r=colorsloop*(12/MAX_PARTICLES)0; particleloop.g=colorsloop*(12/MAX_PARTICLES)1;particleloop.b=colorsloop*(12/MAX_PARTICLES)2;/粒子的紅色顏色粒子的綠色顏色粒子的藍色顏色現在設定每個粒子移動的方向和速度.通過將結果乘于 10.0f 來創(chuàng)造開始時的效果.會以任意一個正或負值結束.這個數值將以任意速度,任意方向移動粒子.particl

14、eloop.xi=float(rand()%50)-26.0f)*10.0f;particleloop.yi=float(rand()%50)-25.0f)*10.0f; particleloop.zi=float(rand()%50)-25.0f)*10.0f;/隨機生成X 軸方向速度隨機生成Y 軸方向速度隨機生成Z 軸方向速度最后,設定加速度的數值.不像一般的加速度僅僅把事物拉下,的加速度能拉出,拉下,拉左,拉右,拉前和xg 設為 0.0f.在 x 方向沒有拉力.設 yg拉后粒子.開始需要強大的向下加速度.為了達到這樣的效果為-0.8f 來產生一個向下的拉力.如果值為正則拉向上.不希望粒子

15、拉近或遠離,所以將 zg 設為 0.0fparticleloop.xg=0.0f;particleloop.yg=-0.8f; particleloop.zg=0.0f;/ 設置 X 軸方向加速度為 0/設置Y 軸方向加速度為-0.8設置Z 軸方向加速度為 0現在為有趣的部分.下面的部分是從哪里拉粒子,檢查加速度等等.你要明白它是怎么實現的,因此仔細的看:)重置Mview 巨陣.在畫粒子位置的時候用 glVertex3f()命令來代替 tranlations,這樣在view 巨陣畫粒子的時候不會改變mDrawGLScene(GLvoid)/ 繪制粒子glClear(GL_COLOR_BUFFE

16、R_BITglLoadIdentity();| GL_DEPTH_BUFFER_BIT);/ 重置模型變換矩陣/ 以黑色背景清楚開始創(chuàng)建一個循環(huán)loop.這個環(huán)將會更新每一個粒子.for (loop=0;loopMAX_PARTICLES;loop+)/ 循環(huán)所有的粒子首先做的事物是檢查粒子是否活躍.如果不活躍,則不被更新.在這個程序中,它們始終活躍.但是在你自己的程序中,你可能想要使某粒子不活躍if (particleloop.active)/ 如果粒子為激活的下面三個變量是確定 x,y 和z 位置的暫時變量.注意:在 z 的位置上加上 zoom 以便的場景在以前的基礎上再移入zoom 個位

17、置.particleloop.x 告訴要畫的x 的位置.particleloop.y 告訴要畫的y 的位置.particleloop.z 告訴要畫的z 的位置float floatfloatx=particleloop.x; y=particleloop.y;z=particleloop.z+zoom;/ 返回X 軸的位置/ 返回Y 軸的位置/ 返回 Z 軸的位置既然知道粒子位置,就能給粒子上色.particleloop.r 保存粒子的亮紅,particleloop.g 保存粒子的亮綠,particleloop.b 保存粒子的亮藍.注意我用 alpha 為粒子生命.當粒子要燃盡時,它會越來越透

18、明直到它最后.這就是為什么粒子的生命不應該超過 1.0f.如果你想粒子燃燒時間長,可降低 fade 減小的速度/ 設置粒子顏色glColor4f(particleloop.r,particleloop.g,particleloop.b,particleloop.life);有粒子的位置,并設置顏色了.所以現在來畫的粒子.用一個三角形帶來代替一個四邊形這樣使程序運行快一點.很多 3D card 畫三角形帶比畫四邊形要快的多.有些 3D card 將四邊形分成兩個三角形,而有些不.所以按照自己的想法來,所以來畫一個生動的三角形帶glBegin(GL_TRIANGLE_STRIP);/ 繪制三角形帶

19、從紅寶書引述:三角形帶就是畫一連續(xù)的三角形(三個邊的多角形)使用vertiV0,V1,V2,然后 V2,V1,V3(注意順序),然后 V2,V3,V4 等等.畫三角形的順序一樣才能保證三角形帶為相同的表面.要求方向是很重要的,例如:剔除,最少用三點來畫當第一個三角形使用 verti0,1 和 2 被畫.如果你看你將會理解用頂點 0,1 和 2 構造第一個三角形(頂端右邊,頂端左邊,底部的右邊).第二個三角形用點 verti2,1 和 3 構造.再一次,如果你注意,點verti2,1 和3 構造第二個三角形(底部右邊,頂端左邊,底部左邊).注意:兩個三角形畫點順序相同.我看到很多的要求第二個三角

20、形反方向畫.這是不對的.Opengl 從新整理頂點來保證所有的三角形為同一方向!注意:你在屏幕上看見的三角形個數是你敘述的頂點的個數減 2.在程序中在有 4 個頂點,所以看見二個三角形glTexCoord2d(1,1); glTexCoord2d(0,1); glTexCoord2d(1,0);glTexCoord2d(0,0);glVertex3f(x+0.5f,y+0.5f,z); glVertex3f(x-0.5f,y+0.5f,z); glVertex3f(x+0.5f,y-0.5f,z);glVertex3f(x-0.5f,y-0.5f,z);最后告訴Opengl畫完三角形帶glEn

21、d();現在能移動粒子.下面公式可能看起來很奇怪,其實很簡單.首先取得當前粒子的x 位置.然后把 x 運動速度加上粒子被1000 倍后的值.所以如果粒子在x 軸(0)上屏幕中心的位置,運動值(xi)為 x 軸方向+10(移動為右),而 slowdown 等于 1,移向右邊以 10/(1*1000)或 0.01f 速度.如果增加 slowdown 值到 2只移動 0.005f.希望能幫助你了解 slowdown 如何工作.那也是為什么用 10.0f 乘開始值來叫象素移動快速,創(chuàng)造一個爆發(fā)效果.y 和z 軸用相同的公式來計算附近移動粒子particleloop.x+=particleloop.xi

22、/(slowdown*1000); particleloop.y+=particleloop.yi/(slowdown*1000);particleloop.z+=particleloop.zi/(slowdown*1000);/更新X 坐標的位置更新Y 坐標的位置更新Z 坐標的位置在計算出下一步粒子移到那里,開始考慮重力和阻力.在下面的第一行,將阻力(xg)和移動速度(xi)相們的移動速度是 10 和阻力是 1.每時每刻粒子都在抵抗阻力.第二次畫粒子時,阻力開始作用,移動速度將會從 10 掉到 9.第三次畫粒子時,阻力再一次作用,移動速度降低到 8.如果粒子燃燒為超過 10 次重畫,它將會最

23、后結束,并向相反方向移動.因為移動速度會變成負值.阻力同樣使用于y 和z 移動速度particleloop.xi+=particleloop.xg; particleloop.yi+=particleloop.yg;particleloop.zi+=particleloop.zg;/更新X 軸方向速度大小更新Y 軸方向速度大小更新Z 軸方向速度大小下行將粒子的生命減少.如果不這么做,粒子無法燒盡.用粒子當前的 life 減去當前的 fade 值.每粒子都有不同的 fade 值,因此他們全部將會以不同的速度燒盡particleloop.life-=particleloop.fade;/ 減少粒子

24、的生命值現在檢查當生命為零的話粒子是否活著if (particleloop.life0.0f)/ 如果粒子生命值小于 0如果粒子是小時(燒盡),會使它復原.給它全值生命和新的衰弱速度.particleloop.life=1.0f;/ 產生一個新的粒子particleloop.fade=float(rand()%100)/1000.0f+0.003f; / 隨機生成衰率也重新設定粒子在屏幕中心放置.重新設定粒子的x,y 和z 位置為零particleloop.x=0.0f;particleloop.y=0.0f;/ 新粒子出現在屏幕的particleloop.z=0.0f;在粒子從新設置之后,將

25、給它新的移動速度/方向.注意:我增加最大和最小值,粒子移動速度為從 50 到 60 的任意值,但是這次沒將移動速度乘 10.這次不想要一個爆發(fā)的效果,而要比較慢地移動粒子.也注意我把xspeed和x 軸移動速度相加,y 軸移動速度和 yspeed 相加.這個控制粒子的移動方向.particleloop.xi=xspeed+float(rand()%60)-32.0f); / 隨機生成粒子速度particleloop.yi=yspeed+float(rand()%60)-30.0f); particleloop.zi=float(rand()%60)-30.0f);最后分配粒子一種新的顏色.變量

26、 col 保存一個數字從 1 到 11(12 種顏色),用這個變量去找紅,綠,度在顏色箱里面.下面第一行表示紅色的強度,數值保存在 colorscol0.所以如果 col 是 0,紅色的亮度就是 1.0f.綠色的和藍色的值用相同的方法.如果你不了解為什么紅色亮度為 1.0f 那 col 就為 0.我將一點點的解釋.看著程序的最前面.找到那行:sic GLfloat colors123.注意:12 行3 列.三個數字的第一行是紅色強度.第二行是綠色強度而且第三行是藍色強度.0,1和2下面描述的 1st,2nd 和 3rd 就是我剛提及的.如果 col 等于 0,要看第一個組.11 是最後一個組(

27、第 12 種顏色).particleloop.r=colorscol0;particleloop.g=colorscol1; particleloop.b=colorscol2;/ 設置粒子顏色下行描述加速度的數值是多少.通過小鍵盤 8 號鍵,增加 yg(y 地心引力)值.這引起向上的力.如果這個程序在循環(huán)外面,那么須生成另一個循環(huán)做相同的工作,因此最好放在這里/ 如果小鍵盤 8 被按住,增加Y 軸方向的加速度if (keysVK_NUMPAD8 & (particleloop.yg-1.5f) particleloop.yg-=0.01f;現在更改向右的拉力.如果按下 6 號鍵時增加向右的拉

28、力./ 如果小鍵盤 6 被按住,增加X 軸方向的加速度if (keysVK_NUMPAD6 & (particleloop.xg-1.5f) particleloop.xg-=0.01f;我僅僅為樂趣增加了一些代碼.兄弟產生很棒的效果:)通過按住 tab 鍵所有粒子都回到屏幕中心.所有的粒子在從新開始運動,再產生一個大的爆發(fā).在粒子變弱之后,你最初的效果會再一次出現if (keysVK_TAB)particleloop.x=0.0f; particleloop.y=0.0f; particleloop.z=0.0f;/ 按 Tab 鍵,使粒子回到原點particleloop.xi=float(

29、rand()%50)-26.0f)*10.0f; / 隨機生成速度particleloop.yi=float(rand()%50)-25.0f)*10.0f; particleloop.zi=float(rand()%50)-25.0f)*10.0f;return TRUE;/ 繪制完畢成功返回代碼KillGLWindow(),CreateGLWindow()和 WndProc()中沒有改變,所以碼直接跳到Wain().我將重寫代我喜歡簡單的代碼.在一行上不想包含很多東西,所以使代碼象一個清潔工:)下面的代碼檢查+是否被按下.如果它和slowdown 一起實現則 slowdown 減少 0.01f.粒子就可以較快速地移動.if (keysVK_ADD & (slowdown1.0f) slowdown-=0.01f;/ 按+號,加速粒子下面的代碼檢查-是否被按下.如果它和slowdown 一起實現則 slowdown 增加 0.01f.粒子就可以較慢速地移動.我實質的極限是 4.0f,我不想它太慢的運動,你可以隨你的要求改變最大最小值if (keysVK_SUBTRACT & (slowdown25) / 空格鍵,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論