Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. // $Header: $
  9. // $NoKeywords: $
  10. //
  11. // Material editor
  12. //=============================================================================
  13. #define WIN32_LEAN_AND_MEAN
  14. #include <windows.h>
  15. #include <io.h>
  16. #include "vstdlib/cvar.h"
  17. #include "appframework/AppFramework.h"
  18. #include "filesystem.h"
  19. #include "materialsystem/imaterialsystem.h"
  20. #include "materialsystem/itexture.h"
  21. #include "materialsystem/IMaterialSystemHardwareConfig.h"
  22. #include "vgui/IVGui.h"
  23. #include "vgui_controls/Panel.h"
  24. #include "vgui/ISurface.h"
  25. #include "vgui_controls/controls.h"
  26. #include "vgui/IScheme.h"
  27. #include "vgui/ILocalize.h"
  28. #include "vgui/IPanel.h"
  29. #include "tier0/dbg.h"
  30. #include "vgui_controls/Frame.h"
  31. #include "appframework/vguimatsysapp.h"
  32. #include "vgui_controls/AnimationController.h"
  33. #include "vgui/iinput.h"
  34. #include "vgui/isystem.h"
  35. #include "tier0/icommandline.h"
  36. #include "materialsystem/MaterialSystem_Config.h"
  37. #include "VGuiMatSurface/IMatSystemSurface.h"
  38. #include "datamodel/dmelement.h"
  39. #include "movieobjects/idmemakefileutils.h"
  40. #include "dme_controls/dmecontrols.h"
  41. #include "IStudioRender.h"
  42. #include "datacache/idatacache.h"
  43. #include "datacache/imdlcache.h"
  44. #include "datamodel/idatamodel.h"
  45. #include "vphysics_interface.h"
  46. #include "materialsystem/MaterialSystemUtil.h"
  47. #include "filesystem_init.h"
  48. #include "dmserializers/idmserializers.h"
  49. #include "datamodel/dmelementfactoryhelper.h"
  50. #include "p4lib/ip4.h"
  51. #include "vstdlib/iprocessutils.h"
  52. #include "tier3/tier3.h"
  53. #include "vgui_controls/perforcefileexplorer.h"
  54. #include "dme_controls/assetbuilder.h"
  55. //-----------------------------------------------------------------------------
  56. // Forward declarations
  57. //-----------------------------------------------------------------------------
  58. // temporary HACK
  59. class _Window_t { int unused; };
  60. _Window_t *g_pWindow = NULL;
  61. const MaterialSystem_Config_t *g_pMaterialSystemConfig;
  62. vgui::Panel *CreateSceneViewerPanel();
  63. //-----------------------------------------------------------------------------
  64. // Spew func
  65. //-----------------------------------------------------------------------------
  66. SpewRetval_t ModelBrowserSpewFunc( SpewType_t spewType, const tchar *pMsg )
  67. {
  68. OutputDebugString( pMsg );
  69. switch( spewType )
  70. {
  71. case SPEW_ASSERT:
  72. g_pCVar->ConsoleColorPrintf( Color( 255, 192, 0, 255 ), pMsg );
  73. #ifdef _DEBUG
  74. return SPEW_DEBUGGER;
  75. #else
  76. return SPEW_CONTINUE;
  77. #endif
  78. case SPEW_ERROR:
  79. g_pCVar->ConsoleColorPrintf( Color( 255, 0, 0, 255 ), pMsg );
  80. return SPEW_ABORT;
  81. case SPEW_WARNING:
  82. g_pCVar->ConsoleColorPrintf( Color( 192, 192, 0, 255 ), pMsg );
  83. break;
  84. case SPEW_MESSAGE:
  85. {
  86. Color c = *GetSpewOutputColor();
  87. if ( !Q_stricmp( GetSpewOutputGroup(), "developer" ) )
  88. g_pCVar->ConsoleDPrintf( pMsg );
  89. else
  90. g_pCVar->ConsoleColorPrintf( c, pMsg );
  91. }
  92. break;
  93. }
  94. return SPEW_CONTINUE;
  95. }
  96. //-----------------------------------------------------------------------------
  97. // redirect spew to debug output window
  98. //-----------------------------------------------------------------------------
  99. SpewRetval_t SpewToODS( SpewType_t spewType, char const *pMsg )
  100. {
  101. OutputDebugString( pMsg );
  102. switch( spewType )
  103. {
  104. case SPEW_MESSAGE:
  105. case SPEW_WARNING:
  106. case SPEW_LOG:
  107. return SPEW_CONTINUE;
  108. case SPEW_ASSERT:
  109. case SPEW_ERROR:
  110. default:
  111. return SPEW_DEBUGGER;
  112. }
  113. }
  114. //-----------------------------------------------------------------------------
  115. // redirect spew to stdout
  116. //-----------------------------------------------------------------------------
  117. SpewRetval_t SpewStdout( SpewType_t spewType, char const *pMsg )
  118. {
  119. _tprintf( "%s", pMsg );
  120. return SPEW_CONTINUE;
  121. }
  122. //-----------------------------------------------------------------------------
  123. // The application object
  124. //-----------------------------------------------------------------------------
  125. class CSceneViewerApp : public CVguiMatSysApp
  126. {
  127. typedef CVguiMatSysApp BaseClass;
  128. public:
  129. // Methods of IApplication
  130. virtual bool Create();
  131. virtual bool PreInit();
  132. virtual int Main();
  133. virtual void PostShutdown();
  134. virtual void Destroy();
  135. virtual const char *GetAppName() { return "SceneViewer"; }
  136. virtual bool AppUsesReadPixels() { return true; }
  137. private:
  138. // Sets a default env_cubemap for rendering materials w/ specularity
  139. void InitDefaultEnvCubemap( );
  140. void ShutdownDefaultEnvCubemap( );
  141. CTextureReference m_DefaultEnvCubemap;
  142. };
  143. //-----------------------------------------------------------------------------
  144. //
  145. //-----------------------------------------------------------------------------
  146. static bool CHLSceneViewerApp_SuggestGameInfoDirFn( CFSSteamSetupInfo const *pFsSteamSetupInfo, char *pchPathBuffer, int nBufferLength, bool *pbBubbleDirectories )
  147. {
  148. const char *pFilename = NULL;
  149. const int nParmCount = CommandLine()->ParmCount();
  150. char pchTmpBuf[ MAX_PATH ];
  151. for ( int nPi = 0; nPi < nParmCount; ++nPi )
  152. {
  153. pFilename = CommandLine()->GetParm( nParmCount - 1 );
  154. Q_MakeAbsolutePath( pchTmpBuf, sizeof( pchTmpBuf ), pFilename );
  155. if ( _access( pchTmpBuf, 04 ) == 0 )
  156. {
  157. Q_strncpy( pchPathBuffer, pchTmpBuf, nBufferLength );
  158. if ( pbBubbleDirectories )
  159. *pbBubbleDirectories = true;
  160. return true;
  161. }
  162. }
  163. return false;
  164. }
  165. //-----------------------------------------------------------------------------
  166. //
  167. //-----------------------------------------------------------------------------
  168. int __stdcall WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
  169. {
  170. static CSceneViewerApp sceneViewerApp; \
  171. static CSteamApplication steamApp( &sceneViewerApp ); \
  172. return AppMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow, &steamApp );
  173. }
  174. // DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( CSceneViewerApp );
  175. //-----------------------------------------------------------------------------
  176. // Create all singleton systems
  177. //-----------------------------------------------------------------------------
  178. bool CSceneViewerApp::Create()
  179. {
  180. if ( CommandLine()->FindParm( "-help" ) )
  181. {
  182. const bool newConsole( SetupWin32ConsoleIO() );
  183. Msg( "\n\n Sceneviewer - Loads and views Valve DMX Assets\n\n" );
  184. Msg( " Synopsis: sceneviewer [ vgui opts ] [ -help ] [ filename.[dmx|obj] ]\n" );
  185. Msg(
  186. "\n"
  187. " Where:\n"
  188. "\n"
  189. " Sceneviewer Options:\n"
  190. "\n"
  191. " -help . . . . . . Prints this information\n"
  192. " -nozoom . . . . . Stop sceneviewer zooming model viewer to occupy all client\n"
  193. " space when a dmx is specified on the command line\n"
  194. " -showasset . . . Stop sceneviewer from hiding the asset builder when a dmx\n"
  195. " file is specified on the command line.\n"
  196. " filename.dmx . . The name of a dmx file to load on start\n"
  197. "\n"
  198. " VGUI Options:\n"
  199. "\n"
  200. " -vproject <$> . . Override VPROJECT environment variable\n"
  201. " -game <$> . . . . Override VPROJECT environment variable\n"
  202. " -remote <$> . . . Add the remote share name\n"
  203. " -host <$> . . . . Set the host name\n"
  204. " -norfs . . . . . Do not use remote filesystem\n"
  205. " -fullscreen . . . Run application fullscreen rather than in a window\n"
  206. " -width <#> . . . Set the window width when running windowed\n"
  207. " -height <#> . . . Set the window height when running windowed\n"
  208. " -adapter <$> . . Set the adapter??\n"
  209. " -ref . . . . . . Set MATERIAL_INIT_REFERENCE_RASTERIZER on adapter??\n"
  210. " -resizing . . . . Allow the window to be resized\n"
  211. " -mat_vsync . . . Wait for VSYNC\n"
  212. " -mat_antialias . Turn on Anti-Aliasing\n"
  213. " -mat_aaquality . Antialiasing quality (set to zero unless you know what you're doing)\n"
  214. "\n"
  215. );
  216. if ( newConsole )
  217. {
  218. Msg( "\n\nPress Any Key Continue..." );
  219. char tmpBuf[ 2 ];
  220. DWORD cRead;
  221. ReadConsole( GetStdHandle( STD_INPUT_HANDLE ), tmpBuf, 1, &cRead, NULL );
  222. }
  223. return false;
  224. }
  225. // FIXME: Enable vs30 shaders while NVidia driver bug exists
  226. CommandLine()->AppendParm( "-box", NULL );
  227. if ( !BaseClass::Create() )
  228. return false;
  229. AppSystemInfo_t appSystems[] =
  230. {
  231. { "vstdlib.dll", PROCESS_UTILS_INTERFACE_VERSION },
  232. { "studiorender.dll", STUDIO_RENDER_INTERFACE_VERSION },
  233. { "vphysics.dll", VPHYSICS_INTERFACE_VERSION },
  234. { "datacache.dll", DATACACHE_INTERFACE_VERSION },
  235. { "datacache.dll", MDLCACHE_INTERFACE_VERSION },
  236. { "", "" } // Required to terminate the list
  237. };
  238. if ( !AddSystems( appSystems ) )
  239. {
  240. return false;
  241. }
  242. // Add the P4 module separately so that if it is absent (say in the SDK) then the other system will initialize properly
  243. AppModule_t p4Module = LoadModule( "p4lib.dll" );
  244. if ( APP_MODULE_INVALID != p4Module )
  245. {
  246. AddSystem( p4Module, P4_INTERFACE_VERSION );
  247. }
  248. AddSystem( g_pDataModel, VDATAMODEL_INTERFACE_VERSION );
  249. AddSystem( g_pDmElementFramework, VDMELEMENTFRAMEWORK_VERSION );
  250. AddSystem( g_pDmSerializers, DMSERIALIZERS_INTERFACE_VERSION );
  251. AddSystem( GetDefaultDmeMakefileUtils(), DMEMAKEFILE_UTILS_INTERFACE_VERSION );
  252. return true;
  253. }
  254. void CSceneViewerApp::Destroy()
  255. {
  256. BaseClass::Destroy();
  257. }
  258. //-----------------------------------------------------------------------------
  259. // Init, shutdown
  260. //-----------------------------------------------------------------------------
  261. bool CSceneViewerApp::PreInit( )
  262. {
  263. if ( !BaseClass::PreInit() )
  264. return false;
  265. SpewOutputFunc( ModelBrowserSpewFunc );
  266. SpewActivate( "console", 1 );
  267. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f, false, false, false, false );
  268. if ( !g_pFullFileSystem || !g_pMaterialSystem || !g_pDataModel || !g_pDmElementFramework || !g_pStudioRender || !g_pDataCache || !g_pMDLCache || !g_pVGuiSurface || !g_pVGui )
  269. {
  270. Warning( "CSceneViewerApp::PreInit: Unable to connect to necessary interface!\n" );
  271. return false;
  272. }
  273. // initialize interfaces
  274. CreateInterfaceFn appFactory = GetFactory();
  275. return vgui::VGui_InitDmeInterfacesList( "SceneViewer", &appFactory, 1 );
  276. }
  277. void CSceneViewerApp::PostShutdown()
  278. {
  279. BaseClass::PostShutdown();
  280. }
  281. //-----------------------------------------------------------------------------
  282. // Sets a default env_cubemap for rendering materials w/ specularity
  283. //-----------------------------------------------------------------------------
  284. void CSceneViewerApp::InitDefaultEnvCubemap( )
  285. {
  286. // Deal with the default cubemap
  287. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  288. ITexture *pCubemapTexture = g_pMaterialSystem->FindTexture( "editor/cubemap", NULL, true );
  289. m_DefaultEnvCubemap.Init( pCubemapTexture );
  290. pRenderContext->BindLocalCubemap( pCubemapTexture );
  291. }
  292. void CSceneViewerApp::ShutdownDefaultEnvCubemap( )
  293. {
  294. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  295. pRenderContext->BindLocalCubemap( NULL );
  296. m_DefaultEnvCubemap.Shutdown( );
  297. }
  298. //-----------------------------------------------------------------------------
  299. // main application
  300. //-----------------------------------------------------------------------------
  301. int CSceneViewerApp::Main()
  302. {
  303. g_pMaterialSystem->ModInit();
  304. if (!SetVideoMode())
  305. return 0;
  306. g_pDataCache->SetSize( 64 * 1024 * 1024 );
  307. InitDefaultEnvCubemap();
  308. g_pMaterialSystemConfig = &g_pMaterialSystem->GetCurrentConfigForVideoCard();
  309. // configuration settings
  310. vgui::system()->SetUserConfigFile("sceneviewer.vdf", "EXECUTABLE_PATH");
  311. // load scheme
  312. if (!vgui::scheme()->LoadSchemeFromFile("resource/BoxRocket.res", "SceneViewer" ))
  313. {
  314. Assert( 0 );
  315. }
  316. g_pVGuiLocalize->AddFile( "resource/boxrocket_%language%.txt" );
  317. // start vgui
  318. g_pVGui->Start();
  319. //vgui::input()->SetAppModalSurface( mainPanel->GetVPanel() );
  320. // load the base localization file
  321. g_pVGuiLocalize->AddFile( "Resource/valve_%language%.txt" );
  322. g_pFullFileSystem->AddSearchPath("platform", "PLATFORM");
  323. g_pVGuiLocalize->AddFile( "Resource/vgui_%language%.txt");
  324. g_pVGuiLocalize->AddFile( "Resource/dmecontrols_%language%.txt");
  325. // add our main window
  326. vgui::Panel *mainPanel = CreateSceneViewerPanel();
  327. // run app frame loop
  328. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  329. vgui::VPANEL root = vgui::surface()->GetEmbeddedPanel();
  330. vgui::surface()->Invalidate( root );
  331. // See if there was a DMX file passed on the command line
  332. for ( int i( CommandLine()->ParmCount() - 1 ); i > 0; --i )
  333. {
  334. const char *const arg( CommandLine()->GetParm( i ) );
  335. if ( arg && *arg != '\0' && _access( arg, 04 ) == 0 )
  336. {
  337. if ( !CommandLine()->FindParm( "-nozoom" ) )
  338. {
  339. KeyValues *oz( new KeyValues( "PinAndZoomIt" ) );
  340. mainPanel->PostMessage( mainPanel, oz );
  341. }
  342. KeyValues *ofs( new KeyValues( "LoadFile" ) );
  343. ofs->SetString( "fullpath", arg );
  344. mainPanel->PostMessage( mainPanel, ofs );
  345. if ( CommandLine()->FindParm( "-showasset" ) )
  346. {
  347. KeyValues *msg( new KeyValues( "ShowAssetBuilder" ) );
  348. mainPanel->PostMessage( mainPanel, msg );
  349. }
  350. if ( CommandLine()->FindParm( "-showcomboeditor" ) )
  351. {
  352. KeyValues *msg( new KeyValues( "ShowComboBuilder" ) );
  353. mainPanel->PostMessage( mainPanel, msg );
  354. }
  355. break;
  356. }
  357. }
  358. int nLastTime = Plat_MSTime();
  359. while (g_pVGui->IsRunning())
  360. {
  361. // Give other applications a chance to run
  362. Sleep( 1 );
  363. int nTime = Plat_MSTime();
  364. if ( ( nTime - nLastTime ) < 16 )
  365. continue;
  366. nLastTime = nTime;
  367. AppPumpMessages();
  368. vgui::GetAnimationController()->UpdateAnimations( Sys_FloatTime() );
  369. g_pMaterialSystem->BeginFrame( 0 );
  370. pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
  371. pRenderContext->ClearBuffers( true, true );
  372. g_pVGui->RunFrame();
  373. g_pVGuiSurface->PaintTraverseEx( root, true );
  374. g_pMaterialSystem->EndFrame();
  375. g_pMaterialSystem->SwapBuffers();
  376. }
  377. delete mainPanel;
  378. ShutdownDefaultEnvCubemap();
  379. g_pMaterialSystem->ModShutdown();
  380. // HACK - this is a bit of a hack, since in theory, there could be multiple of these panels,
  381. // or there could be elements allocated outside of these panels, but since the filenames are hardcoded,
  382. // I don't feel too bad about unloading *all* files to make sure they're caught
  383. int nFiles = g_pDataModel->NumFileIds();
  384. for ( int i = 0; i < nFiles; ++i )
  385. {
  386. DmFileId_t fileid = g_pDataModel->GetFileId( i );
  387. g_pDataModel->UnloadFile( fileid );
  388. }
  389. return 1;
  390. }