📄 shader_simplefog.cpp
字号:
SetView();
}
HRESULT CShaderSimpleFog::Start()
{
m_fAngle = 0.0f;
return S_OK;
}
void CShaderSimpleFog::Keyboard( DWORD dwKey, UINT nFlags, bool bDown)
{
float strafe_factor = 0.1f;
float strafe_min = 0.1f;
UINT charcode;
int maxtess = 70;
if( bDown )
{
switch( dwKey )
{
case 'R':
// increase tesselation
m_nVDiv ++;
GenerateObj();
break;
case 'F':
// decrease tesselation
m_nVDiv --;
if( m_nVDiv < 0 )
m_nVDiv = 0;
else if( m_nVDiv > maxtess )
m_nVDiv = maxtess;
GenerateObj();
break;
case 'G':
// increase tesselation
m_nHDiv ++;
GenerateObj();
break;
case 'D':
// decrease tesselation
m_nHDiv --;
if( m_nHDiv < 0 )
m_nHDiv = 0;
else if( m_nHDiv > maxtess )
m_nHDiv = maxtess;
GenerateObj();
break;
case 'W':
m_bWireframe = !m_bWireframe;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
break;
case VK_UP :
case VK_NUMPAD8 :
m_EyePos.y +=max( strafe_min, fabs( m_EyePos.y * strafe_factor ));
m_vLookAt.y += max( strafe_min, fabs( m_vLookAt.y * strafe_factor ));
SetView();
break;
case VK_DOWN :
case VK_NUMPAD2 :
m_EyePos.y -=max( strafe_min, fabs( m_EyePos.y * strafe_factor ));
m_vLookAt.y -= max( strafe_min, fabs( m_vLookAt.y * strafe_factor ));
SetView();
break;
case VK_LEFT :
case VK_NUMPAD4 :
m_EyePos.x -=max( strafe_min, fabs( m_EyePos.x * strafe_factor ));
m_vLookAt.x -= max( strafe_min, fabs( m_vLookAt.x * strafe_factor ));
SetView();
break;
case VK_RIGHT :
case VK_NUMPAD6 :
m_EyePos.x += max( strafe_min, fabs( m_EyePos.x * strafe_factor ));
m_vLookAt.x += max( strafe_min, fabs( m_vLookAt.x * strafe_factor ));
SetView();
break;
case VK_NUMPAD9 :
case VK_PRIOR : // pageup
m_EyePos.z += max( strafe_min, fabs( m_EyePos.z * strafe_factor ));
m_vLookAt.z += max( strafe_min, fabs( m_vLookAt.z * strafe_factor ));
SetView();
break;
case VK_NUMPAD3 :
case VK_NEXT : // pagedown
m_EyePos.z -= max( strafe_min, fabs( m_EyePos.z * strafe_factor ));
m_vLookAt.z -= max( strafe_min, fabs( m_vLookAt.z * strafe_factor ));
SetView();
break;
case VK_HOME :
case VK_NUMPAD7 :
SetDefaultView();
break;
default:
charcode = MapVirtualKey( dwKey, 2 ); // VK to char code
switch( charcode )
{
case '.':
case '>':
m_fHtFogFac += 0.01f;
//FDebug("fogfac: %f\n", m_fHtFogFac );
break;
case ',':
case '<':
m_fHtFogFac -= 0.01f;
//FDebug("fogfac: %f\n", m_fHtFogFac );
break;
case '[':
case '{':
m_fWidth -= 0.05f;
break;
case ']':
case '}':
m_fWidth += 0.05f;
break;
};
break;
}
}
eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
EBString str;
switch ( Action )
{
case EB_HELP:
str = " Help : F1 - Help\n\n";
str += " W - Wireframe toggle\n\n";
str += " Home - Reset view & terrain\n\n";
str += ". > - Increase height fog\n";
str += ", < - Decrease height fog\n\n";
str += "R - Increase vertical tesselation\n";
str += "F - Decrease \"\"\n";
str += "G - Increase horizontal tesselation \n";
str += "D - Decrease \"\"\n\n";
str += "W - Wireframe\n";
str += "Arrows - Move camera\n";
str += "Home - Reset camera & landscape\n";
str += "PgUP - Move camera up\n";
str += "PgDown - Move camera down\n";
MessageBoxEx( NULL, str.c_str(),
"Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
break;
default:
break;
}
}
HRESULT CShaderSimpleFog::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
D3DXMATRIX matWorld, matInvWorld;
D3DXMATRIX matTemp;
D3DXVECTOR4 eyeObjSpc, lightObjSpc; // eye and light positions in object space
// Clear to grey
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
if( m_bWireframe )
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
else
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
}
// Increase rotation
m_fAngle = 9.0f * ((float)timeGetTime())/1000.0f;
// Set light position:
float lightr = 4.5f;
float lang = m_fAngle * 8.0f;
m_LightPos.x = lightr * (float)sin( D3DXToRadian( lang ) );
m_LightPos.y = lightr * (float)cos( D3DXToRadian( lang ) );
m_LightPos.z = 1.0f;
// Uncomment for no object rotation
// m_fAngle = 0.0f;
D3DXVECTOR3 vRotation;
// World matrix for rendering ground object
// rotate 90 degrees
vRotation = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixRotationAxis( &matTemp, &vRotation, D3DXToRadian( 90.0f ));
// rotate about new vertical axis:
vRotation = D3DXVECTOR3( 0.0f, 0.0f, 1.0f);
D3DXMatrixRotationAxis( &matWorld, &vRotation, D3DXToRadian(m_fAngle));
D3DXMatrixMultiply( &matWorld, &matTemp, &matWorld );
// compute inverse of rotation matrix
D3DXMatrixTranspose( &matInvWorld, &matWorld );
// Transform light and cam pos to object space and set vshader constants
D3DXVec3Transform( &lightObjSpc, &m_LightPos, &matInvWorld );
D3DXVec3Transform( &eyeObjSpc, &m_EyePos, &matInvWorld );
// Set vshader constants
m_pD3DDev->SetVertexShaderConstant( CV_LIGHT_POS_OSPACE, (void*)&lightObjSpc.x, 1 );
m_pD3DDev->SetVertexShaderConstant( CV_EYE_POS_OSPACE, (void*)&eyeObjSpc.x, 1 );
// Set vshader constant to world * view * proj matrix:
D3DXMatrixMultiply( &matTemp, &matWorld, &m_matView );
D3DXMatrixMultiply( &matTemp, &matTemp, &m_matProj );
// Set 4 constants starting with CV_WORLDVIEWPROJ_0
D3DXMatrixTranspose( &matTemp, &matTemp );
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matTemp(0, 0), 4);
m_pD3DDev->SetVertexShader(m_dwSimpleFogVShader);
m_pD3DDev->SetPixelShader(m_dwSimpleFogPixelShader);
m_pD3DDev->SetTexture(0,(LPDIRECT3DBASETEXTURE8)m_pDecalTexture);
m_pD3DDev->SetRenderState( D3DRS_FOGENABLE, true );
// Must set D3DFOG_NONE even though this is the supposed default
m_pD3DDev->SetRenderState( D3DRS_FOGVERTEXMODE, D3DFOG_NONE );
m_pD3DDev->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
m_pD3DDev->SetRenderState( D3DRS_FOGCOLOR, 0x00aaaaaa );
////////////////////////////////////////////////////////////
// A better program would update these only when they
// have changed!
float m_fFogStart, m_fFogEnd, m_fFogRange;
m_fFogStart = 10.0f;
m_fFogEnd = 15.0f;
m_fFogRange = 5.0f;
D3DXVECTOR4 vFog( m_fFogStart, m_fFogEnd, m_fFogRange, 0.5f );
m_pD3DDev->SetVertexShaderConstant( CV_FOGPARAMS, &vFog, 1 );
// Now set attenuation & exp factor for height-based fog
D3DXVECTOR4 vHtFog( m_fHtFogFac, 0.1f, 0.1f, 0.5f );
m_pD3DDev->SetVertexShaderConstant( CV_HEIGHT_FOG_PARAMS, &vHtFog, 1 );
////////////////////////////////////////////////////////////
// Draw the landscape object
if( m_pObj != NULL )
{
m_pObj->Draw( m_pD3DDev );
}
// Set world matrix to light position & render light
// stand-in object:
D3DXMatrixTranslation( &matWorld, m_LightPos.x, m_LightPos.y, m_LightPos.z );
// Setup the transforms
m_pD3DDev->SetTransform(D3DTS_PROJECTION, &m_matProj );
m_pD3DDev->SetTransform(D3DTS_VIEW, &m_matView );
m_pD3DDev->SetTransform(D3DTS_WORLD, &matWorld );
m_pD3DDev->SetVertexShader( SOBJVERT_FVF );
m_pD3DDev->SetPixelShader( m_dwSimpleFogNoLightShader );
m_pD3DDev->SetTexture(0,(LPDIRECT3DBASETEXTURE8) m_pLightObjTexture );
m_pD3DDev->SetRenderState( D3DRS_FOGENABLE, false );
// Draw the light object
if( m_pObjLight != NULL )
{
m_pObjLight->Draw( m_pD3DDev );
}
return hr;
}
HRESULT CShaderSimpleFog::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
if (!(pCaps->TextureCaps & D3DPTEXTURECAPS_PROJECTED))
{
m_strLastError = "Device does not support 3 element texture coordinates!";
return E_FAIL;
}
if (!(pCaps->MaxTextureBlendStages >= 2))
{
m_strLastError = "Not enough texture blend stages!";
return E_FAIL;
}
if(D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion) < 1)
{
m_strLastError = "Device does not support pixel shaders!";
return E_FAIL;
}
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -