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>
905 lines
25 KiB
C++
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);
|
|
}
|