📄 shader_shadows.cpp
字号:
m_Models.clear();
SAFE_RELEASE( m_pTigerTexture );
SAFE_RELEASE(m_pShowShadowMapVB);
SAFE_DELETE(m_pFloorMesh);
SAFE_DELETE(m_pObjectMesh);
SAFE_RELEASE(m_pShadowMap);
SAFE_RELEASE(m_pShadowGen);
SAFE_RELEASE(m_pShadowZBuffer);
SAFE_DELETE(m_pNVDevice);
if (m_pD3DDev)
{
m_pD3DDev->DeleteVertexShader(m_dwShadowGenShader);
m_pD3DDev->DeleteVertexShader(m_dwShadowShowShader);
m_pD3DDev->DeleteVertexShader( m_dwDrawObjectShader );
SAFE_RELEASE(m_pD3DDev);
}
return S_OK;
}
HRESULT CShaderShadows::Start()
{
return S_OK;
}
HRESULT CShaderShadows::SetTransform()
{
D3DXMATRIX matWorld, matView, matProj;
D3DXMATRIX matWorldView, matWorldViewIT;
float unused;
matWorld = m_pNVDevice->GetWorldTransform();
matView = m_pNVDevice->GetViewTransform();
matProj = m_pNVDevice->GetProjectionTransform();
m_pD3DDev->SetTransform( D3DTS_VIEW, (D3DMATRIX*)(&matView) );
m_pD3DDev->SetTransform( D3DTS_WORLD, (D3DMATRIX*)(&matWorld));
m_pD3DDev->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)(&matProj));
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse( &matWorldViewIT, &unused, &matWorldView);
//Projection to clip space
//D3DXMatrixTranspose(&matProj, &matProj);
//m_pD3DDev->SetVertexShaderConstant(CV_PROJ_TXF_0, &matProj(0, 0), 4);
// Projection to view-space
// D3DXMatrixTranspose(&matWorldView, &matWorldView);
// m_pD3DDev->SetVertexShaderConstant(CV_CURR_WORLDVIEW_TXF_0, &matWorldView(0, 0), 3);
return S_OK;
}
D3DXMATRIX CShaderShadows::CreateLightMatrix( const unsigned int& i )
{
D3DXMATRIX matView;
D3DXMatrixIdentity( &matView );
assert( i < LIGHT_COUNT );
if ( i < LIGHT_COUNT )
{
// Light Camera setup
D3DXVECTOR3 vEyePt = m_Lights[ i ].Position;
D3DXVECTOR3 vLookatPt = m_Lights[ i ].Position;
vLookatPt += m_Lights[ i ].Direction;
D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
}
return matView;
}
HRESULT CShaderShadows::CreateShadowMap()
{
// Set up Render to Texture
D3DXMATRIX matView = CreateLightMatrix( 0 );
m_pNVDevice->SetViewTransform(&matView);
LPDIRECT3DSURFACE8 pSurface = 0;
LPDIRECT3DSURFACE8 pBackBuffer = 0;
LPDIRECT3DSURFACE8 pZBuffer = 0;
HRESULT hr = D3D_OK;
{ // save back buffer & Z buffer
hr = m_pD3DDev->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
hr = m_pD3DDev->GetDepthStencilSurface( &pZBuffer );
}
hr = m_pShadowMap->GetSurfaceLevel(0, &pSurface );
// Dx8 will automatically set up the Viewport for us when we call SetRenderTarget()
hr = m_pD3DDev->SetRenderTarget( pSurface, m_pShadowZBuffer );
// Clear to objectID # 00, at closest distance
hr = m_pD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL, 0x00000000, 1.0, 0xffffffff );
m_pD3DDev->SetStreamSource(0, m_pObjectMesh->m_pVB, sizeof(ShadowsVertex));
m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &matView, 4 );
m_pD3DDev->SetVertexShader(m_dwShadowGenShader);
m_pD3DDev->SetTexture(0, m_pShadowGen);
m_pObjectMesh->SetVertexShader( m_dwShadowGenShader );
m_pObjectMesh->SetTexture( m_pShadowGen);
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
// Setup render states
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3DDev->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
// Set up projection matrix for rendering
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetProjectionTransform(&matProj);
// For each object
// Set up Squish matrix that will take the Z depth from the light and map into the depth texture
// such that 0..1 maps to center - radius .. center + radius
// Go through each model and draw to the shadow map
for ( unsigned int i = 0; i < m_Models.size(); ++i )
{
// TODO: Handle case where sphere overlaps that light plane, just clamp the range...?
D3DXMATRIX tempMatrix, modelToLightMatrix;
D3DXMATRIX matModel = m_Models[ i ].mModelMatrix;
D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);
D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );
D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &tempMatrix, 4 );
matView = CreateLightMatrix( 0 );
D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);
//D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );
// set its objectID in the vertex program constants
unsigned int theObjectID = 1 + i;
D3DXVECTOR4 vColorCurrent( (float)( theObjectID ) / 255.0f, 0.0f, 0.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant( CV_CURR_OBJECTID_IN_TEXELS, &vColorCurrent, 1 );
// Compute Squish Matrix - Maps object from Model Space to Light View Space and scales the Z range
// to be 0..1 within the object's bounding sphere
{
// aBounds.Transform( &modelToLightMatrix );
NVBounds aBounds = *(m_pObjectMesh->GetBounds());
aBounds.Transform( &modelToLightMatrix );
// Only really need radius with respect to light space Z
// We are overestimating a bit to eliminate clamping
float theRadius = max( 1.0f, ( aBounds.m_vecMaxExtents.z - aBounds.m_vecMinExtents.z ) / 1.95f );
D3DXVECTOR4 center( aBounds.m_vecCenter.x,
aBounds.m_vecCenter.y,
aBounds.m_vecCenter.z,
1.0f );
// Use center.z - radius to map to a Z of 0
D3DXMATRIX SquishMatrix( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, -( center.z - theRadius ), 1.0f );
D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &SquishMatrix );
D3DXMATRIX SquishMatrix2( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f / theRadius, 0.0f,
0.0f, 0.0f, 0.0f , 1.0f );
D3DXMatrixMultiply( &SquishMatrix, &tempMatrix, &SquishMatrix2 );
// Set the SquishMatrix
D3DXMatrixTranspose( &SquishMatrix, &SquishMatrix );
m_pD3DDev->SetVertexShaderConstant( CV_CURR_SQUISH_TXF_0, &SquishMatrix, 4 );
}
// Set up Texture States & Render
{
// Don't mip map or filter the ShadowGen Texture
m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_POINT );
// Clamp outside of range 0..1
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0x80808080 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 );
// Setup render states
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3DDev->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
hr = m_pObjectMesh->Render( m_pNVDevice );
}
}
{ // Restore Back & Z buffers
if ( pSurface )
{
pSurface->Release(), pSurface = 0;
}
if ( m_pShadowZBuffer )
{
//m_pShadowZBuffer->Release();
}
// Dx8 will automatically set up the Viewport for us when we call SetRenderTarget()
hr = m_pD3DDev->SetRenderTarget( pBackBuffer, pZBuffer );
// Give back refcounts on our local copies
pBackBuffer->Release();
pZBuffer->Release();
}
return hr;
}
HRESULT CShaderShadows::DrawObjects()
{
D3DXMATRIX matView, matTemp, matProj;
// Projection set up
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetProjectionTransform(&matProj);
D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
for ( unsigned int i = 0; i < m_Models.size(); ++i )
{
m_Models[ i ].m_pNVMesh->SetVertexShader( m_dwDrawObjectShader );
m_Models[ i ].m_pNVMesh->SetTexture(m_Models[ i ].m_pOldTexture);
D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
D3DXMatrixMultiply( &matTemp, &m_Models[ i ].mModelMatrix, &matView );
D3DXMatrixMultiply( &matTemp, &matTemp, &matProj);
D3DXMatrixTranspose( &matTemp, &matTemp);
m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &matTemp, 4 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pNVDevice->SetWorldTransform( & m_Models[ i ].mModelMatrix );
SetTransform();
m_Models[ i ].m_pNVMesh->Render(m_pNVDevice);
}
return S_OK;
}
HRESULT CShaderShadows::DrawSeaFloor()
{
D3DXMATRIX matWorld,matView;
// Sea floor
D3DXMatrixScaling( &matWorld, 1.0f, 1.0f, 1.0f);
m_pNVDevice->SetWorldTransform(&matWorld);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
m_pNVDevice->SetViewTransform( &matView );
m_pFloorMesh->SetVertexShader( 0 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
SetTransform();
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pFloorMesh->Render( m_pNVDevice );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -