⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ca_water.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*********************************************************************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 + -