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

            天行健 君子當自強而不息

            D3D中的粒子系統(4)

            14.3具體的粒子系統:雪、火、粒子槍

            現在讓我們用cParticleSystem類開始一個具體的粒子系統,為了說明用意,這些系統的設計很簡單,沒有用到cParticleSystem類所提供的所有靈活性。我們實現雪、火、粒子槍系統。雪系統模擬下落的雪花,火系統模擬看上去像火焰的爆炸,粒子槍系統從照相機位置向對面發射出粒子(用鍵盤)。

            14.3.1 例子程序:雪

            雪系統類定義如下:

                class cSnow : public cParticleSystem
                {
               
            public:
                    cSnow(cBoundingBox* bounding_box, 
            int num_particles);
                    
            virtual void reset_particle(sParticleAttribute* attr);
                    
            virtual void update(float time_delta);
                };

            構造函數提供一個點給邊界盒結構,邊界盒是粒子系統的成員。邊界盒描述雪花在哪個范圍內(體積范圍)下落,如果雪花出了邊界盒,它將被殺死并再生。這樣,雪系統始終能保存有同樣數量的激粒子,構造函數的實現:

                cSnow::cSnow(cBoundingBox* bounding_box, int num_particles)
                {
                    m_bounding_box    = *bounding_box;
                    m_size            = 0.25f;
                    m_vb_num        = 2048;
                    m_vb_offset        = 0;
                    m_vb_batch_num    = 512;
               
                    
            for(int i = 0; i < num_particles; i++)
                        add_particle();
                }

            同樣注意:我們指定頂點緩存的尺寸,每一批的尺寸和開始的偏移。

            reset_particle方法創建一個雪花,在xz軸隨機的位置并在邊界盒的范圍內。設置y軸高度為邊界盒的頂部。我們給雪花一個速度,以便讓雪花下落時稍稍向左傾斜。雪花是白色的。

                void cSnow::reset_particle(sParticleAttribute* attr)
                {
                    attr->is_alive = 
            true;
               
                    
            // get random x, z coordinate for the position of the snow flake
               
                    get_random_vector(&attr->position, &m_bounding_box.m_min, &m_bounding_box.m_max);
               
                    
            // no randomness for height (y-coordinate).  
                    // Snow flake always starts at the top of bounding box.
               
                    attr->position.y = m_bounding_box.m_max.y;
               
                    
            // snow flakes fall downwards and slightly to the left
               
                    attr->velocity.x = get_random_float(0.0f, 1.0f) * (-3.0f);
                    attr->velocity.y = get_random_float(0.0f, 1.0f) * (-10.0f);
                    attr->velocity.z = 0.0f;
               
                    
            // white snow flake
               
                attr->color = WHITE;
                }

            update方法更新粒子和粒子間的位置,并且測試粒子是否在系統的邊界盒之外,如果它已經跳出邊界盒,就再重新創建。
                void cSnow::update(float time_delta)
                {
                    
            for(list<sParticleAttribute>::iterator iter = m_particles.begin(); iter != m_particles.end(); iter++)
                    {
                        iter->position += iter->velocity * time_delta;
               
                        
            // is the point outside bounds?
               
                    if(! m_bounding_box.is_point_inside(iter->position))
                            
            // recycle dead particles, so respawn it.
               
                            reset_particle(&(*iter));
                    }
                }

            執行程序:
                #include "d3dUtility.h"
                #include "camera.h"
                #include "ParticleSystem.h"
                #include <cstdlib>
                #include <ctime>
               
                #pragma warning(disable : 4100)
               
               
            const int WIDTH  = 640;
               
            const int HEIGHT = 480;
               
                IDirect3DDevice9*    g_device;
                cParticleSystem*    g_snow;
                cCamera                g_camera(AIR_CRAFT);
               
               
                ////////////////////////////////////////////////////////////////////////////////////////////////////
               

               
            bool setup()
                {    
                    srand((unsigned 
            int)time(NULL));
               
                    
            // create snow system
               

                    cBoundingBox bounding_box;
                    bounding_box.m_min = D3DXVECTOR3(-10.0f, -10.0f, -10.0f);
                    bounding_box.m_max = D3DXVECTOR3(10.0f, 10.0f, 10.0f);
               
                    g_snow = 
            new cSnow(&bounding_box, 5000);
                    g_snow->init(g_device, "snowflake.dds");
               
                    
            // setup a basic scnen, the scene will be created the first time this function is called.
               
                    draw_basic_scene(g_device, 1.0f);
               
                    
            // set the projection matrix
               
                D3DXMATRIX proj;
                    D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI/4.0f, (
            float)WIDTH/HEIGHT, 1.0f, 1000.0f);
                    g_device->SetTransform(D3DTS_PROJECTION, &proj);
                    
                    
            return true;
                }
               
               
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
               

               
            void cleanup()
                {    
                    delete g_snow;
               
                    
            // pass NULL for the first parameter to instruct cleanup
               
                draw_basic_scene(NULL, 0.0f);
                }
               
               
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
               

               
            bool display(float time_delta)
                {
                    
            // update the camera
               

                    
            if( GetAsyncKeyState(VK_UP) & 0x8000f )
                        g_camera.walk(4.0f * time_delta);
               
                    
            if( GetAsyncKeyState(VK_DOWN) & 0x8000f )
                        g_camera.walk(-4.0f * time_delta);
               
                    
            if( GetAsyncKeyState(VK_LEFT) & 0x8000f )
                        g_camera.yaw(-1.0f * time_delta);
                    
                    
            if( GetAsyncKeyState(VK_RIGHT) & 0x8000f )
                        g_camera.yaw(1.0f * time_delta);
               
                    
            if( GetAsyncKeyState('N') & 0x8000f )
                        g_camera.strafe(-4.0f * time_delta);
               
                    
            if( GetAsyncKeyState('M') & 0x8000f )
                        g_camera.strafe(4.0f * time_delta);
               
                    
            if( GetAsyncKeyState('W') & 0x8000f )
                        g_camera.pitch(1.0f * time_delta);
               
                    
            if( GetAsyncKeyState('S') & 0x8000f )
                        g_camera.pitch(-1.0f * time_delta);    
               
                    
            // update the view matrix representing the camera's new position/orientation
               
                D3DXMATRIX view_matrix;
                    g_camera.get_view_matrix(&view_matrix);
                    g_device->SetTransform(D3DTS_VIEW, &view_matrix);    
               
                    g_snow->update(time_delta);
               
                    
            // render now
               

                    g_device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
               
                    g_device->BeginScene();
               
                    D3DXMATRIX identity_matrix;
                    D3DXMatrixIdentity(&identity_matrix);
                    g_device->SetTransform(D3DTS_WORLD, &identity_matrix);
               
                    draw_basic_scene(g_device, 1.0f);
               
                    
            // order important, render snow last.
               
                    g_device->SetTransform(D3DTS_WORLD, &identity_matrix);
                    g_snow->render();
               
                    g_device->EndScene();
               
                    g_device->Present(NULL, NULL, NULL, NULL);
               
                    
            return true;
                }
               
               
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
               

                LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
                {
                    
            switch(msg)
                    {
                    
            case WM_DESTROY:
                        PostQuitMessage(0);
                        
            break;
               
                    
            case WM_KEYDOWN:
                        
            if(word_param == VK_ESCAPE)
                            DestroyWindow(hwnd);
                        
            break;
                    }
               
                    
            return DefWindowProc(hwnd, msg, word_param, long_param);
                }
               
               
                ///////////////////////////////////////////////////////////////////////////////////////////////////////
               

               
            int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show)
                {
                    
            if(! init_d3d(inst, WIDTH, HEIGHT, true, D3DDEVTYPE_HAL, &g_device))
                    {
                        MessageBox(NULL, "init_d3d() - failed.", 0, MB_OK);
                        
            return 0;
                    }
               
                    
            if(! setup())
                    {
                        MessageBox(NULL, "Steup() - failed.", 0, MB_OK);
                        
            return 0;
                    }
               
                    enter_msg_loop(display);
               
                    cleanup();
                    g_device->Release();
               
                    
            return 0;
                }

            下載源程序

            posted on 2008-04-03 18:21 lovedday 閱讀(1216) 評論(2)  編輯 收藏 引用

            評論

            # re: D3D中的粒子系統(4)[未登錄] 2012-11-12 18:15 哈哈

            學習粒子系統的最好教材  回復  更多評論   

            # re: D3D中的粒子系統(4)[未登錄] 2012-11-12 18:21 哈哈

            好教材  回復  更多評論   

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            精品久久久久久国产三级| 久久九九全国免费| 亚洲午夜久久久影院| 亚洲色大成网站www久久九| 99久久777色| 欧洲国产伦久久久久久久| 午夜天堂精品久久久久| 久久AⅤ人妻少妇嫩草影院| 久久精品国产99久久久古代| 久久99国产亚洲高清观看首页| 久久亚洲色一区二区三区| 久久综合狠狠综合久久| 久久九色综合九色99伊人| 久久国产精品99精品国产| 久久露脸国产精品| 久久er国产精品免费观看2| 亚洲美日韩Av中文字幕无码久久久妻妇 | 国产午夜免费高清久久影院| 国产精品伦理久久久久久| 久久精品亚洲精品国产色婷| 日韩十八禁一区二区久久| 国产成人精品久久综合| 99久久99这里只有免费的精品| 性高湖久久久久久久久AAAAA| 久久婷婷国产麻豆91天堂| 69久久夜色精品国产69| 香蕉久久av一区二区三区| 国产精品久久新婚兰兰| 少妇久久久久久被弄到高潮| 99久久综合狠狠综合久久| 18岁日韩内射颜射午夜久久成人| 欧美亚洲色综久久精品国产| 中文成人无码精品久久久不卡| 久久精品中文字幕第23页| 久久久91人妻无码精品蜜桃HD| 国产精品久久国产精麻豆99网站| 亚洲综合熟女久久久30p| 伊人久久精品无码av一区| 久久综合狠狠综合久久综合88| 人妻少妇久久中文字幕一区二区| 色妞色综合久久夜夜|