📄 water.cpp
字号:
//-----------------------------------------------------------------------------
// Name: MsgProc
// Desc:
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam )
{
switch( uMsg )
{
case WM_KEYDOWN:
m_bKey[wParam] = TRUE;
break;
case WM_KEYUP:
m_bKey[wParam] = FALSE;
break;
case WM_COMMAND:
{
switch( LOWORD(wParam) )
{
case IDM_ADDDROP:
m_Water.Drop();
break;
case IDM_NEXT_TECHNIQUE:
GetNextTechnique(1, FALSE);
break;
case IDM_NEXT_TECHNIQUE_NOVALIDATE:
GetNextTechnique(1, TRUE);
break;
case IDM_PREV_TECHNIQUE:
GetNextTechnique(-1, FALSE);
break;
case IDM_PREV_TECHNIQUE_NOVALIDATE:
GetNextTechnique(-1, TRUE);
break;
case IDM_TOGGLEHELP:
m_bShowHelp = !m_bShowHelp;
break;
}
}
}
return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}
//////////////////////////////////////////////////////////////////////////////
// Types /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#pragma pack(4)
struct ENV_VERTEX
{
D3DXVECTOR3 m_vecPos;
D3DXVECTOR2 m_vecTex;
static const DWORD FVF;
};
const DWORD ENV_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);
//////////////////////////////////////////////////////////////////////////////
// CEnvironment implementation ///////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
CEnvironment::CEnvironment()
{
m_fSize = 1.0f;
m_pDevice = NULL;
memset(m_pSurf, 0x00, sizeof(m_pSurf));
}
CEnvironment::~CEnvironment()
{
}
HRESULT CEnvironment::Initialize(float fSize)
{
m_fSize = fSize;
return S_OK;
}
HRESULT CEnvironment::OnCreateDevice(IDirect3DDevice9* pDevice)
{
m_pDevice = pDevice;
return S_OK;
}
HRESULT CEnvironment::OnResetDevice()
{
return S_OK;
}
HRESULT CEnvironment::OnLostDevice()
{
return S_OK;
}
HRESULT CEnvironment::OnDestroyDevice()
{
return S_OK;
}
HRESULT CEnvironment::SetSurfaces(
IDirect3DTexture9* pXNeg, IDirect3DTexture9* pXPos,
IDirect3DTexture9* pYNeg, IDirect3DTexture9* pYPos,
IDirect3DTexture9* pZNeg, IDirect3DTexture9* pZPos)
{
m_pSurf[0] = pXNeg;
m_pSurf[1] = pXPos;
m_pSurf[2] = pYNeg;
m_pSurf[3] = pYPos;
m_pSurf[4] = pZNeg;
m_pSurf[5] = pZPos;
return S_OK;
}
HRESULT CEnvironment::Draw()
{
float f;
ENV_VERTEX vert[4];
f = 0.5f / 512.0f;
vert[0].m_vecTex = D3DXVECTOR2(0.0f + f, 0.0f + f);
vert[1].m_vecTex = D3DXVECTOR2(0.0f + f, 1.0f - f);
vert[2].m_vecTex = D3DXVECTOR2(1.0f - f, 0.0f + f);
vert[3].m_vecTex = D3DXVECTOR2(1.0f - f, 1.0f - f);
m_pDevice->SetFVF(ENV_VERTEX::FVF);
f = m_fSize * 0.5f;
// XNeg
vert[0].m_vecPos = D3DXVECTOR3(-f, f, f);
vert[1].m_vecPos = D3DXVECTOR3(-f, -f, f);
vert[2].m_vecPos = D3DXVECTOR3(-f, f, -f);
vert[3].m_vecPos = D3DXVECTOR3(-f, -f, -f);
m_pDevice->SetTexture(0, m_pSurf[0]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
// XPos
vert[0].m_vecPos = D3DXVECTOR3( f, f, -f);
vert[1].m_vecPos = D3DXVECTOR3( f, -f, -f);
vert[2].m_vecPos = D3DXVECTOR3( f, f, f);
vert[3].m_vecPos = D3DXVECTOR3( f, -f, f);
m_pDevice->SetTexture(0, m_pSurf[1]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
// YNeg
vert[0].m_vecPos = D3DXVECTOR3(-f, -f, -f);
vert[1].m_vecPos = D3DXVECTOR3(-f, -f, f);
vert[2].m_vecPos = D3DXVECTOR3( f, -f, -f);
vert[3].m_vecPos = D3DXVECTOR3( f, -f, f);
m_pDevice->SetTexture(0, m_pSurf[2]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
// YPos
vert[0].m_vecPos = D3DXVECTOR3(-f, f, f);
vert[1].m_vecPos = D3DXVECTOR3(-f, f, -f);
vert[2].m_vecPos = D3DXVECTOR3( f, f, f);
vert[3].m_vecPos = D3DXVECTOR3( f, f, -f);
m_pDevice->SetTexture(0, m_pSurf[3]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
// ZNeg
vert[0].m_vecPos = D3DXVECTOR3(-f, f, -f);
vert[1].m_vecPos = D3DXVECTOR3(-f, -f, -f);
vert[2].m_vecPos = D3DXVECTOR3( f, f, -f);
vert[3].m_vecPos = D3DXVECTOR3( f, -f, -f);
m_pDevice->SetTexture(0, m_pSurf[4]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
// ZPos
vert[0].m_vecPos = D3DXVECTOR3( f, f, f);
vert[1].m_vecPos = D3DXVECTOR3( f, -f, f);
vert[2].m_vecPos = D3DXVECTOR3(-f, f, f);
vert[3].m_vecPos = D3DXVECTOR3(-f, -f, f);
m_pDevice->SetTexture(0, m_pSurf[5]);
m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, (LPVOID) vert, sizeof(ENV_VERTEX));
return S_OK;
}
#define WATER_SHIFT 6
#define WATER_SIZE (1 << WATER_SHIFT)
#define WATER_AREA (WATER_SIZE * WATER_SIZE)
#define WATER_MASK (WATER_SIZE - 1)
#define WATER_SPHERE_HEIGHT 20.0f
#define WATER_SPHERE_RADIUS2 (35.0f * 35.0f)
#define WATER_INDEX(x, y) \
((x) | ((y) << WATER_SHIFT))
#define WATER_INDEX_WRAP(x, y) \
(((x) & WATER_MASK) | (((y) & WATER_MASK) << WATER_SHIFT))
#if defined(_X86) && !defined(_WIN64)
inline int f2i(float flt)
{
volatile int n;
__asm
{
fld flt
fistp n
}
return n;
}
#else
inline int f2i(float flt)
{
return (int) flt;
}
#endif
//////////////////////////////////////////////////////////////////////////////
// Types /////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#pragma pack(1)
struct WATER_VERTEX
{
D3DXVECTOR3 m_vecPos;
D3DXVECTOR3 m_vecNormal;
D3DCOLOR m_dwDiffuse;
D3DXVECTOR2 m_vecTex;
static const DWORD FVF;
};
const DWORD WATER_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE
| D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);
struct CAUSTICS_VERTEX
{
D3DXVECTOR3 m_vecPos;
D3DCOLOR m_dwDiffuse;
static const DWORD FVF;
};
const DWORD CAUSTICS_VERTEX::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
#pragma pack()
//////////////////////////////////////////////////////////////////////////////
// CWater implementation /////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
CWater::CWater()
{
m_fDepth = 0.0f;
m_fScaleTex = 1.0f;
m_uIndices = 0;
m_uVertices = 0;
m_pRefract = NULL;
m_pSurface = NULL;
m_pDevice = NULL;
m_pibIndices = NULL;
m_pvbVertices = NULL;
m_pvbCaustics = NULL;
}
CWater::~CWater()
{
if(m_pSurface)
delete [] m_pSurface;
}
HRESULT CWater::Initialize(float fSize, float fDepth)
{
m_fSize = fSize;
m_fDepth = fDepth;
m_fScaleTex = 1.0f / fSize;
// Calculate number of vertices and indices
m_uVertices = WATER_AREA;
m_uIndices = m_uVertices * 2;
// Create refraction table
static WATER_REFRACT Refract[512];
if(!m_pRefract)
{
m_pRefract = &Refract[256];
for(UINT u = 0; u < 256; u++)
{
float fCos0 = (float) u / (float) 256.0f;
float f0 = acosf(fCos0);
float fSin0 = sinf(f0);
float fSin1 = fSin0 / 1.333f; // water
float f1 = asinf(fSin1);
float fCos1 = cosf(f1);
m_pRefract[u].fRefract = fSin0 / fSin1 * fCos1 - fCos0;
m_pRefract[u].fRefractNorm = - fSin1 / fSin0;
m_pRefract[u].dwDiffuse = ((((0xff - u)*(0xff - u)*(0xff - u)) << 8) & 0xff000000);
Refract[u] = Refract[256];
}
}
// Create maps
if(!m_pSurface)
{
if( ( m_pSurface = new WATER_SURFACE[WATER_AREA] ) == NULL )
return E_OUTOFMEMORY;
memset(m_pSurface, 0x00, WATER_AREA * sizeof(WATER_SURFACE));
}
return S_OK;
}
HRESULT CWater::OnCreateDevice(IDirect3DDevice9 *pDevice)
{
m_pDevice = pDevice;
return S_OK;
}
HRESULT CWater::OnResetDevice()
{
HRESULT hr;
// Create indices
if(!m_pibIndices)
{
WORD *pwIndices;
if(FAILED(hr = m_pDevice->CreateIndexBuffer(m_uIndices * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibIndices, NULL)))
{
return hr;
}
if(FAILED(hr = m_pibIndices->Lock(0, m_uIndices * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD)))
return hr;
// Fill in indicies
UINT uX = 0, uZ = 0;
WORD *pwIndex = pwIndices;
for(UINT uSize = WATER_SIZE; uSize != 0; uSize -= 2)
{
UINT u;
// Top
for(u = 0; u < uSize; u++)
{
*pwIndex++ = uX + uZ * WATER_SIZE;
*pwIndex++ = uX + uZ * WATER_SIZE + WATER_SIZE;
uX++;
}
uX--;
uZ++;
// Right
for(u = 1; u < uSize; u++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -