#include "stdafx.h" #include "SceneApp.h" #include "WStreamResource.h" #include "NiSearchPath.h" #include "NiScreenText.h" ////////////////////////////////////////////////////////////////////////// // IGame implements. ////////////////////////////////////////////////////////////////////////// IGame* CreateGameInterface(HINSTANCE hAppInst) { NiInit(); SceneApp* cg = (SceneApp*)NiApplication::Create(); if (!cg) { ::MessageBox(NULL, "Unable to create application", "Sunyou Game Interface",MB_OK); NiShutdown(); return NULL; } NiApplication::SetInstanceReference(hAppInst); return (IGame*)cg; } BOOL SceneApp::InitializeForCtrl(HWND hCtrlWnd,ILWStreamSystem* iStreamSys) { m_bWebMode = TRUE; // 我们需要定位工作目录. char Path[2048]; HMODULE hOcx = GetModuleHandle("SceneApp.dll"); NIASSERT(hOcx); //GetCurrentDirectory(1023,Path); GetModuleFileName(hOcx,Path,2047); char* Slash = strrchr(Path,'\\'); NIASSERT(Slash); *++Slash = '\0'; // windows always return path as \\..\\ format. SetCurrentDirectory(Path); m_StreamSystem = iStreamSys; // ActiveX 控件已经创建好了窗口 NiAppWindow* AppWindow = GetAppWindow(); NIASSERT(AppWindow); NIASSERT(AppWindow->GetWindowReference() == NULL); AppWindow->SetWindowReference(hCtrlWnd); AppWindow->SetRenderWindowReference(hCtrlWnd); // 所有纹理必须延迟加载. // 前提: NiSourceTexture::ms_bPreload = true! 只有这样,我们才能尽快地开始提交下载请求. // 我们在PostLinkObject 中来提交请求. NiSourceTexture::SetUsePreloading(TRUE); NiSourceTexture::ms_bStreamMode = TRUE; WStreamResource::SetStreamSystem(m_StreamSystem); WStreamResource::HookNDLCreator(); // Temp NiStrcpy(m_acFilename, NI_MAX_PATH, "Madlab/test.gsa"); // 初始化客户端. if(!Initialize()) { ::MessageBox(hCtrlWnd, "初始化客户端失败.","Sun you web client", MB_OK); return FALSE; } WStreamResource::Initialize(m_StreamSystem); // if(!m_LoadingSink.Create(this)) { return FALSE; } return TRUE; } void SceneApp::Destroy() { m_LoadingSink.Destroy(); WStreamResource::Destroy(); Terminate(); delete this; NiShutdown(); // for determining if there are 'object leaks' unsigned int uiFinalCount = NiRefObject::GetTotalObjectCount(); char acMsg[256]; NiSprintf(acMsg, 256, "\nRefObject counts: ", uiFinalCount); OutputDebugString(acMsg); if (uiFinalCount > 0) { NiSprintf(acMsg, 256, "Application is leaking %u objects\n\n", uiFinalCount); OutputDebugString(acMsg); } else { OutputDebugString("Application has no object leaks.\n\n"); } } void SceneApp::Update() { Lock(); OnIdle(); Unlock(); } //--------------------------------------------------------------------------- NiCamera* FindCamera(NiAVObject* pkObject) { if (NiIsKindOf(NiCamera, pkObject)) { return (NiCamera*) pkObject; } else if (NiIsKindOf(NiNode, pkObject)) { // NiNodes are the primary structural objects in Gamebryo. They // group other Gamebryo scene objects together under a common parent // and coordinate system. NiNodes can have as many children as // necessary, but those children are not guaranteed to be contiguous. NiNode* pkNode = (NiNode*) pkObject; for (unsigned int ui = 0; ui < pkNode->GetArrayCount(); ui++) { NiCamera* pkFoundCamera = FindCamera(pkNode->GetAt(ui)); if (pkFoundCamera) return pkFoundCamera; } } return NULL; } BOOL SceneApp::LoadScene(const char* RefURL,const char* SceneFile, void* Reserve) { NiAlphaAccumulator* pkAccum = NiNew NiAlphaAccumulator; m_spRenderer->SetSorter(pkAccum); NiStream kStream; char RefPath[NI_MAX_PATH]; NiStrcpy(RefPath, NI_MAX_PATH, RefURL); NiSearchPath* SP = kStream.GetSearchPath(); if (SP) { SP->SetReferencePath(RefPath); } // create new input file stream NiFile* kIst = NiFile::GetFile(SceneFile, NiFile::READ_ONLY); if (!kIst || !*kIst) { NiDelete kIst; return FALSE; } bool bSuccess = kStream.Load(kIst); NiDelete kIst; if (!bSuccess) { NiMessageBox(SceneFile, "NIF Error"); return FALSE; } m_spScene = (NiNode*) kStream.GetObjectAt(0); if (m_spScene) { m_spCamera = FindCamera(m_spScene); } if (m_spScene) { m_spScene->Update(0.0f); m_spScene->UpdateProperties(); m_spScene->UpdateEffects(); } if (m_spCamera) { m_spCamera->Update(0.0f); } return TRUE; } ISceneLoadingSink* SceneApp::GetSceneLoadingSink() { return &m_LoadingSink; } // 由WEB客户端调用,当每一个场景对象被加入后,都需要构建正确的场景影响. void SceneApp::ReCacheScene() { Lock(); if (m_spEntityScene) { m_kEntitiesToUpdate.RemoveAll(); PrepareScene(m_spEntityScene); } Unlock(); } BOOL SceneApp::PostLoadScene() { if (!CreateCameraController()) return false; if (!CreateFrame()) return false; RenderSplashScreen("Preparing Scene"); // Generate render clicks so shadows are hooked up - this is necessary // for the geometry to have the correct shaders precreated. if (m_bUseFrameSystem) { NiShadowManager::GenerateRenderClicks(); } PrepareScene(m_spEntityScene); if (m_bVisualTrackersCreated) { if (!CreateVisualTrackers()) { NiMessageBox("Failed: Couldn't create Visual Trackers", "Failed"); return false; } SetShowAllTrackers(true); } if (!m_bWebMode) { m_pkText->SetString(""); m_pkText->SetVisible(false); } m_Loading = FALSE; return TRUE; }