📄 water.cpp
字号:
// Create light
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = m_colorLight.r;
light.Diffuse.g = m_colorLight.g;
light.Diffuse.b = m_colorLight.b;
light.Diffuse.a = m_colorLight.a;
light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
light.Specular.a = 0.0f;
light.Direction.x = m_vecLight.x;
light.Direction.y = m_vecLight.y;
light.Direction.z = m_vecLight.z;
m_pd3dDevice->SetLight(0, &light);
m_pd3dDevice->LightEnable(0, TRUE);
// Create material
D3DMATERIAL9 material;
ZeroMemory(&material, sizeof(material));
material.Diffuse.a = 1.0f;
material.Specular.r = 0.5f;
material.Specular.g = 0.5f;
material.Specular.b = 0.5f;
material.Power = 20.0f;
m_pd3dDevice->SetMaterial(&material);
// Setup render states
m_pd3dDevice->SetFVF(D3DFVF_XYZ);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &m_matIdentity);
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
m_pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
m_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
m_pd3dDevice->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetSamplerState(1, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);
// Create caustic texture
D3DDISPLAYMODE mode;
m_pd3dDevice->GetDisplayMode( 0, &mode );
if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, D3DUSAGE_RENDERTARGET, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)) &&
FAILED(hr = D3DXCreateTexture(m_pd3dDevice, WATER_CAUSTICS_SIZE, WATER_CAUSTICS_SIZE, 1, 0, mode.Format, D3DPOOL_DEFAULT, &m_pCausticTex)))
{
return hr;
}
D3DSURFACE_DESC desc;
m_pCausticTex->GetSurfaceLevel(0, &m_pCausticSurf);
m_pCausticSurf->GetDesc(&desc);
if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height,
desc.Format, FALSE, D3DFMT_UNKNOWN, &m_pRenderToSurface)))
{
return hr;
}
// Effect
m_pEffect->OnResetDevice();
m_pEffect->SetMatrix("mID", &m_matIdentity);
m_pEffect->SetMatrix("mENV", &m_matIdentity);
m_pEffect->SetTexture("tFLR", m_pFloorTex);
m_pEffect->SetTexture("tCAU", m_pCausticTex);
m_pEffect->SetTexture("tENV", m_pSkyCubeTex);
if(FAILED(hr = GetNextTechnique(0, FALSE)))
return hr;
// Set surfaces
if(FAILED(hr = m_Environment.SetSurfaces(
m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_X], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_X],
m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Y], m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Y],
m_pSkyTex[D3DCUBEMAP_FACE_POSITIVE_Z], m_pSkyTex[D3DCUBEMAP_FACE_NEGATIVE_Z])))
{
return hr;
}
if(FAILED(hr = m_Water.OnResetDevice()))
return hr;
if(FAILED(hr = m_Environment.OnResetDevice()))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
m_pFont->InvalidateDeviceObjects();
m_pFontSmall->InvalidateDeviceObjects();
m_Water.OnLostDevice();
m_Environment.OnLostDevice();
m_pEffect->OnLostDevice();
SAFE_RELEASE(m_pRenderToSurface);
SAFE_RELEASE(m_pCausticSurf);
SAFE_RELEASE(m_pCausticTex);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
m_pFont->DeleteDeviceObjects();
m_pFontSmall->DeleteDeviceObjects();
m_Water.OnDestroyDevice();
m_Environment.OnDestroyDevice();
SAFE_RELEASE(m_pFloorTex);
SAFE_RELEASE(m_pSkyCubeTex);
SAFE_RELEASE(m_pEffect);
for(UINT i = 0; i < 6; i++)
SAFE_RELEASE(m_pSkyTex[i]);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
HRESULT hr;
//
// Process keyboard input
//
D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);
if(m_bKey[VK_NUMPAD1] || m_bKey[VK_LEFT]) vecT.x -= 1.0f; // Slide Left
if(m_bKey[VK_NUMPAD3] || m_bKey[VK_RIGHT]) vecT.x += 1.0f; // Slide Right
if(m_bKey[VK_DOWN]) vecT.y -= 1.0f; // Slide Down
if(m_bKey[VK_UP]) vecT.y += 1.0f; // Slide Up
if(m_bKey['W']) vecT.z -= 2.0f; // Move Forward
if(m_bKey['S']) vecT.z += 2.0f; // Move Backward
if(m_bKey['A'] || m_bKey[VK_NUMPAD8]) vecR.x -= 1.0f; // Pitch Down
if(m_bKey['Z'] || m_bKey[VK_NUMPAD2]) vecR.x += 1.0f; // Pitch Up
if(m_bKey['E'] || m_bKey[VK_NUMPAD6]) vecR.y -= 1.0f; // Turn Right
if(m_bKey['Q'] || m_bKey[VK_NUMPAD4]) vecR.y += 1.0f; // Turn Left
if(m_bKey[VK_NUMPAD9]) vecR.z -= 2.0f; // Roll CW
if(m_bKey[VK_NUMPAD7]) vecR.z += 2.0f; // Roll CCW
m_vecVelocity = m_vecVelocity * 0.9f + vecT * 0.1f;
m_vecAngularVelocity = m_vecAngularVelocity * 0.9f + vecR * 0.1f;
//
// Update position and view matricies
//
D3DXMATRIXA16 matT, matR;
D3DXQUATERNION qR;
vecT = m_vecVelocity * m_fElapsedTime * m_fSpeed;
vecR = m_vecAngularVelocity * m_fElapsedTime * m_fAngularSpeed;
D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
D3DXMatrixMultiply(&m_matPosition, &matT, &m_matPosition);
D3DXQuaternionRotationYawPitchRoll(&qR, vecR.y, vecR.x, vecR.z);
D3DXMatrixRotationQuaternion(&matR, &qR);
D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);
//
// Update simulation
//
if(!m_bPause && m_bDrawWater)
{
BOOL bCaustics = m_bDrawCaustics && m_pEffect->IsParameterUsed("tCAU", NULL);
D3DXVECTOR3 vecPos(m_matPosition._41, m_matPosition._42, m_matPosition._43);
D3DXVECTOR3 vecLight(0.0f, 1.0f, 0.0f);
m_Water.Update(vecPos, vecLight, bCaustics);
m_fTime += m_fSecsPerFrame;
if(bCaustics)
{
if(SUCCEEDED(m_pRenderToSurface->BeginScene(m_pCausticSurf, NULL)))
{
D3DXMATRIXA16 matProj;
D3DXMATRIXA16 matView;
D3DXMatrixOrthoRH(&matProj, 63.0f, 63.0f, 1.0f, 100.0f);
D3DXMatrixRotationX(&matView, 0.5f * D3DX_PI);
matView._43 = -50.0f;
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, 0xff000000, 0.0f, 0);
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_Water.DrawCaustics();
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
m_pRenderToSurface->EndScene( 0 );
}
else
{
m_bDrawCaustics = FALSE;
m_pEffect->SetTexture("tCAU", NULL);
if(FAILED(hr = GetNextTechnique(0, FALSE)))
return hr;
}
}
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
HRESULT hr;
if(FAILED(hr = m_pd3dDevice->BeginScene()))
return hr;
// Draw Environment
FLOAT fAspectRatio = (FLOAT)m_d3dsdBackBuffer.Width / (FLOAT)m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovRH(&m_matProjection, D3DXToRadian(60.0f), fAspectRatio, 0.1f, 2000.0f);
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);
if(m_bDrawEnvironment)
{
D3DXMATRIXA16 mat(m_matView);
mat._41 = mat._42 = mat._43 = 0.0f;
m_pd3dDevice->SetTransform(D3DTS_VIEW, &mat);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
m_Environment.Draw();
m_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
else
{
m_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
}
m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);
// Draw water
if(m_bDrawWater)
{
// Setup matrices
if(m_pEffect->IsParameterUsed("mENV", NULL))
{
D3DXMATRIXA16 matP(m_matPosition);
matP._41 = matP._42 = matP._43 = 0.0f;
D3DXMATRIXA16 mat;
D3DXMatrixScaling(&mat, 1.0f, 1.0f, -1.0f);
D3DXMatrixMultiply(&mat, &matP, &mat);
// matCube
m_pEffect->SetMatrix("mENV", &mat);
}
// Draw water
UINT uPasses;
m_pEffect->Begin(&uPasses, 0);
for(UINT uPass = 0; uPass < uPasses; uPass++)
{
m_pEffect->Pass(uPass);
m_Water.DrawSurface();
}
m_pEffect->End();
}
// Show info
m_pFont->DrawText( 2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats );
m_pFont->DrawText( 2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats );
TCHAR szText[100];
wsprintf( szText, _T("Using Technique %d"), m_iTechnique );
m_pFontSmall->DrawText( 2, 40, D3DCOLOR_ARGB(255,255,100,100), szText );
if( m_bShowHelp )
{
m_pFontSmall->DrawText( 2, 60, D3DCOLOR_ARGB(255,100,100,200),
_T("Keyboard controls:") );
m_pFontSmall->DrawText( 20, 80, D3DCOLOR_ARGB(255,100,100,200),
_T("Add Drop\n")
_T("Next Technique\n")
_T("Next Tech. (no validate)\n")
_T("Prev Technique\n")
_T("Prev Tech. (no validate)\n")
_T("Move\nTurn\nPitch\nSlide\n")
_T("Help\nChange device\nExit") );
m_pFontSmall->DrawText( 210, 80, D3DCOLOR_ARGB(255,100,100,200),
_T("D\n")
_T("PageDn\nShift-PageDn\n")
_T("PageUp\nShift-PageUp\n")
_T("W,S\nE,Q\nA,Z\nArrow keys\n")
_T("F1\nF2\nEsc") );
}
else
{
m_pFontSmall->DrawText( 2, 60, D3DCOLOR_ARGB(255,100,100,200),
_T("Press F1 for help") );
}
if(FAILED(hr = m_pd3dDevice->EndScene()))
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
// to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
SAFE_DELETE( m_pFont );
SAFE_DELETE( m_pFontSmall );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -