• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

              C++博客 :: 首頁 :: 聯系 ::  :: 管理
              163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(48)

            我參與的團隊

            搜索

            •  

            積分與排名

            • 積分 - 401320
            • 排名 - 59

            最新評論

            閱讀排行榜

            評論排行榜

            歡迎來到第十九課.你已經學習了很多知識,并且現在想自己來實踐.我將在這講解一個新命令... 三角形帶(我的理解就是畫很多三角形來組合成我們要的形狀),它非常容易使用,當畫很多三角形的時候能加快你程序的運行速度.在本課中,我將會教你該如何做一個半復雜的微粒程序.一旦您了解微粒程序的原理后,在創建例如:火,煙,噴泉等效果將是很輕松的事情.我必須警告你!直到今天我從未寫一個真正的粒子程序.我想寫一個"出名"的復雜的粒子程序.我嘗試過,但在我了解我不能控制所有點變瘋狂之后我放棄了!!!你也許不相信我要告訴你的,但這個課程從頭到尾都是我自己的想法.開始我沒有一點想法,并且沒有任何技術數據放在我的面前.我開始考慮粒子,突然我的腦袋裝滿想法(腦袋開啟了??):給予每個粒子生命,任意變化顏色,速度,重力影響等等.來適應環境的變化,把每個粒子看成單一的從這個點運動到另一個點的顆粒.很快我完成了這個項目.我看看時鐘然后有個想法突然出現.四個小時過去了!我偶爾記得已經停止喝咖啡,眨眼,但是4個小時...?盡管這個程序我覺得很棒,并象我想象的那么嚴密的運行,但它不可能是最好的粒子引擎,這個我不關心,只要他運行好就可以.并且我能把它運行在我的項目中.如果你是那種想了解透徹的人,那么你要花費很多時間在網絡上查找資料并弄明白它.在程序中有很多小的代碼會看起來很模糊:)本課教程所用的部分代碼來自于Lesson1.但有很多新的代碼,因此我將重寫一些發生代碼變化的部分(使它更容易了解).
            下面用到的代碼來自于Lesson6,我將會增加5行新的代碼在我們程序的前面.第一行"stdio.h"允許我們讀文件中的數據.它和我們以前用在紋理映射當中是一樣的.第二行定義了一些我們要在屏幕上顯示的粒子的數目.告訴程序MAX_PARTICLES在這里的數值為1000.第三條行將不斷分離的彩色的粒子栓牢在一起,并設置為默認情況.sp和rp用來確定空格鍵和返回鍵是否有按住.
             
              

            #define    MAX_PARTICLES    1000        // 定義最大的粒子數
            bool    rainbow=true;            // 是否為彩虹模式
            bool    sp;                // 空格鍵是否被按下
            bool    rp;                // 回車鍵是否被按下

              
             下面四行是復雜的變量.變量slowdown控制粒子移動的快慢.數值愈高,移動越慢.數值越底,移動越快.如果數值降低,粒子將快速的移動!粒子的速度影響它們在熒屏中移動的距離.記住速度慢的粒子不會射很遠的.變量xspeed和yspeed控制尾部的方向.xspeed將會增加粒子在x軸上速度.如果xspeed是正值粒子將會向右邊移動多.如果xspeed負價值,粒子將會向左邊移動多.那個值越高,就向那個方向移動比較多.yspeed工作相同的方法,但是在y軸上.因為有其它的因素影響粒子的運動,所以我要說"多".xspeed和yspeed有助于在我們想要的方向上移動粒子.最后是變量zoom,我們用該變量移入或移出我們的屏幕.在粒子引擎里,有時可看見更多的圖象,而且當接近你時很酷
             
              

            float    slowdown=2.0f;            // 減速粒子
            float    xspeed;                // X方向的速度
            float    yspeed;                // Y方向的速度
            float    zoom=-40.0f;            // 沿Z軸縮放

              
             我們定義了一個復雜的循環變量叫做Loop.我們用這變量預先定義粒子并在屏幕中畫粒子.col用來給予粒子不同的顏色.delay用來控制在彩虹模式中圓的顏色變化.最后,我們設定一個存儲空間(粒子紋理).我用紋理而不用點的重要原因是,點的速度慢,而且挺麻煩的.其次紋理很酷:)你用一個正方形的粒子,一張你臉的小圖片,一張星星的圖片等等.很好控制! 
              

            GLuint    loop;                // 循環變量
            GLuint    col;                // 當前的顏色
            GLuint    delay;                // 彩虹效果延遲

              
             好!現在是有趣的東西.下段程序描述單一粒子結構,這是我們給予粒子的屬性.我們用布爾型變量active開始,如果為true,我們的粒子為活躍的.如果為false則粒子為死的,此時我們就刪除它.在程序中我沒有使用活躍的,因為它很好的實現.變量life和fade來控制粒子顯示多久以及顯示時候的亮度.隨著life數值的降低fade的數值也相應降低.這將導致一些粒子比其他粒子燃燒的時間長.
             
              

            typedef struct                        // 創建粒子數據結構
            {
                bool    active;                    // 是否激活
                float    life;                    // 粒子生命
                float    fade;                    // 衰減速度

              
             變量r,g和b用來表示粒子的紅色強度,綠色強度和藍色強度.當r的值變成1.0f時粒子將會很紅,當三個變量全為1.0f時則粒子將變成白色.
             
              

                float    r;                    // 紅色值
                float    g;                    // 綠色值
                float    b;                    // 藍色值

              
             變量x.y和z控制粒子在屏幕上顯示的位置.x表示粒子在x軸上的位置.y表示y軸上的位置.z表示粒子z軸上的位置
             
              

                float    x;                    // X 位置
                float    y;                    // Y 位置
                float    z;                    // Z 位置

              
             下面三個變量很重要.這三個變量控制粒子在每個軸上移動的快慢和方向.如果xi是負價粒子將會向左移動,正值將會向右移動.如果yi是負值粒子將會向下移動,正值將向上.最后,如果zi負值粒子將會向熒屏內部移動,正植將移向觀察者.  
              

                float    xi;                    // X 方向
                float    yi;                    // Y 方向
                float    zi;                    // Z 方向

              
             最后,另外3個變量!每一個變量可被看成加速度.如果xg正值時,粒子將會被拉倒右邊,負值將拉向左邊.所以如果粒子向左移動(負的)而我們給它一個正的加速度,粒子速度將變慢.最后將向反方向移動(高中物理).yg拉下或拉上.zg拉進或拉出屏幕.
             
              

                float    xg;                    // X 方向重力加速度
                float    yg;                    // Y 方向重力加速度
                float    zg;                    // Z 方向重力加速度

              
             結構的名字為particles. 
              

            }
            particles;                        // 粒子數據結構

              
             下面我們創建一個數組叫particle.數組存儲MAX_PARTICLES個元素.也就是說我們創建1000(MAX_PARTICLES)個粒子,存儲空間為每個粒子提供相應的信息
             
              

            particles particle[MAX_PARTICLES];                // 保存1000個粒子的數組

              
             在顏色數組上我們減少一些代碼來存儲12中不同的顏色.對每一個顏色從0到11我們存儲亮紅,亮綠,和亮藍.下面的顏色表里包含12個漸變顏色從紅色到紫羅蘭色 
              

            static GLfloat colors[12][3]=                // 彩虹顏色
            {
                {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.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}
            };

              
             這段代碼調用前面的代碼載入位圖,與前面的代碼相同,只是位圖的名稱不同。載入一符名為Particle.bmp的位圖 
              

                if (TextureImage[0]=LoadBMP("Data/Particle.bmp"))    // 載入粒子紋理

              
             窗口改變大小的代碼和前面一樣,不需要改變  
              
              
             我們使用光滑的陰影,清除背景為黑色,關閉深度測試,綁定并映射紋理.啟用映射位圖后我們選擇粒子紋理。唯一的改變就是禁用深度測試和初始化粒子 
              

                glDisable(GL_DEPTH_TEST);                        //禁止深度測試

              
             下面代碼初始化每個粒子.我們從活躍的粒子開始.如果粒子不活躍,它在熒屏上將不出現,無論它有多少life.當我們使粒子活躍之後,我們給它life.我懷疑給粒子生命和顏色漸變的是否是最好的方法,但當它運行一次后,效果很好!life滿值是1.0f.這也給粒子完整的光亮.
             
              

                for (loop=0;loop<MAX_PARTICLES;loop++)                //初始化所有的粒子
                {
                    particle[loop].active=true;                    // 使所有的粒子為激活狀態
                    particle[loop].life=1.0f;                    // 所有的粒子生命值為最大

              
             我們通過給定的值來設定粒子退色快慢.每次粒子被拉的時候life隨著fade而減小.結束的數值將是0~99中的任意一個,然后平分1000份來得到一個很小的浮點數.最后我們把結果加上0.003f來使fade速度值不為0
             
              

                    particle[loop].fade=float(rand()%100)/1000.0f+0.003f;        // 隨機生成衰減速率

              
             既然粒子是活躍的,而且我們又給它生命,下面將給它顏色數值.一開始,我們就想每個粒子有不同的顏色.我怎么做才能使每個粒子與前面顏色箱里的顏色一一對應那?數學很簡單,我們用loop變量乘以箱子中顏色的數目與粒子最大值(MAX_PARTICLES)的余數.這樣防止最后的顏色數值大于最大的顏色數值(12).舉例:900*(12/900)=12.1000*(12/1000)=12,等等
             
              

                    particle[loop].r=colors[loop*(12/MAX_PARTICLES)][0];        // 粒子的紅色顏色
                    particle[loop].g=colors[loop*(12/MAX_PARTICLES)][1];        // 粒子的綠色顏色
                    particle[loop].b=colors[loop*(12/MAX_PARTICLES)][2];        // 粒子的藍色顏色

              
             現在設定每個粒子移動的方向和速度.我們通過將結果乘于10.0f來創造開始時的爆炸效果.我們將會以任意一個正或負值結束.這個數值將以任意速度,任意方向移動粒子. 
              

                    particle[loop].xi=float((rand()%50)-26.0f)*10.0f;        // 隨機生成X軸方向速度
                    particle[loop].yi=float((rand()%50)-25.0f)*10.0f;        // 隨機生成Y軸方向速度
                    particle[loop].zi=float((rand()%50)-25.0f)*10.0f;        // 隨機生成Z軸方向速度

              
             最后,我們設定加速度的數值.不像一般的加速度僅僅把事物拉下,我們的加速度能拉出,拉下,拉左,拉右,拉前和拉后粒子.開始我們需要強大的向下加速度.為了達到這樣的效果我們將xg設為0.0f.在x方向沒有拉力.我們設yg為-0.8f來產生一個向下的拉力.如果值為正則拉向上.我們不希望粒子拉近或遠離我們,所以將zg設為0.0f
             
              

                    particle[loop].xg=0.0f;                        // 設置X軸方向加速度為0
                    particle[loop].yg=-0.8f;                        //  設置Y軸方向加速度為-0.8
                    particle[loop].zg=0.0f;                        //  設置Z軸方向加速度為0
                }

              
             現在為有趣的部分.下面的部分是我們從哪里拉粒子,檢查加速度等等.你要明白它是怎么實現的,因此仔細的看:)我們重置Modelview巨陣.在畫粒子位置的時候用glVertex3f()命令來代替tranlations,這樣在我們畫粒子的時候不會改變modelview巨陣
             
              

            int DrawGLScene(GLvoid)                                // 繪制粒子
            {
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);                // 以黑色背景清楚
                glLoadIdentity();                                // 重置模型變換矩陣

              
             我們開始創建一個循環loop.這個環將會更新每一個粒子.  
              

                for (loop=0;loop<MAX_PARTICLES;loop++)                    // 循環所有的粒子
                {

              
             首先我們做的事物是檢查粒子是否活躍.如果不活躍,則不被更新.在這個程序中,它們始終活躍.但是在你自己的程序中,你可能想要使某粒子不活躍  
              

                    if (particle[loop].active)                    // 如果粒子為激活的
                    {

              
             下面三個變量是我們確定x,y和z位置的暫時變量.注意:在z的位置上我們加上zoom以便我們的場景在以前的基礎上再移入zoom個位置.particle[loop].x告訴我們要畫的x的位置.particle[loop].y告訴我們要畫的y的位置.particle[loop].z告訴我們要畫的z的位置     float x=particle[loop].x;                // 返回X軸的位置
                        float y=particle[loop].y;                // 返回Y軸的位置
                        float z=particle[loop].z+zoom;            // 返回Z軸的位置

              
             既然知道粒子位置,就能給粒子上色.particle[loop].r保存粒子的亮紅,particle[loop].g保存粒子的亮綠,particle[loop].b保存粒子的亮藍.注意我用alpha為粒子生命.當粒子要燃盡時,它會越來越透明直到它最后消失.這就是為什么粒子的生命不應該超過1.0f.如果你想粒子燃燒時間長,可降低fade減小的速度
             
              

                        // 設置粒子顏色
                        glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);

              
             我們有粒子的位置,并設置顏色了.所以現在我們來畫我們的粒子.我們用一個三角形帶來代替一個四邊形這樣使程序運行快一點.很多3D card畫三角形帶比畫四邊形要快的多.有些3D card將四邊形分成兩個三角形,而有些不.所以我們按照我們自己的想法來,所以我們來畫一個生動的三角形帶
             
              

                        glBegin(GL_TRIANGLE_STRIP);                // 繪制三角形帶

              
              從紅寶書引述:三角形帶就是畫一連續的三角形(三個邊的多角形)使用vertices V0,V1,V2,然后V2,V1,V3(注意順序),然后V2,V3,V4等等.畫三角形的順序一樣才能保證三角形帶為相同的表面.要求方向是很重要的,例如:剔除,最少用三點來畫當第一個三角形使用vertices0,1和2被畫.如果你看圖片你將會理解用頂點0,1和2構造第一個三角形(頂端右邊,頂端左邊,底部的右邊).第二個三角形用點vertices2,1和3構造.再一次,如果你注意圖片,點vertices2,1和3構造第二個三角形(底部右邊,頂端左邊,底部左邊).注意:兩個三角形畫點順序相同.我看到很多的網站要求第二個三角形反方向畫.這是不對的.Opengl從新整理頂點來保證所有的三角形為同一方向!注意:你在屏幕上看見的三角形個數是你敘述的頂點的個數減2.在程序中在我們有4個頂點,所以我們看見二個三角形
             
              

                            glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z);
                            glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z);
                            glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z);
                            glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z);
              
             最后我們告訴Opengl我們畫完三角形帶
             
              

                        glEnd();

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

                        particle[loop].x+=particle[loop].xi/(slowdown*1000);    // 更新X坐標的位置
                        particle[loop].y+=particle[loop].yi/(slowdown*1000);    // 更新Y坐標的位置
                        particle[loop].z+=particle[loop].zi/(slowdown*1000);    // 更新Z坐標的位置

              
             在計算出下一步粒子移到那里,開始考慮重力和阻力.在下面的第一行,將阻力(xg)和移動速度(xi)相加.我們的移動速度是10和阻力是1.每時每刻粒子都在抵抗阻力.第二次畫粒子時,阻力開始作用,移動速度將會從10掉到9.第三次畫粒子時,阻力再一次作用,移動速度降低到8.如果粒子燃燒為超過10次重畫,它將會最后結束,并向相反方向移動.因為移動速度會變成負值.阻力同樣使用于y和z移動速度  
              

                        particle[loop].xi+=particle[loop].xg;            // 更新X軸方向速度大小
                        particle[loop].yi+=particle[loop].yg;            // 更新Y軸方向速度大小
                        particle[loop].zi+=particle[loop].zg;            // 更新Z軸方向速度大小

              
             下行將粒子的生命減少.如果我們不這么做,粒子無法燒盡.我們用粒子當前的life減去當前的fade值.每粒子都有不同的fade值,因此他們全部將會以不同的速度燒盡
             
              

                        particle[loop].life-=particle[loop].fade;        // 減少粒子的生命值

              
             現在我們檢查當生命為零的話粒子是否活著  
              

                        if (particle[loop].life<0.0f)                    // 如果粒子生命值小于0
                        {

              
             如果粒子是小時(燒盡),我們將會使它復原.我們給它全值生命和新的衰弱速度. 
              

                            particle[loop].life=1.0f;                // 產生一個新的粒子
                            particle[loop].fade=float(rand()%100)/1000.0f+0.003f;    // 隨機生成衰減速率

              
             我們也重新設定粒子在屏幕中心放置.我們重新設定粒子的x,y和z位置為零 
              

                            particle[loop].x=0.0f;                    // 新粒子出現在屏幕的中央
                            particle[loop].y=0.0f;                   
                            particle[loop].z=0.0f;                   
              
             在粒子從新設置之后,將給它新的移動速度/方向.注意:我增加最大和最小值,粒子移動速度為從50到60的任意值,但是這次我們沒將移動速度乘10.我們這次不想要一個爆發的效果,而要比較慢地移動粒子.也注意我把xspeed和x軸移動速度相加,y軸移動速度和yspeed相加.這個控制粒子的移動方向. 
              

                            particle[loop].xi=xspeed+float((rand()%60)-32.0f);    // 隨機生成粒子速度
                            particle[loop].yi=yspeed+float((rand()%60)-30.0f);   
                            particle[loop].zi=float((rand()%60)-30.0f);       
              
             最后我們分配粒子一種新的顏色.變量col保存一個數字從1到11(12種顏色),我們用這個變量去找紅,綠,藍亮度在顏色箱里面.下面第一行表示紅色的強度,數值保存在colors[col][0].所以如果col是0,紅色的亮度就是1.0f.綠色的和藍色的值用相同的方法讀取.如果你不了解為什么紅色亮度為1.0f那col就為0.我將一點點的解釋.看著程序的最前面.找到那行:static GLfloat colors[12][3].注意:12行3列.三個數字的第一行是紅色強度.第二行是綠色強度而且第三行是藍色強度.[0],[1]和[2]下面描述的1st,2nd和3rd就是我剛提及的.如果col等于0,我們要看第一個組.11 是最後一個組(第12種顏色).
             
              

                            particle[loop].r=colors[col][0];            // 設置粒子顏色
                            particle[loop].g=colors[col][1];           
                            particle[loop].b=colors[col][2];           
                        }

              
             下行描述加速度的數值是多少.通過小鍵盤8號鍵,我們增加yg(y 地心引力)值.這引起向上的力.如果這個程序在循環外面,那么我們必須生成另一個循環做相同的工作,因此我們最好放在這里
             
              

                        // 如果小鍵盤8被按住,增加Y軸方向的加速度
                        if (keys[VK_NUMPAD8] && (particle[loop].yg<1.5f)) particle[loop].yg+=0.01f;

              
             這行是產生相反的效果.通過2號鍵,減小yg值,引起向下的力
             
              

                        // 如果小鍵盤2被按住,減少Y軸方向的加速度
                        if (keys[VK_NUMPAD2] && (particle[loop].yg>-1.5f)) particle[loop].yg-=0.01f;

              
             現在更改向右的拉力.如果按下6號鍵時增加向右的拉力.
             
              

                        // 如果小鍵盤6被按住,增加X軸方向的加速度
                        if (keys[VK_NUMPAD6] && (particle[loop].xg<1.5f)) particle[loop].xg+=0.01f;

              
             最后如果4號鍵被按下則增加向左的拉力.這些按鍵給了我們很酷的結果.舉例來說:你可以用粒子造一條向上設的水流.通過增加向下的引力可以形成泉水
             
              

                        // 如果小鍵盤4被按住,減少X軸方向的加速度
                        if (keys[VK_NUMPAD4] && (particle[loop].xg>-1.5f)) particle[loop].xg-=0.01f;

              
             我僅僅為樂趣增加了一些代碼.我的兄弟產生很棒的效果:)通過按住tab鍵所有粒子都回到屏幕中心.所有的粒子在從新開始運動,再產生一個大的爆發.在粒子變弱之后,你最初的效果會再一次出現
             
              

                        if (keys[VK_TAB])                        // 按Tab鍵,使粒子回到原點
                        {
                            particle[loop].x=0.0f;                   
                            particle[loop].y=0.0f;                   
                            particle[loop].z=0.0f;                   
                            particle[loop].xi=float((rand()%50)-26.0f)*10.0f;    // 隨機生成速度
                            particle[loop].yi=float((rand()%50)-25.0f)*10.0f;   
                            particle[loop].zi=float((rand()%50)-25.0f)*10.0f;   
                        }
                    }
                }
                return TRUE;                                    // 繪制完畢成功返回
            }

              
             代碼KillGLWindow(),CreateGLWindow()和WndProc()中沒有改變,所以我們直接跳到WinMain().我將重寫代碼 
              
              
             我喜歡簡單的代碼.在一行上不想包含很多東西,所以使代碼象一個清潔工:)下面的代碼檢查"+"是否被按下.如果它和slowdown一起實現則slowdown減少0.01f.粒子就可以較快速地移動.
             
              

                            if (keys[VK_ADD] && (slowdown>1.0f)) slowdown-=0.01f;        // 按+號,加速粒子

              
             下面的代碼檢查"-"是否被按下.如果它和slowdown一起實現則slowdown增加0.01f.粒子就可以較慢速地移動.我實質的極限是4.0f,我不想它太慢的運動,你可以隨你的要求改變最大最小值 
              

                            if (keys[VK_SUBTRACT] && (slowdown<4.0f)) slowdown+=0.01f;    // 按-號,減速粒子

              
             下面的代碼檢測Page Up是否被按下.如果是,則zoom增加.從而導致粒子靠近我們 
              

                            if (keys[VK_PRIOR]) zoom+=0.1f;        // 按Page Up鍵,讓粒子靠近視點

              
             下行代碼檢測Page Down是否別按下,如果是,則zoom減小.從而導師粒子離開我們
             
              

                            if (keys[VK_NEXT]) zoom-=0.1f;        // 按Page Down,讓粒子遠離視點

              
             下面的代碼檢驗enter鍵是否被按下.如果是,并且沒有被一直按著,我們將讓計算機把rp變為true,然后我們固定彩虹模式.如果彩虹模式為true,將其變成false.如果為false,將其變成true.最后一行檢測enter是否被釋放,如果釋放rp為false并告訴計算機該鍵不被按下
             
              

                            if (keys[VK_RETURN] && !rp)        // 按住回車鍵,切換彩虹模式
                            {
                                rp=true;           
                                rainbow=!rainbow;       
                            }
                            if (!keys[VK_RETURN]) rp=false;       
              
             下面程序有點亂.第一行檢查space鍵是否被按下并沒有沒一直按著.并檢查彩虹模式是否開始運行,如果是,檢查delay是否大于25.delay是我創建的顯示彩虹效果的數值.如果你曾經改變顏色結構,粒子將顯示不同顏色.通過創建一個delay,在顏色改變之前,一組粒子將是一種顏色.如果space按下,彩虹運行,delay值大于25則顏色改變
             
              

                            if ((keys[' '] && !sp) || (rainbow && (delay>25)))    // 空格鍵,變換顏色
                            {

              
             下面行是為了當space按下則彩虹關掉而設置的.如果我們不關掉彩虹模式,顏色會繼續變化直到enter再被按下.也就是說人們按下space來代替enter是想叫粒子顏色自己變化 
              

                                if (keys[' ']) rainbow=false;   

              
             如果space鍵被按下,或者彩虹模式已開始,并且delay大于25,我們叫計算機知道space鍵被按下通過叫sp為true.然后我們將delay設定回0以便它能在到25.最后我們增加col的值以便它通過顏色箱里面改變成另一個顏色. 
              

                                sp=true;           
                                delay=0;           
                                col++;               
              
             如果顏色值大于11,我們把它重新設為零.如果我們不重新設定為零,程序將去找第13顏色.而我們只有12種顏色!尋找不存在的顏色將會導致程序癱瘓 
              

                                if (col>11) col=0;
                            }

              
             最后如果space鍵不被按下,我們將sp設為false。 
              

                            if (!keys[' '])    sp=false;        // 如果釋放空格鍵,記錄這個狀態

              
             現在對粒子增加一些控制.還記得我們從開始定義的2變量么?一個xspeed,一個yspeed.在粒子燃盡之后,我們給它新的移動速度且把新的速度加入到xspeed和yspeed中.這樣當粒子被創建時將影響粒子的速度. 舉例來說:粒子在x軸上的速度為5在y軸上的速度為0.當我們減少xspeed到-10,我們將以-10(xspeed)+5(最初的移動速度)的速度移動.這樣我們將以5的速度向左移動.明白了么??無論如何,下面的代碼檢測UP是否被按下.如果它,yspeed將增加這將引起粒子向上運動.最大速度不超過200.速度在快就不好看了
             
              

                            // 按上增加粒子Y軸正方向的速度
                            if (keys[VK_UP] && (yspeed<200)) yspeed+=1.0f;

              
             這行檢查Down鍵是否被按下,如果它是,yspeed將減少.這將引起粒子向下運動.再一次,最大速度為200 
              

                            // 按下減少粒子Y軸正方向的速度
                            if (keys[VK_DOWN] && (yspeed>-200)) yspeed-=1.0f;

              
             現在我們檢查Right鍵是否被按下.如果它是..xspeed將被增加.粒子將移到右邊.最大速度為200 
              

                            // 按右增加粒子X軸正方向的速度
                            if (keys[VK_RIGHT] && (xspeed<200)) xspeed+=1.0f;

              
             最后我們檢查Left鍵是否被按下.如果是...你猜....xspeed被減小,粒子開始向左移動.最大速度為200 
              

                            // 按左減少粒子X軸正方向的速度
                            if (keys[VK_LEFT] && (xspeed>-200)) xspeed-=1.0f;

              
             最后我們要增加delay的數值.像我在前面所說,delay是控制彩色變化的 
              

                            delay++;            // 增加彩虹模式的顏色切換延遲

              
             在課程中,我試著把所有細節都講清楚,并且簡單的了解粒子系統.這個粒子系統能在游戲產生例如火,水,雪,爆炸,流行等效果.程序能簡單的修改參數來實現新的效果(例:煙花效果)
             
             


            posted on 2007-12-16 14:27 sdfasdf 閱讀(4607) 評論(2)  編輯 收藏 引用 所屬分類: OPENGL

            Feedback

            # re: NEHE的OPENGL教程 第十九課 粒子系統 2007-12-17 09:04 學海一人
            ding  回復  更多評論
              

            # re: NEHE的OPENGL教程 第十九課 粒子系統 2007-12-17 09:06 美妹
            謝謝  回復  更多評論
              

            亚洲伊人久久成综合人影院| 日本久久久精品中文字幕| 麻豆久久久9性大片| 人妻精品久久无码专区精东影业| 国内精品久久久久久久久电影网 | 国产成人久久精品二区三区| 久久久久久一区国产精品| 日韩久久久久久中文人妻| 国产成人香蕉久久久久| 亚洲女久久久噜噜噜熟女| 精品免费久久久久国产一区| 伊人久久大香线蕉综合Av| 国产精品成人无码久久久久久 | 久久99精品久久久久久水蜜桃 | 久久夜色精品国产| 久久久久99精品成人片试看| 欧美粉嫩小泬久久久久久久| 99久久国产综合精品麻豆| 久久精品无码一区二区WWW| 91久久精品视频| 久久人妻少妇嫩草AV无码专区| 性高湖久久久久久久久AAAAA| 久久福利青草精品资源站| 久久精品国产免费观看| 亚洲?V乱码久久精品蜜桃| 久久亚洲国产精品123区| 国产激情久久久久影院| 亚洲一区中文字幕久久| 91精品国产综合久久久久久 | 久久精品一区二区三区中文字幕| 久久亚洲私人国产精品vA | 99久久人人爽亚洲精品美女| 国产精品对白刺激久久久| 久久综合香蕉国产蜜臀AV| 久久久久久亚洲Av无码精品专口| 成人久久免费网站| 伊人久久精品无码av一区| 久久亚洲精品中文字幕| 99精品国产99久久久久久97 | 久久久久久亚洲精品无码| 午夜视频久久久久一区 |