📄 ca_water.cpp
字号:
/*********************************************************************NVMH2****
Path: c:\Dev\devrel\Nv_sdk_4\Dx8\NVEffectsBrowser\Effects\BlinnBumpDynamicMap
File: CA_Water.cpp
Copyright (C) 1999, 2000 NVIDIA Corporation
This file is provided without support, instruction, or implied warranty of any
kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is
not liable under any circumstances for any damages or loss whatsoever arising
from the use or inability to use this file or items derived from it.
Comments:
3/17/01 - Greg James - This is fun stuff!
******************************************************************************/
#include <crtdbg.h>
#include "eb_effect.h"
#include "CA_Water.h"
#include "nvtex.h"
#include "..\..\..\CommonSrc\NV_Error.h" // for FDebug
#include "Constants.h"
#include "PixelConstants.h"
using namespace nv_objects;
using namespace std;
#define INITIAL_FILENAME "start.tga"
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
CA_Water::CA_Water( EBEffect * pEffect )
{
assert( pEffect != NULL );
m_pEBEffect = pEffect;
m_bWireframe = false;
m_pInitialStateTexture = NULL;
m_pDropletTexture = NULL;
m_dwVertexShader = 0;
m_dwEqualWeight_PostMultShader = 0;
m_dwNeighborForceCalc_1 = 0;
m_dwNeighborForceCalc_2 = 0;
m_dwApplyForceShader = 0;
m_dwApplyVelocityShader = 0;
m_dwPSH_NormalMapCreate = 0;
m_dwPSH_NormalMapCreate2_Scale = 0;
m_pVertexBuffer = NULL;
mpBackbufferColor = 0 ;
mpBackbufferDepth = 0 ;
m_bDrawOutput = true;
for ( int i = 0; i < kMaxNumTargets; ++i )
{
mpTextureFiltered[i] = 0;
mpFilterTarget [i] = 0;
}
}
CA_Water::~CA_Water()
{
Free();
}
/////////////////////////////////////////////////////////
HRESULT CA_Water::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
// check vertex shading support
if(D3DSHADER_VERSION_MAJOR(pCaps->VertexShaderVersion) < 1)
{
m_strLastError = "Device does not support vertex shaders!";
return E_FAIL;
}
if(D3DSHADER_VERSION_MINOR(pCaps->VertexShaderVersion) < 1)
{
m_strLastError = "Device does not support 1.1 vertex shaders!";
return E_FAIL;
}
// check simultaneous texture support
if(pCaps->MaxSimultaneousTextures < 4)
{
m_strLastError = "Device does not support 4 simultaneous textures!";
return E_FAIL;
}
// check pixel shader support
if(D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion) < 1)
{
m_strLastError = "Device does not support pixel shaders!";
return E_FAIL;
}
if(D3DSHADER_VERSION_MINOR(pCaps->PixelShaderVersion) < 1)
{
m_strLastError = "Device does not support 1.1 pixel shaders!";
return E_FAIL;
}
if(pCaps->MaxTextureBlendStages < 8)
{
m_strLastError = "Device does not support 8 register combiners!";
return E_FAIL;
}
return S_OK;
}
void CA_Water::ReleaseNVTextures( nv_objects::NVTexture *** pTex, int num )
{
for( int i=0; i < num; i++ )
{
if( *pTex[i] != NULL )
{
SAFE_DELETE( *pTex[i] );
*pTex[i] = NULL;
}
}
}
void CA_Water::ReleaseNVTextures()
{
const int NUM = 2;
nv_objects::NVTexture ** pTex[NUM];
pTex[0] = &m_pInitialStateTexture;
pTex[1] = &m_pDropletTexture;
ReleaseNVTextures( pTex, NUM );
}
HRESULT CA_Water::LoadNVTexture( LPDIRECT3DDEVICE8 pD3DDev, nv_objects::NVTexture * pTex, EBString filename )
{
HRESULT hr = S_OK;
hr = pTex->CreateFromFile( pD3DDev, GetFilePath( filename.c_str() ) );
if (FAILED(hr))
{
m_strLastError = "Couldn't load texture: ";
m_strLastError += filename;
assert( false );
}
return( hr );
}
void CA_Water::LoadRulesAndOtherMaps()
{
// This one does not re-create the render targets
// if new maps of different resolution are loaded
// while running. Only Initialize() creates
// the render targets.
ReleaseNVTextures();
////////////////////////////////////////////////
m_pInitialStateTexture = new nv_objects::NVTexture();
assert( m_pInitialStateTexture != NULL );
LoadNVTexture( m_pD3DDev, m_pInitialStateTexture, INITIAL_FILENAME );
////////////////////////////////////////////////
m_pDropletTexture = new nv_objects::NVTexture();
assert( m_pInitialStateTexture != NULL );
LoadNVTexture( m_pD3DDev, m_pDropletTexture, "Droplet1.bmp" );
}
std::string CA_Water::GetFilePath( const std::string& strFileName )
{
assert( m_pEBEffect != NULL );
return( m_pEBEffect->GetFilePath( strFileName ) );
}
HRESULT CA_Water::LoadAndCreateShader(const std::string& strFilePath,
const DWORD* pDeclaration,
DWORD Usage,
EBSHADERTYPE ShaderType,
DWORD* pHandle)
{
assert( m_pEBEffect != NULL );
return( m_pEBEffect->LoadAndCreateShader( strFilePath, pDeclaration, Usage, ShaderType, pHandle ));
}
HRESULT CA_Water::Initialize( EBEffect * pEffect, LPDIRECT3DDEVICE8 pDev )
{
// Called when effect is selected from list in browser
// Free() is called when effect is de-selected
int i;
HRESULT hr;
// get the device
assert( pDev != NULL );
m_pD3DDev = pDev;
m_pD3DDev->AddRef(); // released on Free()
assert( pEffect != NULL );
m_pEBEffect = pEffect;
// See class header for what each variable represents!
m_bReset = true;
m_bAnimate = true;
m_bSingleStep = false;
m_bSlow = true;
m_bFarther = false;
m_bWrap = true;
m_bCreateNormalMap = true;
m_bDrawOutput = true;
m_bMulticolor = false;
m_bUseNormalMapMethod2 = true;
m_bApplyInteriorBoundaries = true;
m_eRenderMode = FULLSCREEN_CURRENT_POSITION;
m_nSkipInterval = 0;
m_nFlipState = 0;
m_nThreshCnt = 0;
m_fhalfoff = 0.500f;
m_fNrmlSTScale = 0.8f;
m_dwSleepDelay = 20;
m_fEqRestore_factor = 0.5f;
/////////////////////
m_nThresh = 0;
m_nLowThresh = 6;
m_fBlend = 0.25f;
m_fVelFactor = 0.50f;
m_fBlurDist = 0.5f;
m_fEqRestore_factor = 0.5f;
m_fDropletFreq = 0.175f;
/////////////////////////////////
m_dwCurrentPixelShader = NULL;
m_dwCurrentVertexShader = NULL;
m_pCurrentRulesTex = NULL;
/////////////////////////////////
// create the vertex and pixel shaders
vector<DWORD> Declaration;
Declaration.push_back(D3DVSD_STREAM(0));
Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3));
Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT2));
Declaration.push_back(D3DVSD_END());
m_dwVertexShader = 0;
hr = LoadAndCreateShader(GetFilePath("TexCoord_4_Offset.vso"), &Declaration[0], 0, SHADERTYPE_VERTEX, &m_dwVertexShader);
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
hr = LoadAndCreateShader(GetFilePath("EqualWeightCombine_PostMult.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwEqualWeight_PostMultShader));
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// Load pixel shaders for neighbor force calc
// 1st pass = 3 samples & center
hr = LoadAndCreateShader(GetFilePath("NeighborForceCalc.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwNeighborForceCalc_1 ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// 2nd pass of force calc = 1 sample & center
hr = LoadAndCreateShader(GetFilePath("NeighborForceCalc2.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwNeighborForceCalc_2 ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// pixel shader for applying force to height field
hr = LoadAndCreateShader(GetFilePath("ApplyForceShader.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwApplyForceShader ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// pixel shader for applying force to height field
hr = LoadAndCreateShader(GetFilePath("ApplyVelocityShader.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwApplyVelocityShader ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// pixel shader for creating normal maps
hr = LoadAndCreateShader(GetFilePath("NormalMapCreate.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwPSH_NormalMapCreate ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
// pixel shader for creating normal maps with scalable red & green
// components for the s and t axis
hr = LoadAndCreateShader(GetFilePath("NormalMapCreate2_Scale.pso"), NULL, 0, SHADERTYPE_PIXEL,
&(m_dwPSH_NormalMapCreate2_Scale ) );
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
///////////////////////////////////////////////////////////////////////////////////////
// get a pointer to the current back-buffer (so we can restore it later)
m_pD3DDev->GetRenderTarget( &mpBackbufferColor );
m_pD3DDev->GetDepthStencilSurface( &mpBackbufferDepth );
D3DXVECTOR4 commonconst( 0.0f, 0.5f, 1.0f, 2.0f );
m_pD3DDev->SetVertexShaderConstant( CV_CONSTS_1, &commonconst, 1);
/////////////////////////////////
// load the initial conditions texture map, rules map, and
// optional final color re-mapping map
// The "rules" texture determines how the neighbor accumulation
// maps to new pixels in the next generation
LoadRulesAndOtherMaps();
hr = CreateTextureRenderTarget();
ASSERT_IF_FAILED(hr);
////////////////////////////////////////////////////////////////////////////
D3DSURFACE_DESC ddsd;
m_pInitialStateTexture->GetTexture()->GetLevelDesc(0, &ddsd);
// create vertex buffer
hr = m_pD3DDev->CreateVertexBuffer( 4 * sizeof(QuadVertex), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVertexBuffer);
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
return hr;
QuadVertex *pBuff;
if (m_pVertexBuffer)
{
hr = m_pVertexBuffer->Lock(0, 4 * sizeof(QuadVertex),(BYTE**)&pBuff, 0);
ASSERT_IF_FAILED(hr);
if (FAILED(hr))
{
m_strLastError = "Couldn't lock buffer!";
return hr;
}
float uv_base;
float uv_max;
uv_base = 0.0f;
uv_max = 1.0f;
for (i = 0; i < 4; ++i)
{
pBuff->Position = D3DXVECTOR3((i==0 || i==3) ? -1.0f : 1.0f,
(i<2) ? -1.0f : 1.0f,
0.0f);
pBuff->Tex = D3DXVECTOR2((i==0 || i==3) ? uv_base : uv_max ,
(i<2) ? uv_max : uv_base );
pBuff++;
}
m_pVertexBuffer->Unlock();
}
CreateAndWriteUVOffsets(ddsd.Width, ddsd.Height);
SetInitialRenderStates();
return hr;
}
HRESULT CA_Water::Free()
{
SAFE_RELEASE( m_pVertexBuffer ); // sets pointers to null after delete
ReleaseNVTextures();
if (m_pD3DDev)
{
m_pD3DDev->DeleteVertexShader(m_dwVertexShader);
m_pD3DDev->DeletePixelShader(m_dwEqualWeight_PostMultShader);
m_pD3DDev->DeletePixelShader(m_dwNeighborForceCalc_1);
m_pD3DDev->DeletePixelShader(m_dwNeighborForceCalc_2);
m_pD3DDev->DeletePixelShader(m_dwApplyForceShader);
m_pD3DDev->DeletePixelShader(m_dwApplyVelocityShader);
m_pD3DDev->DeletePixelShader(m_dwPSH_NormalMapCreate);
m_pD3DDev->DeletePixelShader(m_dwPSH_NormalMapCreate2_Scale);
m_dwPSH_NormalMapCreate2_Scale = 0;
m_dwPSH_NormalMapCreate = 0;
m_dwVertexShader = 0;
m_dwEqualWeight_PostMultShader = 0;
m_dwNeighborForceCalc_1 = 0;
m_dwNeighborForceCalc_2 = 0;
m_dwApplyForceShader = 0;
m_dwApplyVelocityShader = 0;
for (int i = 0; i < kMaxNumTargets; ++i)
{
SAFE_RELEASE(mpFilterTarget[i]);
SAFE_RELEASE(mpTextureFiltered[i]);
}
SAFE_RELEASE(mpBackbufferColor);
SAFE_RELEASE(mpBackbufferDepth);
SAFE_RELEASE(m_pD3DDev); // we AddRef()'d in Initialize
}
m_pEBEffect = NULL;
m_pD3DDev = NULL;
return S_OK;
}
HRESULT CA_Water::Start()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -