Direct3D---三维粒子之雪花

//=============================================================================
// Name: SnowParticleClass.h
//  Des: 一个封装了雪花粒子系统系统的类的头文件
// 2013年 3月31日  Create by 浅墨 
//=============================================================================


#pragma once
#include "D3DUtil.h"
#define  PARTICLE_NUMBER  15000         //雪花粒子数量,显卡不好、运行起来卡的童鞋请取小一点。
#define  SNOW_SYSTEM_LENGTH_X   20000   //雪花飞扬区域的长度
#define  SNOW_SYSTEM_WIDTH_Z    20000   //雪花飞扬区域的宽度
#define  SNOW_SYSTEM_HEIGHT_Y   20000   //雪花飞扬区域的高度

//-------------------------------------------------------------------------------------------------
//雪花粒子的FVF顶点结构和顶点格式
//-------------------------------------------------------------------------------------------------
struct POINTVERTEX
{
    float x, y, z;    //顶点位置
    float u, v ;      //顶点纹理坐标
};
#define D3DFVF_POINTVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)


//-------------------------------------------------------------------------------------------------
// Desc: 雪花粒子结构体的定义
//-------------------------------------------------------------------------------------------------
struct  SNOWPARTICLE
{
    float x, y, z;         //坐标位置
    float RotationY;       //雪花绕自身Y轴旋转角度
    float RotationX;       //雪花绕自身X轴旋转角度
    float FallSpeed;       //雪花下降速度
    float RotationSpeed;   //雪花旋转速度
    int   TextureIndex;    //纹理索引数
};

//-------------------------------------------------------------------------------------------------
// Desc: 粒子系统类的定义
//-------------------------------------------------------------------------------------------------
class SnowParticleClass
{
private:
    LPDIRECT3DDEVICE9        m_pd3dDevice;              //D3D设备对象
    SNOWPARTICLE             m_Snows[PARTICLE_NUMBER];  //雪花粒子数组
    LPDIRECT3DVERTEXBUFFER9  m_pVertexBuffer;           //粒子顶点缓存
    LPDIRECT3DTEXTURE9       m_pTexture[6];             //雪花纹理数组

public:
    SnowParticleClass(LPDIRECT3DDEVICE9 pd3dDevice);    //构造函数
    ~SnowParticleClass();                              //析构函数
    HRESULT InitSnowParticle();                         //粒子系统初始化函数
    HRESULT UpdateSnowParticle( float fElapsedTime);    //粒子系统更新函数
    HRESULT RenderSnowParticle( );                      //粒子系统渲染函数
};                              

//=============================================================================
// Name: SnowParticleClass.cpp
//  Des: 一个封装了雪花粒子系统系统的类的源文件
// 2013年 3月31日  Create by 浅墨 
//=============================================================================

#include "d3dx9.h"
#include "SnowParticleClass.h"


//-------------------------------------------------------------------------------------------------
// Desc: 构造函数
//-------------------------------------------------------------------------------------------------
SnowParticleClass::SnowParticleClass(LPDIRECT3DDEVICE9 pd3dDevice)
{
    //给各个参数赋初值
    m_pd3dDevice=pd3dDevice;
    m_pVertexBuffer=NULL;   
    for(int i=0; i<5; i++)
        m_pTexture[i] = NULL; 
}

//-------------------------------------------------------------------------------------------------
// Name:  SnowParticleClass::InitSnowParticle( )
// Desc: 粒子系统初始化函数
//-------------------------------------------------------------------------------------------------
HRESULT SnowParticleClass::InitSnowParticle( )
{
    //初始化雪花粒子数组
    srand(GetTickCount());
    for(int i=0; i<PARTICLE_NUMBER; i++)
    {   
        m_Snows[i].x        = float(rand()%SNOW_SYSTEM_LENGTH_X-SNOW_SYSTEM_LENGTH_X/2);
        m_Snows[i].z        = float(rand()%SNOW_SYSTEM_WIDTH_Z-SNOW_SYSTEM_WIDTH_Z/2);
        m_Snows[i].y        = float (rand()%SNOW_SYSTEM_HEIGHT_Y);
        m_Snows[i].RotationY   = (rand()%100)/50.0f*D3DX_PI;
        m_Snows[i].RotationX   = (rand()%100)/50.0f*D3DX_PI;
        m_Snows[i].FallSpeed   = 300.0f + rand()%500;
        m_Snows[i].RotationSpeed   = 5.0f +  rand()%10/10.0f;
        m_Snows[i].TextureIndex = rand()%6;
    }


    //创建雪花粒子顶点缓存
    m_pd3dDevice->CreateVertexBuffer( 4*sizeof(POINTVERTEX), 0, 
        D3DFVF_POINTVERTEX,D3DPOOL_MANAGED, &m_pVertexBuffer, NULL );

    //填充雪花粒子顶点缓存
    POINTVERTEX vertices[] =
    {
        { -30.0f, 0.0f, 0.0f,   0.0f, 1.0f, },
        { -30.0f, 60.0f, 0.0f,  0.0f, 0.0f, },
        {  30.0f, 0.0f, 0.0f,   1.0f, 1.0f, }, 
        {  30.0f, 60.0f, 0.0f,  1.0f, 0.0f, }
    };
    //加锁
    VOID* pVertices;
    m_pVertexBuffer->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 );
    //访问
    memcpy( pVertices, vertices, sizeof(vertices) );
    //解锁
    m_pVertexBuffer->Unlock();

    //创建6种雪花纹理
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow1.jpg", &m_pTexture[0] );
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow2.jpg", &m_pTexture[1] );
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow3.jpg", &m_pTexture[2] );
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow4.jpg", &m_pTexture[3] );
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow5.jpg", &m_pTexture[4] );
    D3DXCreateTextureFromFile( m_pd3dDevice, L"GameMedia\\snow6.jpg", &m_pTexture[5] );

    return S_OK;
}


//-------------------------------------------------------------------------------------------------
// Name:  SnowParticleClass::UpdateSnowParticle( )
// Desc: 粒子系统更新函数
//-------------------------------------------------------------------------------------------------
HRESULT SnowParticleClass::UpdateSnowParticle( float fElapsedTime)
{

    //一个for循环,更新每个雪花粒子的当前位置和角度
    for(int i=0; i<PARTICLE_NUMBER; i++)
    {
        m_Snows[i].y -= m_Snows[i].FallSpeed*fElapsedTime;

        //如果雪花粒子落到地面, 重新将其高度设置为最大
        if(m_Snows[i].y<0)
            m_Snows[i].y = SNOW_SYSTEM_WIDTH_Z;
        //更改自旋角度
        m_Snows[i].RotationY    += m_Snows[i].RotationSpeed * fElapsedTime;
        m_Snows[i].RotationX  += m_Snows[i].RotationSpeed * fElapsedTime;
    }

    return S_OK;
}


//-------------------------------------------------------------------------------------------------
// Name:  SnowParticleClass::RenderSnowParticle( )
// Desc: 粒子系统渲染函数
//-------------------------------------------------------------------------------------------------
HRESULT SnowParticleClass::RenderSnowParticle(  )
{
    //禁用照明效果
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, false );

    //设置纹理状态
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1) //将纹理颜色混合的第一个参数的颜色值用于输出
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );   //纹理颜色混合的第一个参数的值就取纹理颜色值
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );      //缩小过滤状态采用线性纹理过滤
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );      //放大过滤状态采用线性纹理过滤

    //设置Alpha混合系数,透明贴图,将图片背景黑色去掉
    m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);   //打开Alpha混合
    m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);   //源混合系数设为1
    m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);  //目标混合系数设为1

    //设置背面消隐剔除模式为不剔除任何面
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

    //渲染雪花
    for(int i=0; i<PARTICLE_NUMBER; i++)
    {
        //构造并设置当前雪花粒子的世界矩阵
        static D3DXMATRIX matYaw, matPitch, matTrans, matWorld;
        D3DXMatrixRotationY(&matYaw, m_Snows[i].RotationY);
        D3DXMatrixRotationX(&matPitch, m_Snows[i].RotationX);
        D3DXMatrixTranslation(&matTrans, m_Snows[i].x, m_Snows[i].y, m_Snows[i].z);
        matWorld = matYaw * matPitch * matTrans;
        m_pd3dDevice->SetTransform( D3DTS_WORLD,  &matWorld);

        //渲染当前雪花粒子
        m_pd3dDevice->SetTexture( 0, m_pTexture[m_Snows[i].TextureIndex] );         //设置纹理
        m_pd3dDevice->SetStreamSource(0, m_pVertexBuffer, 0, sizeof(POINTVERTEX));  //把包含的几何体信息的顶点缓存和渲染流水线相关联  
        m_pd3dDevice->SetFVF(D3DFVF_POINTVERTEX);                 //设置FVF灵活顶点格式
        //从第0个点开始用D3DPT_TRIANGLELIST 模式渲染2个三角形
        m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);   //绘制

    }

    //恢复相关渲染状态:Alpha混合 、剔除状态、光照
    m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, true );

    return S_OK;
}

//-------------------------------------------------------------------------------------------------
// Desc: 析构函数
//-------------------------------------------------------------------------------------------------
SnowParticleClass::~SnowParticleClass()
{
    SAFE_RELEASE(m_pVertexBuffer);

    for(int i=0;i<3; i++)
    {
        SAFE_RELEASE(m_pTexture[i]);
    }
}

调用:

描述:全局变量的声明

SnowParticleClass*  g_pSnowParticles = NULL;  //雪花粒子系统的指针实例

Objects_Init()
描述:渲染资源初始化函数,在此函数中进行要被渲染的物体的资源的初始化

//创建并初始化雪花粒子系统
    g_pSnowParticles = new SnowParticleClass(g_pd3dDevice);
    g_pSnowParticles->InitSnowParticle();

Direct3D_Render()
描述:使用Direct3D进行渲染

//绘制雪花粒子系统
    g_pSnowParticles->UpdateSnowParticle(fTimeDelta);
    g_pSnowParticles->RenderSnowParticle();

WinMain()

//消息循环过程
    MSG msg = { 0 };  //初始化msg
    while( msg.message != WM_QUIT )         //使用while循环
    {
        static FLOAT fLastTime  = (float)::timeGetTime();
        static FLOAT fCurrTime  = (float)::timeGetTime();
        static FLOAT fTimeDelta = 0.0f;
        fCurrTime  = (float)::timeGetTime();
        fTimeDelta = (fCurrTime - fLastTime) / 1000.0f;
        fLastTime  = fCurrTime;

        if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。
        {
            TranslateMessage( &msg );       //将虚拟键消息转换为字符消息
            DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。
        }
        else
        {
            Direct3D_Update(hwnd,fTimeDelta);         //调用更新函数,进行画面的更新
            Direct3D_Render(hwnd,fTimeDelta);         //调用渲染函数,进行画面的渲染          
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值