📄 shader_shadows.cpp
字号:
HRESULT CShaderShadows::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
D3DXMATRIX matWorld;
D3DXMATRIX matView;
m_pD3DDev->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
float const kSpeed = .25f;
float const fKickFreq = kSpeed * pTimer->GetDuration();
float const fPhase = kSpeed * pTimer->GetDuration() / 3.0f;
// Move the object in a circle
D3DXMATRIX matScale, matTrans1, matRotate1, matRotate2;
D3DXMATRIX matBank, matLocalRotate;
D3DXMatrixRotationY( &matLocalRotate, D3DX_PI/2.0f);
D3DXMatrixRotationX( &matBank, D3DX_PI/8.0f);
D3DXMatrixRotationZ( &matRotate1, 2*D3DX_PI);
D3DXMatrixRotationY( &matRotate2, fPhase );
D3DXMatrixScaling( &matScale, 1.0f, 1.0f, 1.0f );
D3DXMatrixTranslation( &matTrans1, -12*sinf(fPhase) , sinf(fKickFreq) + 4, 10-30*cosf(fPhase) );
D3DXMatrixIdentity(&matWorld);
D3DXMatrixMultiply( &matWorld, &matTrans1, &matWorld);
D3DXMatrixMultiply( &matWorld, &matScale, &matWorld);
D3DXMatrixMultiply( &matWorld, &matRotate2, &matWorld);
D3DXMatrixMultiply( &matWorld, &matRotate1, &matWorld);
D3DXMatrixMultiply( &matWorld, &matBank, &matWorld);
D3DXMatrixMultiply( &matWorld, &matLocalRotate, &matWorld);
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (mbWireFrame) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
if (m_bPause)
return hr;
m_Models[ 0 ].mModelMatrix = matWorld;
CreateShadowMap();
// Camera setup
D3DXVECTOR3 const vEyePt = D3DXVECTOR3( 5.0f, 5.0f, 0.0f);
D3DXVECTOR3 const vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);
D3DXVECTOR3 const vUp = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
m_pNVDevice->SetViewTransform(&matView);
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, BACKGROUND_COLOR, 1.0, 0);
// Projection set up
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetProjectionTransform(&matProj);
D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
DrawSeaFloor();
DrawObjects();
m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_NONE );
unsigned int theObjectID = 0x00;
D3DXVECTOR4 vColorCurrent( (float)( theObjectID ) / 255.0f, 0.0f, 0.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant( CV_CURR_OBJECTID_IN_TEXELS, &vColorCurrent, 1 );
m_pFloorMesh->SetVertexShader( m_dwDrawObjectShader );
m_pFloorMesh->SetVertexShader( m_dwShadowShowShader );
// Set tfactor to r = 1, g = 1, b = 1, a = 0
m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0x00ffffff );
// Compare by doing ShadowGen - ShadowMap
//
// Shadow Gen should always be >= ShadowMap
//
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_SUBTRACT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 );
m_pD3DDev->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_TFACTOR );
m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR );
m_pD3DDev->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE );
// Reject pixels that are in shadow
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
m_pD3DDev->SetRenderState( D3DRS_ALPHAREF, 0x0 );
m_pD3DDev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_EQUAL );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
// 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 );
D3DXMATRIX tempMatrix, modelToLightMatrix;
{
D3DXMATRIX matView = CreateLightMatrix( 0 );
// TODO: Handle case where sphere overlaps that light plane, just clamp the range...?
D3DXMATRIX matModel;
D3DXMatrixIdentity( &matModel );
D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);
D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );
D3DXMATRIX temp2( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.5f,
0.0f, 0.0f, 0.0f, 0.5f );
D3DXMatrixMultiply( &tempMatrix, &tempMatrix, &temp2 );
m_pObjectMesh->SetVertexShader( m_dwShadowShowShader );
m_pObjectMesh->SetTexture( m_pShadowGen);
D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &tempMatrix, 4 );
// Set up projection matrix for rendering
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetProjectionTransform(&matProj);
D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
D3DXMatrixMultiply( &matView, &matView, &matProj);
D3DXMatrixTranspose( &matView, &matView );
m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &matView, 4 );
D3DXMatrixTranspose( &matView, &matView);
m_pD3DDev->SetTexture(0, m_pShadowGen);
m_pD3DDev->SetTexture(1, m_pShadowMap);
// m_pFloorMesh->Render(m_pNVDevice);
}
for ( unsigned int i = 0; i < m_Models.size(); ++i )
{
D3DXMATRIX matTemp;
// Projection set up
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetProjectionTransform(&matProj);
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->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
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 );
D3DXMATRIX matModel = m_Models[ i ].mModelMatrix;
matView = CreateLightMatrix( 0 );
D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);
//D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );
// off set to texture coordinates
D3DXMATRIX temp2( 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.5f,
0.0f, 0.0f, 0.0f, 0.5f );
D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &temp2 );
D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &tempMatrix, 4 );
m_Models[ i ].m_pNVMesh->SetTexture(m_pShadowGen);
m_pD3DDev->SetTexture(1, m_pShadowMap);
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
m_pD3DDev->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE );
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
m_pD3DDev->SetVertexShader(0);
m_Models[ i ].m_pNVMesh->SetVertexShader(m_dwShadowShowShader);
m_Models[ i ].m_pNVMesh->Render(m_pNVDevice);
}
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
if ( m_bShowShadowMap )
{
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_FILLMODE, D3DFILL_SOLID );
m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
m_pD3DDev->SetStreamSource(0, m_pShowShadowMapVB, sizeof(TLVertex));
m_pD3DDev->SetVertexShader(TLVertex::FVF );
m_pD3DDev->SetTexture(0, m_pShadowMap);
m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 );
// Restore render states
m_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
}
return hr;
}
HRESULT CShaderShadows::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
// check vertex shading support
// check simultaneous texture support (only need 2...)
if(pCaps->MaxSimultaneousTextures < 2)
{
m_strLastError = "Device does not support 4 simultaneous textures!";
return E_FAIL;
}
// only need very few, simple register combiners...
if(pCaps->MaxTextureBlendStages < 2)
{
m_strLastError = "Device does not support 2 register combiners!";
return E_FAIL;
}
return S_OK;
}
void CShaderShadows::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
switch ( Action )
{
case EB_HELP:
{
::MessageBoxEx( NULL, " Help : F1 - Help \n\n Home - Reset To Defaults \n\n W - Wireframe Toggle \n\n Pause/Space - Toggle pausing the animation \n\n +/- - Lengthen/Shorten Blur Length",
"Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
}
break;
case EB_WIREFRAME:
{
mbWireFrame = !mbWireFrame;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_PAUSE:
{
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
break;
case EB_RESET :
{
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
m_pMouseUI->Reset();
break;
}
case VK_LEFT :
{
m_pMouseUI->Translate( -1.0f, 0.0f, 0.0f );
break;
}
case VK_RIGHT :
{
m_pMouseUI->Translate( 1.0f, 0.0f, 0.0f );
break;
}
case VK_UP :
{
m_pMouseUI->Translate( 0.0f, 0.0f, -1.0f );
break;
}
case VK_DOWN :
{
m_pMouseUI->Translate( 0.0f, 0.0f, 1.0f );
break;
}
case EB_PAGEUP :
{
m_pMouseUI->Translate( 0.0f, 1.0f, 0.0f );
break;
}
case EB_PAGEDOWN :
{
m_pMouseUI->Translate( 0.0f, -1.0f, 0.0f );
break;
}
case EB_ADD :
{
m_pMouseUI->Translate( 0.0f, 0.0f, 1.0f );
break;
}
case EB_SUBTRACT :
{
m_pMouseUI->Translate( 0.0f, 0.0f, -1.0f );
break;
}
default:
break;
}
}
void CShaderShadows::MouseButton(HWND hWnd, eButtonID button, bool bDown, int x, int y)
{
if(button == MOUSE_LEFTBUTTON)
{
if(bDown)
{
m_pMouseUI->OnLButtonDown(x, y);
}
else
{
m_pMouseUI->OnLButtonUp(x, y);
}
}
return;
}
void CShaderShadows::MouseMove(HWND hWnd, int x, int y)
{
m_pMouseUI->OnMouseMove(x, y);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -