📄 doc.cpp
字号:
/* Copyright (C) Greg James, 2001.
* All rights reserved worldwide.
*
* This software is provided "as is" without express or implied
* warranties. You may freely copy and compile this source into
* applications you distribute provided that the copyright text
* below is included in the resulting source code, for example:
* "Portions Copyright (C) Greg James, 2001"
*/
// Doc.cpp : implementation of the CNVEffectsDoc class
//
#include "stdafx.h"
#include "NVEffectsBrowser.h"
#include "Doc.h"
using namespace nv_objects;
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CNVEffectsDoc
IMPLEMENT_DYNCREATE(CNVEffectsDoc, CDocument)
BEGIN_MESSAGE_MAP(CNVEffectsDoc, CDocument)
//{{AFX_MSG_MAP(CNVEffectsDoc)
ON_COMMAND(IDM_CAPTURE_BEGINMOVIE, OnCaptureBeginmovie)
ON_UPDATE_COMMAND_UI(IDM_CAPTURE_BEGINMOVIE, OnUpdateCaptureBeginmovie)
ON_COMMAND(IDM_CAPTURE_ENDMOVIE, OnCaptureEndmovie)
ON_UPDATE_COMMAND_UI(IDM_CAPTURE_ENDMOVIE, OnUpdateCaptureEndmovie)
ON_COMMAND(IDM_CAPTURE_SAVEIMAGE, OnCaptureSaveimage)
ON_UPDATE_COMMAND_UI(IDM_CAPTURE_SAVEIMAGE, OnUpdateCaptureSaveimage)
ON_COMMAND(IDM_DEVICE_FORCESOFTWAREVP, OnDeviceForcesoftwarevp)
ON_UPDATE_COMMAND_UI(IDM_DEVICE_FORCESOFTWAREVP, OnUpdateDeviceForcesoftwarevp)
ON_COMMAND(IDM_DEVICE_REFERENCE, OnDeviceReference)
ON_UPDATE_COMMAND_UI(IDM_DEVICE_REFERENCE, OnUpdateDeviceReference)
ON_COMMAND(ID_FILE_HARDWAREDEVICE, OnFileHardwaredevice)
ON_UPDATE_COMMAND_UI(ID_FILE_HARDWAREDEVICE, OnUpdateFileHardwaredevice)
ON_COMMAND(IDM_OPTIONS_EXPANDALL, OnOptionsExpandall)
ON_UPDATE_COMMAND_UI(IDM_OPTIONS_EXPANDALL, OnUpdateOptionsExpandall)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CNVEffectsDoc construction/destruction
CNVEffectsDoc::CNVEffectsDoc()
: m_pMovie(NULL),
m_pTimer(NULL),
m_pRenderView(NULL),
m_pTreeView(NULL),
m_bEffectMenu(false),
m_bValidEffect(false),
m_bStarted(false),
m_pCurrentEffect(NULL),
m_bMovieRecording(false)
{
m_pProgramFormView[0] = NULL;
m_pProgramFormView[1] = NULL;
}
CNVEffectsDoc::~CNVEffectsDoc()
{
}
bool CNVEffectsDoc::FileFoundCallback(const WIN32_FIND_DATA& FindData, const std::string& strDirectory)
{
EffectFileData EffectData;
memcpy(&EffectData.m_FindData, &FindData, sizeof(WIN32_FIND_DATA));
EffectData.m_strDirectory = strDirectory;
EffectData.hLib = NULL;
tmapEffectFileData::iterator itrFound;
itrFound = m_EffectFileData.find(FindData.cFileName);
if (itrFound != m_EffectFileData.end())
{
DISPDBG(0, "Found alternate version of " << FindData.cFileName << " in :" << strDirectory);
ULARGE_INTEGER LastWriteNew = *(ULARGE_INTEGER*)(&EffectData.m_FindData.ftLastWriteTime);
ULARGE_INTEGER LastWriteOld = *(ULARGE_INTEGER*)(&(*itrFound).second.m_FindData.ftLastWriteTime);
if (LastWriteNew.QuadPart > LastWriteOld.QuadPart)
{
DISPDBG(0, "Keeping newer dll in :" << strDirectory);
(*itrFound).second = EffectData;
}
else
{
DISPDBG(0, "Keeping older dll in :" << (*itrFound).second.m_strDirectory);
}
}
else
{
DISPDBG(0, "Found new dll, " << FindData.cFileName << " ,in :" << strDirectory);
m_EffectFileData.insert(make_pair<std::string, EffectFileData>(FindData.cFileName, EffectData));
}
return true;
}
bool CEffectSearch::FileFoundCallback(const WIN32_FIND_DATA& FindData, const std::string& strDirectory)
{
if (m_pDoc)
return m_pDoc->FileFoundCallback(FindData, strDirectory);
return false;
}
BOOL CNVEffectsDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// Update the message string
if (m_pRenderView)
m_pRenderView->SetMsg("Loading effects...");
// Find and register the dll's
HMODULE hProcess = GetModuleHandle(NULL);
string strProcessPath;
strProcessPath.resize(MAX_PATH);
DWORD dwReturnSize = GetModuleFileName((HINSTANCE)hProcess, &strProcessPath[0], MAX_PATH);
assert(dwReturnSize <= MAX_PATH); // Should never happen
string::size_type Pos = strProcessPath.find_last_of("\\", strProcessPath.size());
if (Pos != strProcessPath.npos)
{
strProcessPath = strProcessPath.substr(0, Pos);
}
else
{
strProcessPath = ".\\";
}
CEffectSearch EffectSearch;
EffectSearch.m_pDoc = this;
EffectSearch.FindFile("*.dll", strProcessPath, true);
// Walk the list of loaded .dll's and create them.
tmapEffectFileData::iterator itrEffects;
itrEffects = m_EffectFileData.begin();
while (itrEffects != m_EffectFileData.end())
{
(*itrEffects).second.hLib = NULL;
string strLoad = (*itrEffects).second.m_strDirectory + "\\" + (*itrEffects).second.m_FindData.cFileName;
HINSTANCE hLib = LoadLibrary(strLoad.c_str());
if (hLib != NULL)
{
LPCREATEEFFECT pCreate = (LPCREATEEFFECT)GetProcAddress(hLib, "CreateEffect");
LPGETEFFECTNUM pEffectNum = (LPGETEFFECTNUM)GetProcAddress(hLib, "GetNumEffects");
if (pEffectNum && pCreate)
{
// Store the loaded library
(*itrEffects).second.hLib = hLib;
unsigned int EffectNum = pEffectNum();
for (unsigned int i = 0; i < EffectNum; i++)
{
EBEffect* pEffect;
pEffect = pCreate(i);
if (pEffect)
{
ostringstream strError;
// Update the properties so that we have basic configuration support
pEffect->UpdateProperties();
EBProperty* pVerProp = pEffect->GetProperty("EffectVersion");
if (pVerProp && pVerProp->IsKindOf(EBTYPE_DWORD_PROP))
{
DWORD dwVer = pVerProp->ReadValue(pEffect);
if (dwVer <= theApp.GetVersion())
{
// Quick hack to try to start on the simplest shader so we don't get annoyed
// by a shader that can't run on the current device.
if (strcmp((*itrEffects).second.m_FindData.cFileName, "quad.dll") == 0)
m_listEffects.push_front(pEffect);
else
m_listEffects.push_back(pEffect);
}
else
{
pEffect->DestroyEffect();
pEffect = NULL;
strError << "Can't load effect " << (*itrEffects).second.m_FindData.cFileName << " , Unsupported Version: " << dwVer;
MessageBox(NULL, strError.str().c_str(), "Warning", MB_ICONEXCLAMATION | MB_OK);
}
}
else
{
pEffect->DestroyEffect();
pEffect = NULL;
strError << "Can't find effect version in " << (*itrEffects).second.m_FindData.cFileName;
MessageBox(NULL, strError.str().c_str(), "Error", MB_ICONEXCLAMATION | MB_OK);
}
}
}
}
else
{
FreeLibrary(hLib);
}
}
itrEffects++;
}
m_pTimer = new EBTimer();
m_pMovie = new NVMovie();
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CNVEffectsDoc serialization
void CNVEffectsDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
}
else
{
}
}
/////////////////////////////////////////////////////////////////////////////
// CNVEffectsDoc diagnostics
#ifdef _DEBUG
void CNVEffectsDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CNVEffectsDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
void CNVEffectsDoc::OnIdle()
{
if (m_pRenderView)
GetRenderWnd()->Render();
}
/////////////////////////////////////////////////////////////////////////////
// CNVEffectsDoc commands
void CNVEffectsDoc::Tick()
{
m_pTimer->Frame();
if (m_bValidEffect)
{
EBProperty* pProp = m_pCurrentEffect->GetProperty("EffectDirtyFlags");
if (pProp && pProp->IsKindOf(EBTYPE_DWORD_PROP))
{
DWORD dwDirtyFlags = pProp->ReadValue(m_pCurrentEffect);
if (dwDirtyFlags != 0)
{
RebuildEffect(dwDirtyFlags);
// Must re-get the effectdirty property because we caused the
// effect to rebuild it's property list.
pProp = m_pCurrentEffect->GetProperty("EffectDirtyFlags");
if (pProp)
pProp->WriteValue(m_pCurrentEffect, (DWORD)0);
}
}
m_pCurrentEffect->Tick(m_pTimer);
if (m_bMovieRecording)
{
m_pMovie->AddFrame();
}
}
}
void CNVEffectsDoc::OnChangedViewList()
{
DWORD dwProgramView = 0;
CDocument::OnChangedViewList();
if (!m_pRenderView)
{
POSITION pos = GetFirstViewPosition();
// Find the display view
while(pos != NULL)
{
CView* pView = GetNextView( pos );
if (pView->IsKindOf(RUNTIME_CLASS(CRenderView)))
{
m_pRenderView = DYNAMIC_DOWNCAST(CRenderView, pView);
DISPDBG(3, "Found RenderView");
}
else if(pView->IsKindOf(RUNTIME_CLASS(CProgramFormView)))
{
CProgramFormView* pProgramFormView = DYNAMIC_DOWNCAST(CProgramFormView, pView);
m_pProgramFormView[dwProgramView++] = pProgramFormView;
}
else if (pView->IsKindOf(RUNTIME_CLASS(CShaderTree)))
{
m_pTreeView = DYNAMIC_DOWNCAST(CShaderTree, pView);
DISPDBG(3, "Found Tree View");
}
}
}
}
bool CNVEffectsDoc::BuildEffectMenu(EBEffect* pEffect)
{
bool bPendingSeperator = false;
DWORD dwMenuID = IDM_MENUFREE1;
if (m_bEffectMenu)
{
// Find a better way to get the last menu position
AfxGetMainWnd()->GetMenu()->DeleteMenu(4, MF_BYPOSITION);
}
m_EffectMenu.DestroyMenu();
m_mapMenuItem.clear();
if (m_bValidEffect)
{
// Rebuild menus
m_EffectMenu.CreatePopupMenu();
// Update the Effect's properties
pEffect->UpdateProperties();
// Walk the property list and add any we recognise to the menu
EBProperty* pProp = pEffect->GetFirstProperty();
while (pProp != NULL)
{
string strName = pProp->GetPropertyName();
// not interested in private properties
if (pProp->GetFlags() & PROPFLAG_PRIVATE)
{
pProp = pEffect->GetNextProperty();
continue;
}
if (bPendingSeperator)
{
m_EffectMenu.AppendMenu(MF_SEPARATOR);
bPendingSeperator = false;
}
// Boolean properties
if (pProp->IsKindOf(EBTYPE_BOOL_PROP))
{
m_EffectMenu.AppendMenu(MF_STRING, dwMenuID, strName.c_str());
bool bValue = static_cast<EBProperty*>(pProp)->ReadValue(pEffect);
CheckMenuItem(m_EffectMenu.m_hMenu, dwMenuID, bValue ? MF_CHECKED : MF_UNCHECKED);
m_mapMenuItem.insert(make_pair<DWORD, CEffectMenuItem>(dwMenuID, CEffectMenuItem(pProp, m_EffectMenu.m_hMenu, dwMenuID)));
dwMenuID++;
}
else if (pProp->IsKindOf(EBTYPE_TRIGGER_PROP))
{
m_EffectMenu.AppendMenu(MF_STRING, dwMenuID, strName.c_str());
m_mapMenuItem.insert(make_pair<DWORD, CEffectMenuItem>(dwMenuID, CEffectMenuItem(pProp, m_EffectMenu.m_hMenu, dwMenuID)));
dwMenuID++;
}
// Enum properties. More work, need to add a popup
else if (pProp->IsKindOf(EBTYPE_ENUM_PROP))
{
EBEnumProperty* pEnumProp = static_cast<EBEnumProperty*>(pProp);
t_listEnum mapEnumerants = pEnumProp->GetEnumerants();
if (!mapEnumerants.empty())
{
t_listEnum::const_iterator itrEnum = mapEnumerants.begin();
if (dwMenuID != IDM_MENUFREE1)
m_EffectMenu.AppendMenu(MF_SEPARATOR);
while (itrEnum != mapEnumerants.end())
{
assert(*itrEnum);
m_EffectMenu.AppendMenu(MF_STRING, dwMenuID, (*itrEnum)->GetPropertyName().c_str());
if (pEnumProp->ReadValue(pEffect) == (*itrEnum)->GetValue())
{
CheckMenuItem(m_EffectMenu.m_hMenu, dwMenuID, MF_CHECKED);
}
else
{
CheckMenuItem(m_EffectMenu.m_hMenu, dwMenuID, MF_UNCHECKED);
}
m_mapMenuItem.insert(make_pair<DWORD, CEffectMenuItem>(dwMenuID, CEffectMenuItem((*itrEnum), m_EffectMenu.m_hMenu, dwMenuID)));
dwMenuID++;
itrEnum++;
}
bPendingSeperator = true;
}
}
pProp = pEffect->GetNextProperty();
}
// Create the menu
if (dwMenuID != IDM_MENUFREE1)
{
string strTitle;
EBProperty* pEffectName = pEffect->GetProperty("EffectName");
if (pEffectName && pEffectName->IsKindOf(EBTYPE_STRING_PROP))
{
strTitle = pEffectName->ReadValue(pEffect);
}
else
{
strTitle = ("Unknown!");
}
AfxGetMainWnd()->GetMenu()->AppendMenu(MF_POPUP, (UINT)m_EffectMenu.m_hMenu, strTitle.c_str());
m_bEffectMenu = true;
}
AfxGetMainWnd()->DrawMenuBar();
}
return true;
}
bool CNVEffectsDoc::SetCurrentEffect(EBEffect* pEffect)
{
string strTitle;
assert(pEffect);
assert(m_pRenderView);
if (m_pCurrentEffect && m_bValidEffect)
m_pCurrentEffect->Free();
m_pCurrentEffect = pEffect;
m_bValidEffect = true;
HRESULT hr = S_OK;
string strError;
{
// Put up the busy wait cursor while we get ready
CWaitCursor Wait;
// Select the appropriate type of rendering window
switch (pEffect->API()) {
case GFXAPI_D3D:
hr = m_pRenderView->SetRenderMode(CRenderView::D3DRenderMode);
break;
case GFXAPI_OPENGL :
hr = m_pRenderView->SetRenderMode(CRenderView::OGLRenderMode);
break;
default:
strError = "Effect uses unknown rendering API.";
hr = E_FAIL;
}
// Check if the effect can use this rendering window
if (SUCCEEDED(hr))
hr = GetRenderWnd()->SetupEffect(pEffect);
}
// Get the error string if the
if (hr == NVEFF_ERR_NOTINITIALIZED) {
strError = "Rendering window not initialized.";
} else if (FAILED(hr)) {
EBProperty* pErr = pEffect->GetProperty("LastError");
if (pErr->IsKindOf(EBTYPE_STRING_PROP)) {
strError = pErr->ReadValue(pEffect);
strError += "\nTry selecting a different device from the file menu.";
} else {
strError = "Unknown problem (test does not export LastError property).";
}
}
if (FAILED(hr)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -