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