📄 shader_morph.cpp
字号:
// Camera setup
D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f);
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
// View
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
// Projection
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 1.0f, 1000.0f);
m_pNVDevice->SetViewTransform(&matView);
m_pNVDevice->SetProjectionTransform(&matProj);
return S_OK;
}
HRESULT CShaderMorph::Free()
{
SAFE_RELEASE(m_pDolphinMap);
SAFE_RELEASE(m_pDolphinIB);
SAFE_RELEASE(m_pDolphinVB[0]);
SAFE_RELEASE(m_pDolphinVB[1]);
SAFE_RELEASE(m_pDolphinVB[2]);
while(!m_vecCausticTextures.empty())
{
LPDIRECT3DTEXTURE8 pTexture = m_vecCausticTextures.back();
SAFE_RELEASE(pTexture);
m_vecCausticTextures.pop_back();
}
SAFE_DELETE(m_pFloorMesh);
SAFE_DELETE(m_pNVDevice);
if (m_pD3DDev)
{
m_pD3DDev->DeleteVertexShader(m_dwDolphinShader);
m_pD3DDev->DeleteVertexShader(m_dwSeaFloorShader);
SAFE_RELEASE(m_pD3DDev);
}
return S_OK;
}
HRESULT CShaderMorph::Start()
{
return S_OK;
}
HRESULT CShaderMorph::SetTransform()
{
D3DXMATRIX matWorld, matView, matProj;
D3DXMATRIX matWorldView;
D3DXMATRIX matWorldViewIT;
D3DXMATRIX matWorldViewProj;
matWorld = m_pNVDevice->GetWorldTransform();
matView = m_pNVDevice->GetViewTransform();
matProj = m_pNVDevice->GetProjectionTransform();
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matWorldView, &matProj);
D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
D3DXMatrixTranspose(&matWorldView, &matWorldView);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
D3DXMatrixTranspose(&matWorldView, &matWorldView);
// Worldview transform
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matWorldViewIT(0, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matWorldViewIT(1, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matWorldViewIT(2, 0), 1);
return S_OK;
}
HRESULT CShaderMorph::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
D3DXMATRIX matWorld;
D3DXMATRIX matView;
D3DXMATRIX matTemp;
if (m_bPause)
return S_OK;
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, WATER_COLOR, 1.0, 0);
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
float fKickFreq = pTimer->GetDuration() * 2.0f;
float fPhase = pTimer->GetDuration() / 3.0f;
// Select the second frame to lerp with, based on the time.
// We have 3 meshes - the middle and the top for the up phase, the
// middle and the bottom for the down phase
float fSinTheta = sin(fKickFreq);
if (fSinTheta < 0.0f)
{
fSinTheta = -fSinTheta;
hr = m_pD3DDev->SetStreamSource(1, m_pDolphinVB[0], sizeof(DolphinVertex));
if (FAILED(hr))
return hr;
}
else
{
hr = m_pD3DDev->SetStreamSource(1, m_pDolphinVB[2], sizeof(DolphinVertex));
if (FAILED(hr))
return hr;
}
m_pD3DDev->SetStreamSource(0, m_pDolphinVB[1], sizeof(DolphinVertex));
m_pD3DDev->SetIndices(m_pDolphinIB, 0);
m_pD3DDev->SetVertexShader(m_dwDolphinShader);
// Put the weights in the vertex shader
m_pD3DDev->SetVertexShaderConstant(CV_WEIGHT, D3DXVECTOR4(1.0f - fSinTheta, fSinTheta, 0.0f, 0.0f), 1);
// Move the dolphin in a circle
D3DXMATRIX matScale, matTrans1, matRotate1, matRotate2;
D3DXMatrixRotationZ( &matRotate1, -cosf(fKickFreq)/6 );
D3DXMatrixRotationY( &matRotate2, fPhase );
D3DXMatrixScaling( &matScale, 0.01f, 0.01f, 0.01f );
D3DXMatrixTranslation( &matTrans1, -5*sinf(fPhase), sinf(fKickFreq)/2, 10-10*cosf(fPhase) );
D3DXMatrixIdentity(&matWorld);
D3DXMatrixMultiply( &matWorld, &matTrans1, &matWorld);
D3DXMatrixMultiply( &matWorld, &matScale, &matWorld);
D3DXMatrixMultiply( &matWorld, &matRotate2, &matWorld);
D3DXMatrixMultiply( &matWorld, &matRotate1, &matWorld);
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
// Create a directional light
D3DXVECTOR3 vLightToEye;
D3DXVECTOR3 vLight(0.0f, -1.0f, 0.0f);
D3DXVECTOR4 vLightEye;
// Transform direction vector into eye space
matView = m_pNVDevice->GetViewTransform();
D3DXVec3Normalize(&vLightToEye, &vLight);
D3DXVec3TransformNormal(&vLightToEye, &vLightToEye, &matView);
D3DXVec3Normalize(&vLightToEye, &vLightToEye);
// Shader math requires that the vector is to the light
vLightEye.x = -vLightToEye.x;
vLightEye.y = -vLightToEye.y;
vLightEye.z = -vLightToEye.z;
vLightEye.w = 1.0f;
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT1_DIRECTION, &vLightEye.x, 1);
D3DXVECTOR4 vLightAmbient(0.2f, 0.2f, 0.2f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT1_AMBIENT, &vLightAmbient.x, 1);
if (m_pDolphinMap)
m_pD3DDev->SetTexture(0, m_pDolphinMap);
DWORD tex = ((DWORD)(pTimer->GetDuration()*32))%32;
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
// Copy the alpha through from the vertex shader
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
// Note that this premodulate is possible because the vertex shader has cunningly setup
// the alpha channel to contain the intensity of the light.
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDCURRENTALPHA);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
if ((m_vecCausticTextures.size() > tex) && m_vecCausticTextures[tex])
m_pD3DDev->SetTexture(1, m_vecCausticTextures[tex]);
hr = m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumIndices/3);
// Sea roof
D3DXMatrixRotationZ(&matWorld, D3DX_PI);
matWorld._42 += 10.0f;
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_pD3DDev->SetTexture(1, m_vecCausticTextures[tex]);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
m_pFloorMesh->Render(m_pNVDevice);
// Sea floor
D3DXMatrixScaling( &matWorld, 1.0f, 1.0f, 1.0f);
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
m_pFloorMesh->Render(m_pNVDevice);
return hr;
}
HRESULT CShaderMorph::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
if (!(pCaps->MaxSimultaneousTextures >= 2))
{
m_strLastError = "Device cannot dual texture!";
return E_FAIL;
}
if (!(pCaps->TextureOpCaps & D3DTEXOPCAPS_BLENDCURRENTALPHA))
{
m_strLastError = "Device cannot handle BLENDCURRENTALPHA operation!";
return E_FAIL;
}
return S_OK;
}
void CShaderMorph::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 W - Wireframe Toggle \n\n P\\Pause - Pause animation\n\n",
"Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
}
break;
case EB_WIREFRAME:
{
m_bWireframe = !m_bWireframe;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_PAUSE:
{
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
default:
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -