📄 soft shadows.cpp
字号:
{
break;
}
}
break;
}
default:
{
return DefWindowProc( hWnd, msg, wParam, lParam );
}
break;
}
return 0;
}
//-----------------------------------------------------------------------------
// Name: Initialize()
// Desc: Initialize Direct3D
//-----------------------------------------------------------------------------
HRESULT Initialize()
{
// Create the Direct3D object
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if( g_pD3D == NULL )
{
MessageBox( g_hWnd, "Unable to create the Direct3D object!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Display mode
D3DDISPLAYMODE d3ddm;
// Get the suitable display mode
UINT uNumModes = g_pD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
// Select the best mode (offering the highest frequency at the specified resolution)
D3DDISPLAYMODE* pModes = new D3DDISPLAYMODE[uNumModes];
for( UINT uMode = 0; uMode < uNumModes; uMode++ )
{
// Enumerate the adapter modes
if( FAILED( g_pD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, uMode, &pModes[uMode] ) ) )
{
MessageBox( g_hWnd, "Unable to enumerate adapter display mode!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
}
for( uMode = 0; uMode < uNumModes; uMode++ )
{
if( pModes[uMode].Width == SCREEN_WIDTH && pModes[uMode].Height == SCREEN_HEIGHT )
{
if( pModes[uMode + 1].Width == SCREEN_WIDTH && pModes[uMode + 1].Height == SCREEN_HEIGHT )
{
if( pModes[uMode].RefreshRate > pModes[uMode + 1].RefreshRate )
{
d3ddm = pModes[uMode];
}
else
{
d3ddm = pModes[uMode + 1];
}
}
else
{
d3ddm = pModes[uMode];
}
}
else if( pModes[uMode].Width > SCREEN_WIDTH || pModes[uMode].Height > SCREEN_HEIGHT ) {
break;
}
}
// Delete the list
delete [] pModes;
if( FAILED( g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
MessageBox( g_hWnd, "Unable to find suitable display mode!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// If we are using windowed mode
if( g_bWindowed )
g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
if( FAILED( g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
MessageBox( g_hWnd, "Unable to get adapter display mode!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Get the hardware caps
D3DCAPS9 d3dCaps;
if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, &d3dCaps ) ) )
{
MessageBox( g_hWnd, "Unable to get hardware caps!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Check for vertex/pixel shaders 2.0 support
if( d3dCaps.VertexShaderVersion < D3DVS_VERSION( 2, 0 ) || d3dCaps.PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
{
MessageBox( g_hWnd, "Vertex/Pixel shaders 2.0 not supported!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Check for R32F surface format support
if( FAILED( g_pD3D->CheckDepthStencilMatch( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format,
D3DFMT_R32F, D3DFMT_D16 ) ) )
{
MessageBox( g_hWnd, "R32F format not supported!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
DWORD dwBehaviorFlags = 0;
if( d3dCaps.VertexProcessingCaps != 0 )
dwBehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
else
dwBehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.BackBufferWidth = d3ddm.Width;
d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = g_hWnd;
d3dpp.Windowed = g_bWindowed;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
if( g_bWindowed )
{
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
}
else
{
d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
}
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
{
MessageBox( g_hWnd, "Unable to create the Direct3D device!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Create the font object
if( FAILED( D3DXCreateFont( g_pd3dDevice, 16, 0, FW_BOLD, 1, false, DEFAULT_CHARSET,
OUT_TT_ONLY_PRECIS, 0, 0, "Veranda", &g_pFont ) ) )
{
MessageBox( g_hWnd, "Unable to create the font object!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Load the scene
LPD3DXMESH pTempScene = NULL;
if( FAILED( D3DXLoadMeshFromX( "Media/Soft Shadows.x", D3DXMESH_32BIT, g_pd3dDevice,
NULL, NULL, NULL, NULL, &pTempScene ) ) )
{
MessageBox( g_hWnd, "Unable to load Soft Shadows.x", "Error", MB_OK | MB_ICONERROR );
return E_FAIL;
}
pTempScene->CloneMesh( D3DXMESH_32BIT, dwElement, g_pd3dDevice, &g_pScene );
SAFE_RELEASE( pTempScene );
// Compute the normals and tangents for the scene
D3DXComputeNormals( g_pScene, NULL );
// Create the effect
LPD3DXBUFFER pBufferErrors = NULL;
if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "Media/Soft Shadows.fx", NULL, NULL, 0,
NULL, &g_pEffect, &pBufferErrors ) ) )
{
LPVOID pErrors = pBufferErrors->GetBufferPointer();
MessageBox(NULL, (const char*)pErrors, ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
SAFE_RELEASE( pBufferErrors );
// Create the quad vertex buffer
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 4 * sizeof(QuadVertex), D3DUSAGE_WRITEONLY, FVF_QUADVERTEX,
D3DPOOL_DEFAULT, &g_pQuadVB, NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create vertex buffer!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Copy the vertices
QuadVertex* pVertices;
g_pQuadVB->Lock( 0, 0, (void**)&pVertices, 0 );
pVertices[0].p = D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f );
pVertices[1].p = D3DXVECTOR4( 0.0f, SCREEN_HEIGHT / 2, 0.0f, 1.0f );
pVertices[2].p = D3DXVECTOR4( SCREEN_WIDTH / 2, 0.0f, 0.0f, 1.0f );
pVertices[3].p = D3DXVECTOR4( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 0.0f, 1.0f );
pVertices[0].t = D3DXVECTOR2( 0.0f, 0.0f );
pVertices[1].t = D3DXVECTOR2( 0.0f, 1.0f );
pVertices[2].t = D3DXVECTOR2( 1.0f, 0.0f );
pVertices[3].t = D3DXVECTOR2( 1.0f, 1.0f );
g_pQuadVB->Unlock();
// Load the color and spot maps
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Color_Floor.dds", &g_pColorMap_Floor ) ) )
{
MessageBox( g_hWnd, "Unable to load Color_Floor.dds", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/Color_Statue.dds", &g_pColorMap_Statue ) ) )
{
MessageBox( g_hWnd, "Unable to load Color_Statue.dds", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, "Media/SpotMap.dds", &g_pSpotMap ) ) )
{
MessageBox( g_hWnd, "Unable to load SpotMap.dds", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Create the shadow map
if( FAILED( g_pd3dDevice->CreateTexture( SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 1, D3DUSAGE_RENDERTARGET,
D3DFMT_R32F, D3DPOOL_DEFAULT, &g_pShadowMap, NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create shadow map!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Grab the texture's surface
g_pShadowMap->GetSurfaceLevel( 0, &g_pShadowSurf );
// Create the screen-sized buffer map
if( FAILED( g_pd3dDevice->CreateTexture( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1, D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pScreenMap, NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create screen map!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Grab the texture's surface
g_pScreenMap->GetSurfaceLevel( 0, & g_pScreenSurf );
// Create the blur maps
for( int i = 0; i < 2; i++ )
{
if( FAILED( g_pd3dDevice->CreateTexture( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1, D3DUSAGE_RENDERTARGET,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pBlurMap[i], NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create blur map!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Grab the texture's surface
g_pBlurMap[i]->GetSurfaceLevel( 0, & g_pBlurSurf[i] );
}
// Create the shadow depth surface
if( FAILED( g_pd3dDevice->CreateDepthStencilSurface( SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, D3DFMT_D16,
D3DMULTISAMPLE_NONE, 0, TRUE, &g_pShadowDepth, NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create shadow depth surface!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
// Create the general depth surface
if( FAILED( g_pd3dDevice->CreateDepthStencilSurface( SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, D3DFMT_D16,
D3DMULTISAMPLE_NONE, 0, TRUE, &g_pNewDepthRT, NULL ) ) )
{
MessageBox( g_hWnd, "Unable to create general depth surface!", ERROR, MB_OK | MB_ICONERROR );
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ShutDown()
// Desc: ShutDown Direct3D
//-----------------------------------------------------------------------------
HRESULT ShutDown()
{
// Clean up
SAFE_RELEASE( g_pFont );
SAFE_RELEASE( g_pScene );
SAFE_RELEASE( g_pEffect );
SAFE_RELEASE( g_pColorMap_Floor );
SAFE_RELEASE( g_pColorMap_Statue );
SAFE_RELEASE( g_pSpotMap );
SAFE_RELEASE( g_pShadowMap );
SAFE_RELEASE( g_pShadowSurf );
SAFE_RELEASE( g_pShadowDepth );
SAFE_RELEASE( g_pScreenMap );
SAFE_RELEASE( g_pScreenSurf );
SAFE_RELEASE( g_pBlurMap[0] );
SAFE_RELEASE( g_pBlurSurf[0] );
SAFE_RELEASE( g_pBlurMap[1] );
SAFE_RELEASE( g_pBlurSurf[1] );
SAFE_RELEASE( g_pNewDepthRT );
SAFE_RELEASE( g_pOldColorRT );
SAFE_RELEASE( g_pOldDepthRT );
SAFE_RELEASE( g_pd3dDevice );
SAFE_RELEASE( g_pD3D );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Setup effect variables and update stuff
//-----------------------------------------------------------------------------
HRESULT FrameMove()
{
//
// Camera space matrices
//
// Computee the world matrix
D3DXMATRIX matWorld;
D3DXMatrixIdentity( &matWorld );
// Compute the view matrix
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &g_vEyePos, &g_vEyeAim, &g_vUp );
// Compute the projection matrix
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian(60.0f), (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, 1.0f, 1024.0f );
// Compute the world-view-projection matrix
D3DXMATRIX matWorldViewProj = matWorld * matView * matProj;
// World inverse matrix
D3DXMATRIX matWorldIT;
D3DXMatrixInverse( &matWorldIT, NULL, &matWorld );
D3DXMatrixTranspose( &matWorldIT, &matWorldIT );
//
// Light space matrices
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -