📄 blois.cpp
字号:
for( i = 0; i < nFaces; i++ )
{
oIdx[i].m_Idx[0] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[0];
oIdx[i].m_Idx[1] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[1];
oIdx[i].m_Idx[2] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[2];
}
m_WaterMesh->UnlockIndexBuffer();
}
HRESULT CMyD3DApplication::CreateClearBuffer()
{
HRESULT hr;
if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 4 * kVSize,
D3DUSAGE_WRITEONLY,
0,
D3DPOOL_MANAGED,
&m_BumpVBuffer,
NULL) ) )
{
return hr;
}
ClearVert* ptr;
if( FAILED( hr = m_BumpVBuffer->Lock( 0, 0, (void **)&ptr, 0 ) ) )
return hr;
ptr[2].m_Pos.x = -1.f;
ptr[2].m_Pos.y = -1.f;
ptr[2].m_Pos.z = 0.5f;
ptr[2].m_Uv.x = 0.5f / kBumpTexSize;
ptr[1].m_Uv.y = 0.5f / kBumpTexSize;
ptr[0] = ptr[2];
ptr[0].m_Pos.y += 2.f;
ptr[0].m_Uv.y += 1.f;
ptr[1] = ptr[2];
ptr[1].m_Pos.x += 2.f;
ptr[1].m_Pos.y += 2.f;
ptr[1].m_Uv.x += 1.f;
ptr[1].m_Uv.y += 1.f;
ptr[3] = ptr[2];
ptr[3].m_Pos.x += 2.f;
ptr[3].m_Uv.x += 1.f;
m_BumpVBuffer->Unlock();
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()
{
// TODO: setup render states
// Setup a material
D3DMATERIAL9 mtrl;
D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
m_pd3dDevice->SetMaterial( &mtrl );
// Set up the textures
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
// Set miscellaneous render states
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F );
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
// Set the world matrix
D3DXMATRIX matIdentity;
D3DXMatrixIdentity( &matIdentity );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matIdentity );
// Set the projection matrix
FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovLH( &m_matProjection, D3DX_PI/4, fAspect, 1.0f, 10000.0f );
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProjection);
// Set up lighting states
D3DLIGHT9 light;
D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, -2.0f );
m_pd3dDevice->SetLight( 0, &light );
m_pd3dDevice->LightEnable( 0, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
// Restore the font
m_pFont->RestoreDeviceObjects();
HRESULT hr;
// Create our bump map. We'll composite the normals of our texture waves into this with renders.
if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, kBumpTexSize, kBumpTexSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_BumpTex)) &&
FAILED(hr = D3DXCreateTexture(m_pd3dDevice, kBumpTexSize, kBumpTexSize, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_BumpTex)))
{
return hr;
}
D3DSURFACE_DESC desc;
m_BumpTex->GetSurfaceLevel(0, &m_BumpSurf);
m_BumpSurf->GetDesc(&desc);
if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height,
desc.Format, FALSE, D3DFMT_UNKNOWN, &m_BumpRender)))
return hr;
m_CompCosinesEff->OnResetDevice();
m_WaterEff->OnResetDevice();
return S_OK;
}
static void Clamp(float& val, float lo, float hi)
{
if( val < lo )
val = lo;
else if( val > hi )
val = hi;
}
void CMyD3DApplication::MoveOnInput()
{
//
// Process keyboard input
//
D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vecZ(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]) vecZ.z -= 1.0f; // Turn Right
if(m_bKey['Q'] || m_bKey[VK_NUMPAD4]) vecZ.z += 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
const float speed = 10.f;
const float angSpeed = D3DX_PI / 5.f;
vecT *= speed * m_fElapsedTime;
vecR *= angSpeed * m_fElapsedTime;
vecZ *= angSpeed * m_fElapsedTime;
if(m_bKey[VK_SHIFT])
{
vecT *= 4.f;
vecR *= 4.f;
vecZ *= 4.f;
}
//
// Update position and view matricies
//
D3DXMATRIXA16 matT, matR, matZ;
D3DXQUATERNION qR;
D3DXQUATERNION qZ;
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);
D3DXQuaternionRotationYawPitchRoll(&qZ, vecZ.y, vecZ.x, vecZ.z);
D3DXMatrixRotationQuaternion(&matZ, &qZ);
D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
D3DXMatrixMultiply(&m_matPosition, &m_matPosition, &matZ);
D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);
float timeScale = m_bKey[VK_SHIFT] ? m_fElapsedTime : -m_fElapsedTime;
// MoreOptions
// Debounce the toggles
const float kMinToggle = 0.5f;
if( m_fTime - m_LastToggle > kMinToggle )
{
// Reset
if(m_bKey['R'])
{
if( m_bKey[VK_SHIFT] )
ResetWater();
else
InitWaves();
m_LastToggle = m_fTime;
}
// Show bump
if(m_bKey['B'])
{
m_bDrawBump = !m_bDrawBump;
m_LastToggle = m_fTime;
}
if(m_bKey[VK_SPACE])
{
m_bShowHelp = !m_bShowHelp;
m_LastToggle = m_fTime;
}
}
// Water Height
if(m_bKey['H'])
m_GeoState.m_WaterLevel += timeScale * 3.f;
// Geo Wave Height
if(m_bKey['J'])
{
m_GeoState.m_AmpOverLen += timeScale * 0.05f;
Clamp(m_GeoState.m_AmpOverLen, 0.f, 0.1f);
}
// Geo Chop
if(m_bKey['K'])
{
m_GeoState.m_Chop += timeScale * 0.5f;
Clamp(m_GeoState.m_Chop, 0.f, 4.f);
}
// Tex Wave Height
if(m_bKey['U'])
{
m_TexState.m_AmpOverLen += timeScale * 0.05f;
Clamp(m_TexState.m_AmpOverLen, 0.f, 0.5f);
}
// Tex scale
if(m_bKey['Y'])
{
m_TexState.m_RippleScale += timeScale * 1.f;
Clamp(m_TexState.m_RippleScale, 5.f, 50.f);
}
if(m_bKey['N'])
{
m_TexState.m_Noise += timeScale * 0.1f;
Clamp(m_TexState.m_Noise, 0.f, 1.f);
}
if(m_bKey['O'])
{
m_GeoState.m_AngleDeviation += timeScale * 10.f;
Clamp(m_GeoState.m_AngleDeviation, 0.f, 180.f);
}
if(m_bKey['P'])
{
m_TexState.m_AngleDeviation += timeScale * 10.f;
Clamp(m_TexState.m_AngleDeviation, 0.f, 180.f);
}
if(m_bKey['G'])
{
m_GeoState.m_EnvRadius *= 1.f + timeScale * 0.5f;
Clamp(m_GeoState.m_EnvRadius, 100.f, 10000.f);
}
if(m_bKey['F'])
{
m_GeoState.m_EnvHeight += timeScale * 10.f;
Clamp(m_GeoState.m_EnvHeight, -100.f, 100.f);
}
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
// TODO: update world
// Update user input state
MoveOnInput();
UpdateTexWaves(m_fElapsedTime);
UpdateGeoWaves(m_fElapsedTime);
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 );
pUserInput->bMoveUp = ( m_bActive && (GetAsyncKeyState( VK_UP ) & 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()
{
RenderTexture();
// Clear the viewport
m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0x00707070, 1.0f, 0L );
// Begin the scene
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
{
// TODO: render world
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);
m_pd3dDevice->SetTexture(0, m_LandTex);
m_LandMesh->DrawSubset(0);
m_pd3dDevice->SetTexture(0, NULL);
m_PillarsMesh->DrawSubset(0);
RenderWater();
if( m_bDrawBump )
{
D3DXMATRIXA16 matIdent;
D3DXMatrixIdentity(&matIdent);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &matIdent);
matIdent._11 = 0.5f;
matIdent._22 = 0.5f;
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matIdent);
m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
m_pd3dDevice->SetTexture(0, m_BumpTex);
m_pd3dDevice->SetFVF(kClearVertFVF);
m_pd3dDevice->SetStreamSource(0, m_BumpVBuffer, 0, kVSize);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
}
// Render stats and help text
RenderText();
// End the scene.
m_pd3dDevice->EndScene();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RenderText()
// Desc: Renders stats and help text to the scene.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -