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方法创建一个雪花,在x、z轴随机的位置并在边界盒的范围内。设置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;
    }

下载源程序

D3D中的粒子系统(4)相关推荐

  1. D3D中的粒子系统(1)

    许多自然现象是由很多小的小颗粒组成的,它们有相似的行为.(例如,雪花落下,闪烁的火焰,冲出枪管的"子弹"),粒子系统用来模拟这种现象. 14.1 粒子和点精灵(Point Spri ...

  2. DirectX中的粒子系统

    自然界中有现象包含了大量的行为相同的,微小粒子,比如:雪花,烟火等,粒子系统通常用来描述这些场景. 粒子是自然界中一种微小的东西,所以显示例子的最好的方法就是使用点图元,但是点图元在被光栅化的时候会被 ...

  3. [VC] 【游戏编程】构架游戏中的粒子系统 图文教程

    转载自:http://www.52pojie.cn/thread-165772-1-1.html Expression GameEngine Particle System的实现效果   动画原图: ...

  4. 详解Unity中的粒子系统Particle System (十二 | 终)

    前言 终于来到了最后一篇,粒子系统宣告终结!这十来篇博客删删改改写了半个多月,真是离谱.今天该讲案例与粒子系统的应用,那么我们就进入正题吧! 目录 前言 本系列提要 一.如何做出效果 二.案例演示 1 ...

  5. 详解Unity中的粒子系统Particle System (三)

    前言 上一篇我们详细讲解了有关主模块的全部内容,已经对粒子系统的基本运作有了足够的了解,本篇就来讲一下被粒子系统默认启用的Emission.Shape.Renderer模块又在粒子系统中扮演着怎么样的 ...

  6. 详解Unity中的粒子系统Particle System (一)

    前言 游戏中很多炫酷效果的背后都离不开粒子系统,比如击中.爆炸.火焰.崩塌.喷射.烟雾等等.Unity也我们提供了强大的粒子系统,模块化的设计,上百个参数供我们调节使用,足以创造出非常震撼的效果了,本 ...

  7. 详解Unity中的粒子系统Particle System (二)

    前言 上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解.从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状 ...

  8. 详解Unity中的粒子系统Particle System (七)

    前言 本篇来讲一讲Collision和Triggers模块,这两个模块主要用于粒子系统与物理世界的交互,一个是碰撞器,另一个是触发器.有了这两个模块我们又可以做出更炫酷的粒子效果啦! 目录 前言 本系 ...

  9. 详解Unity中的粒子系统Particle System (九)

    前言 今天讲Texture Sheet Animation模块,先前我们已经讲了很多很多模块,通过上述模块可以实现很酷的效果,但是缺了一点真实感.比如说爆炸特效,仅指望单独的粒子来模拟真实的爆炸效果是 ...

最新文章

  1. Nancy总结(三)Nancy资料介绍
  2. python语言面试基础_【python面试指北】1.语言基础
  3. git 分支合并_教你玩转Git-分支合并
  4. 同方自主可控系统服务器,自主可控 同方超强TR1210服务器!
  5. 常见跨域解决方案以及Ocelot 跨域配置
  6. 随机数公式生成一个负数和正数之间的数_java产生从负数到正数范围的随机数方法...
  7. 真正理解 git fetch, git pull 以及 FETCH_HEAD
  8. xp电脑怎么进入bios
  9. Entity Framework加载相关实体——Explicit Loading
  10. bzoj 2752 9.20考试第三题 高速公路(road)题解
  11. android对象关系映射框架ormlite学习之单表操作
  12. pycharm中安装三方库和cmd下载三方库的选择与区别
  13. 生产企业全流程生产管控_如何通过创建流程使生产率提高10倍
  14. Spark Bloom Filter 测试
  15. fedora如何下载软件
  16. 【博客566】Linux内核系统日志查看方式汇总
  17. linux系统定时器中断优先级,请教定时器中断与串口中断优先级配置问题
  18. matlab提取车牌字符程序,如何用matlab提取和识别车牌数?
  19. 苏州新导RFID仓库管理系统解决方案,黄河水电与新能源的仓库管理
  20. 超快速视频格式转换器

热门文章

  1. Lintcode: Unique Paths
  2. SQL --分支取数据
  3. ubuntu下svn使用指南
  4. android动画Rotate
  5. Gradle: 警告:编码 GBK 的不可映射字符
  6. Android中AVD(Android Virtual Device)不能启动的处理方法
  7. datatable修改csv的最后一列
  8. 正确地启动hadoop
  9. tensorflow学习笔记:tf.control_dependencies,tf.GraphKeys.UPDATE_OPS,tf.get_collection
  10. linux修复u盘文件系统,linux下转换U盘文件系统