// WBWaterNormalTexGenerator.cpp: implementation of the WBWaterNormalTexGenerator class. // ////////////////////////////////////////////////////////////////////// #include "./WBWaterNormalTexGenerator.h" #include "./WBWaterNormalTexGenVShader.h" #include "SceneManager.h" #include "SceneStateMgr.h" /*#include "WBShaderConst.h" #include "WBRenderState.h" */ ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// WBWaterNormalTexGenerator::WBWaterNormalTexGenerator() { int i; m_pDevice = NULL; m_pBackColorSurf = NULL; m_pBackDepthSurf = NULL; memset(m_strDisplaceMap,0,sizeof(char) * 256); m_pDisplaceMap = NULL; m_pQuadBuffer = NULL; D3DXMatrixIdentity(&m_matWorldViewProject); for(i = 0; i < RENDERTARGET_NUM; i++ ) { m_pRenderTargetTex[i] = NULL; m_pRenderTargetSurf[i] = NULL; } m_fTexelSizeX = 1.0f; m_fTexelSizeY = 1.0f; m_fBlurDist = 0.1100f; // Bluring Wave m_pFocusTexSrc = NULL; m_iFlipState = 0; // m_pVShader = NULL; m_pShader = NULL; } WBWaterNormalTexGenerator::~WBWaterNormalTexGenerator() { } void WBWaterNormalTexGenerator::Init(LPDIRECT3DDEVICE8 pDevice,int iSizeX,int iSizeY,char *strDisplaceMap) { int i; if(pDevice != NULL) { for(i = 0; i < 5; i++ ) { // Texture Coord Init for(int j = 0; j < 4 ; j++ ) { m_TextureCoord[i].m_vecOffset[j] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f); } } //m_pVShader = new WBWaterNormalTexGenVShader; m_pShader = new WBWaterNormalTexGenShader; m_iFlipState = 0; m_pDevice = pDevice; m_iTexSizeX = iSizeX; m_iTexSizeY = iSizeY; strcpy(m_strDisplaceMap,strDisplaceMap); m_DropWaters.clear(); m_iChangeState = 0; m_fNormalSTScale = 0.8f; m_fScrollU = 0.0f; m_fScrollV = 0.0f; m_fDropletMinSize = 0.25f; m_fDropletMaxSize = 0.35f; /* m_fDropletMinSize = 0.05f; m_fDropletMaxSize = 0.35f; */ /* m_fDropletMinSize = 0.25f; m_fDropletMaxSize = 0.65f; */ m_fWindX = 0.0f; m_fWindY = 0.0f; /* m_fWindX = 0.001f; m_fWindY = 0.01f; */ m_pDevice->GetRenderTarget(&m_pBackColorSurf); m_pDevice->GetDepthStencilSurface(&m_pBackDepthSurf); LoadDisplaceMap(); CreateRenderTexture(iSizeX,iSizeY); CreateVertex(); CreateMatrix(); CreateUvOffset(iSizeX,iSizeY); // Texture Clear m_iFocusTexSrc = 0; m_iFocusTexDst = 2; m_iStepTex = 1; m_pFocusTexSrc = m_pRenderTargetTex[m_iFocusTexSrc]; m_iFocusDisTexDst = 3; m_pDevice->SetRenderTarget(m_pRenderTargetSurf[m_iFocusTexDst],NULL); m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x80808080, 1.0f, 0 ); m_pDevice->SetRenderTarget(m_pRenderTargetSurf[m_iFocusTexSrc],NULL); m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x80808080, 1.0f, 0 ); BackRenderTarget(); SetWaterValue(); } else { m_pDevice = NULL; } } void WBWaterNormalTexGenerator::SetWaterValue() { m_fDropletFreq = 0.1750f; m_fPosAtten = 0.980f; //m_fPosAtten = 0.880f; m_fEqRestore_factor = 0.17f; m_fVelFactor = 0.50f; m_fForceFactor = 0.50f; //m_fBlurDist = 0.1100f; m_fBlurDist = 0.6100f; m_fNormalSTScale = 0.230000f; CreateUvBlur(); } void WBWaterNormalTexGenerator::BackRenderTarget() { if(m_pDevice != NULL) { if(m_pBackColorSurf != NULL && m_pBackDepthSurf != NULL) { m_pDevice->SetRenderTarget(m_pBackColorSurf,m_pBackDepthSurf); } } } // Render Target À» µ¤´Â quad »ý¼º void WBWaterNormalTexGenerator::CreateVertex() { float fMin = 0.0f; float fMax = 1.0f; if(m_pDevice == NULL) return; m_pDevice->CreateVertexBuffer(sizeof(WBWaterQuad) * 4, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,0,D3DPOOL_DEFAULT,&m_pQuadBuffer); WBWaterQuad *pVert = NULL; if(m_pQuadBuffer) { m_pQuadBuffer->Lock(0,sizeof(WBWaterQuad) * 4,(BYTE **)&pVert,0); for(int i = 0 ;i < 4; i++ ) { pVert->vecPos = D3DXVECTOR3((i==0 || i==3) ? -1.0f : 1.0f, (i<2)? -1.0f : 1.0f, 0.0f); pVert->vecTexcoord = D3DXVECTOR2((i==0 || i==3) ? fMin : fMax , (i<2)? fMax : fMin ); pVert++; } m_pQuadBuffer->Unlock(); } } void WBWaterNormalTexGenerator::CreateUvOffset(int iSizeX,int iSizeY) { int i; m_fTexelSizeX = 1.0f/ (float)(iSizeX); m_fTexelSizeY = 1.0f/ (float)(iSizeY); float fOffsetX = m_fTexelSizeX / 2.0f; float fOffsetY = m_fTexelSizeY / 2.0f; float fTu = m_fTexelSizeX; float fTv = m_fTexelSizeY; int iSet; float fScale = 1.0f; iSet = 0; m_TextureCoord[iSet].m_vecOffset[0] = D3DXVECTOR4(0.0f + fOffsetX, 0.0f+ fOffsetY,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[1] = m_TextureCoord[iSet].m_vecOffset[0]; m_TextureCoord[iSet].m_vecOffset[2] = m_TextureCoord[iSet].m_vecOffset[0]; m_TextureCoord[iSet].m_vecOffset[3] = m_TextureCoord[iSet].m_vecOffset[0]; iSet = 1; float fNfs = 1.5f; fScale = fNfs; m_TextureCoord[iSet].m_vecOffset[0] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[1] = D3DXVECTOR4(-fTu,-fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[2] = D3DXVECTOR4(fTu,-fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[3] = D3DXVECTOR4(fTu,fTv,0.0f,0.0f); for( i=0; i<4; i++ ) { m_TextureCoord[iSet].m_vecOffset[i].x *= fScale; m_TextureCoord[iSet].m_vecOffset[i].y *= fScale; m_TextureCoord[iSet].m_vecOffset[i].x += m_fWindX; m_TextureCoord[iSet].m_vecOffset[i].y += m_fWindY; m_TextureCoord[iSet].m_vecOffset[i].x += fOffsetX; m_TextureCoord[iSet].m_vecOffset[i].y += fOffsetY; } iSet = 2; fScale = fNfs; m_TextureCoord[iSet].m_vecOffset[0] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[1] = D3DXVECTOR4(-fTu,fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[2] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[3] = D3DXVECTOR4(0.0f,0.0f,0.0f,0.0f); for( i=0; i<4; i++ ) { m_TextureCoord[iSet].m_vecOffset[i].x *= fScale; m_TextureCoord[iSet].m_vecOffset[i].y *= fScale; if( i==1 ) { m_TextureCoord[iSet].m_vecOffset[i].x += m_fWindX; m_TextureCoord[iSet].m_vecOffset[i].y += m_fWindY; } m_TextureCoord[iSet].m_vecOffset[i].x += fOffsetX; m_TextureCoord[iSet].m_vecOffset[i].y += fOffsetY; } iSet = 4; fScale = 1.0f; m_TextureCoord[iSet].m_vecOffset[0] = D3DXVECTOR4(-fTu,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[1] = D3DXVECTOR4(fTu,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[2] = D3DXVECTOR4(0.0f,fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[3] = D3DXVECTOR4(0.0f,-fTv,0.0f,0.0f); for( i=0; i<4; i++ ) { m_TextureCoord[iSet].m_vecOffset[i].x *= fScale; m_TextureCoord[iSet].m_vecOffset[i].y *= fScale; m_TextureCoord[iSet].m_vecOffset[i].x += fOffsetX; m_TextureCoord[iSet].m_vecOffset[i].y += fOffsetY; } CreateUvBlur(); } void WBWaterNormalTexGenerator::CreateUvBlur() { int iSet; float fScale; int i; float fTu = m_fTexelSizeX; float fTv = m_fTexelSizeY; float fOffsetX = m_fTexelSizeX / 2.0f; float fOffsetY = m_fTexelSizeY / 2.0f; iSet = 3; fScale = m_fBlurDist; fOffsetX += m_fScrollU; // Scrolling Factor fOffsetY += m_fScrollV; m_TextureCoord[iSet].m_vecOffset[0] = D3DXVECTOR4(0.0f,-fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[1] = D3DXVECTOR4(fTu,0.0f,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[2] = D3DXVECTOR4(0.0f,fTv,0.0f,0.0f); m_TextureCoord[iSet].m_vecOffset[3] = D3DXVECTOR4(-fTu,0.0f,0.0f,0.0f); for( i=0; i<4; i++ ) { m_TextureCoord[iSet].m_vecOffset[i].x *= fScale; m_TextureCoord[iSet].m_vecOffset[i].y *= fScale; m_TextureCoord[iSet].m_vecOffset[i].x += fOffsetX; m_TextureCoord[iSet].m_vecOffset[i].y += fOffsetY; } } void WBWaterNormalTexGenerator::CreateMatrix() { D3DXMATRIX matWorld; D3DXMATRIX matView; D3DXMATRIX matProject; D3DXMATRIX matViewProject; D3DXMatrixIdentity(&matWorld); D3DXVECTOR3 const vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f ); D3DXVECTOR3 const vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 const vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp); D3DXMatrixOrthoLH(&matProject, 4.0f, 4.0f, 0.2f, 20.0f); D3DXMatrixMultiply(&matViewProject, &matView, &matProject); D3DXMatrixScaling( & matWorld, 2.0f, 2.0f, 1.0f); D3DXMatrixMultiply( & m_matWorldViewProject, &matWorld, &matViewProject); D3DXMatrixTranspose( &m_matWorldViewProject,&m_matWorldViewProject); } void WBWaterNormalTexGenerator::Release() { if(m_pDisplaceMap != NULL) { delete m_pDisplaceMap; m_pDisplaceMap = NULL; } for(int i = 0; i < RENDERTARGET_NUM; i++ ) { if(m_pRenderTargetTex[i] != NULL) { m_pRenderTargetTex[i]->Release(); m_pRenderTargetTex[i] = NULL; } if(m_pRenderTargetSurf[i] != NULL) { m_pRenderTargetSurf[i]->Release(); m_pRenderTargetSurf[i] = NULL; } } if(m_pQuadBuffer != NULL) { m_pQuadBuffer->Release(); m_pQuadBuffer = NULL; } /*if(m_pVShader != NULL) { delete m_pVShader; m_pVShader = NULL; } */ if(m_pShader != NULL) { delete m_pShader; m_pShader = NULL; } } // ·»´õ Target Texture 4Àå°ú surface 4ÀåÀ» »ý¼º ÇÑ´Ù. void WBWaterNormalTexGenerator::CreateRenderTexture(int iSizeX,int iSizeY) { int i; if((iSizeX <= 0) || (iSizeY <= 0)) return; if((m_pBackColorSurf == NULL) || (m_pBackDepthSurf == NULL)) return; for( i=0; i < RENDERTARGET_NUM; i++ ) { if(m_pRenderTargetTex[i] != NULL) { m_pRenderTargetTex[i]->Release(); m_pRenderTargetTex[i] = NULL; } if(m_pRenderTargetSurf[i] != NULL) { m_pRenderTargetSurf[i]->Release(); m_pRenderTargetSurf[i] = NULL; } } for( i = 0; i < RENDERTARGET_NUM; i++ ) { m_pDevice->CreateTexture(iSizeX,iSizeY,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,&m_pRenderTargetTex[i]); m_pRenderTargetTex[i]->GetSurfaceLevel(0,&m_pRenderTargetSurf[i]); m_pDevice->SetRenderTarget(m_pRenderTargetSurf[i],NULL); m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0x80808080, 1.0f, 0 ); } m_pDevice->SetRenderTarget(m_pBackColorSurf,m_pBackDepthSurf); } void WBWaterNormalTexGenerator::LoadDisplaceMap() { if(m_pDisplaceMap != NULL) { delete m_pDisplaceMap; m_pDisplaceMap = NULL; } /* m_pDisplaceMap = new WBTexture; m_pDisplaceMap->LoadTexture(m_strDisplaceMap); */ char path[256]; GetCurrentDirectory(256,path); sprintf(path,"%s\\Texture\\Shader\\",path); CTexture::SetPath(path); m_pDisplaceMap = new CTexture; m_pDisplaceMap->Load(m_strDisplaceMap); } void WBWaterNormalTexGenerator::Update() { if(m_pDevice != NULL) { /* m_pDevice->SetVertexShader(NULL); m_pDevice->SetPixelShader(NULL); */ // SetNormalGenConstants(); SetNormalGenRenderState(); // SetWaterValue(); m_pDevice->GetRenderTarget( &m_pBackColorSurf ); m_pDevice->GetDepthStencilSurface( &m_pBackDepthSurf ); // Vertex Shader Setting // Texture Coordinate Offset Add //m_pVShader->Apply(); SetZeroOffset(0); m_pShader->Apply(); // m_pDevice->SetVertexShader(m_dwTexOffsetVShader); m_pDevice->SetStreamSource(0, m_pQuadBuffer,sizeof(WBWaterQuad)); CSceneManager::GetDevice()->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_matWorldViewProject(0, 0), 4); //CSceneManager::GetDevice()->BeginScene(); // Normal map Render ProcessNormalMap(); // Normal map Update //CSceneManager::GetDevice()->EndScene(); m_pDevice->SetRenderTarget(m_pBackColorSurf,m_pBackDepthSurf); m_pBackColorSurf->Release(); m_pBackDepthSurf->Release(); } } void WBWaterNormalTexGenerator::SetZeroOffset(int iOff) { if(m_pShader != NULL) { if(m_pShader->m_pVShader != NULL) { m_pShader->m_pVShader->SetZeroOffset(m_TextureCoord[iOff].m_vecOffset); } } /* if(m_pVShader != NULL) m_pVShader->SetZeroOffset(m_TextureCoord[iOff].m_vecOffset); */ } void WBWaterNormalTexGenerator::SetNormalGenRenderState() { if(m_pDevice != NULL) { // Texture Coordinate Offset Value Zero Setting SetZeroOffset(0); CSceneManager::GetDevice()->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1); CSceneManager::GetDevice()->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1); for(int i = 0; i < 4; i++ ) { CSceneStateMgr::_SetD3DTextureStageState(i,D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); CSceneStateMgr::_SetD3DTextureStageState(i,D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU | i ); CSceneStateMgr::_SetD3DTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT ); } CSceneStateMgr::_SetD3DTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); // For wrapped textures, you should use only the D3DTSS_ADDRESSU/V/W // states, unless you are doing cube environment mapping. CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP0, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP1, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP2, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP3, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP4, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP5, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP6, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_WRAP7, 0); CSceneStateMgr::_SetD3DRenderState(D3DRS_CULLMODE, D3DCULL_NONE); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZENABLE, D3DZB_FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_FOGENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_DITHERENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHATESTENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO ); CSceneStateMgr::_SetD3DRenderState(D3DRS_ZWRITEENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_SPECULARENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_STENCILENABLE, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_LIGHTING, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_COLORVERTEX, FALSE ); CSceneStateMgr::_SetD3DRenderState(D3DRS_FILLMODE, D3DFILL_SOLID ); } } void WBWaterNormalTexGenerator::ProcessNormalMap() { int iTmp; HRESULT hr; switch( m_iFlipState ) { case 0: m_iFocusTexSrc = 0; m_pFocusTexSrc = m_pRenderTargetTex[m_iFocusTexSrc]; m_iStepTex = 1; m_iFocusTexDst = 2; m_iFocusDisTexDst = 3; hr = m_pDevice->SetRenderTarget(m_pRenderTargetSurf[m_iFocusTexDst], NULL); m_pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x80808080,1.0f,0); hr = m_pDevice->SetRenderTarget(m_pRenderTargetSurf[m_iFocusTexSrc], NULL); m_pDevice->Clear(0,NULL,D3DCLEAR_TARGET,0x80808080,1.0f,0); break; case 1: // Swap Src Dst Change iTmp = m_iFocusTexDst; m_iFocusTexDst = m_iFocusTexSrc; m_iFocusTexSrc = iTmp; m_pFocusTexSrc = m_pRenderTargetTex[m_iFocusTexSrc]; m_iStepTex = 1; m_iFocusDisTexDst = 3; break; default: break; } D3DXVECTOR4 vecOffset(0.0f, 1.0f, 0.0f, 0.0f); CSceneManager::GetDevice()->SetVertexShaderConstant( CV_ONOFF_1, &vecOffset, 1); /// Render Texture D3DXVECTOR4 tmp_vec( m_fEqRestore_factor, m_fEqRestore_factor, m_fEqRestore_factor, m_fEqRestore_factor ); CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_EQ_REST_FAC, &tmp_vec, 1); CSceneStateMgr::_SetD3DRenderState( D3DRS_FILLMODE,D3DFILL_SOLID ); for(int i = 0; i < 4; i++ ) { CSceneStateMgr::_SetD3DTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); CSceneStateMgr::_SetD3DTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); CSceneStateMgr::_SetD3DTextureStageState( i, D3DTSS_MIPFILTER, D3DTEXF_NONE ); } // Set constant at which to apply force to velocity float pix_force_mult[4] = { 0.0f, m_fForceFactor, 0.0f, 0.0f }; // only green component! CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_MULTFACTOR_1, &pix_force_mult, 1 ); // Set constant at which to apply velocity to height float pix_vel_mult[4] = { 0.0f, 0.0f, m_fVelFactor, m_fVelFactor }; // only blue component CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_MULTFACTOR_2, &pix_vel_mult, 1 ); CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE, false ); CreateUvBlur(); CSceneManager::GetDevice()->SetTexture(0,NULL); CSceneManager::GetDevice()->SetTexture(1,NULL); CSceneManager::GetDevice()->SetTexture(2,NULL); CSceneManager::GetDevice()->SetTexture(3,NULL); CSceneManager::GetDevice()->SetRenderTarget( m_pRenderTargetSurf[m_iFocusTexDst], NULL); CSceneManager::GetDevice()->SetTexture(0,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(1,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(2,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(3,m_pFocusTexSrc); m_pShader->PixelShaderApply(WATER_EQUALCOMBINE); // m_pShader->Apply(); SetZeroOffset(3); // Render Quad CSceneManager::GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); iTmp = m_iFocusTexDst; m_iFocusTexDst = m_iFocusTexSrc; m_iFocusTexSrc = iTmp; m_pFocusTexSrc = m_pRenderTargetTex[m_iFocusTexSrc]; float rnd_freq; rnd_freq = (float)rand()/((float)RAND_MAX); if( m_fDropletFreq > rnd_freq ) { float scale = m_fDropletMinSize; scale += ( m_fDropletMaxSize - m_fDropletMinSize ) * ((float)rand()/((float)RAND_MAX)); // Use these to restrict the droplet so it never crosses the texture // border. This is a bad idea in general, as it will make tiling more // obvious. // float x = scale / 2.0f + (1.0f - scale ) * (float)rand()/((float)RAND_MAX); // float y = scale / 2.0f + (1.0f - scale ) * (float)rand()/((float)RAND_MAX); // Use these to not restrict placement based on size -- // Feel free to render noise displacements that cross the edges, provided // you add a copy to the opposite edge to preserve tiling and not make // high-frequency artifacts along the texture edge. float x = (float)rand()/((float)RAND_MAX); float y = (float)rand()/((float)RAND_MAX); // Add a droplet to the temporary storage. // They will all be drawn in the call DrawDroplets() AddDropWater( x, y, scale ); // Now check if the droplet hits the texture edge, and if // so, add other droplets to the other edges to preserve // tiling and not give rise to high frequency differences // along the edges. if( x < scale / 2.0f ) { AddDropWater( x + 1.0f, y, scale ); if( y < scale / 2.0f ) { AddDropWater( x, y + 1.0f, scale ); AddDropWater( x + 1.0f, y + 1.0f, scale ); } else if( y > 1.0f - scale / 2.0f ) { AddDropWater( x, y - 1.0f, scale ); AddDropWater( x + 1.0f, y - 1.0f, scale ); } } else if( x > 1.0f - scale / 2.0f ) { AddDropWater( x - 1.0f, y, scale ); if( y < scale / 2.0f ) { AddDropWater( x, y + 1.0f, scale ); AddDropWater( x - 1.0f, y + 1.0f, scale ); } else if( y > 1.0f - scale / 2.0f ) { AddDropWater( x, y - 1.0f, scale ); AddDropWater( x - 1.0f, y - 1.0f, scale ); } } else { if( y < scale / 2.0f ) AddDropWater( x, y + 1.0f, scale ); else if( y > 1.0f - scale / 2.0f ) AddDropWater( x, y - 1.0f, scale ); } } // Now draw DropWaters DrawDropWaters(); CSceneManager::GetDevice()->SetRenderTarget(m_pRenderTargetSurf[m_iStepTex],NULL); m_pShader->PixelShaderApply(WATER_ANI1); SetZeroOffset(1); CSceneStateMgr::_SetD3DRenderState(D3DRS_ALPHABLENDENABLE,FALSE); CSceneManager::GetDevice()->SetTexture(0,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(1,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(2,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(3,m_pFocusTexSrc); CSceneManager::GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); CSceneManager::GetDevice()->SetRenderTarget(m_pRenderTargetSurf[m_iFocusTexDst],NULL); m_pShader->PixelShaderApply(WATER_ANI2); SetZeroOffset(2); tmp_vec = D3DXVECTOR4( 0.0f, 0.0f, m_fPosAtten, m_fPosAtten ); CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_POSITIONMASK, & tmp_vec , 1); CSceneManager::GetDevice()->SetTexture(0,m_pRenderTargetTex[m_iStepTex]); CSceneManager::GetDevice()->SetTexture(1,m_pFocusTexSrc); CSceneManager::GetDevice()->SetTexture(2,NULL); CSceneManager::GetDevice()->SetTexture(3,NULL); CSceneManager::GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); // Normal Map Generate CreateDot3x2EMBMMapSteps(); // ´ÙÀ½ÀÇ FlipState setting switch( m_iFlipState ) { case 0: m_iFlipState = 1; break; case 1: m_iFlipState = 1; break; default: break; } } void WBWaterNormalTexGenerator::AddDropWater( float fX, float fY, float fScale ) { D3DXVECTOR3 vecPos(fX,fY,fScale); m_DropWaters.push_back(vecPos); } void WBWaterNormalTexGenerator::DrawDropWaters() { int i; float x,y; float scale; CSceneManager::GetDevice()->SetPixelShader(NULL); // Green channel == drop velocity CSceneManager::GetDevice()->SetTexture(0,m_pDisplaceMap->GetTexture()); CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN ); CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE, true ); CSceneStateMgr::_SetD3DRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE ); CSceneStateMgr::_SetD3DRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 ); CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR ); // blue only CSceneStateMgr::_SetD3DTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); CSceneStateMgr::_SetD3DTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); CSceneStateMgr::_SetD3DRenderState( D3DRS_FOGENABLE, false ); D3DXMATRIX matWorld; D3DXMATRIX matView; D3DXMATRIX matProj; D3DXMATRIX matViewProj; D3DXMATRIX matWorldViewProj; D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f ); D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); // 2.0f cause translation extends from -1 to 1 D3DXMatrixOrthoLH(&matProj, 2.0f, 2.0f, 0.2f, 20.0f); // x,y, zmin zmax m_pShader->Apply(); for( i=0; i < m_DropWaters.size(); i++) { // shift [0,1.0] coords into [-1,1] range x = ( m_DropWaters[i].x - 0.5f ) * 2.0f; y = ( m_DropWaters[i].y - 0.5f ) * 2.0f; scale = m_DropWaters[i].z; // alter matrix to place the droplet appropriately D3DXVECTOR3 vLookatPt = D3DXVECTOR3( x, y, 0.0f ); // Set World, View, Projection, and combination matrices. D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp); D3DXMatrixMultiply(&matViewProj, &matView, &matProj); D3DXMatrixScaling(&matWorld, scale, scale, 1.0f); D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj); D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); CSceneManager::GetDevice()->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); CSceneManager::GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); } /* matWorld = WBRenderState::GetWorldTransform(); matView = WBRenderState::GetViewTransform(); matProj = WBRenderState::GetProjectTransform(); D3DXMATRIX matTemp; D3DXMatrixMultiply(&matTemp, &matWorld, &matView); D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj); // Projection to clip space D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj); CSceneManager::GetDevice()->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4); */ CSceneManager::GetDevice()->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_matWorldViewProject(0, 0), 4); m_DropWaters.clear(); CSceneStateMgr::_SetD3DRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_ALPHA ); // Turn off alpha blending CSceneStateMgr::_SetD3DRenderState( D3DRS_ALPHABLENDENABLE, false ); } void WBWaterNormalTexGenerator::CreateDot3x2EMBMMapSteps() { D3DXVECTOR4 offset( 0.0f, 0.0f, 0.0f, 0.0f); CSceneManager::GetDevice()->SetRenderTarget( m_pRenderTargetSurf[ m_iFocusDisTexDst ], NULL ); CSceneManager::GetDevice()->SetTexture(0,m_pRenderTargetTex[m_iFocusTexDst]); CSceneManager::GetDevice()->SetTexture(1,m_pRenderTargetTex[m_iFocusTexDst]); CSceneManager::GetDevice()->SetTexture(2,m_pRenderTargetTex[m_iFocusTexDst]); CSceneManager::GetDevice()->SetTexture(3,m_pRenderTargetTex[m_iFocusTexDst]); // Red mask first float pix_masks[4] = { m_fNormalSTScale, 0.0f, 0.0f, 0.0f }; CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_RED_MASK, &pix_masks, 1 ); // Now green mask & scale: pix_masks[0] = 0.0f; pix_masks[1] = m_fNormalSTScale; CSceneManager::GetDevice()->SetPixelShaderConstant( PCN_GREEN_MASK, &pix_masks, 1 ); m_pShader->PixelShaderApply(WATER_TEXOFFSET); m_pShader->Apply(); // use nearest neighbor offsets SetZeroOffset(4); CSceneManager::GetDevice()->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2); } void WBWaterNormalTexGenerator::SetWindX(float fX) { m_fWindX += fX; CreateUvOffset(m_iTexSizeX,m_iTexSizeY); } void WBWaterNormalTexGenerator::SetWindY(float fY) { m_fWindY += fY; CreateUvOffset(m_iTexSizeX,m_iTexSizeY); }