I'm trying to render a simple shadow map in DirectX 10. I've pieced together some code from a number of tutorials. I'm trying to render to a depth stencil view from the lights perspective and then bind that to a texture and render the scene from the camera's perspective. The standard shadow map method. But the output from the depth stencil view rendering is blank(checked in PerfHUD). When I render the from the light perspective to the standard view port the scene elements show up, so it can't be the light's transform matrices. Below is some of my code.
In OnD3D10CreateDevice:
// Create Shadow Texture
D3D10_TEXTURE2D_DESC dstex;
dstex.Width = 800;
dstex.Height = 800;
dstex.MipLevels = 1;
dstex.ArraySize = 1;
dstex.SampleDesc.Count = 1;
dstex.SampleDesc.Quality = 0;
//dstex.Format = DXGI_FORMAT_R24G8_TYPELESS;
dstex.Format = DXGI_FORMAT_R32_TYPELESS;
dstex.Usage = D3D10_USAGE_DEFAULT;
dstex.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
dstex.CPUAccessFlags = 0;
dstex.MiscFlags = 0;
SAFE_RELEASE(g_pShadowMapDepth);
if( FAILED( pd3dDevice->CreateTexture2D( &dstex, NULL, &g_pShadowMapDepth ) ) )
{
DXUTTRACE( L"Failed to create depth stencil texture\n" );
return false;
}
// Create the depth stencil view for the shadow map
D3D10_DEPTH_STENCIL_VIEW_DESC DescDS;
//DescDS.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
DescDS.Format = DXGI_FORMAT_D32_FLOAT;
DescDS.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
DescDS.Texture2D.MipSlice = 0;
SAFE_RELEASE(g_pShadowMapDepthView);
if( FAILED( pd3dDevice->CreateDepthStencilView( g_pShadowMapDepth, &DescDS, &g_pShadowMapDepthView ) ) )
{
DXUTTRACE( L"Failed to create depth stencil view for a depth map\n" );
return false;
}
// Create the shader resource view for the shadow map
D3D10_SHADER_RESOURCE_VIEW_DESC SRVDesc;
ZeroMemory( &SRVDesc, sizeof( SRVDesc ) );
//SRVDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
SRVDesc.Format = DXGI_FORMAT_R32_FLOAT;
SRVDesc.ViewDimension = D3D10_SRV_DIMENSION_TEXTURE2D;
//D3D10_DSV_DIMENSION_TEXTURE2DMS;
SRVDesc.Texture2D.MipLevels = 1;
SRVDesc.Texture2D.MostDetailedMip = 0;
if( FAILED( pd3dDevice->CreateShaderResourceView( g_pShadowMapDepth, &SRVDesc, &g_pShadowMapTextureRV ) ) )
{
DXUTTRACE( L"Failed to create shader resource view for a depth stencil\n" );
return false;
}
OnD3D10FrameRender:
void CALLBACK OnD3D10FrameRender( ID3D10Device* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
//
// Clear the back buffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
ID3D10RenderTargetView* pRTV = DXUTGetD3D10RenderTargetView();
pd3dDevice->ClearRenderTargetView( pRTV, ClearColor );
// If the settings dialog is being shown, then
// render it instead of rendering the app's scene
if( g_D3DSettingsDlg.IsActive() )
{
g_D3DSettingsDlg.OnRender( fElapsedTime );
return;
}
//
// Clear the depth stencil
//
ID3D10DepthStencilView* pDSV = DXUTGetD3D10DepthStencilView();
pd3dDevice->ClearDepthStencilView( pDSV, D3D10_CLEAR_DEPTH, 1.0, 0 );
//pd3dDevice->ClearDepthStencilView( g_pShadowMapDepthView, D3D10_CLEAR_DEPTH, 1.0, 0 );
//
// Update variables that change once per frame
//
g_pProjectionVariable->SetMatrix( (float*)g_Camera.GetProjMatrix() );
g_pViewVariable->SetMatrix( (float*)g_Camera.GetViewMatrix() );
g_pWorldVariable->SetMatrix( (float*)&g_World );
//
// Set the Vertex Layout
//
pd3dDevice->IASetInputLayout( g_pVertexLayout );
//
// Render the mesh
//
UINT Strides[1];
UINT Offsets[1];
ID3D10Buffer* pVB[1];
pVB[0] = g_Mesh.GetVB10(0,0);
Strides[0] = (UINT)g_Mesh.GetVertexStride(0,0);
Offsets[0] = 0;
pd3dDevice->IASetVertexBuffers( 0, 1, pVB, Strides, Offsets );
pd3dDevice->IASetIndexBuffer( g_Mesh.GetIB10(0), g_Mesh.GetIBFormat10(0), 0 );
D3D10_TECHNIQUE_DESC techDesc;
g_pTechnique->GetDesc( &techDesc );
SDKMESH_SUBSET* pSubset = NULL;
ID3D10ShaderResourceView* pDiffuseRV = NULL;
D3D10_PRIMITIVE_TOPOLOGY PrimType;
// Set a Viewport for rendering to shadow map
D3D10_VIEWPORT SMVP;
SMVP.Height = 800; // TODO: Mod this to global?
SMVP.Width = 800;
SMVP.MinDepth = 0;
SMVP.MaxDepth = 1;
SMVP.TopLeftX = 0;
SMVP.TopLeftY = 0;
pd3dDevice->RSSetViewports( 1, &SMVP );
ID3D10RenderTargetView * nullView[] = {NULL};
pd3dDevice->OMSetRenderTargets(1, nullView, g_pShadowMapDepthView);
//pd3dDevice->OMSetRenderTargets(1, &pRTV, g_pShadowMapDepthView);
//g_pTechnique->GetPassByIndex(0)->Apply(0);
for( UINT subset = 0; subset < g_Mesh.GetNumSubsets(0); ++subset )
{
pSubset = g_Mesh.GetSubset( 0,subset );
PrimType = g_Mesh.GetPrimitiveType10( (SDKMESH_PRIMITIVE_TYPE)pSubset->PrimitiveType );
pd3dDevice->IASetPrimitiveTopology( PrimType );
//pDiffuseRV = g_Mesh.GetMaterial(pSubset->MaterialID)->pDiffuseRV10;
//g_ptxDiffuseVariable->SetResource( pDiffuseRV );
g_pTechnique->GetPassByIndex( 0 )->Apply(0);
pd3dDevice->DrawIndexed( (UINT)pSubset->IndexCount, 0, (UINT)pSubset->VertexStart );
}
// Second pass render to color buffer
// TODO: define windowSize
SMVP.Height = g_WindowSizeY;
SMVP.Width = g_WindowSizeX;
SMVP.MinDepth = 0;
SMVP.MaxDepth = 1;
SMVP.TopLeftX = 0;
SMVP.TopLeftY = 0;
pd3dDevice->RSSetViewports( 1, &SMVP );
pd3dDevice->OMSetRenderTargets( 1, &pRTV, pDSV );
// Set ShadowTexture
g_pShadowMapTextureVariable->SetResource( g_pShadowMapTextureRV );
//g_pTechnique->GetPassByIndex(1)->Apply(0);
for( UINT subset = 0; subset < g_Mesh.GetNumSubsets(0); ++subset )
{
pSubset = g_Mesh.GetSubset( 0,subset );
PrimType = g_Mesh.GetPrimitiveType10( (SDKMESH_PRIMITIVE_TYPE)pSubset->PrimitiveType );
pd3dDevice->IASetPrimitiveTopology( PrimType );
pDiffuseRV = g_Mesh.GetMaterial(pSubset->MaterialID)->pDiffuseRV10;
g_ptxDiffuseVariable->SetResource( pDiffuseRV );
g_pTechnique->GetPassByIndex( 1 )->Apply(0);
pd3dDevice->DrawIndexed( (UINT)pSubset->IndexCount, 0, (UINT)pSubset->VertexStart );
}
//Unbind ShadowTexture
g_pShadowMapTextureVariable->SetResource( NULL );
g_pTechnique->GetPassByIndex(1)->Apply(0);
//the mesh class also had a render method that allows rendering the mesh with the most common options
//g_Mesh.Render( pd3dDevice, g_pTechnique, g_ptxDiffuseVariable );
//
// Render the UI
//
g_HUD.OnRender( fElapsedTime );
g_SampleUI.OnRender( fElapsedTime );
RenderText();
}