1
0
forked from metin2/client
Files
client/GameLib/SnowEnvironment.cpp

354 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();
}