www.pudn.com > fluid.rar > Substance2D.cpp, change:2006-10-28,size:5710b
#include "stableHeader.h"
#include "Substance2D.h"
#include "DTKUtil.h"
#include "DTKScreenAlignedQuad.h"
namespace DTK
{
Substance2D::Substance2D(uint uWidth ,uint uHeight )
:m_uWidth(uWidth),
m_uHeight(uHeight),
m_uCurSrc(0),
m_dissipate(0.95f),
m_unit(1.0f,1.0f),
m_bNeedInject(false),
m_pD3DDevice(NULL),
m_pShader(NULL)
{
for (uint uBuf=0; uBuf<BUFFER_NUM; ++uBuf)
{
m_apSubstanceTex[uBuf]= NULL;
m_apSubstanceSurf[uBuf]= NULL;
}
}
Substance2D::~Substance2D()
{
}
void Substance2D::reset()
{
clearRenderTarget(m_apSubstanceSurf[s0()]);
}
void Substance2D::setUint(Vector2 unit)
{
m_unit = unit;
}
void Substance2D::setDissipation(float dis)
{
m_dissipate =dis;
}
void Substance2D::injectSource(const Substance2D::PointSource& src)
{
m_src = src;
m_bNeedInject = true;
}
void Substance2D::timeStep(IDirect3DTexture9* pVelField,float dt)
{
assert(m_pD3DDevice);
assert(m_pShader);
HRESULT hr;
DTK::RenderTargetStateBlock rtsb;
rtsb.capture(m_pD3DDevice,1);
float sTexSize[] = {m_uWidth,m_uHeight};
float sTexelSize[]={1.0f/sTexSize[0],1.0f/sTexSize[1]};
D3DSURFACE_DESC desc;
V(pVelField->GetLevelDesc(0,&desc));
float vTexSize[]={desc.Width,desc.Height};
float vTexelSize[]={1.0f/vTexSize[0],1.0f/vTexSize[1]};
V(m_pShader->SetTechnique(m_hSubstanceTech));
V(m_pShader->SetFloatArray(m_hSTexSize,sTexSize,2));
V(m_pShader->SetFloatArray(m_hSTexelSize,sTexelSize,2));
V(m_pShader->SetFloatArray(m_hVTexSize,vTexSize,2));
V(m_pShader->SetFloatArray(m_hVTexelSize,vTexelSize,2));
if (m_bNeedInject)
{
V(m_pShader->SetFloatArray(m_hSrcColor,
reinterpret_cast<const float*>(&m_src.m_s),4));
V(m_pShader->SetFloatArray(m_hSrcPos,
reinterpret_cast<const float*>(&m_src.m_pos_rt),2));
V(m_pShader->SetFloat(m_hSrcR,m_src.m_r));
V(m_pShader->SetTexture(m_hSubstanceTex,m_apSubstanceTex[s0()]));
V(m_pD3DDevice->SetRenderTarget(0,m_apSubstanceSurf[s1()]));
V(m_pShader->Begin(NULL,NULL));
V(m_pShader->BeginPass(0));
DTK::ScreenAlignedQuad::instance().draw();
V(m_pShader->EndPass());
V(m_pShader->End());
loop_s0(s1());
m_bNeedInject = false;
}
//time step
//------------------------------------------------------------------------------
V(m_pShader->SetFloat(m_hDis,m_dissipate));
V(m_pShader->SetFloatArray(m_hUnit,reinterpret_cast<const float*>(&m_unit),2));
V(m_pShader->SetFloat(m_hDt,dt));
V(m_pShader->SetTexture(m_hVelFieldTex,pVelField));
V(m_pShader->SetTexture(m_hSubstanceTex,m_apSubstanceTex[s0()]));
V(m_pD3DDevice->SetRenderTarget(0,m_apSubstanceSurf[s1()]));
V(m_pShader->Begin(NULL,NULL));
V(m_pShader->BeginPass(1));
DTK::ScreenAlignedQuad::instance().draw();
V(m_pShader->EndPass());
V(m_pShader->End());
loop_s0(s1());
rtsb.restore(m_pD3DDevice);
}
IDirect3DTexture9* Substance2D::getSubstance()
{
return m_apSubstanceTex[s0()];
}
void Substance2D::createShader()
{
assert(m_pD3DDevice);
HRESULT hr;
SAFE_RELEASE(m_pShader);
DWORD dwShaderFlags = NULL;
//dwShaderFlags |= D3DXSHADER_NO_PRESHADER | D3DXSHADER_PREFER_FLOW_CONTROL;
//dwShaderFlags |= D3DXFX_NOT_CLONEABLE;
//dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT | D3DXSHADER_DEBUG;
//dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT | D3DXSHADER_DEBUG;
V(D3DXCreateEffectFromFile(m_pD3DDevice,L"../shader/substance.fx",NULL,NULL,dwShaderFlags,NULL,
&m_pShader,NULL));
m_hSrcColor = m_pShader->GetParameterByName(NULL,"g_srcColor");
m_hSrcPos = m_pShader->GetParameterByName(NULL,"g_srcPos_rt");
m_hSrcR = m_pShader->GetParameterByName(NULL,"g_srcR");
m_hDis = m_pShader->GetParameterByName(NULL,"g_dis");
m_hUnit = m_pShader->GetParameterByName(NULL,"g_unit");
m_hDt = m_pShader->GetParameterByName(NULL,"g_dt");
m_hVelFieldTex = m_pShader->GetParameterByName(NULL,"velFieldTex");
m_hSubstanceTex = m_pShader->GetParameterByName(NULL,"substanceTex");
m_hSTexSize = m_pShader->GetParameterByName(NULL,"g_sTexSize");
m_hSTexelSize = m_pShader->GetParameterByName(NULL,"g_sTexelSize");
m_hVTexSize = m_pShader->GetParameterByName(NULL,"g_vTexSize");
m_hVTexelSize = m_pShader->GetParameterByName(NULL,"g_vTexelSize");
m_hSubstanceTech = m_pShader->GetTechniqueByName("substance");
}
void Substance2D::onCreateDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc , void* pUserContext )
{
assert(m_pD3DDevice == NULL);
m_pD3DDevice = pd3dDevice;
assert(m_pD3DDevice);
createShader();
}
void Substance2D::onResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
assert(m_pD3DDevice);
HRESULT hr;
m_pShader->OnResetDevice();
for (uint uBuf=0; uBuf<BUFFER_NUM; ++uBuf)
{
SAFE_RELEASE(m_apSubstanceTex[uBuf]);
SAFE_RELEASE(m_apSubstanceSurf[uBuf]);
V(D3DXCreateTexture(m_pD3DDevice,m_uWidth,m_uHeight,1,D3DUSAGE_RENDERTARGET,D3DFMT_A16B16G16R16F,
D3DPOOL_DEFAULT,m_apSubstanceTex+uBuf));
V(m_apSubstanceTex[uBuf]->GetSurfaceLevel(0,m_apSubstanceSurf+uBuf));
}
reset();
}
void Substance2D::onLostDevice( void* pUserContext )
{
m_pShader->OnLostDevice();
for (uint uBuf=0; uBuf<BUFFER_NUM; ++uBuf)
{
SAFE_RELEASE(m_apSubstanceTex[uBuf]);
SAFE_RELEASE(m_apSubstanceSurf[uBuf]);
}
}
void Substance2D::onDestroyDevice( void* pUserContext )
{
SAFE_RELEASE(m_pShader);
}
}