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