. . . . . . . . . . . . . . Blog Garden' C plus plus (My technology Impire!)

................................................................ It‘s a age of economic globalization and Infomation globalization........................................

[引] 微软DirectX9.0中粒子系统示例的源代码注释

[引] 微软DirectX9.0中粒子系统示例的源代码注释

创建点精灵顶点结构与顶点FVF

struct POINTVERTEX

{

    D3DXVECTOR3 v;

    D3DCOLOR    color;

 

    static const DWORD FVF;

};

const DWORD POINTVERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

 

粒子结构:

struct PARTICLE

{

    BOOL        m_bSpark;     // spark火星,是指主粒子碰撞到地面后能量较弱的粒子

 

    D3DXVECTOR3 m_vPos;       // Current position当前位置

    D3DXVECTOR3 m_vVel;       // Current velocity当前速度

 

    D3DXVECTOR3 m_vPos0;      // Initial position初始位置

    D3DXVECTOR3 m_vVel0;      // Initial velocity初始速度

    FLOAT       m_fTime0;     // Time of creation创建时间

 

    D3DXCOLOR   m_clrDiffuse; // Initial diffuse color初始散射光颜色

    D3DXCOLOR   m_clrFade;    // Faded diffuse color消失时颜色

    FLOAT       m_fFade;      // Fade progression消隐进程

 

    PARTICLE*   m_pNext;      // Next particle in list下一粒子指针

};

 

 

enum PARTICLE_COLORS { COLOR_WHITE, COLOR_RED, COLOR_GREEN, COLOR_BLUE, NUM_COLORS };

 

 

D3DXCOLOR g_clrColor[NUM_COLORS] =

{

    D3DXCOLOR( 1.0f,   1.0f,   1.0f,   1.0f ),

    D3DXCOLOR( 1.0f,   0.5f,   0.5f,   1.0f ),

    D3DXCOLOR( 0.5f,   1.0f,   0.5f,   1.0f ),

    D3DXCOLOR( 0.125f, 0.5f,   1.0f,   1.0f )

};

 

 

DWORD g_clrColorFade[NUM_COLORS] =

{

    D3DXCOLOR( 1.0f,   0.25f,   0.25f,   1.0f ),

    D3DXCOLOR( 1.0f,   0.25f,   0.25f,   1.0f ),

    D3DXCOLOR( 0.25f,  0.75f,   0.25f,   1.0f ),

    D3DXCOLOR( 0.125f, 0.25f,   0.75f,   1.0f )

};

 

粒子管理系统:

class CParticleSystem

{

protected:

    FLOAT     m_fRadius;

 

    DWORD     m_dwBase;  //顶点缓冲区的基值

       DWORD     m_dwFlush;  //顶点缓冲区的块的大小

    DWORD     m_dwDiscard;     //顶点缓冲区的大小

 

    DWORD     m_dwParticles;    //活动粒子的数目

    DWORD     m_dwParticlesLim;     //活动粒子数目限制

    PARTICLE* m_pParticles;//活动粒子链表

    PARTICLE* m_pParticlesFree;//消亡粒子链表

 

    // Geometry

    LPDIRECT3DVERTEXBUFFER9 m_pVB;

 

public:

    CParticleSystem( DWORD dwFlush, DWORD dwDiscard, FLOAT fRadius );

   ~CParticleSystem();

 

    HRESULT RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice );

    HRESULT InvalidateDeviceObjects();

//更新函数

    HRESULT Update( FLOAT fSecsPerFrame, DWORD dwNumParticlesToEmit,

                  const D3DXCOLOR &dwEmitColor, const D3DXCOLOR &dwFadeColor,

                    FLOAT fEmitVel, D3DXVECTOR3 vPosition );

//渲染函数

    HRESULT Render( LPDIRECT3DDEVICE9 pd3dDevice );

};

 

class CMyD3DApplication中有关粒子的成员:

   // Particle stuff

    LPDIRECT3DTEXTURE9       m_pParticleTexture;

    CParticleSystem*           m_pParticleSystem;

    DWORD                 m_dwNumParticlesToEmit;

    DWORD                 m_dwParticleColor;

    BOOL                    m_bAnimateEmitter;

 

    BYTE                    m_bKey[256];

    BOOL                    m_bDrawReflection;

    BOOL                    m_bCanDoAlphaBlend;

BOOL                    m_bDrawHelp;

 

CMyD3DApplication::CMyD3DApplication()中:(用于粒子结构中某些变量的初始化)

    m_pParticleSystem      = new CParticleSystem( 512, 2048, 0.03f );

    m_pParticleTexture     = NULL;

    m_dwNumParticlesToEmit = 10;

    m_bAnimateEmitter      = FALSE;

m_dwParticleColor      = COLOR_WHITE;

 

    m_bDrawReflection      = FALSE;

    m_bCanDoAlphaBlend     = FALSE;

    m_bDrawHelp            = FALSE;

 

CMyD3DApplication::InitDeviceObjects()中:

   if( FAILED( D3DUtil_CreateTexture( m_pd3dDevice, _T("Particle.bmp"),

                                       &m_pParticleTexture ) ) )           //创建了所使用了纹理

        return D3DAPPERR_MEDIANOTFOUND;

//查询是否能够使用Alpha混合

m_bCanDoAlphaBlend = (m_d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA) &&

 (m_d3dCaps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA);

if( m_bCanDoAlphaBlend )

    m_bDrawReflection = TRUE;

 

CMyD3DApplication::RestoreDeviceObjects()中:

    // Initialize the particle system

    if( FAILED( hr = m_pParticleSystem->RestoreDeviceObjects( m_pd3dDevice ) ) )

        return hr;

 

CMyD3DApplication::FrameMove()中:

HRESULT CMyD3DApplication::FrameMove()

{

    // Slow things down for the REF device如果使用REF,将速度减慢

    if( m_d3dCaps.DeviceType == D3DDEVTYPE_REF )

        m_fElapsedTime = 0.05f;

 

    // Determine emitter position确定发射位置

    D3DXVECTOR3 vEmitterPostion( 0.0f, 0.0f, 0.f );

    if( m_bAnimateEmitter )             //如果为动态发射,发射位置为圆形轨道

        vEmitterPostion = D3DXVECTOR3( 3*sinf(m_fTime), 0.0f, 3*cosf(m_fTime) );

 

    // Update particle system更新粒子系统

m_pParticleSystem->Update(m_fElapsedTime,  m_dwNumParticlesToEmit,  g_clrColor[m_dwParticleColor],

g_clrColorFade[m_dwParticleColor], 8.0f, vEmitterPostion );

    return S_OK;

}

 

 

CMyD3DApplication::Render()中:

 

   // Draw reflection of particles渲染反射粒子

    if( m_bDrawReflection )             //如果支持alpha混合,才能够渲染反射粒子

    {

        D3DXMATRIXA16 matReflectedView;

        D3DXMatrixReflect( &matReflectedView, &m_planeGround );

        D3DXMatrixMultiply( &matReflectedView, &matReflectedView, &m_matView );       

   

        m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

        m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );

        m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );

        m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

 

        m_pd3dDevice->SetTransform( D3DTS_VIEW, &matReflectedView );

        m_pd3dDevice->SetTexture( 0, m_pParticleTexture );

        m_pParticleSystem->Render( m_pd3dDevice );

 

        m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );

        m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );//不使用alpha混合

    }

 

 

    // Draw the ground

    if( m_bDrawReflection )

    {

        m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );//打开alpha混合

        m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );

        m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    }

 

    m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );

    m_pd3dDevice->SetTexture( 0, m_pGroundTexture );

    m_pd3dDevice->SetFVF( COLORVERTEX::FVF );

    m_pd3dDevice->SetStreamSource( 0, m_pGroundVB, 0, sizeof(COLORVERTEX) );

    m_pd3dDevice->SetIndices( m_pGroundIB );

m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, m_dwNumGroundVertices, 0,

m_dwNumGroundIndices/3 );

 

 

    // Draw particles

    m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );

    m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );

    m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );

 

    m_pd3dDevice->SetTexture(0, m_pParticleTexture );

    m_pParticleSystem->Render( m_pd3dDevice );

 

    m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );

    m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

 

 

CParticleSystem类的实现:

CParticleSystem::CParticleSystem( DWORD dwFlush, DWORD dwDiscard, float fRadius ) //512, 2048, 0.03

{

    m_fRadius        = fRadius;    //粒子的半径,初始值为0.03

 

    m_dwBase         = dwDiscard;   //顶点缓冲区的基值,初始值为2048

    m_dwFlush        = dwFlush;        //顶点缓冲区的块的大小,初始值为512

       m_dwDiscard      = dwDiscard;     //顶点缓冲区的大小限制,初始值为2048

 

 

    m_dwParticles    = 0; //当前粒子数,初始值为0

    m_dwParticlesLim = 2048; //最多粒子数

 

    m_pParticles     = NULL;//活动粒子链表

    m_pParticlesFree = NULL;  //消亡粒子链表

       m_pVB            = NULL;

}

 

CParticleSystem::~CParticleSystem()

{

       InvalidateDeviceObjects();

 

    while( m_pParticles )

    {

        PARTICLE* pSpark = m_pParticles;

        m_pParticles = pSpark->m_pNext;

        delete pSpark;

    }

 

    while( m_pParticlesFree )

    {

        PARTICLE *pSpark = m_pParticlesFree;

        m_pParticlesFree = pSpark->m_pNext;

        delete pSpark;

    }

}

 

HRESULT CParticleSystem::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )

{

    HRESULT hr;

 

    // Create a vertex buffer for the particle system.  The size of this buffer

    // does not relate to the number of particles that exist.  Rather, the

    // buffer is used as a communication channel with the device. we fill in

    // a bit, and tell the device to draw.  While the device is drawing, we

    // fill in the next bit using NOOVERWRITE.  We continue doing this until

    // we run out of vertex buffer space, and are forced to DISCARD the buffer

// and start over at the beginning.

//为粒子系统创建顶点缓冲区。该缓冲区的大小与已存在粒子的数目无关。

//该缓冲区被用作与设备的沟通通道。我们填写一部分后,告知设备进行渲染。

//当设备进行渲染时,我们通过使用NOOVERWRITE再填写下一部分。

//我们持续这样的过程。直至用完顶点缓冲区的空间,随后强迫DISCARD缓冲区并从新开始。

 

    if(FAILED(hr = pd3dDevice->CreateVertexBuffer( m_dwDiscard *

              sizeof(POINTVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY | D3DUSAGE_POINTS,

        POINTVERTEX::FVF, D3DPOOL_DEFAULT, &m_pVB, NULL )))

       {

        return E_FAIL;

       }

 

    return S_OK;

}

 

HRESULT CParticleSystem::InvalidateDeviceObjects()

{

    SAFE_RELEASE( m_pVB );

 

    return S_OK;

}

 

HRESULT CParticleSystem::Update( FLOAT fSecsPerFrame, //传入值为0.05

DWORD dwNumParticlesToEmit,//传入值为10

                                 const D3DXCOLOR &clrEmitColor,//白色

                                 const D3DXCOLOR &clrFadeColor, //白色

float fEmitVel, //8.0

                                 D3DXVECTOR3 vPosition )  

{

    PARTICLE *pParticle, **ppParticle;

    static float fTime = 0.0f;

    fTime += fSecsPerFrame; //程序运行时间

 

    ppParticle = &m_pParticles; //处理活动粒子链表

 

    while( *ppParticle )

    {

        pParticle = *ppParticle;

 

        // Calculate new position计算粒子新位置

        float fT = fTime - pParticle->m_fTime0; //粒子已生存时间

        float fGravity;

 

        if( pParticle->m_bSpark ) //如果粒子为火星,受重力影响小,消亡快

        {

            fGravity = -5.0f;

            pParticle->m_fFade -= fSecsPerFrame * 2.25f;// 粒子生成时,m_fFade=1.0

        }

        Else               //如果粒子为火花,受重力影响大,消亡慢

        {

            fGravity = -9.8f;

            pParticle->m_fFade -= fSecsPerFrame * 0.25f;

        }

 

        pParticle->m_vPos    = pParticle->m_vVel0 * fT + pParticle->m_vPos0; //粒子位置

        pParticle->m_vPos.y += (0.5f * fGravity) * (fT * fT);            //粒子受重力影响后的位置

        pParticle->m_vVel.y  = pParticle->m_vVel0.y + fGravity * fT; //粒子y方向上的速度

 

        if( pParticle->m_fFade < 0.0f )   

            pParticle->m_fFade = 0.0f;

 

        // Kill old particles去除老粒子(如果粒子为火花且y坐标小于粒子半径,或粒子为火星并已消亡)

        if( pParticle->m_vPos.y < m_fRadius ||            

            pParticle->m_bSpark && pParticle->m_fFade <= 0.0f )

        {

            // Emit sparks如果粒子为火花,则由火花变为火星

            if( !pParticle->m_bSpark )

            {

                for( int i=0; i<4; i++ )  //一个火花生成4个火星

                {

                    PARTICLE *pSpark;

 

                    if( m_pParticlesFree ) //查看消亡粒子链表中是否有粒子

                    {

                        pSpark = m_pParticlesFree;

                        m_pParticlesFree = pSpark->m_pNext;

                    }

                    Else              //如果没有则生成新粒子

                    {

                        if( NULL == ( pSpark = new PARTICLE ) )

                            return E_OUTOFMEMORY;

                    }

 

//将火星插入到活动粒子链表

                    pSpark->m_pNext = pParticle->m_pNext;

                    pParticle->m_pNext = pSpark;

 

                                   //设置火星初始值

                    pSpark->m_bSpark  = TRUE;

                    pSpark->m_vPos0   = pParticle->m_vPos;    

                    pSpark->m_vPos0.y = m_fRadius;    

 

                    FLOAT fRand1 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 2.00f;

                    FLOAT fRand2 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 0.25f;

 

//计算火星初始速度

                    pSpark->m_vVel0.x  = pParticle->m_vVel.x * 0.25f + cosf(fRand1) * sinf(fRand2);

                    pSpark->m_vVel0.z  = pParticle->m_vVel.z * 0.25f + sinf(fRand1) * sinf(fRand2);

                    pSpark->m_vVel0.y  = cosf(fRand2);

                    pSpark->m_vVel0.y *= ((FLOAT)rand()/(FLOAT)RAND_MAX) * 1.5f;

 

                                   //最初火星的当前位置与速度

                    pSpark->m_vPos = pSpark->m_vPos0;

                    pSpark->m_vVel = pSpark->m_vVel0;

 

                    D3DXColorLerp( &pSpark->m_clrDiffuse, &pParticle->m_clrFade,

                                   &pParticle->m_clrDiffuse, pParticle->m_fFade );

                    pSpark->m_clrFade = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);

                    pSpark->m_fFade   = 1.0f;

                    pSpark->m_fTime0  = fTime;

                }

            }

 

            // Kill particle将该粒子从活动粒子链表中删除,添加到消亡粒子链表

            *ppParticle = pParticle->m_pNext;

            pParticle->m_pNext = m_pParticlesFree;

            m_pParticlesFree = pParticle;

 

            if(!pParticle->m_bSpark)

                m_dwParticles--;

        }

        else //如果不需要去除该粒子,则指向下一粒子

        {

            ppParticle = &pParticle->m_pNext;

        }

    }

 

    // Emit new particles产生新粒子(不超过m_dwParticlesLim时,增加dwNumParticlesToEmit个粒子)

    DWORD dwParticlesEmit = m_dwParticles + dwNumParticlesToEmit;

    while( m_dwParticles < m_dwParticlesLim && m_dwParticles < dwParticlesEmit )

    {

        if( m_pParticlesFree )

        {

            pParticle = m_pParticlesFree;

            m_pParticlesFree = pParticle->m_pNext;

        }

        else

        {

            if( NULL == ( pParticle = new PARTICLE ) )

                return E_OUTOFMEMORY;

        }

 

        pParticle->m_pNext = m_pParticles;

        m_pParticles = pParticle;

        m_dwParticles++;

 

        // Emit new particle发射新粒子

        FLOAT fRand1 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 2.0f;

        FLOAT fRand2 = ((FLOAT)rand()/(FLOAT)RAND_MAX) * D3DX_PI * 0.25f;

 

        pParticle->m_bSpark = FALSE;

 

        pParticle->m_vPos0 = vPosition + D3DXVECTOR3( 0.0f, m_fRadius, 0.0f );

 

        pParticle->m_vVel0.x  = cosf(fRand1) * sinf(fRand2) * 2.5f;

        pParticle->m_vVel0.z  = sinf(fRand1) * sinf(fRand2) * 2.5f;

        pParticle->m_vVel0.y  = cosf(fRand2);

        pParticle->m_vVel0.y *= ((FLOAT)rand()/(FLOAT)RAND_MAX) * fEmitVel;

 

        pParticle->m_vPos = pParticle->m_vPos0;

        pParticle->m_vVel = pParticle->m_vVel0;

 

        pParticle->m_clrDiffuse  = clrEmitColor;

        pParticle->m_clrFade    = clrFadeColor;

        pParticle->m_fFade      = 1.0f;

        pParticle->m_fTime0     = fTime;

    }

 

    return S_OK;

}

 

 

//-----------------------------------------------------------------------------

// Name: Render()

// Desc: Renders the particle system using either pointsprites (if supported)

//       or using 4 vertices per particle

//-----------------------------------------------------------------------------

HRESULT CParticleSystem::Render( LPDIRECT3DDEVICE9 pd3dDevice )

{

    HRESULT hr;

 

    // Set the render states for using point sprites设置点精灵的渲染状态

    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, TRUE );

    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  TRUE );

    pd3dDevice->SetRenderState( D3DRS_POINTSIZE,     FtoDW(0.08f) );

    pd3dDevice->SetRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.00f) );

    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_A,  FtoDW(0.00f) );

    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_B,  FtoDW(0.00f) );

    pd3dDevice->SetRenderState( D3DRS_POINTSCALE_C,  FtoDW(1.00f) );

 

    // Set up the vertex buffer to be rendered建立渲染用顶点缓冲区

    pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(POINTVERTEX) );

    pd3dDevice->SetFVF( POINTVERTEX::FVF );

 

    PARTICLE*    pParticle = m_pParticles;

    POINTVERTEX* pVertices;

    DWORD        dwNumParticlesToRender = 0;

 

       // Lock the vertex buffer.  We fill the vertex buffer in small

       // chunks, using D3DLOCK_NOOVERWRITE.  When we are done filling

       // each chunk, we call DrawPrim, and lock the next chunk.  When

       // we run out of space in the vertex buffer, we start over at

       // the beginning, using D3DLOCK_DISCARD.

//锁定顶点缓冲区,通过使用D3DLOCK_NOOVERWRITE,我们将一块块的填充顶点缓存区。

//我们填充完一块后,调用DrawPrimitive,并锁定下一块缓冲区。

//当我们用完顶点缓冲区内的空间后,通过使用D3DLOCK_DISCARD,重新开始。

 

       m_dwBase += m_dwFlush;

 

       if(m_dwBase >= m_dwDiscard)

              m_dwBase = 0;

 

       if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX),

              (void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) )

    {

              return hr;

    }

 

             

 

    // Render each particle渲染粒子

    while( pParticle )

    {

        D3DXVECTOR3 vPos(pParticle->m_vPos);

        D3DXVECTOR3 vVel(pParticle->m_vVel);

        FLOAT       fLengthSq = D3DXVec3LengthSq(&vVel);

        UINT        dwSteps;

 

        if( fLengthSq < 1.0f )       dwSteps = 2;

        else if( fLengthSq <  4.00f ) dwSteps = 3;

        else if( fLengthSq <  9.00f ) dwSteps = 4;

        else if( fLengthSq < 12.25f ) dwSteps = 5;

        else if( fLengthSq < 16.00f ) dwSteps = 6;

        else if( fLengthSq < 20.25f ) dwSteps = 7;

        else                    dwSteps = 8;

 

        vVel *= -0.04f / (FLOAT)dwSteps;     //渲染位置的改变量

 

              //通过插值计算粒子颜色

        D3DXCOLOR clrDiffuse;

        D3DXColorLerp(&clrDiffuse, &pParticle->m_clrFade, &pParticle->m_clrDiffuse, pParticle->m_fFade);

        DWORD dwDiffuse = (DWORD) clrDiffuse;

 

        // Render each particle a bunch of times to get a blurring effect在一段时间内多次渲染一个粒子,获得模糊效果

        for( DWORD i = 0; i < dwSteps; i++ )

        {

            pVertices->v     = vPos;

            pVertices->color = dwDiffuse;

            pVertices++;

 

            if( ++dwNumParticlesToRender == m_dwFlush )

            {

                // Done filling this chunk of the vertex buffer.  Lets unlock and

                // draw this portion so we can begin filling the next chunk.

//如果已经填满了该块顶点缓冲区。将其解锁,并描绘该部分。

//随后我们可以开始填充下一块

 

                m_pVB->Unlock();

 

if(FAILED(hr=pd3dDevice->DrawPrimitive(D3DPT_POINTLIST,m_dwBase,

                                                                      dwNumParticlesToRender)))

                                   return hr;

 

                // Lock the next chunk of the vertex buffer.  If we are at the

                // end of the vertex buffer, DISCARD the vertex buffer and start

                // at the beginning.  Otherwise, specify NOOVERWRITE, so we can

                // continue filling the VB while the previous chunk is drawing.

//锁定下一块顶点缓冲区,如果我们处于顶点缓冲区的末尾,DISCARD该顶点缓冲区,并重新开始。//否则,指定为NOOVERWRITE,在描绘前一块缓冲区后,我们可以继续填充顶点缓冲区。

                            m_dwBase += m_dwFlush;

 

                            if(m_dwBase >= m_dwDiscard)

                                   m_dwBase = 0;

 

                            if( FAILED( hr = m_pVB->Lock( m_dwBase * sizeof(POINTVERTEX), m_dwFlush * sizeof(POINTVERTEX), (void**) &pVertices, m_dwBase ? D3DLOCK_NOOVERWRITE : D3DLOCK_DISCARD ) ) )

                {

                                   return hr;

                }

 

                dwNumParticlesToRender = 0;

            }

 

            vPos += vVel;

        }

 

        pParticle = pParticle->m_pNext;

    }

 

    // Unlock the vertex buffer顶点缓冲区解锁

    m_pVB->Unlock();

 

    // Render any remaining particles渲染剩余顶点缓冲区

    if( dwNumParticlesToRender )

    {

        if(FAILED(hr = pd3dDevice->DrawPrimitive( D3DPT_POINTLIST, m_dwBase, dwNumParticlesToRender )))

                     return hr;

    }

 

    // Reset render states重新设置渲染状态

    pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE );

    pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE,  FALSE );

 

    return S_OK;

}

posted on 2006-10-04 03:39 Technical Consultant 阅读(1577) 评论(0)  编辑 收藏 引用 所属分类: Game Develope & Game Engine


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


My Links

Blog Stats

常用链接

留言簿(3)

随笔分类(47)

随笔档案(45)

文章分类(87)

文章档案(87)

相册

C++

Database

Game Develope & Game Engine

Java

News

Web

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜