www.pudn.com > waterworld_src_exe.rar > waterworld.cpp


//----------------------------------------------------------------------------- 
// File: waterworld.cpp 
// 
// Desc: DirectX window application created by the DirectX AppWizard 
//----------------------------------------------------------------------------- 
#define STRICT 
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include "DXUtil.h" 
#include "D3DEnumeration.h" 
#include "D3DSettings.h" 
#include "D3DApp.h" 
#include "D3DFont.h" 
#include "D3DUtil.h" 
#include "resource.h" 
#include "waterworld.h" 
 
 
 
//----------------------------------------------------------------------------- 
// Global access to the app (needed for the global WndProc()) 
//----------------------------------------------------------------------------- 
CMyD3DApplication* g_pApp  = NULL; 
HINSTANCE          g_hInst = NULL; 
 
/* 
regular vert with tangent 
*/ 
typedef struct 
{ 
    D3DXVECTOR3 p; 
    D3DXVECTOR3 n; 
    D3DXVECTOR3 p2;  // Wave Height Scale 
    FLOAT       tu1, tv1, tw1; 
    D3DXVECTOR3 t; 
 } VERTEX; 
 
D3DVERTEXELEMENT9 decl[] = 
{ 
	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, 
	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, 
	{0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, 
	{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, 
	{0, 48, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, 
D3DDECL_END() 
}; 
 
#define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1| D3DFVF_TEXCOORDSIZE3(0)) 
 
//----------------------------------------------------------------------------- 
// Name: WinMain() 
// Desc: Entry point to the program. Initializes everything, and goes into a 
//       message-processing loop. Idle time is used to render the scene. 
//----------------------------------------------------------------------------- 
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) 
{ 
    CMyD3DApplication d3dApp; 
 
    g_pApp  = &d3dApp; 
    g_hInst = hInst; 
 
    InitCommonControls(); 
    if( FAILED( d3dApp.Create( hInst ) ) ) 
        return 0; 
 
    return d3dApp.Run(); 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: CMyD3DApplication() 
// Desc: Application constructor.   Paired with ~CMyD3DApplication() 
//       Member variables should be initialized to a known state here.   
//       The application window has not yet been created and no Direct3D device  
//       has been created, so any initialization that depends on a window or  
//       Direct3D should be deferred to a later stage.  
//----------------------------------------------------------------------------- 
CMyD3DApplication::CMyD3DApplication() 
{ 
    m_dwCreationWidth           = 500; 
    m_dwCreationHeight          = 375; 
    m_strWindowTitle            = TEXT( "waterworld" ); 
    m_d3dEnumeration.AppUsesDepthBuffer   = TRUE; 
	m_bStartFullscreen			= false; 
	m_bShowCursorWhenFullscreen	= false; 
 
    // Create a D3D font using d3dfont.cpp 
    m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD ); 
    m_bLoadingApp               = TRUE; 
 
    ZeroMemory( &m_UserInput, sizeof(m_UserInput) ); 
    m_fWorldRotX                = 0.0f; 
    m_fWorldRotY                = 0.0f; 
 
    // Read settings from registry 
    ReadSettings(); 
 
    m_bShowHelp = FALSE; 
	m_pStatsFont  = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD ); 
    m_pSmallFont  = new CD3DFont( _T("Arial"), 9, D3DFONT_BOLD ); 
 
	m_pVertBuff = NULL; 
	m_pIndxBuff = NULL; 
	m_pSkyBoxVertBuff = NULL; 
	m_pSkyBoxIndxBuff = NULL; 
	m_pTex = NULL; 
	m_pHeightTex = NULL; 
	m_psBumpMap = NULL; 
	m_pCubeTex = NULL; 
 
	m_dwNumVerts = 0; 
	m_dwNumFaces = 0; 
 
	m_bVertexShader    = TRUE; 
	m_bPixelShader     = TRUE; 
	m_bZBuffer         = TRUE; 
	D3DXMatrixIdentity( &m_matInitial ); 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: ~CMyD3DApplication() 
// Desc: Application destructor.  Paired with CMyD3DApplication() 
//----------------------------------------------------------------------------- 
CMyD3DApplication::~CMyD3DApplication() 
{ 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: OneTimeSceneInit() 
// Desc: Paired with FinalCleanup(). 
//       The window has been created and the IDirect3D9 interface has been 
//       created, but the device has not been created yet.  Here you can 
//       perform application-related initialization and cleanup that does 
//       not depend on a device. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::OneTimeSceneInit() 
{ 
    // TODO: perform one time initialization 
 
    // Drawing loading status message until app finishes loading 
    SendMessage( m_hWnd, WM_PAINT, 0, 0 ); 
 
    m_bLoadingApp = FALSE; 
 
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: ReadSettings() 
// Desc: Read the app settings from the registry 
//----------------------------------------------------------------------------- 
VOID CMyD3DApplication::ReadSettings() 
{ 
    HKEY hkey; 
    if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY,  
        0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) ) 
    { 
        // TODO: change as needed 
 
        // Read the stored window width/height.  This is just an example, 
        // of how to use DXUtil_Read*() functions. 
        DXUtil_ReadIntRegKey( hkey, TEXT("Width"), &m_dwCreationWidth, m_dwCreationWidth ); 
        DXUtil_ReadIntRegKey( hkey, TEXT("Height"), &m_dwCreationHeight, m_dwCreationHeight ); 
 
        RegCloseKey( hkey ); 
    } 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: WriteSettings() 
// Desc: Write the app settings to the registry 
//----------------------------------------------------------------------------- 
VOID CMyD3DApplication::WriteSettings() 
{ 
    HKEY hkey; 
 
    if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY,  
        0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) ) 
    { 
        // TODO: change as needed 
 
        // Write the window width/height.  This is just an example, 
        // of how to use DXUtil_Write*() functions. 
        DXUtil_WriteIntRegKey( hkey, TEXT("Width"), m_rcWindowClient.right ); 
        DXUtil_WriteIntRegKey( hkey, TEXT("Height"), m_rcWindowClient.bottom ); 
 
        RegCloseKey( hkey ); 
    } 
} 
 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: ConfirmDevice() 
// Desc: Called during device initialization, this code checks the display device 
//       for some minimum set of capabilities 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, 
                                          D3DFORMAT Format ) 
{ 
    UNREFERENCED_PARAMETER( Format ); 
    UNREFERENCED_PARAMETER( dwBehavior ); 
    UNREFERENCED_PARAMETER( pCaps ); 
     
    BOOL bCapsAcceptable; 
 
    // TODO: Perform checks to see if these display caps are acceptable. 
    bCapsAcceptable = TRUE; 
 
    if( bCapsAcceptable )          
        return S_OK; 
    else 
        return E_FAIL; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: InitDeviceObjects() 
// Desc: Paired with DeleteDeviceObjects() 
//       The device has been created.  Resources that are not lost on 
//       Reset() can be created here -- resources in D3DPOOL_MANAGED, 
//       D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM.  Image surfaces created via 
//       CreateOffScreenPlainSurface are never lost and can be created here.  Vertex 
//       shaders and pixel shaders can also be created here as they are not 
//       lost on Reset(). 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::InitDeviceObjects() 
{ 
    // TODO: create device objects 
	HRESULT hr; 
 
	hr = D3DXCreateTextureFromFile(m_pd3dDevice, "media\\Waterbump.bmp", &m_pHeightTex); 
	if (FAILED(hr)) 
		return hr; 
     
	hr = D3DXCreateCubeTextureFromFile(m_pd3dDevice,"media\\skybox.dds", &m_pCubeTex); 
	if (FAILED(hr)) 
		return hr; 
     
 
    m_pStatsFont->InitDeviceObjects( m_pd3dDevice ); 
    m_pSmallFont->InitDeviceObjects( m_pd3dDevice ); 
 
    if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( decl, &m_pVertexDeclaration ) ) ) 
    { 
        return DXTRACE_ERR( TEXT("CreateVertexDeclaration"), hr ); 
    } 
 
	// Create and fill the bumpmap 
    if( FAILED( InitBumpMap() ) ) 
        return E_FAIL; 
 
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: RestoreDeviceObjects() 
// Desc: Paired with InvalidateDeviceObjects() 
//       The device exists, but may have just been Reset().  Resources in 
//       D3DPOOL_DEFAULT and any other device state that persists during 
//       rendering should be set here.  Render states, matrices, textures, 
//       etc., that don't change during rendering can be set once here to 
//       avoid redundant state setting during Render() or FrameMove(). 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::RestoreDeviceObjects() 
{ 
    m_pStatsFont->RestoreDeviceObjects(); 
    m_pSmallFont->RestoreDeviceObjects(); 
 
 
	m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE ); 
    m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); 
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); 
 
	m_fCamXPos = 0.0f; 
	m_fCamYPos = 0.0f; 
	m_fCamZPos = 1.0f; 
	m_fXCenter = 0.0f; 
	m_fYCenter = 0.0f; 
	m_fZCenter = 0.0f; 
 
    // Set the transform matrices 
    D3DXVECTOR3 vEyePt    = D3DXVECTOR3( m_fCamXPos, m_fCamYPos, m_fCamZPos ); 
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( m_fXCenter, m_fYCenter, m_fZCenter ); 
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f,  0.0f ); 
     
 
    D3DXMatrixIdentity( &m_matWorld ); 
    D3DXMatrixLookAtLH( &m_matView, &vEyePt, &vLookatPt, &vUpVec ); 
    FLOAT fAspect = m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height; 
    D3DXMatrixPerspectiveFovLH( &m_matProj, D3DX_PI/2, fAspect, 1.0f, 1000.0f ); 
 
    m_pd3dDevice->SetTransform( D3DTS_WORLD,      &m_matWorld ); 
    m_pd3dDevice->SetTransform( D3DTS_VIEW,       &m_matView ); 
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProj ); 
 
		 
	D3DXMATRIX mat; 
	D3DXMatrixIdentity( &m_matInitial); 
    D3DXMatrixRotationX( &mat, D3DX_PI * 0.5f); 
    D3DXMatrixMultiply( &m_matInitial, &m_matInitial, &mat ); 
    D3DXMatrixTranslation( &mat, 0.0f, -1.5f, -10.0f); 
    D3DXMatrixMultiply( &m_matInitial, &m_matInitial, &mat ); 
 
	float radius = 20; 
	int hres = 120; 
	int vres = 40; 
 
	m_dwNumFaces = hres * vres * 2; 
	m_dwNumVerts = (hres + 1) * (vres + 1); 
 
 
	HRESULT hr; 
	// Create index buffer 
    { 
        WORD* pIndices; 
 
        if( FAILED( hr = m_pd3dDevice->CreateIndexBuffer( m_dwNumFaces*sizeof(WORD)*3, 
                                                          D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, 
                                                          D3DPOOL_DEFAULT, &m_pIndxBuff,NULL ) ) ) 
            return hr; 
 
        if( FAILED( hr = m_pIndxBuff->Lock( 0, m_dwNumFaces*sizeof(WORD)*3, (void **)&pIndices, 0 ) ) ) 
            return hr; 
 
		 
	 
		int i; 
		for (i = 0; i < hres; i++) 
			for (int j = 0; j < vres; j++) 
			{ 
				*pIndices++ = (WORD) (i      * (vres + 1) + j    ); 
				*pIndices++ = (WORD) ((i + 1)* (vres + 1) + j + 1); 
	            *pIndices++ = (WORD) (i      * (vres + 1) + j + 1); 
			 
				*pIndices++ = (WORD) (i      * (vres + 1) + j    ); 
				*pIndices++ = (WORD) ((i + 1)* (vres + 1) + j    ); 
                *pIndices++ = (WORD) ((i + 1)* (vres + 1) + j + 1); 
				 
			} 
     
	 
		 
        if( FAILED( hr = m_pIndxBuff->Unlock() ) ) 
            return hr; 
    } 
 
	float xmin = -30.0f; 
	float xmax =  30.0f; 
	float ymin = -10.0f; 
	float ymax =  10.0f; 
 
    // Create vertex buffer 
    { 
        VERTEX *pVertices; 
 
        if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( m_dwNumVerts*sizeof(VERTEX), 
                                                           D3DUSAGE_WRITEONLY, 0, 
                                                           D3DPOOL_DEFAULT, &m_pVertBuff,NULL ) ) ) 
            return hr; 
 
        if( FAILED( hr = m_pVertBuff->Lock( 0, m_dwNumVerts*sizeof(VERTEX), (void**)&pVertices, 0 ) ) ) 
            return hr; 
 
       
	 
		for (int i = 0; i <= hres; i++) 
			for (int j = 0; j <= vres; j++) 
			{ 
				float ii = i/(float)hres; 
				float jj = j/(float)vres; 
 
				pVertices->n[0] = 0.0f; 
				pVertices->n[1] = 0.0f; 
				pVertices->n[2] = -1.0f; 
				pVertices->t[0] = 0.0f; 
				pVertices->t[1] = -1.0f; 
				pVertices->t[2] = 0.0f; 
				pVertices->p[0] = xmin + ii * (xmax - xmin); 
				pVertices->p[1] = ymin + jj * (ymax - ymin);; 
				pVertices->p[2] = 0.0f; 
				pVertices->tu1 = ii; 
				pVertices->tv1 = jj; 
 
				pVertices->p2[0] = (float)(2.0f * max(fabs(ii - 0.5f), fabs(jj - 0.5f))); 
			 
				pVertices++;	 
			} 
 
        if( FAILED( hr = m_pVertBuff->Unlock() ) ) 
            return hr; 
    } 
 
	// Create SkyBox index buffer 
    { 
        WORD* pIndices; 
 
        if( FAILED( hr = m_pd3dDevice->CreateIndexBuffer( 12*sizeof(WORD)*3, 
                                                          D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, 
                                                          D3DPOOL_DEFAULT, &m_pSkyBoxIndxBuff,NULL ) ) ) 
            return hr; 
 
        if( FAILED( hr = m_pSkyBoxIndxBuff->Lock( 0, 12*sizeof(WORD)*3, (void**)&pIndices, 0 ) ) ) 
            return hr; 
 
		 
	 
		*pIndices++ = 0; *pIndices++ = 2; *pIndices++ = 6;  
		*pIndices++ = 0; *pIndices++ = 6; *pIndices++ = 4;  
		*pIndices++ = 1; *pIndices++ = 3; *pIndices++ = 7;  
		*pIndices++ = 1; *pIndices++ = 7; *pIndices++ = 5;  
		*pIndices++ = 0; *pIndices++ = 2; *pIndices++ = 3;  
		*pIndices++ = 0; *pIndices++ = 3; *pIndices++ = 1;  
		*pIndices++ = 4; *pIndices++ = 7; *pIndices++ = 6;  
		*pIndices++ = 4; *pIndices++ = 5; *pIndices++ = 7;  
		*pIndices++ = 2; *pIndices++ = 7; *pIndices++ = 3;  
		*pIndices++ = 2; *pIndices++ = 6; *pIndices++ = 7;  
		*pIndices++ = 0; *pIndices++ = 1; *pIndices++ = 4;  
		*pIndices++ = 4; *pIndices++ = 1; *pIndices++ = 5;  
	 
		 
        if( FAILED( hr = m_pSkyBoxIndxBuff->Unlock() ) ) 
            return hr; 
    } 
 
 
    // Create SkyBox vertex buffer 
    { 
        VERTEX *pVertices; 
 
        if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 8*sizeof(VERTEX), 
                                                           D3DUSAGE_WRITEONLY, 0, 
                                                           D3DPOOL_DEFAULT, &m_pSkyBoxVertBuff,NULL ) ) ) 
            return hr; 
 
        if( FAILED( hr = m_pSkyBoxVertBuff->Lock( 0, 8*sizeof(VERTEX), (void**)&pVertices, 0 ) ) ) 
            return hr; 
 
       
		radius = 80; 
		for (int i = 0; i <= 1; i++) 
			for (int j = 0; j <= 1; j++) 
				for (int k = 0; k <= 1; k++) 
				{ 
					float x = (float)(i * 2 - 1); 
					float y = (float)(j * 2 - 1); 
					float z = (float)(k * 2 - 1); 
			 
					pVertices->n[0] = x; 
					pVertices->n[1] = y; 
					pVertices->n[2] = 1; 
					pVertices->p[0] = x * radius; 
					pVertices->p[1] = y * radius; 
					pVertices->p[2] = z * radius; 
			 
				pVertices++;	 
			} 
 
        if( FAILED( hr = m_pSkyBoxVertBuff->Unlock() ) ) 
            return hr; 
    } 
 
	// Create vertex shader 
    { 
		ID3DXBuffer* shader = 0; 
		ID3DXBuffer* errorBuffer = 0; 
		ID3DXConstantTable* MultiTexCT = 0; 
 
		hr = D3DXCompileShaderFromFile( 
			"shaders\\OceanWater.vsh", 
			0, 
			0, 
			"Main", // entry point function name 
			"vs_2_0", 
			D3DXSHADER_DEBUG, 
			&shader, 
			&errorBuffer, 
			&MultiTexCT); 
 
		if(FAILED(hr)) 
		{ 
			::MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0); 
			return false;	 
		} 
		 
		// Create Pixel Shader 
		hr = m_pd3dDevice->CreateVertexShader( 
			(DWORD*)shader->GetBufferPointer(), 
			&m_pVertexShader); 
 
    } 
 
	// Create pixel shader 
    { 
		ID3DXBuffer* shader = 0; 
		ID3DXBuffer* errorBuffer = 0; 
		ID3DXConstantTable* MultiTexCT = 0; 
 
		D3DXHANDLE BumpTex0Handle = 0; 
		D3DXHANDLE BumpTex1Handle = 0; 
		D3DXHANDLE CubeTexHandle = 0; 
 
		D3DXCONSTANT_DESC BumpTex0Desc; 
		D3DXCONSTANT_DESC BumpTex1Desc; 
		D3DXCONSTANT_DESC CubeTexDesc; 
		UINT count; 
 
		hr = D3DXCompileShaderFromFile( 
			"shaders\\OceanWater.psh", 
			0, 
			0, 
			"Main", // entry point function name 
			"ps_2_0", 
			D3DXSHADER_DEBUG, 
			&shader, 
			&errorBuffer, 
			&MultiTexCT); 
 
		if(FAILED(hr)) 
		{ 
			::MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0); 
			return false;	 
		} 
		 
		// Create Pixel Shader 
		hr = m_pd3dDevice->CreatePixelShader( 
			(DWORD*)shader->GetBufferPointer(), 
			&m_pPixelShader); 
 
		BumpTex0Handle = MultiTexCT->GetConstantByName(0, "BumpTex0"); 
		BumpTex1Handle = MultiTexCT->GetConstantByName(0, "BumpTex1"); 
		CubeTexHandle = MultiTexCT->GetConstantByName(0, "CubeTex"); 
 
		MultiTexCT->GetConstantDesc(BumpTex0Handle,&BumpTex0Desc,&count); 
		MultiTexCT->GetConstantDesc(BumpTex1Handle,&BumpTex1Desc,&count); 
		MultiTexCT->GetConstantDesc(CubeTexHandle,&CubeTexDesc,&count); 
 
		m_pd3dDevice->SetTexture(0, m_psBumpMap); 
		m_pd3dDevice->SetTexture(1, m_psBumpMap); 
		m_pd3dDevice->SetTexture(2, m_pCubeTex); 
 
		m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); 
		m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); 
		m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); 
		m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); 
		m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); 
		m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); 
   } 
 
    return S_OK;  
} 
 
 
//----------------------------------------------------------------------------- 
// Name: FrameMove() 
// Desc: Called once per frame, the call is the entry point for animating 
//       the scene. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::FrameMove() 
{ 
	m_matWorld = m_matInitial; 
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld ); 
 
	// Set up the vertex/pixel shader constants 
    { 
		// c0    - Composite World-View-Projection Matrix 
		// c4	 - ModelSpace Camera Position 
		// c5    - {waveHeight0, waveHeight1, waveHeight2, waveHeight3}  (0.04, 0.05, 0.0025, 0.0025) 
		// c6    - {waveOffset0, waveOffset1, waveOffset2, waveOffset3}  (0.0, 0.2, 0.0, 0.0)  
		// c7    - {waveSpeed0, waveSpeed1, waveSpeed2, waveSpeed3}   (0.2, 0.15, 0.4, 0.4) 
		// c8    - {waveDirX0, waveDirX1, waveDirX2, waveDirX3}   (0.25, 0.0, -0.7, -0.8) 
		// c9    - {waveDirY0, waveDirY1, waveDirY2, waveDirY3}   (0.0, 0.15, -0.7, 0.1) 
		// c10   - { time } 
		// c11   - {basetexcoord distortion x0, y0, x1, y1} (0.031, 0.04, -0.03, 0.02) 
     	// c12   - World Martix 
 
		D3DXVECTOR4 c4( m_fCamXPos, m_fCamYPos, m_fCamZPos, 1.0 );	 
		D3DXVECTOR4 c5( 0.04f, 0.05f, 0.0025f, 0.0025f ); 
		D3DXVECTOR4 c6( 0.0f, 0.2f, 0.0f, 0.0f ); 
		D3DXVECTOR4 c7( 0.2f, 0.15f, 0.4f, 0.4f ); 
		D3DXVECTOR4 c8( 2.5f, 0.5f, -7.0f, -8.0f ); 
		D3DXVECTOR4 c9( 1.0f, 1.5f, -7.0f, 1.0f ); 
		D3DXVECTOR4 c10( (float)m_fTime*0.75f, 0.0f, 0.0f, 0.0f); 
		D3DXVECTOR4 c11( 0.031f, 0.04f, -0.03f, 0.02f); 
		 
		m_pd3dDevice->SetVertexShaderConstantF(  4, c4,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  5, c5,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  6, c6,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  7, c7,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  8, c8,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  9, c9,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  10, c10,  1 ); 
		m_pd3dDevice->SetVertexShaderConstantF(  11, c11,  1 ); 
			 
		D3DXMATRIX mat; 
        D3DXMatrixMultiply( &mat, &m_matView, &m_matProj ); 
        D3DXMatrixMultiply( &mat, &m_matWorld, &mat ); 
        D3DXMatrixTranspose( &mat, &mat ); 
       	m_pd3dDevice->SetVertexShaderConstantF(  0, (float*)&mat,  4 ); 
     
        D3DXMatrixTranspose( &mat, &m_matWorld ); 
       	m_pd3dDevice->SetVertexShaderConstantF(  12, (float*)&mat,  4 ); 
 
         
		//c0 -  watercolor (0.22f, 0.548f, 0.456f, 0.0206f) 
		//c1 - highlightColor (0.8, 0.76, 0.62, 1) 
 
		D3DXVECTOR4 c0p( 0.22f, 0.548f, 0.456f, 0.0206f ); 
		D3DXVECTOR4 c1p( 0.8f, 0.76f, 0.62f, 1.0f ); 
	 
		m_pd3dDevice->SetPixelShaderConstantF(  0, c0p,  1 ); 
		m_pd3dDevice->SetPixelShaderConstantF(  1, c1p,  1 ); 
    } 
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: UpdateInput() 
// Desc: Update the user input.  Called once per frame  
//----------------------------------------------------------------------------- 
void CMyD3DApplication::UpdateInput( UserInput* pUserInput ) 
{ 
    pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 ); 
    pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 ); 
    pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 ); 
    pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 ); 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: Render() 
// Desc: Called once per frame, the call is the entry point for 3d 
//       rendering. This function sets up render states, clears the 
//       viewport, and renders the scene. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::Render() 
{ 
    // Clear the viewport 
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000080, 1.0f, 0L ); 
 
    // Begin the scene  
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) 
    {	 
         
		// Draw the Sky Box 
		D3DXMATRIX mat; 
		D3DXMatrixIdentity( &mat); 
		m_pd3dDevice->SetTransform( D3DTS_WORLD, &mat ); 
		m_pd3dDevice->SetTexture(0, m_pCubeTex); 
 
		m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 
                                   D3DTSS_TCI_CAMERASPACENORMAL);  
 
		m_pd3dDevice->SetVertexShader( NULL ); 
		m_pd3dDevice->SetFVF(D3DFVF_VERTEX); 
	   	m_pd3dDevice->SetStreamSource( 0, m_pSkyBoxVertBuff, 0,sizeof(VERTEX) ); 
        m_pd3dDevice->SetIndices( m_pSkyBoxIndxBuff);		 
		m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0, 0, 8, 
                                            0, 12 ); 
 
		// Restore state to draw ocean 
		m_pd3dDevice->SetTexture(2, m_pCubeTex); 
		m_pd3dDevice->SetTexture(0, m_psBumpMap); 
		m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld ); 
		m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0);  
                                
 
		m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, m_bZBuffer ); 
		if (m_pVertexShader) 
		{ 
			m_pd3dDevice->SetVertexDeclaration( m_pVertexDeclaration ); 
			m_pd3dDevice->SetVertexShader( m_pVertexShader ); 
		} 
 
        if (m_pPixelShader)  
			m_pd3dDevice->SetPixelShader( m_pPixelShader ); 
 
		m_pd3dDevice->SetStreamSource( 0, m_pVertBuff, 0,sizeof(VERTEX) ); 
        m_pd3dDevice->SetIndices( m_pIndxBuff);		 
		m_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0, 0, m_dwNumVerts, 
                                            0, m_dwNumFaces ); 
 
 
        // Show frame rate 
        m_pStatsFont->DrawText( 2,  0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats ); 
        m_pStatsFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats ); 
 
 
		 if( m_bShowHelp ) 
        { 
            m_pSmallFont->DrawText(  2, 40, D3DCOLOR_ARGB(255,255,255,255), 
                                    _T("Keyboard controls:") ); 
            m_pSmallFont->DrawText( 20, 60, D3DCOLOR_ARGB(255,255,255,255), 
                                    _T("Help\nChange device\nExit") ); 
            m_pSmallFont->DrawText( 210, 60, D3DCOLOR_ARGB(255,255,255,255), 
                                     _T("F1\nF2\nEsc") ); 
        } 
        else 
        { 
            m_pSmallFont->DrawText(  2, 40, D3DCOLOR_ARGB(255,255,255,255),  
                               _T("Press F1 for help") ); 
        } 
 
 
        // End the scene. 
        m_pd3dDevice->EndScene(); 
    } 
 
    return S_OK; 
} 
 
//----------------------------------------------------------------------------- 
// Name: InitBumpMap() 
// Desc: Converts data from m_pHeightTex into m_psBumpMap. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::InitBumpMap() 
{ 
    LPDIRECT3DTEXTURE9 psBumpSrc = m_pHeightTex; 
    D3DSURFACE_DESC    d3dsd; 
    D3DLOCKED_RECT     d3dlr; 
 
    psBumpSrc->GetLevelDesc( 0, &d3dsd ); 
    // Create the bumpmap's surface and texture objects 
    if( FAILED( m_pd3dDevice->CreateTexture( d3dsd.Width, d3dsd.Height, 1, 0,  
        D3DFMT_V8U8, D3DPOOL_MANAGED, &m_psBumpMap,NULL ) ) ) 
    { 
        return E_FAIL; 
    } 
 
    // Fill the bits of the new texture surface with bits from 
    // a private format. 
    psBumpSrc->LockRect( 0, &d3dlr, 0, 0 ); 
    DWORD dwSrcPitch = (DWORD)d3dlr.Pitch; 
    BYTE* pSrcTopRow = (BYTE*)d3dlr.pBits; 
    BYTE* pSrcCurRow = pSrcTopRow; 
    BYTE* pSrcBotRow = pSrcTopRow + (dwSrcPitch * (d3dsd.Height - 1) ); 
 
    m_psBumpMap->LockRect( 0, &d3dlr, 0, 0 ); 
    DWORD dwDstPitch = (DWORD)d3dlr.Pitch; 
    BYTE* pDstTopRow = (BYTE*)d3dlr.pBits; 
    BYTE* pDstCurRow = pDstTopRow; 
    //BYTE* pDstBotRow = pDstTopRow + (dwDstPitch * (d3dsd.Height - 1) ); 
 
    for( DWORD y=0; yUnlockRect(0); 
    psBumpSrc->UnlockRect(0); 
 
    return S_OK; 
} 
 
//----------------------------------------------------------------------------- 
// Name: RenderText() 
// Desc: Renders stats and help text to the scene. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::RenderText() 
{ 
    D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0); 
    TCHAR szMsg[MAX_PATH] = TEXT(""); 
 
    // Output display stats 
    FLOAT fNextLine = 40.0f;  
 
    lstrcpy( szMsg, m_strDeviceStats ); 
    fNextLine -= 20.0f; 
    m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
 
    lstrcpy( szMsg, m_strFrameStats ); 
    fNextLine -= 20.0f; 
    m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
 
    // Output statistics & help 
    fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;  
    wsprintf( szMsg, TEXT("Arrow keys: Up=%d Down=%d Left=%d Right=%d"),  
              m_UserInput.bRotateUp, m_UserInput.bRotateDown, m_UserInput.bRotateLeft, m_UserInput.bRotateRight ); 
    fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
    sprintf( szMsg, TEXT("World State: %0.3f, %0.3f"),  
                    m_fWorldRotX, m_fWorldRotY ); 
    fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
    lstrcpy( szMsg, TEXT("Use arrow keys to update input") ); 
    fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
    lstrcpy( szMsg, TEXT("Press 'F2' to configure display") ); 
    fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg ); 
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: MsgProc() 
// Desc: Overrrides the main WndProc, so the sample can do custom message 
//       handling (e.g. processing mouse, keyboard, or menu commands). 
//----------------------------------------------------------------------------- 
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam, 
                                    LPARAM lParam ) 
{ 
  	// Trap context menu 
    if( WM_CONTEXTMENU == msg ) 
        return 0; 
 
	// Perform commands when keys are released 
    if( WM_KEYUP == msg ) 
    { 
        switch( wParam ) 
        { 
        case VK_F1: 
            m_bShowHelp = !m_bShowHelp; 
            break; 
        } 
    } 
 
    return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam ); 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: InvalidateDeviceObjects() 
// Desc: Invalidates device objects.  Paired with RestoreDeviceObjects() 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::InvalidateDeviceObjects() 
{ 
    // TODO: Cleanup any objects created in RestoreDeviceObjects() 
 	SAFE_RELEASE( m_pVertBuff ); 
	SAFE_RELEASE( m_pIndxBuff ); 
 	SAFE_RELEASE( m_pSkyBoxVertBuff ); 
	SAFE_RELEASE( m_pSkyBoxIndxBuff ); 
	SAFE_RELEASE( m_pVertexShader ); 
	SAFE_RELEASE( m_pPixelShader ); 
	m_pStatsFont->InvalidateDeviceObjects(); 
	m_pSmallFont->InvalidateDeviceObjects(); 
 
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: DeleteDeviceObjects() 
// Desc: Paired with InitDeviceObjects() 
//       Called when the app is exiting, or the device is being changed, 
//       this function deletes any device dependent objects.   
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::DeleteDeviceObjects() 
{ 
    // TODO: Cleanup any objects created in InitDeviceObjects() 
	SAFE_RELEASE( m_pVertBuff ); 
	SAFE_RELEASE( m_pIndxBuff ); 
	SAFE_RELEASE( m_pSkyBoxVertBuff ); 
	SAFE_RELEASE( m_pSkyBoxIndxBuff ); 
	m_pd3dDevice->SetTexture(0, NULL); 
	m_pd3dDevice->SetTexture(1, NULL); 
	SAFE_RELEASE( m_pTex ); 
	SAFE_RELEASE( m_pHeightTex ); 
	SAFE_RELEASE( m_psBumpMap ); 
	SAFE_RELEASE( m_pCubeTex ); 
	SAFE_RELEASE( m_pVertexDeclaration); 
 
    m_pStatsFont->DeleteDeviceObjects(); 
    m_pSmallFont->DeleteDeviceObjects(); 
  
    return S_OK; 
} 
 
 
 
 
//----------------------------------------------------------------------------- 
// Name: FinalCleanup() 
// Desc: Paired with OneTimeSceneInit() 
//       Called before the app exits, this function gives the app the chance 
//       to cleanup after itself. 
//----------------------------------------------------------------------------- 
HRESULT CMyD3DApplication::FinalCleanup() 
{ 
    // TODO: Perform any final cleanup needed 
    // Cleanup D3D font 
    SAFE_DELETE( m_pStatsFont ); 
	SAFE_DELETE( m_pSmallFont ); 
 
    return S_OK; 
}