📄 water.cpp
字号:
//-----------------------------------------------------------------------------
// File: Water.cpp
//
// Desc:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#define STRICT
#include <Windows.h>
#include <commctrl.h>
#include <tchar.h>
#include <stdio.h>
#include <d3dx9.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "D3DFont.h"
#include "resource.h"
#define WATER_DEPTH 20.0f
#define WATER_CAUSTICS_SIZE 128
//-----------------------------------------------------------------------------
// Name: CEnvironment
// Desc: The environment that is reflected in the water
//-----------------------------------------------------------------------------
class CEnvironment
{
public:
CEnvironment();
~CEnvironment();
HRESULT Initialize(float fSize);
HRESULT OnCreateDevice(IDirect3DDevice9* pDevice);
HRESULT OnResetDevice();
HRESULT OnLostDevice();
HRESULT OnDestroyDevice();
HRESULT SetSurfaces(
IDirect3DTexture9* pXNeg, IDirect3DTexture9* pXPos,
IDirect3DTexture9* pYNeg, IDirect3DTexture9* pYPos,
IDirect3DTexture9* pZNeg, IDirect3DTexture9* pZPos);
HRESULT Draw();
protected:
float m_fSize;
IDirect3DDevice9* m_pDevice;
IDirect3DTexture9* m_pSurf[6];
};
struct WATER_REFRACT
{
// Vrefract = (V + refract * N) * norm
float fRefract;
float fRefractNorm;
DWORD dwDiffuse;
};
struct WATER_SURFACE
{
float fHeight;
float fVelocity;
};
//-----------------------------------------------------------------------------
// Name: CWater
// Desc: The water that is rendered
//-----------------------------------------------------------------------------
class CWater
{
FLOAT m_fSize;
FLOAT m_fDepth;
FLOAT m_fScaleTex;
FLOAT m_fAvgHeight;
FLOAT m_fSphereHeight;
FLOAT m_fSphereRadius2;
UINT m_uIndices;
UINT m_uVertices;
WATER_SURFACE *m_pSurface;
WATER_REFRACT *m_pRefract;
IDirect3DDevice9 *m_pDevice;
IDirect3DIndexBuffer9 *m_pibIndices;
IDirect3DVertexBuffer9 *m_pvbVertices;
IDirect3DVertexBuffer9 *m_pvbCaustics;
public:
CWater();
~CWater();
HRESULT Initialize(float fSize, float fDepth);
HRESULT OnCreateDevice(IDirect3DDevice9 *pDevice);
HRESULT OnResetDevice();
HRESULT OnLostDevice();
HRESULT OnDestroyDevice();
HRESULT Drop();
HRESULT Update(D3DXVECTOR3 &vecPos, D3DXVECTOR3 &vecLight, BOOL bCalcCaustics);
HRESULT DrawCaustics();
HRESULT DrawSurface();
};
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication
// Desc:
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
public:
CMyD3DApplication();
HRESULT GetNextTechnique(INT nDir, BOOL bBypassValidate);
virtual HRESULT OneTimeSceneInit();
virtual HRESULT InitDeviceObjects();
virtual HRESULT RestoreDeviceObjects();
virtual HRESULT InvalidateDeviceObjects();
virtual HRESULT DeleteDeviceObjects();
virtual HRESULT FrameMove();
virtual HRESULT Render();
virtual HRESULT FinalCleanup();
virtual LRESULT MsgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
private:
CWater m_Water;
CEnvironment m_Environment;
LPD3DXEFFECT m_pEffect;
UINT m_iTechnique;
LPD3DXRENDERTOSURFACE m_pRenderToSurface;
D3DXVECTOR4 m_vecLight;
D3DXCOLOR m_colorLight;
LPDIRECT3DTEXTURE9 m_pFloorTex;
LPDIRECT3DTEXTURE9 m_pCausticTex;
LPDIRECT3DSURFACE9 m_pCausticSurf;
LPDIRECT3DTEXTURE9 m_pSkyTex[6];
LPDIRECT3DCUBETEXTURE9 m_pSkyCubeTex;
CD3DFont* m_pFont;
CD3DFont* m_pFontSmall;
BYTE m_bKey[256];
BOOL m_bPause;
BOOL m_bDrawWater;
BOOL m_bDrawCaustics;
BOOL m_bDrawEnvironment;
BOOL m_bShowHelp;
FLOAT m_fSpeed;
FLOAT m_fAngularSpeed;
FLOAT m_fTime;
FLOAT m_fSecsPerFrame;
D3DXVECTOR3 m_vecVelocity;
D3DXVECTOR3 m_vecAngularVelocity;
D3DXMATRIXA16 m_matIdentity;
D3DXMATRIXA16 m_matView;
D3DXMATRIXA16 m_matPosition;
D3DXMATRIXA16 m_matProjection;
};
//-----------------------------------------------------------------------------
// 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;
InitCommonControls();
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication
// Desc:
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
m_strWindowTitle = _T("Water");
m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_pFontSmall = new CD3DFont( _T("Arial"), 9, D3DFONT_BOLD );
// Water
m_pEffect = NULL;
m_iTechnique = 0;
m_vecLight = D3DXVECTOR4(0.5f, -1.0f, 1.0f, 0.0f);
m_colorLight = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
m_pFloorTex = NULL;
m_pCausticTex = NULL;
m_pCausticSurf = NULL;
m_pSkyCubeTex = NULL;
for(UINT i = 0; i < 6; i++)
m_pSkyTex[i] = NULL;
// Misc
memset(m_bKey, 0x00, sizeof(m_bKey));
m_fSpeed = 25.0f;
m_fAngularSpeed = 1.0f;
m_fSecsPerFrame = 0.0f;
m_fTime = 0.0f;
m_vecVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
m_vecAngularVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
D3DXMatrixIdentity(&m_matIdentity);
D3DXMatrixIdentity(&m_matView);
D3DXMatrixIdentity(&m_matPosition);
D3DXMatrixIdentity(&m_matProjection);
m_bShowHelp = FALSE;
m_bPause = FALSE;
}
//-----------------------------------------------------------------------------
// Name: GetNextTechnique
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::GetNextTechnique(INT nDir, BOOL bBypassValidate)
{
D3DXEFFECT_DESC effect;
UINT iTechnique = m_iTechnique;
m_pEffect->GetDesc(&effect);
for(;;)
{
iTechnique += nDir;
// cast is needed because iTechnique is unsigned, so always >= 0
if(((INT_PTR)iTechnique) < 0)
iTechnique = effect.Techniques - 1;
if(iTechnique >= effect.Techniques)
iTechnique = 0;
if(nDir && (iTechnique == m_iTechnique))
break;
if(!nDir)
nDir = 1;
m_pEffect->SetTechnique(m_pEffect->GetTechnique( iTechnique ));
if(bBypassValidate || (iTechnique == effect.Techniques - 1) ||
(m_bDrawCaustics || !m_pEffect->IsParameterUsed("tCAU", NULL)) && SUCCEEDED(m_pEffect->ValidateTechnique(NULL)))
{
m_iTechnique = iTechnique;
char szText[256];
sprintf(szText, "Water - Technique %d", m_iTechnique);
SetWindowText(m_hWnd, szText);
return S_OK;
}
}
m_pEffect->SetTechnique(m_pEffect->GetTechnique( m_iTechnique ));
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
HRESULT hr;
// Initialize Water
if(FAILED(hr = m_Water.Initialize(64.0f, WATER_DEPTH)))
return hr;
// Initialize Environment
if(FAILED(hr = m_Environment.Initialize(1000.0f)))
return hr;
// Misc stuff
D3DXMatrixRotationX(&m_matPosition, D3DX_PI * -0.3f);
m_matPosition._42 = 15.0f;
m_matPosition._43 = 15.0f;
D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
HRESULT hr;
TCHAR sz[512];
m_bDrawWater = TRUE;
m_bDrawCaustics = TRUE;
m_bDrawEnvironment = TRUE;
// Initialize the font's internal textures
m_pFont->InitDeviceObjects( m_pd3dDevice );
m_pFontSmall->InitDeviceObjects( m_pd3dDevice );
// Floor
if( FAILED( hr = DXUtil_FindMediaFileCb( sz, sizeof(sz), _T("Water.bmp") ) ) )
return hr;
D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
D3DX_DEFAULT, 0, NULL, NULL, &m_pFloorTex);
// Sky
TCHAR* szSkyTex[6] =
{
_T("lobbyxpos.jpg"), _T("lobbyxneg.jpg"),
_T("lobbyypos.jpg"), _T("lobbyyneg.jpg"),
_T("lobbyzpos.jpg"), _T("lobbyzneg.jpg")
};
for(UINT i = 0; i < 6; i++)
{
if( FAILED( hr = DXUtil_FindMediaFileCb(sz, sizeof(sz), szSkyTex[i]) ) )
return hr;
D3DXCreateTextureFromFileEx(m_pd3dDevice, sz, D3DX_DEFAULT, D3DX_DEFAULT,
1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, &m_pSkyTex[i]);
}
if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP )
{
if( FAILED( hr = DXUtil_FindMediaFileCb(sz, sizeof(sz), TEXT("LobbyCube.dds") ) ) )
return hr;
if( FAILED( hr = D3DXCreateCubeTextureFromFile( m_pd3dDevice, sz, &m_pSkyCubeTex ) ) )
return hr;
}
// OnCreateDevice
if(FAILED(hr = m_Water.OnCreateDevice(m_pd3dDevice)))
return hr;
if(FAILED(hr = m_Environment.OnCreateDevice(m_pd3dDevice)))
return hr;
// Effect
DXUtil_FindMediaFileCb(sz, sizeof(sz), _T("water.fx"));
if(FAILED(hr = D3DXCreateEffectFromFile(m_pd3dDevice, sz, NULL, NULL, 0, NULL, &m_pEffect, NULL)))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
HRESULT hr;
// Restore the font
m_pFont->RestoreDeviceObjects();
m_pFontSmall->RestoreDeviceObjects();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -