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++

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