// Shader_Rain.cpp: implementation of the CShader_Rain class. // ////////////////////////////////////////////////////////////////////// #include "Shader_Rain.h" #include "Shader_RainV.h" #include "SceneManager.h" #include "SceneStateMgr.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CShader_Rain::CShader_Rain() { m_pVertexShader = new CShader_RainV; m_pDevice = CSceneManager::GetDevice(); } CShader_Rain::~CShader_Rain() { if(m_pVertexShader != NULL) { delete m_pVertexShader; m_pVertexShader = NULL; } } void CShader_Rain::Apply() { if(m_pVertexShader != NULL) { m_pVertexShader->Apply(); } CSceneStateMgr::_SetD3DRenderState(D3DRS_LIGHTING, FALSE); CSceneStateMgr::_SetD3DRenderState(D3DRS_POINTSPRITEENABLE, TRUE); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSCALEENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.1f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE_MAX, FtoDW(64.0f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE, FtoDW(32.0f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSCALE_A, FtoDW(1.00f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSCALE_B, FtoDW(0.00f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSCALE_C, FtoDW(0.00f) ); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_TEXTURE ); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE, TRUE); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE, FALSE); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); CSceneStateMgr::_SetD3DRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE,D3DCULL_CCW); } void CShader_Rain::UnApply() { ApplyOldState(); CSceneStateMgr::_SetD3DRenderState(D3DRS_POINTSPRITEENABLE, FALSE); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE, FALSE); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE, TRUE); /* CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE_MIN, FtoDW(0.1f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE_MAX, FtoDW(64.0f) ); CSceneStateMgr::_SetD3DRenderState( D3DRS_POINTSIZE, FtoDW(32.0f) ); */ } float CalcTriangleArea(D3DXVECTOR3 vecA,D3DXVECTOR3 vecB,D3DXVECTOR3 vecC) { // ÇÀÇ ¹ýÄ¢(TriangleÀÇ ³ÐÀÌ return) float fS; float fLen[3]; D3DXVECTOR3 vecAB,vecBC,vecCA; vecAB = vecB - vecA; fLen[0] = D3DXVec3Length(&vecAB); vecBC = vecC - vecB; fLen[1] = D3DXVec3Length(&vecBC); vecCA = vecA - vecC; fLen[2] = D3DXVec3Length(&vecCA); fS = (fLen[0] + fLen[1] + fLen[2]) / 2.0f; return (float)sqrt(fS * (fS - fLen[0]) * (fS - fLen[1]) * (fS - fLen[2])); } // Create Rain(Point Sprite)Buffer void CreateRainBuffer(LPDIRECT3DVERTEXBUFFER8 pRainBuffer,DWORD &dwVertsNum,D3DXVECTOR3 *pPos,D3DXVECTOR3 *pNormal,WORD *pIndex,int iIndexNum) { int i; float fArea = 0.0f; D3DXVECTOR3 vecA,vecB,vecC; D3DXVECTOR3 vecNA,vecNB,vecNC; if((pRainBuffer == NULL) || (dwVertsNum == 0)) { if(pRainBuffer != NULL) { pRainBuffer->Release(); pRainBuffer = NULL; } for(i=0; i < iIndexNum; i+=3 ) { vecA = pPos[pIndex[i]]; vecB = pPos[pIndex[i+1]]; vecC = pPos[pIndex[i+2]]; fArea += CalcTriangleArea(vecA,vecB,vecC); } dwVertsNum = (fArea * SPLASH_RATIOS); CSceneManager::GetDevice()->CreateVertexBuffer(dwVertsNum * sizeof(RainVertex),0,0,D3DPOOL_MANAGED,&pRainBuffer); } fArea = 0.0f; RainVertex *pRainVert = NULL; pRainBuffer->Lock(0,0,(BYTE **)&pRainVert,0); for(i = 0; i < iIndexNum; i+=3) { vecA = pPos[pIndex[i]]; vecB = pPos[pIndex[i+1]]; vecC = pPos[pIndex[i+2]]; vecNA = pNormal[pIndex[i]]; vecNB = pNormal[pIndex[i+1]]; vecNC = pNormal[pIndex[i+2]]; fArea += (SPLASH_RATIOS * CalcTriangleArea(vecA,vecB,vecC)); while(fArea > 1.0f) { float fR1,fR2; D3DXVECTOR3 vecS,vecT; fR1 = ((float)(rand() % 1000)) / 1000.0f; fR2 = 1.0f - fR1; fR2 = fR2 * ((float)(rand() % 1000) / 1000.0f); vecS = vecB - vecA; vecT = vecC - vecA; pRainVert->vecPos = D3DXVECTOR3((vecA.x + vecS.x * fR1 + vecT.x * fR2), (vecA.y + vecS.y * fR1 + vecT.y * fR2), (vecA.z + vecS.z * fR1 + vecT.z * fR2)); pRainVert->vecNormal = D3DXVECTOR3(((vecNA.x + vecNB.x + vecNC.x) / 3.0f), ((vecNA.y + vecNB.y + vecNC.y) / 3.0f), ((vecNA.z + vecNB.z + vecNC.z) / 3.0f)); pRainVert->fLoop = (float)(100 + rand() % 900) / 100.0f; fArea -= 1.0f; pRainVert++; } } pRainBuffer->Unlock(); }