• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

            D3D中的粒子系統(tǒng)(2)

            新建網(wǎng)頁(yè) 1

            14.2粒子系統(tǒng)的組成

            粒子系統(tǒng)是粒子的集合,用來(lái)保存和顯示這些粒子。粒子系統(tǒng)維護(hù)所有粒子的全部屬性,影響系統(tǒng)中的所有粒子:粒子的尺寸,起始的位置及應(yīng)用在粒子上的紋理等。粒子系統(tǒng)的方法負(fù)責(zé)更新、顯示、殺死和創(chuàng)建粒子。

            雖然不同的具體(與抽象是相對(duì)的)粒子系統(tǒng)有不同的行為,我們歸納并找到一些所有的粒子系統(tǒng)共有的基本屬性,我們把這些公共的屬性放到一個(gè)抽象的cParticleSystem基類(lèi),它是我們所有的具體粒子系統(tǒng)的父類(lèi),現(xiàn)在讓我們看一下cParticleSystem類(lèi):

                class cParticleSystem
                {
               
            protected:
                    IDirect3DDevice9*            m_device;
                    D3DXVECTOR3                    m_origin;
                    cBoundingBox                m_bounding_box;
                    
            float                        m_emit_rate;        // rate new particles are added to system
               
                float                        m_size;                // size of particles
               
                    IDirect3DTexture9*            m_texture;
                    IDirect3DVertexBuffer9*     m_vertex_buffer;
                    list<sParticleAttribute>    m_particles;
                    
            int                            m_max_particles;    // max allowed particles system can have
               
                    // following three data elements used for rendering the particle system efficiently
               

                    DWORD    m_vb_num;        
            // particle number in vertex buffer
               
                DWORD    m_vb_offset;    // offset in vertex buffer to lock
               
                DWORD    m_vb_batch_num;    // number of vertices to lock starting at m_vb_offset
               

               
            public:
                    cParticleSystem();
                    
            virtual ~cParticleSystem();
               
                    
            virtual bool init(IDirect3DDevice9*    device, const char* texture_filename);
                    
            virtual void reset();
               
                    
            // sometimes we don't want to free the memory of a dead particle, but rather respawn it instead.
               
                virtual void reset_particle(sParticleAttribute* particl_attr) = 0;
                    
            virtual void add_particle();
               
                    
            virtual void update(float time_delta) = 0;
               
                    
            virtual void pre_render();
                    
            virtual void render();
                    
            virtual void post_render();
               
                    
            bool is_empty();
                    
            bool is_dead();
               
               
            protected:
                    
            virtual void remove_dead_particles();
                };

            一些數(shù)據(jù)成員:

            ·        m_origin粒子系統(tǒng)的原點(diǎn), 這是粒子系統(tǒng)產(chǎn)生時(shí)的位置。

            ·        m_bounding_box創(chuàng)建粒子系統(tǒng)使用的邊界盒,用于限制粒子的活動(dòng)范圍。例如,假如我們讓雪系統(tǒng)只落在一個(gè)圍繞高山的峰頂?shù)捏w積內(nèi),我們會(huì)定義一個(gè)包括這個(gè)體積的邊界盒, 出界的粒子將會(huì)被殺死。

            ·        m_emit_rate新增加到系統(tǒng)中的粒子的速度。通常的標(biāo)準(zhǔn)是每秒。

            ·        m_size系統(tǒng)中所有粒子的尺寸。

            ·        m_particles系統(tǒng)中粒子屬性的一個(gè)列表。 我們用這個(gè)列表創(chuàng)建,釋放及更新粒子。 當(dāng)我們準(zhǔn)備畫(huà)粒子時(shí), 我們COPY列表節(jié)點(diǎn)的一部分到頂點(diǎn)緩存并畫(huà)粒子,同時(shí)我們COPY另外一批粒子,然后重復(fù)這一過(guò)程直到繪制完所有粒子。

            ·        m_max_particles在給定的時(shí)間內(nèi),系統(tǒng)中允許的粒子最大數(shù)。例如,如果創(chuàng)建粒子的速度比釋放快的話, 隨著時(shí)間的增長(zhǎng)粒子的數(shù)量將會(huì)是巨大的,這個(gè)成員將避免出現(xiàn)這樣的問(wèn)題。

            ·        m_vb_num在給定的時(shí)間內(nèi)頂點(diǎn)緩存中能夠保存的粒子的數(shù)量,這個(gè)值與實(shí)際的粒子系統(tǒng)中的粒子數(shù)量無(wú)關(guān)。

            注意:m_vb_offsetm_vb_batch_num數(shù)據(jù)成員在渲染粒子系統(tǒng)時(shí)使用,我們?cè)谏院?/span>討論。

            方法:

            cParticleSystem/ ~cParticleSystem用來(lái)初始化默認(rèn)值和用來(lái)釋放設(shè)備接口 (vertex buffer, texture)。

                cParticleSystem::cParticleSystem()
                {
                    m_device        = NULL;
                    m_vertex_buffer = NULL;
                    m_texture        = NULL;
                }
               
                cParticleSystem::~cParticleSystem()
                {
                    safe_release<IDirect3DVertexBuffer9*>(m_vertex_buffer);
                    safe_release<IDirect3DTexture9*>(m_texture);
                }

            init這個(gè)方法做與設(shè)備無(wú)關(guān)的初始化工作,比如創(chuàng)建用來(lái)保存點(diǎn)精靈的頂點(diǎn)緩存或創(chuàng)建紋理。
                bool cParticleSystem::init(IDirect3DDevice9* device, const char* texture_filename)
                {
                    
            // Vertex buffer's number does not equal the number of particles in our system.  
                    // We use the vertex buffer to draw a portion of our particles at a time.  
                    // The arbitrary number we choose for the vertex buffer is specified by the m_vb_num variable.
               

                    m_device = device;
               
                    HRESULT hr;
               
                    hr = device->CreateVertexBuffer(
                            m_vb_num * 
            sizeof(sParticle),
                            D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS | D3DUSAGE_WRITEONLY,
                            PARTICLE_FVF,
                            D3DPOOL_DEFAULT,    
            // D3DPOOL_MANAGED can't be used with D3DUSAGE_DYNAMIC
               
                        &m_vertex_buffer,
                            NULL);
               
                    
            if(FAILED(hr))
                    {
                        MessageBox(NULL, "CreateVertexBuffer() - FAILED", "ParticleSystem", MB_OK);
                        
            return false;
                    }
               
                    hr = D3DXCreateTextureFromFile(device, texture_filename, &m_texture);
               
                    
            if(FAILED(hr))
                    {
                        MessageBox(NULL, "D3DXCreateTextureFromFile() - FAILED", "ParticleSystem", MB_OK);
                        
            return false;
                    }
               
                    
            return true;
                }

            o       注意: 我們使用動(dòng)態(tài)的頂點(diǎn)緩存(D3DUSAGE DYNAMIC)。 因?yàn)槲覀冃枰诿繋懈挛覀兊牧W?span lang="EN-US">,意思是我們將會(huì)去存取頂點(diǎn)緩存的內(nèi)存,回想一下,訪問(wèn)一個(gè)靜態(tài)的頂點(diǎn)緩存慢得不可接受, 所以我們使用動(dòng)態(tài)的頂點(diǎn)緩存。

            o       查看我們用過(guò)的 D3DUSAGE_POINTS標(biāo)記,它說(shuō)明頂點(diǎn)緩存將保存點(diǎn)精靈。

            o       頂點(diǎn)緩存的尺寸是由m_vb_num預(yù)先確定的,而且與系統(tǒng)中粒子的數(shù)量無(wú)關(guān)。 也就是說(shuō), m_vb_num將小于等于系統(tǒng)中粒子的數(shù)量。 這是因?yàn)殇秩玖W酉到y(tǒng)是一批一批的,不是一次渲染全部。

            o       我們使用默認(rèn)的內(nèi)存池(pool)代替通常使用的托管內(nèi)存池,因?yàn)閯?dòng)態(tài)頂點(diǎn)緩存不能用在托管內(nèi)存池中。

            reset這個(gè)方法重新設(shè)置系統(tǒng)中每個(gè)粒子的屬性:

                void cParticleSystem::reset()
                {
                    
            for(list<sParticleAttribute>::iterator iter = m_particles.begin(); iter != m_particles.end(); iter++)
                        reset_particle(&(*iter));
                }

            reset_particle這個(gè)方法重新設(shè)置粒子的屬性。如何重設(shè)粒子的屬性,這依賴于具體粒子系統(tǒng)的特性。因此我們定義這個(gè)方法為虛擬的,等待子類(lèi)去實(shí)現(xiàn)。

             add_particle這個(gè)方法用來(lái)在系統(tǒng)中增加一個(gè)粒子。在增加它到粒子列表之前,使用reset_particle方法先初始化粒子:

                void cParticleSystem::add_particle()
                {
                    sParticleAttribute attr;
                    reset_particle(&attr);
               
                    m_particles.push_back(attr);
                }

            update這個(gè)方法更新系統(tǒng)中所有的粒子。因?yàn)檫@個(gè)的方法的執(zhí)行取決于具體粒子系統(tǒng)的特性,因此我們定義這個(gè)方法為抽象的,等待子類(lèi)去實(shí)現(xiàn)。

            render這個(gè)方法用來(lái)顯示系統(tǒng)中所有的粒子。

            pre_render用它來(lái)初始化渲染狀態(tài),在渲染前設(shè)置。 因?yàn)橄到y(tǒng)與系統(tǒng)之間是不同的,所以我們定義它為虛擬的。 默認(rèn)將執(zhí)行下列代碼:

                void cParticleSystem::pre_render()
                {
                    m_device->SetRenderState(D3DRS_LIGHTING,          FALSE);
                    m_device->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
                    m_device->SetRenderState(D3DRS_POINTSCALEENABLE,  TRUE);
                    m_device->SetRenderState(D3DRS_POINTSIZE,          float_to_dword(m_size));
                    m_device->SetRenderState(D3DRS_POINTSIZE_MIN,      float_to_dword(0.0f));
               
                    
            // control the size of the particle relative to distance
               
                    m_device->SetRenderState(D3DRS_POINTSCALE_A,    float_to_dword(0.0f));
                    m_device->SetRenderState(D3DRS_POINTSCALE_B,    float_to_dword(0.0f));
                    m_device->SetRenderState(D3DRS_POINTSCALE_C,    float_to_dword(1.0f));
               
                    
            // use alpha from texture
               
                    m_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
                    m_device->SetTextureStageState(0, D3DTSS_ALPHAOP,    D3DTOP_SELECTARG1);
               
                    m_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
                    m_device->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);
                    m_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
                }

              注意:我們使用alpha混合渲染,以便設(shè)置紋理的alpha通道,來(lái)設(shè)置紋理像素的透明,用它產(chǎn)生多種效果。一種特殊的情況是:獲得象紋理那樣的非矩形的粒子。例如,獲得一個(gè)圓形“雪球形”的粒子,我們使用一個(gè)簡(jiǎn)單的帶有alpha通道的紋理,它看上去是背景為黑色的帶有白色圓形的樣子。因此,顯示出來(lái)時(shí)只是一個(gè)白圓,這比白色的矩形紋理要好。

             post_render用它去保存所有渲染狀態(tài)。因?yàn)橄到y(tǒng)與系統(tǒng)間是不同的,所以我們定義它為虛擬的。默認(rèn)將執(zhí)行下列代碼:

                void cParticleSystem::post_render()
                {
                    m_device->SetRenderState(D3DRS_LIGHTING, TRUE);
                    m_device->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
                    m_device->SetRenderState(D3DRS_POINTSCALEENABLE,  FALSE);
                    m_device->SetRenderState(D3DRS_ALPHABLENDENABLE,  FALSE);
                }

             is_empty如果為True則在當(dāng)前的系統(tǒng)中沒(méi)有粒子, 否則為false.

                bool cParticleSystem::is_empty()
                {
                    
            return m_particles.empty();
                }

            is_dead如果為True則系統(tǒng)中的所有粒子都是死的,否則為false。
                bool cParticleSystem::is_dead()
                {
                    
            for(list<sParticleAttribute>::iterator iter = m_particles.begin(); iter != m_particles.end(); iter++)
                    {
                        
            // Is there at least one living particle? If yes, the system is not dead.
               
                    if(iter->is_alive)
                            
            return false;
                    }
               
                    
            // No living particles found, the system must be dead.
               
                return true;
                }

            remove_dead_particles搜索屬_particle性表,從表中殺死并刪除粒子。

                void cParticleSystem::remove_dead_particles()
                {
                    list<sParticleAttribute>::iterator iter = m_particles.begin();
               
                    
            while(iter != m_particles.end())
                    {        
                        
            if(! iter->is_alive)
                            
            // erase returns the next iterator, so no need to increment to the next one ourseleves.
               
                            iter = m_particles.erase(iter);
                        
            else
                            iter++;    
            // next in list
               
                }
                }

            posted on 2008-04-03 17:24 lovedday 閱讀(1058) 評(píng)論(0)  編輯 收藏 引用

            公告

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            隨筆分類(lèi)(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評(píng)論

            国产精品99久久久久久www| 久久福利青草精品资源站免费 | 久久成人国产精品| 国产精品无码久久综合| 亚洲狠狠综合久久| 久久妇女高潮几次MBA| 久久99精品国产99久久6男男| 狠狠色伊人久久精品综合网| 奇米影视7777久久精品人人爽| 欧洲成人午夜精品无码区久久| 91久久精品电影| 久久青青草原精品国产| 性高朝久久久久久久久久| 狠狠色婷婷综合天天久久丁香| 久久精品一区二区三区AV| 91久久精品无码一区二区毛片| 久久天天躁狠狠躁夜夜不卡| 97超级碰碰碰碰久久久久| 日韩人妻无码精品久久免费一| 久久久久国产一区二区| 26uuu久久五月天| 国内精品久久久久久久97牛牛| 久久99国产精品久久99小说| 精品久久综合1区2区3区激情| 久久久久久亚洲精品成人| 亚洲国产精品18久久久久久| 久久久国产亚洲精品| 久久男人中文字幕资源站| 精品人妻伦一二三区久久| 国产精品免费久久久久影院| 久久婷婷国产麻豆91天堂| 狠狠久久亚洲欧美专区 | 国产三级观看久久| 亚洲国产精品婷婷久久| 久久精品九九亚洲精品天堂| 久久99精品久久久久婷婷| 久久精品夜夜夜夜夜久久| 国产精品9999久久久久| 97精品久久天干天天天按摩| 精品久久一区二区| 热99re久久国超精品首页|