📄 shader_halo.cpp
字号:
//
// Description: Called when we switch away from this demo. Free up all the
// memory that is in use.
// ------------------------------------------------------------------------------
HRESULT CShaderHalo::Free()
{
SAFE_RELEASE(m_pVertexBuffer);
SAFE_RELEASE(m_pIndexBuffer);
if (m_pD3DDev)
{
m_pD3DDev->DeleteVertexShader(m_dwNormalShader);
m_pD3DDev->DeleteVertexShader(m_dwHaloShader);
m_pD3DDev->DeleteVertexShader(m_dwToonShader);
SAFE_RELEASE(m_pD3DDev);
}
SAFE_DELETE(m_pUI);
return S_OK;
}
HRESULT CShaderHalo::LoadXFile(const char* fileName, const DWORD dwFVF)
{
ID3DXMesh* tempMesh, *tempMeshFVF;
ID3DXBuffer* tempMaterials;
HRESULT hr = D3DXLoadMeshFromX(const_cast<char*>(fileName), D3DXMESH_VB_SYSTEMMEM, m_pD3DDev, NULL,
&tempMaterials, &m_dwNumSections, &tempMesh);
//comptr to ensure this object gets released
ComPtr< ID3DXBuffer* > tempMaterialBuffer( tempMaterials, COMPTR_DONT_ADD_REF );
ComPtr< ID3DXMesh* > tempMesh2( tempMesh, COMPTR_DONT_ADD_REF );
if(FAILED(hr))
return hr;
//compute bounding sphere
HVertex* pBuff;
hr = tempMesh->LockVertexBuffer(D3DLOCK_READONLY, (BYTE**)&pBuff);
if(FAILED(hr))
return hr;
D3DXComputeBoundingSphere(pBuff, tempMesh->GetNumVertices(), tempMesh->GetFVF(), &m_vecCenter, &m_fRadius);
tempMesh->UnlockVertexBuffer();
//convert to our format, and also make writeonly
hr = tempMesh->CloneMeshFVF(D3DXMESH_WRITEONLY, dwFVF, m_pD3DDev, &tempMeshFVF);
if(FAILED(hr))
return hr;
//comptr to ensure this object gets released
ComPtr< ID3DXMesh* > tempMesh4( tempMeshFVF, COMPTR_DONT_ADD_REF );
tempMeshFVF->GetVertexBuffer(&m_pVertexBuffer);
tempMeshFVF->GetIndexBuffer(&m_pIndexBuffer);
m_dwNumVerts = tempMeshFVF->GetNumVertices();
m_dwNumFaces = tempMeshFVF->GetNumFaces();
return S_OK;
}
// ------------------------------------------------------------------------------
// CShaderHalo::Start
//
// Description: Called to reset
// ------------------------------------------------------------------------------
HRESULT CShaderHalo::Start()
{
return S_OK;
}
// ------------------------------------------------------------------------------
// CShaderHalo::Tick
//
// Description: This function is called every frame. Here is where we write
// and update constants, clear the z- and back-buffer and render our
// primitives
// ------------------------------------------------------------------------------
HRESULT CShaderHalo::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
SetVertexShaderMatrices();
/*
float value = sin(D3DXToRadian(m_fAngle));
value = fabs(value);
m_fAngle += 2.0f;
if(m_fAngle > 180.0f)
m_fAngle = 0.0f;
// */
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID));
if(m_eDisplayOption == HALO_DISPLAY)
{
// vary the halo +/- 10%
float const kPulse = 0.25f * m_fEdgeSize * sin(1.25f*pTimer->GetDuration());
m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0L);
//pass one
//arg1 is diffuse
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
m_pD3DDev->SetVertexShader(m_dwHaloShader);
D3DXVECTOR4 color(0.9f, 0.9f, 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_COLOR, &color, 1);
D3DXVECTOR4 perturb(kPulse+m_fEdgeSize, 0.0f, 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_SCALING, &perturb, 1);
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVerts, 0, m_dwNumFaces);
//pass two
m_pD3DDev->SetVertexShader(m_dwNormalShader);
m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVerts, 0, m_dwNumFaces);
}
else
{
m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00BFBFBF, 1.0f, 0L);
//pass one
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
m_pD3DDev->SetVertexShader(m_dwHaloShader);
D3DXVECTOR4 color(0.0f, 0.0f, 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_COLOR, &color, 1);
D3DXVECTOR4 perturb(m_fEdgeSize, 0.0f, 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_SCALING, &perturb, 1);
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVerts, 0, m_dwNumFaces);
//pass two
//arg2 is the texture
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pD3DDev->SetVertexShader(m_dwToonShader);
m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVerts, 0, m_dwNumFaces);
}
return hr;
}
void CShaderHalo::MouseButton(HWND hWnd, eButtonID button, bool bDown, int x, int y)
{
if(button == MOUSE_LEFTBUTTON)
{
if(bDown)
{
m_pUI->OnLButtonDown(x, y);
}
else
{
m_pUI->OnLButtonUp(x, y);
}
}
return;
}
void CShaderHalo::MouseMove(HWND hWnd, int x, int y)
{
m_pUI->OnMouseMove(x, y);
return;
}
void CShaderHalo::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
if(bDown)
{
switch(dwKey)
{
case 'W' :
case 'w' :
{
m_bWireframe = !m_bWireframe;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
break;
}
case 'H' :
case VK_F1 :
{
::MessageBoxEx( NULL, " Help : F1 - Help \n\n Home - Reset To Defaults \n\n W - Wireframe Toggle \n\n Space\\Pause - Toggle Pause/Resume \n\n Left Button & Mouse - Rotate Object\n\n Shift Left Button & Mouse - Pan Camera \n\n Ctrl Left Button & Mouse - Move Camera In & Out\n\n + increase silhouette width\n\n - decrease silhouette width",
"Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
break;
}
case VK_HOME :
case VK_END :
case VK_NUMPAD7 :
case VK_NUMPAD1 :
case '7' :
case '1' :
{
m_pUI->Reset();
m_bWireframe = false;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
break;
}
case VK_ADD:
case 0xBB:
case '+':
case '=':
{
if(m_fEdgeSize <= 10.0f)
m_fEdgeSize += 0.02f;
break;
}
case VK_SUBTRACT:
case 0xBD:
case '-':
case '_':
{
m_fEdgeSize -= 0.02f;
if(m_fEdgeSize < 0)
m_fEdgeSize = 0;
break;
}
default :
{
break;
}
}
}
SetVertexShaderMatrices();
return;
}
void CShaderHalo::PropertyUpdateCallback(const EBProperty* pProperty, bool bWritten)
{
if (!bWritten)
return;
EBString name;
if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
{
name = pProperty->GetPropertyName();
if(name == EBString(STR_INCREASE_EDGE))
{
Keyboard(VK_ADD, 0, true);
}
else if (name == EBString(STR_DECREASE_EDGE))
{
Keyboard(VK_SUBTRACT, 0, true);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -