forked from metin2/client
354 lines
11 KiB
C++
354 lines
11 KiB
C++
|
#include "StdAfx.h"
|
|||
|
#include "SnowEnvironment.h"
|
|||
|
|
|||
|
#include "../EterLib/StateManager.h"
|
|||
|
#include "../EterLib/Camera.h"
|
|||
|
#include "../EterLib/ResourceManager.h"
|
|||
|
#include "SnowParticle.h"
|
|||
|
|
|||
|
void CSnowEnvironment::Enable()
|
|||
|
{
|
|||
|
if (!m_bSnowEnable)
|
|||
|
{
|
|||
|
Create();
|
|||
|
}
|
|||
|
|
|||
|
m_bSnowEnable = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::Disable()
|
|||
|
{
|
|||
|
m_bSnowEnable = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::Update(const D3DXVECTOR3 & c_rv3Pos)
|
|||
|
{
|
|||
|
if (!m_bSnowEnable)
|
|||
|
{
|
|||
|
if (m_kVct_pkParticleSnow.empty())
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
m_v3Center=c_rv3Pos;
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::Deform()
|
|||
|
{
|
|||
|
if (!m_bSnowEnable)
|
|||
|
{
|
|||
|
if (m_kVct_pkParticleSnow.empty())
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
const D3DXVECTOR3 & c_rv3Pos=m_v3Center;
|
|||
|
|
|||
|
static long s_lLastTime = CTimer::Instance().GetCurrentMillisecond();
|
|||
|
long lcurTime = CTimer::Instance().GetCurrentMillisecond();
|
|||
|
float fElapsedTime = float(lcurTime - s_lLastTime) / 1000.0f;
|
|||
|
s_lLastTime = lcurTime;
|
|||
|
|
|||
|
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
|||
|
if (!pCamera)
|
|||
|
return;
|
|||
|
|
|||
|
const D3DXVECTOR3 & c_rv3View = pCamera->GetView();
|
|||
|
|
|||
|
D3DXVECTOR3 v3ChangedPos = c_rv3View * 3500.0f + c_rv3Pos;
|
|||
|
v3ChangedPos.z = c_rv3Pos.z;
|
|||
|
|
|||
|
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
|||
|
for (; itor != m_kVct_pkParticleSnow.end();)
|
|||
|
{
|
|||
|
CSnowParticle * pSnow = *itor;
|
|||
|
pSnow->Update(fElapsedTime, v3ChangedPos);
|
|||
|
|
|||
|
if (!pSnow->IsActivate())
|
|||
|
{
|
|||
|
CSnowParticle::Delete(pSnow);
|
|||
|
|
|||
|
itor = m_kVct_pkParticleSnow.erase(itor);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
++itor;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (m_bSnowEnable)
|
|||
|
{
|
|||
|
for (int p = 0; p < min(10, m_dwParticleMaxNum - m_kVct_pkParticleSnow.size()); ++p)
|
|||
|
{
|
|||
|
CSnowParticle * pSnowParticle = CSnowParticle::New();
|
|||
|
pSnowParticle->Init(v3ChangedPos);
|
|||
|
m_kVct_pkParticleSnow.push_back(pSnowParticle);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::__BeginBlur()
|
|||
|
{
|
|||
|
if (!m_bBlurEnable)
|
|||
|
return;
|
|||
|
|
|||
|
ms_lpd3dDevice->GetRenderTarget(&m_lpOldSurface);
|
|||
|
ms_lpd3dDevice->GetDepthStencilSurface(&m_lpOldDepthStencilSurface);
|
|||
|
ms_lpd3dDevice->SetRenderTarget(m_lpSnowRenderTargetSurface, m_lpSnowDepthSurface);
|
|||
|
ms_lpd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
|
|||
|
|
|||
|
STATEMANAGER.SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
|||
|
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
|||
|
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTALPHA);
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::__ApplyBlur()
|
|||
|
{
|
|||
|
if (!m_bBlurEnable)
|
|||
|
return;
|
|||
|
|
|||
|
// {
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_COLORVERTEX ,TRUE);
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE , D3DMCS_COLOR1 );
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
|||
|
// STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
|||
|
// DWORD alphaColor = 0xFFFFFF | ((DWORD)(0.6f*255.0f) << 24);
|
|||
|
//
|
|||
|
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, alphaColor, 0,0) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, alphaColor, 1,0) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, alphaColor, 0,1) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, alphaColor, 1,1) };
|
|||
|
// //<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ؽ<EFBFBD><D8BD>ĸ<EFBFBD> <20><><EFBFBD>´<EFBFBD>.
|
|||
|
// STATEMANAGER.SetTexture(0,m_lpAccumTexture);
|
|||
|
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
|||
|
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
|||
|
// }
|
|||
|
//
|
|||
|
// {
|
|||
|
// STATEMANAGER.SetRenderTarget(m_lpAccumRenderTargetSurface, m_lpAccumDepthSurface);
|
|||
|
//
|
|||
|
// BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f, 0xFFFFFF, 0,0) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(wTextureSize,0.0f,0.0f),1.0f, 0xFFFFFF, 1,0) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(0.0f,wTextureSize,0.0f),1.0f, 0xFFFFFF, 0,1) ,
|
|||
|
// BlurVertex(D3DXVECTOR3(wTextureSize,wTextureSize,0.0f),1.0f, 0xFFFFFF, 1,1) };
|
|||
|
//
|
|||
|
// STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
|||
|
// STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
|
|||
|
// STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
|||
|
// STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
|||
|
// }
|
|||
|
|
|||
|
///////////////
|
|||
|
{
|
|||
|
ms_lpd3dDevice->SetRenderTarget(m_lpOldSurface, m_lpOldDepthStencilSurface);
|
|||
|
|
|||
|
STATEMANAGER.SetTexture(0,m_lpSnowTexture);
|
|||
|
STATEMANAGER.SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
|
|||
|
|
|||
|
D3DSURFACE_DESC desc;
|
|||
|
m_lpOldSurface->GetDesc(&desc);
|
|||
|
float sx = (float)desc.Width ;
|
|||
|
float sy = (float)desc.Height;
|
|||
|
SAFE_RELEASE( m_lpOldSurface );
|
|||
|
SAFE_RELEASE( m_lpOldDepthStencilSurface );
|
|||
|
|
|||
|
BlurVertex V[4] = { BlurVertex(D3DXVECTOR3(0.0f,0.0f,0.0f),1.0f ,0xFFFFFF, 0,0) ,
|
|||
|
BlurVertex(D3DXVECTOR3(sx,0.0f,0.0f),1.0f ,0xFFFFFF, 1,0) ,
|
|||
|
BlurVertex(D3DXVECTOR3(0.0f,sy,0.0f),1.0f ,0xFFFFFF, 0,1) ,
|
|||
|
BlurVertex(D3DXVECTOR3(sx,sy,0.0f),1.0f ,0xFFFFFF, 1,1) };
|
|||
|
|
|||
|
STATEMANAGER.SetVertexShader( D3DFVF_XYZRHW | D3DFVF_DIFFUSE|D3DFVF_TEX1 );
|
|||
|
STATEMANAGER.DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,V,sizeof(BlurVertex));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::Render()
|
|||
|
{
|
|||
|
if (!m_bSnowEnable)
|
|||
|
{
|
|||
|
if (m_kVct_pkParticleSnow.empty())
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
__BeginBlur();
|
|||
|
|
|||
|
DWORD dwParticleCount = min(m_dwParticleMaxNum, m_kVct_pkParticleSnow.size());
|
|||
|
|
|||
|
CCamera * pCamera = CCameraManager::Instance().GetCurrentCamera();
|
|||
|
if (!pCamera)
|
|||
|
return;
|
|||
|
|
|||
|
const D3DXVECTOR3 & c_rv3Up = pCamera->GetUp();
|
|||
|
const D3DXVECTOR3 & c_rv3Cross = pCamera->GetCross();
|
|||
|
|
|||
|
SParticleVertex * pv3Verticies;
|
|||
|
if (SUCCEEDED(m_pVB->Lock(0, sizeof(SParticleVertex)*dwParticleCount*4, (BYTE **) &pv3Verticies, D3DLOCK_DISCARD)))
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
std::vector<CSnowParticle*>::iterator itor = m_kVct_pkParticleSnow.begin();
|
|||
|
for (; i < dwParticleCount && itor != m_kVct_pkParticleSnow.end(); ++i, ++itor)
|
|||
|
{
|
|||
|
CSnowParticle * pSnow = *itor;
|
|||
|
pSnow->SetCameraVertex(c_rv3Up, c_rv3Cross);
|
|||
|
pSnow->GetVerticies(pv3Verticies[i*4+0],
|
|||
|
pv3Verticies[i*4+1],
|
|||
|
pv3Verticies[i*4+2],
|
|||
|
pv3Verticies[i*4+3]);
|
|||
|
}
|
|||
|
m_pVB->Unlock();
|
|||
|
}
|
|||
|
|
|||
|
STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
|||
|
STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
|||
|
STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
|||
|
STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
|||
|
STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
|||
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
|||
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
|
|||
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
|||
|
STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
|||
|
STATEMANAGER.SetTexture(1, NULL);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
|||
|
STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
|||
|
|
|||
|
m_pImageInstance->GetGraphicImagePointer()->GetTextureReference().SetTextureStage(0);
|
|||
|
STATEMANAGER.SetIndices(m_pIB, 0);
|
|||
|
STATEMANAGER.SetStreamSource(0, m_pVB, sizeof(SParticleVertex));
|
|||
|
STATEMANAGER.SetVertexShader(D3DFVF_XYZ | D3DFVF_TEX1);
|
|||
|
STATEMANAGER.DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, dwParticleCount*4, 0, dwParticleCount*2);
|
|||
|
STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE);
|
|||
|
STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE);
|
|||
|
STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE);
|
|||
|
|
|||
|
__ApplyBlur();
|
|||
|
}
|
|||
|
|
|||
|
bool CSnowEnvironment::__CreateBlurTexture()
|
|||
|
{
|
|||
|
if (!m_bBlurEnable)
|
|||
|
return true;
|
|||
|
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpSnowTexture)))
|
|||
|
return false;
|
|||
|
if (FAILED(m_lpSnowTexture->GetSurfaceLevel(0, &m_lpSnowRenderTargetSurface)))
|
|||
|
return false;
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpSnowDepthSurface)))
|
|||
|
return false;
|
|||
|
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateTexture(m_wBlurTextureSize, m_wBlurTextureSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &m_lpAccumTexture)))
|
|||
|
return false;
|
|||
|
if (FAILED(m_lpAccumTexture->GetSurfaceLevel(0, &m_lpAccumRenderTargetSurface)))
|
|||
|
return false;
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateDepthStencilSurface(m_wBlurTextureSize, m_wBlurTextureSize, D3DFMT_D16, D3DMULTISAMPLE_NONE, &m_lpAccumDepthSurface)))
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CSnowEnvironment::__CreateGeometry()
|
|||
|
{
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateVertexBuffer(sizeof(SParticleVertex)*m_dwParticleMaxNum*4,
|
|||
|
D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY,
|
|||
|
D3DFVF_XYZ | D3DFVF_TEX1,
|
|||
|
D3DPOOL_SYSTEMMEM,
|
|||
|
&m_pVB)))
|
|||
|
return false;
|
|||
|
|
|||
|
if (FAILED(ms_lpd3dDevice->CreateIndexBuffer(sizeof(WORD)*m_dwParticleMaxNum*6,
|
|||
|
D3DUSAGE_WRITEONLY,
|
|||
|
D3DFMT_INDEX16,
|
|||
|
D3DPOOL_MANAGED,
|
|||
|
&m_pIB)))
|
|||
|
return false;
|
|||
|
|
|||
|
WORD* dstIndices;
|
|||
|
if (FAILED(m_pIB->Lock(0, sizeof(WORD)*m_dwParticleMaxNum*6, (BYTE**)&dstIndices, 0)))
|
|||
|
return false;
|
|||
|
|
|||
|
const WORD c_awFillRectIndices[6] = { 0, 2, 1, 2, 3, 1, };
|
|||
|
for (int i = 0; i < m_dwParticleMaxNum; ++i)
|
|||
|
{
|
|||
|
for (int j = 0; j < 6; ++j)
|
|||
|
{
|
|||
|
dstIndices[i*6 + j] = i*4 + c_awFillRectIndices[j];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
m_pIB->Unlock();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool CSnowEnvironment::Create()
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
|
|||
|
if (!__CreateBlurTexture())
|
|||
|
return false;
|
|||
|
|
|||
|
if (!__CreateGeometry())
|
|||
|
return false;
|
|||
|
|
|||
|
CGraphicImage * pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer("d:/ymir work/special/snow.dds");
|
|||
|
m_pImageInstance = CGraphicImageInstance::New();
|
|||
|
m_pImageInstance->SetImagePointer(pImage);
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::Destroy()
|
|||
|
{
|
|||
|
SAFE_RELEASE(m_lpSnowTexture);
|
|||
|
SAFE_RELEASE(m_lpSnowRenderTargetSurface);
|
|||
|
SAFE_RELEASE(m_lpSnowDepthSurface);
|
|||
|
SAFE_RELEASE(m_lpAccumTexture);
|
|||
|
SAFE_RELEASE(m_lpAccumRenderTargetSurface);
|
|||
|
SAFE_RELEASE(m_lpAccumDepthSurface);
|
|||
|
SAFE_RELEASE(m_pVB);
|
|||
|
SAFE_RELEASE(m_pIB);
|
|||
|
|
|||
|
stl_wipe(m_kVct_pkParticleSnow);
|
|||
|
CSnowParticle::DestroyPool();
|
|||
|
|
|||
|
if (m_pImageInstance)
|
|||
|
{
|
|||
|
CGraphicImageInstance::Delete(m_pImageInstance);
|
|||
|
m_pImageInstance = NULL;
|
|||
|
}
|
|||
|
|
|||
|
__Initialize();
|
|||
|
}
|
|||
|
|
|||
|
void CSnowEnvironment::__Initialize()
|
|||
|
{
|
|||
|
m_bSnowEnable = FALSE;
|
|||
|
m_lpSnowTexture = NULL;
|
|||
|
m_lpSnowRenderTargetSurface = NULL;
|
|||
|
m_lpSnowDepthSurface = NULL;
|
|||
|
m_lpAccumTexture = NULL;
|
|||
|
m_lpAccumRenderTargetSurface = NULL;
|
|||
|
m_lpAccumDepthSurface = NULL;
|
|||
|
m_pVB = NULL;
|
|||
|
m_pIB = NULL;
|
|||
|
m_pImageInstance = NULL;
|
|||
|
|
|||
|
m_kVct_pkParticleSnow.reserve(m_dwParticleMaxNum);
|
|||
|
}
|
|||
|
|
|||
|
CSnowEnvironment::CSnowEnvironment()
|
|||
|
{
|
|||
|
m_bBlurEnable = FALSE;
|
|||
|
m_dwParticleMaxNum = 3000;
|
|||
|
m_wBlurTextureSize = 512;
|
|||
|
|
|||
|
__Initialize();
|
|||
|
}
|
|||
|
CSnowEnvironment::~CSnowEnvironment()
|
|||
|
{
|
|||
|
Destroy();
|
|||
|
}
|