📄 doc.cpp
字号:
// Unable to setup effect
MessageBox(m_pRenderView->GetSafeHwnd(), strError.c_str(),
"Error Selecting Effect", MB_OK | MB_ICONEXCLAMATION);
pEffect->Free();
return m_bValidEffect = false;
}
// Set the effect title
EBProperty* pEffectName = pEffect->GetProperty("EffectName");
if (pEffectName && pEffectName->IsKindOf(EBTYPE_STRING_PROP))
{
strTitle = pEffectName->ReadValue(pEffect);
}
else
{
strTitle = ("Unknown!");
}
SetTitle(strTitle.c_str());
// Show the current program
m_pProgramFormView[0]->SetEffect(pEffect);
m_pProgramFormView[1]->SetEffect(pEffect);
// Build the effect menu
BuildEffectMenu(pEffect);
// Start rendering if the effect is valid
if (m_bValidEffect) {
m_pTimer->Start(30.0f);
pEffect->Start();
GetRenderWnd()->Clear();
GetRenderWnd()->ShowWindow(SW_SHOW);
}
return m_bValidEffect = true;
}
bool CNVEffectsDoc::RebuildEffect(DWORD dwDirtyFlags)
{
if (dwDirtyFlags & EBEFFECT_DIRTY_PUBLICSTATE)
{
BuildEffectMenu(m_pCurrentEffect);
}
if (dwDirtyFlags & EBEFFECT_DIRTY_VERTEXSHADERS)
{
if (m_pProgramFormView[0]->GetViewType() == VIEWTYPE_VERTEX)
{
m_pProgramFormView[0]->SetEffect(m_pCurrentEffect);
}
else
{
m_pProgramFormView[1]->SetEffect(m_pCurrentEffect);
}
}
if (dwDirtyFlags & EBEFFECT_DIRTY_PIXELSHADERS)
{
if (m_pProgramFormView[0]->GetViewType() == VIEWTYPE_PIXEL)
{
m_pProgramFormView[0]->SetEffect(m_pCurrentEffect);
}
else
{
m_pProgramFormView[1]->SetEffect(m_pCurrentEffect);
}
}
// Update the menu
BuildEffectMenu(m_pCurrentEffect);
return true;
}
bool CNVEffectsDoc::Start()
{
if (m_listEffects.empty())
{
MessageBox(NULL, "No effects found!", "ERROR", MB_ICONEXCLAMATION | MB_OK);
return false;
}
SetCurrentEffect(m_listEffects.front());
// Always have a valid effect pointer, even if the effect is not valid
if (!m_pCurrentEffect)
m_pCurrentEffect = m_listEffects.front();
m_pTreeView->PopulateTree();
m_bStarted = true;
return true;
}
bool CNVEffectsDoc::MenuHandler(UINT nID)
{
std::map<UINT, CEffectMenuItem>::const_iterator itrProperty = m_mapMenuItem.find(nID);
if (itrProperty == m_mapMenuItem.end())
return false;
CEffectMenuItem MenuItem = (*itrProperty).second;
EBProperty* pProp = MenuItem.m_pProperty;
if (pProp == NULL)
return false;
// Find out what type of property we are looking at and handle it appropriately.
if (pProp->IsKindOf(EBTYPE_BOOL_PROP))
{
bool bValue = pProp->ReadValue(m_pCurrentEffect);
bValue = !bValue;
pProp->WriteValue(m_pCurrentEffect, bValue);
CheckMenuItem(MenuItem.m_hMenu, MenuItem.m_MenuID, bValue ? MF_CHECKED : MF_UNCHECKED);
}
else if (pProp->IsKindOf(EBTYPE_TRIGGER_PROP))
{
EBTriggerProperty* pTrigger = static_cast<EBTriggerProperty*>(pProp);
pTrigger->Trigger(m_pCurrentEffect);
}
// Enumerated types have sub-menus with options in them.
// Look at the flags to check if it's a static enum (can't do iskindof because
// enums can be many different types
else if (pProp->GetFlags() & PROPFLAG_ENUMSTATIC)
{
HMENU hEnumMenu = NULL;
EBEnumValue* pEnumVal = static_cast<EBEnumValue*>(pProp);
EBEnumProperty* pEnumProp = pEnumVal->GetParent();
// Write the new property value
pEnumProp->WriteValue(m_pCurrentEffect, pEnumVal->GetValue());
// Walk the list of enumerants and set the menus checkboxes
t_listEnum mapEnumerants = pEnumProp->GetEnumerants();
t_listEnum::const_iterator itrEnum = mapEnumerants.begin();
while (itrEnum != mapEnumerants.end())
{
itrProperty = m_mapMenuItem.begin();
while (itrProperty != m_mapMenuItem.end())
{
// If this item is the current enumerant in the list...
if ((*itrProperty).second.m_pProperty == (*itrEnum))
{
CEffectMenuItem ThisItem = (*itrProperty).second;
// .. Check/uncheck the value
if ((*itrEnum)->GetValue() == pEnumVal->GetValue())
{
CheckMenuItem(ThisItem.m_hMenu, ThisItem.m_MenuID, MF_CHECKED);
}
else
{
CheckMenuItem(ThisItem.m_hMenu, ThisItem.m_MenuID, MF_UNCHECKED);
}
break;
}
itrProperty++;
}
itrEnum++;
}
}
return true;
}
BOOL CNVEffectsDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
std::map<UINT, CEffectMenuItem>::const_iterator itrProperty = m_mapMenuItem.find(nID);
if (itrProperty != m_mapMenuItem.end())
{
if (nCode == CN_COMMAND && !pHandlerInfo)
MenuHandler(nID);
return true;
}
return CDocument::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
HRESULT CNVEffectsDoc::InitDeviceObjects()
{
if (m_bStarted && m_bValidEffect)
{
SetCurrentEffect(m_pCurrentEffect);
}
return S_OK;
}
HRESULT CNVEffectsDoc::DeleteDeviceObjects()
{
if (m_bStarted)
{
m_pCurrentEffect->Free();
}
return S_OK;
}
HRESULT CNVEffectsDoc::ConfirmDevice(EBEffect *pEffect)
{
if (m_bStarted)
{
return GetRenderWnd()->ConfirmDevice(pEffect);
}
return S_OK;
}
void CNVEffectsDoc::OnCaptureSaveimage()
{
HRESULT hr;
LPDIRECT3DDEVICE8 pDevice;
LPDIRECT3DSURFACE8 pBackBuffer;
D3DLOCKED_RECT LockedRect;
D3DSURFACE_DESC SurfaceDesc;
BITMAPINFO bmi;
BITMAPFILEHEADER bmf;
DWORD Pitch;
int y, x;
WORD Color16;
DWORD* ScanLine;
DWORD ScanItem;
// XXX - Shouldn't be force casting...clean this up!
((CRenderD3DWnd*) GetRenderWnd())->GetDevice(&pDevice);
const char* Filter = "Bitmap Files (*.bmp)|*.bmp||";
CFileDialog FileDialog(false, ".bmp", "effect.bmp", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, Filter);
if (FileDialog.DoModal() != IDOK)
{
SAFE_RELEASE(pDevice);
return;
}
CString PathName = FileDialog.GetPathName();
CFile file;
if( !file.Open(PathName, CFile::modeWrite|CFile::modeCreate) )
{
MessageBox(NULL, "Failed to open file!", "Error", MB_OK | MB_ICONEXCLAMATION);
return;
}
hr = pDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
if (FAILED(hr))
{
MessageBox(NULL, "Failed to get backbuffer!", "Error", MB_OK | MB_ICONEXCLAMATION);
SAFE_RELEASE(pDevice);
return;
}
pBackBuffer->GetDesc(&SurfaceDesc);
// Get the pitch of the backbuffer
switch(SurfaceDesc.Format)
{
case D3DFMT_A8R8G8B8:
Pitch = SurfaceDesc.Width * 4;
break;
case D3DFMT_R5G6B5:
case D3DFMT_A1R5G5B5:
Pitch = SurfaceDesc.Width * 2;
break;
}
ZeroMemory(&bmf, sizeof(BITMAPFILEHEADER));
bmf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPFILEHEADER) + ((SurfaceDesc.Width * 4) * SurfaceDesc.Height);
bmf.bfType = ((WORD) ('M' << 8) | 'B');
bmf.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
// Write out the bitmap info
file.Write(&bmf, sizeof(BITMAPFILEHEADER));
// Fill in the bitmapinfo structure
ZeroMemory(&bmi, sizeof(BITMAPINFOHEADER));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = SurfaceDesc.Width;
bmi.bmiHeader.biHeight = SurfaceDesc.Height;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 4000;
bmi.bmiHeader.biYPelsPerMeter = 4000;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
// Write out the bitmap info
file.Write(&bmi, sizeof(BITMAPINFO));
pBackBuffer->LockRect(&LockedRect, NULL, D3DLOCK_READONLY);
if (LockedRect.Pitch != 0)
Pitch = LockedRect.Pitch;
ScanLine = (DWORD*)HeapAlloc(GetProcessHeap(), 0, SurfaceDesc.Width * 4);
switch(SurfaceDesc.Format)
{
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
for (y = SurfaceDesc.Height - 1; y >= 0; y--)
{
file.Write(((BYTE*)LockedRect.pBits + (y * Pitch)), SurfaceDesc.Width * 4);
}
break;
case D3DFMT_R5G6B5:
for (y = SurfaceDesc.Height - 1; y >= 0; y--)
{
ScanItem = 0;
for (x = 0; x < SurfaceDesc.Width; x++)
{
Color16 = *((WORD*)((BYTE*)LockedRect.pBits + (y * Pitch)) + x);
ScanLine[ScanItem++] = (((Color16 & 0xF800) >> 8) << 16) |
(((Color16 & 0x07E0) >> 3) << 8) |
(((Color16 & 0x001F) << 3));
}
file.Write(ScanLine, ScanItem * 4);
}
break;
case D3DFMT_A1R5G5B5:
for (y = SurfaceDesc.Height - 1; y >= 0; y--)
{
ScanItem = 0;
for (x = 0; x < SurfaceDesc.Width; x++)
{
Color16 = *((WORD*)((BYTE*)LockedRect.pBits + (y * Pitch)) + x);
ScanLine[ScanItem++] = (((Color16 & 0x7C00) >> 8) << 16) |
(((Color16 & 0x03E0) >> 2) << 8) |
(((Color16 & 0x001F) << 3));
}
file.Write(ScanLine, ScanItem * 4);
}
break;
default:
assert(0 && "Error - unknown surface format during save");
break;
}
HeapFree(GetProcessHeap(), 0, ScanLine);
pBackBuffer->UnlockRect();
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(pDevice);
}
void CNVEffectsDoc::OnUpdateCaptureSaveimage(CCmdUI* pCmdUI)
{
pCmdUI->Enable(TRUE);
}
void CNVEffectsDoc::OnCaptureBeginmovie()
{
HRESULT hr;
LPDIRECT3DSURFACE8 pBackBuffer;
LPDIRECT3DDEVICE8 pDevice;
// XXX - Shouldn't be force casting...fix this!
((CRenderD3DWnd*) GetRenderWnd())->GetDevice(&pDevice);
hr = pDevice->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
if (FAILED(hr))
{
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(pDevice);
return;
}
const char* Filter = "AVI Files (*.avi)|*.avi||";
CFileDialog FileDialog(false, ".avi", "out.avi", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, Filter);
if (FileDialog.DoModal() == IDOK)
{
CString PathName = FileDialog.GetPathName();
if (m_pMovie->BeginRecord((LPCTSTR)PathName, pBackBuffer))
{
m_bMovieRecording = true;
}
SAFE_RELEASE(pBackBuffer);
SAFE_RELEASE(pDevice);
}
}
void CNVEffectsDoc::OnUpdateCaptureBeginmovie(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!m_bMovieRecording);
}
void CNVEffectsDoc::OnCaptureEndmovie()
{
m_pMovie->EndRecord();
m_bMovieRecording = false;
}
void CNVEffectsDoc::OnUpdateCaptureEndmovie(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_bMovieRecording);
}
void CNVEffectsDoc::OnFileHardwaredevice()
{
theApp.SetDeviceType(D3DDEVTYPE_HAL);
ChangeDevice();
}
void CNVEffectsDoc::OnUpdateFileHardwaredevice(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck((int)theApp.GetDeviceType() == D3DDEVTYPE_HAL);
}
void CNVEffectsDoc::OnDeviceReference()
{
theApp.SetDeviceType(D3DDEVTYPE_REF);
ChangeDevice();
}
void CNVEffectsDoc::OnUpdateDeviceReference(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck((int)theApp.GetDeviceType() == D3DDEVTYPE_REF);
}
void CNVEffectsDoc::OnDeviceForcesoftwarevp()
{
theApp.SetForceSoftwareVP(!theApp.GetForceSoftwareVP());
ChangeDevice();
}
void CNVEffectsDoc::OnUpdateDeviceForcesoftwarevp(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck((int)theApp.GetForceSoftwareVP());
}
void CNVEffectsDoc::ChangeDevice()
{
m_pRenderView->UpdateDevice(m_pCurrentEffect);
m_pTreeView->PopulateTree();
}
bool CNVEffectsDoc::DoTestPopup(int x, int y)
{
if (m_EffectMenu.m_hMenu)
m_EffectMenu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, x, y, (CWnd*)m_pRenderView);
return true;
}
void CNVEffectsDoc::OnCloseDocument()
{
if (m_pCurrentEffect)
m_pCurrentEffect->Free();
while(!m_listEffects.empty())
{
EBEffect* pEffect = m_listEffects.back();
pEffect->DestroyEffect();
m_listEffects.pop_back();
};
tmapEffectFileData::iterator itrEffects = m_EffectFileData.begin();
while (itrEffects != m_EffectFileData.end())
{
HINSTANCE hLib = (*itrEffects).second.hLib;
if (hLib)
FreeLibrary(hLib);
(*itrEffects).second.hLib = NULL;
itrEffects++;
}
m_EffectFileData.clear();
SAFE_DELETE(m_pTimer);
SAFE_DELETE(m_pMovie);
CDocument::OnCloseDocument();
}
void CNVEffectsDoc::OnOptionsExpandall()
{
theApp.SetExpandAll(!theApp.GetExpandAll());
}
void CNVEffectsDoc::OnUpdateOptionsExpandall(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(theApp.GetExpandAll());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -