📄 soft shadows.cpp
字号:
// View matrix
D3DXVECTOR3 vLightPos = D3DXVECTOR3( 40.0f, 60.0f, -40.0f );
D3DXVECTOR3 vLightAim = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXMatrixLookAtLH( &matView, &vLightPos, &vLightAim, &g_vUp );
// Compute the projection matrix
D3DXMatrixOrthoLH( &matProj, 45.0f, 45.0f, 1.0f, 1024.0f );
// Compute the light-view-projection matrix
D3DXMATRIX matLightViewProj = matWorld * matView * matProj;
// Compute the texture matrix
float fTexOffs = 0.5 + (0.5 / (float)SHADOW_MAP_SIZE);
D3DXMATRIX matTexAdj( 0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
fTexOffs, fTexOffs, 0.0f, 1.0f );
D3DXMATRIX matTexture = matLightViewProj * matTexAdj;
// Setup the effect variables
g_pEffect->SetMatrix( "g_matWorldViewProj", &matWorldViewProj );
g_pEffect->SetMatrix( "g_matLightViewProj", &matLightViewProj );
g_pEffect->SetMatrix( "g_matWorld", &matWorld );
g_pEffect->SetMatrix( "g_matWorldIT", &matWorldIT );
g_pEffect->SetMatrix( "g_matTexture", &matTexture );
g_pEffect->SetVector( "g_vLightPos", (D3DXVECTOR4*)&vLightPos );
g_pEffect->SetVector( "g_vEyePos", (D3DXVECTOR4*)&g_vEyePos );
g_pEffect->SetVector( "g_vLightColor", &D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 0.5f ) );
g_pEffect->SetBool("g_bFiltered", g_bFiltered);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Render the frame
//-----------------------------------------------------------------------------
HRESULT Render()
{
// Clear the viewport
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
// Begin rendering the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Grab the old render target and depth buffer
g_pd3dDevice->GetRenderTarget( 0, &g_pOldColorRT );
g_pd3dDevice->GetDepthStencilSurface( &g_pOldDepthRT );
// Render the scene depth to the shadow map
g_pd3dDevice->SetRenderTarget( 0, g_pShadowSurf );
g_pd3dDevice->SetDepthStencilSurface( g_pShadowDepth );
// Clear the viewport
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFFFFFFF, 1.0f, 0 );
// Set the technique
g_pEffect->SetTechnique( "techShadow" );
// Render the effect
UINT uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
for( UINT uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the floor
g_pScene->DrawSubset(0);
// Draw the statue
g_pScene->DrawSubset(1);
g_pScene->DrawSubset(2);
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
if( g_bSoftShadows )
{
// Render the shadowed scene into the screen map
g_pd3dDevice->SetRenderTarget( 0, g_pScreenSurf );
g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
// Clear the viewport
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
// Set the technique
g_pEffect->SetTechnique( "techUnlit" );
// Set the textures
g_pEffect->SetTexture( "tShadowMap", g_pShadowMap );
// Render the effect
uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
for( uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the floor
g_pScene->DrawSubset(0);
// Draw the statue
g_pScene->DrawSubset(1);
g_pScene->DrawSubset(2);
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
// Blur the screen map horizontally
g_pd3dDevice->SetRenderTarget( 0, g_pBlurSurf[0] );
g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
// Clear the viewport
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
// Set the technique
g_pEffect->SetTechnique( "techBlurH" );
// Compute the Gaussian offsets
GetGaussianOffsets(TRUE, D3DXVECTOR2(1.0f / (FLOAT)SHADOW_MAP_SIZE, 1.0f / (FLOAT)SHADOW_MAP_SIZE),
g_vSampleOffsets, g_fSampleWeights);
g_pEffect->SetValue("g_vSampleOffsets", g_vSampleOffsets, 15 * sizeof(D3DXVECTOR2));
g_pEffect->SetValue("g_fSampleWeights", g_fSampleWeights, 15 * sizeof(FLOAT));
// Set the textures
g_pEffect->SetTexture( "tScreenMap", g_pScreenMap );
// Render the effect
uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
for( uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the quad
g_pd3dDevice->SetStreamSource( 0, g_pQuadVB, 0, sizeof(QuadVertex) );
g_pd3dDevice->SetFVF( FVF_QUADVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
// Blur the screen map vertically
g_pd3dDevice->SetRenderTarget( 0, g_pBlurSurf[1] );
g_pd3dDevice->SetDepthStencilSurface( g_pNewDepthRT );
// Clear the viewport
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
// Set the technique
g_pEffect->SetTechnique( "techBlurV" );
// Compute the Gaussian offsets
GetGaussianOffsets(FALSE, D3DXVECTOR2(1.0f / (FLOAT)SHADOW_MAP_SIZE, 1.0f / (FLOAT)SHADOW_MAP_SIZE),
g_vSampleOffsets, g_fSampleWeights);
g_pEffect->SetValue("g_vSampleOffsets", g_vSampleOffsets, 15 * sizeof(D3DXVECTOR2));
g_pEffect->SetValue("g_fSampleWeights", g_fSampleWeights, 15 * sizeof(FLOAT));
// Set the textures
g_pEffect->SetTexture( "tBlurHMap", g_pBlurMap[0] );
// Render the effect
uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
for( uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the quad
g_pd3dDevice->SetStreamSource( 0, g_pQuadVB, 0, sizeof(QuadVertex) );
g_pd3dDevice->SetFVF( FVF_QUADVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
// Restore the render target and depth buffer
g_pd3dDevice->SetRenderTarget( 0, g_pOldColorRT );
g_pd3dDevice->SetDepthStencilSurface( g_pOldDepthRT );
SAFE_RELEASE( g_pOldColorRT );
SAFE_RELEASE( g_pOldDepthRT );
// Finally, render the shadowed scene
g_pEffect->SetTechnique( "techScene" );
// Set the textures
g_pEffect->SetTexture( "tBlurVMap", g_pBlurMap[1] );
g_pEffect->SetTexture( "tSpotMap", g_pSpotMap );
// Render the effect
uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
// Do we need to render the scene in wireframe mode
if( g_bWireframe )
g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
for( uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the floor
g_pEffect->SetTexture( "tColorMap", g_pColorMap_Floor );
g_pEffect->CommitChanges();
g_pScene->DrawSubset(0);
// Draw the statue
g_pEffect->SetTexture( "tColorMap", g_pColorMap_Statue );
g_pEffect->CommitChanges();
g_pScene->DrawSubset(1);
g_pScene->DrawSubset(2);
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
// Restore the render state
g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
}
else
{
// Restore the render target and depth buffer
g_pd3dDevice->SetRenderTarget( 0, g_pOldColorRT );
g_pd3dDevice->SetDepthStencilSurface( g_pOldDepthRT );
SAFE_RELEASE( g_pOldColorRT );
SAFE_RELEASE( g_pOldDepthRT );
// Otherwise, render the scene with hard shadows
g_pEffect->SetTechnique( "techSceneHard" );
// Set the textures
g_pEffect->SetTexture( "tShadowMap", g_pShadowMap );
g_pEffect->SetTexture( "tSpotMap", g_pSpotMap );
// Render the effect
uPasses = 0;
g_pEffect->Begin( &uPasses, 0 );
// Do we need to render the scene in wireframe mode
if( g_bWireframe )
g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
for( uPass = 0; uPass < uPasses; uPass++ )
{
// Set the current pass
g_pEffect->BeginPass( uPass );
// Draw the floor
g_pEffect->SetTexture( "tColorMap", g_pColorMap_Floor );
g_pEffect->CommitChanges();
g_pScene->DrawSubset(0);
// Draw the statue
g_pEffect->SetTexture( "tColorMap", g_pColorMap_Statue );
g_pEffect->CommitChanges();
g_pScene->DrawSubset(1);
g_pScene->DrawSubset(2);
// End the current pass
g_pEffect->EndPass();
}
// End the effect
g_pEffect->End();
// Restore the render state
g_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
}
// Display the frame stats
if( g_bDisplayStats )
{
TCHAR szStats[255];
sprintf( szStats, "Framerate : %2.1f", g_fFramerate );
RECT rc = { 5, 5, 0, 0 };
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP, 0xFFFFAA00 );
sprintf( szStats, "Use arrow and Z, X keys to move around the scene" );
SetRect( &rc, 5, SCREEN_HEIGHT - 40, 0, 0 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP, 0xFFFFAA00 );
sprintf( szStats, "Press W to toggle wireframe display" );
SetRect( &rc, 5, SCREEN_HEIGHT - 20, 0, 0 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP, 0xFFFFAA00 );
sprintf( szStats, "Press S to toggle soft shadows" );
SetRect( &rc, 350, SCREEN_HEIGHT - 40, 0, 0 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP, 0xFFFFAA00 );
sprintf( szStats, "Press G to pump out a screenshot" );
SetRect( &rc, 350, SCREEN_HEIGHT - 20, 0, 0 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_CALCRECT, 0xFFFFAA00 );
g_pFont->DrawText( NULL, szStats, -1, &rc, DT_NOCLIP, 0xFFFFAA00 );
}
// End rendering the scene and present it
g_pd3dDevice->EndScene();
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ScreenGrab()
// Desc: Saves the backbuffer to a file
//-----------------------------------------------------------------------------
HRESULT ScreenGrab()
{
//
// Grab the back buffer and save it to a file
//
D3DDISPLAYMODE d3ddm;
g_pd3dDevice->GetDisplayMode( 0, &d3ddm );
g_pd3dDevice->CreateOffscreenPlainSurface( d3ddm.Width, d3ddm.Height, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &g_pScreenshot, NULL );
g_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pScreenshot );
TCHAR szScreenshot[32];
sprintf( szScreenshot, "ScreenShot%d.bmp", g_uNumScreenshots++ );
D3DXSaveSurfaceToFile( szScreenshot, D3DXIFF_BMP, g_pScreenshot, NULL, NULL );
SAFE_RELEASE( g_pScreenshot );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -