Files
Client/GameTools/Zallad3D SceneClass/WBWaterNormalTexGenerator.cpp
LGram16 dd97ddec92 Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code:
- Client: Game client source (moved to Client/Client/)
- Server: Game server source
- GameTools: Development tools
- CryptoSource: Encryption utilities
- database: Database scripts
- Script: Game scripts
- rylCoder_16.02.2008_src: Legacy coder tools
- GMFont, Game: Additional resources

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 20:17:20 +09:00

905 lines
25 KiB
C++
Raw Permalink 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.
// 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 <20><> <20><><EFBFBD><EFBFBD> quad <20><><EFBFBD><EFBFBD>
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;
}
}
// <20><><EFBFBD><EFBFBD> Target Texture 4<><34><EFBFBD><EFBFBD> surface 4<><34><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
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();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 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);
}