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.

1023 lines
30 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #define PROTECTED_THINGS_DISABLE
  7. #define WIN32_LEAN_AND_MEAN
  8. #include <windows.h>
  9. #include "materialsystem/imaterialsystem.h"
  10. #include "materialsystem/IMaterialSystemHardwareConfig.h"
  11. #include "materialsystem/imaterialproxyfactory.h"
  12. #include "filesystem.h"
  13. #include "bitmap/imageformat.h"
  14. #include "materialsystem/MaterialSystem_Config.h"
  15. #include "tier0/icommandline.h"
  16. #include "tier1/strtools.h"
  17. #include "mathlib/mathlib.h"
  18. #include "materialsystem/imesh.h"
  19. #include "materialsystem/imaterial.h"
  20. #include "materialsystem/imaterialvar.h"
  21. #include "bitmap/tgawriter.h"
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <direct.h>
  25. #include "vstdlib/cvar.h"
  26. #include "KeyValues.h"
  27. #include "tier1/utlbuffer.h"
  28. #include "tier2/tier2.h"
  29. #define CHECKERBOARD_DIMS 16
  30. IMaterial *g_pProceduralMaterial = NULL;
  31. static char g_pCommandLine[1024];
  32. static int g_ArgC = 0;
  33. static char* g_ppArgV[32];
  34. static HWND g_HWnd = 0;
  35. static CreateInterfaceFn g_MaterialsFactory;
  36. static CSysModule *g_MaterialsDLL = NULL;
  37. static int g_RenderWidth = 640;
  38. static int g_RenderHeight = 480;
  39. static int g_RefreshRate = 60;
  40. static bool g_Exiting = false;
  41. void CreateLightmapPages( void );
  42. void RenderFrame( void );
  43. //-----------------------------------------------------------------------------
  44. // Command-line...
  45. //-----------------------------------------------------------------------------
  46. int FindCommand( const char *pCommand )
  47. {
  48. for ( int i = 0; i < g_ArgC; i++ )
  49. {
  50. if ( !stricmp( pCommand, g_ppArgV[i] ) )
  51. return i;
  52. }
  53. return -1;
  54. }
  55. const char* CommandArgument( const char *pCommand )
  56. {
  57. int cmd = FindCommand( pCommand );
  58. if ((cmd != -1) && (cmd < g_ArgC - 1))
  59. {
  60. return g_ppArgV[cmd+1];
  61. }
  62. return 0;
  63. }
  64. void SetupCommandLine( const char* pCommandLine )
  65. {
  66. Q_strncpy( g_pCommandLine, pCommandLine, sizeof( g_pCommandLine ) );
  67. g_ArgC = 0;
  68. char* pStr = g_pCommandLine;
  69. while ( *pStr )
  70. {
  71. pStr = strtok( pStr, " " );
  72. if( !pStr )
  73. {
  74. break;
  75. }
  76. g_ppArgV[g_ArgC++] = pStr;
  77. pStr += strlen(pStr) + 1;
  78. }
  79. }
  80. //-----------------------------------------------------------------------------
  81. // DummyMaterialProxyFactory...
  82. //-----------------------------------------------------------------------------
  83. class DummyMaterialProxyFactory : public IMaterialProxyFactory
  84. {
  85. public:
  86. virtual IMaterialProxy *CreateProxy( const char *proxyName ) {return NULL;}
  87. virtual void DeleteProxy( IMaterialProxy *pProxy ) {}
  88. };
  89. static DummyMaterialProxyFactory g_DummyMaterialProxyFactory;
  90. //-----------------------------------------------------------------------------
  91. // Spew function!
  92. //-----------------------------------------------------------------------------
  93. SpewRetval_t SpewFunc( SpewType_t spewType, char const *pMsg )
  94. {
  95. OutputDebugString( pMsg );
  96. switch( spewType )
  97. {
  98. case SPEW_MESSAGE:
  99. case SPEW_WARNING:
  100. case SPEW_LOG:
  101. OutputDebugString( pMsg );
  102. return SPEW_CONTINUE;
  103. case SPEW_ASSERT:
  104. case SPEW_ERROR:
  105. default:
  106. ::MessageBox( NULL, pMsg, "Error!", MB_OK );
  107. return SPEW_DEBUGGER;
  108. }
  109. }
  110. //-----------------------------------------------------------------------------
  111. // Error...
  112. //-----------------------------------------------------------------------------
  113. void DisplayError( const char* pError, ... )
  114. {
  115. va_list argptr;
  116. char msg[1024];
  117. va_start( argptr, pError );
  118. Q_vsnprintf( msg, sizeof( msg ), pError, argptr );
  119. va_end( argptr );
  120. MessageBox( 0, msg, 0, MB_OK );
  121. }
  122. IFileSystem *g_pFileSystem;
  123. static CSysModule *g_pFileSystemModule = NULL;
  124. static CreateInterfaceFn g_pFileSystemFactory = NULL;
  125. static bool FileSystem_LoadDLL( void )
  126. {
  127. g_pFileSystemModule = Sys_LoadModule( "filesystem_stdio.dll" );
  128. Assert( g_pFileSystemModule );
  129. if( !g_pFileSystemModule )
  130. {
  131. return false;
  132. }
  133. g_pFileSystemFactory = Sys_GetFactory( g_pFileSystemModule );
  134. if( !g_pFileSystemFactory )
  135. {
  136. return false;
  137. }
  138. g_pFileSystem = ( IFileSystem * )g_pFileSystemFactory( FILESYSTEM_INTERFACE_VERSION, NULL );
  139. Assert( g_pFileSystem );
  140. if( !g_pFileSystem )
  141. {
  142. return false;
  143. }
  144. return true;
  145. }
  146. void FileSystem_UnloadDLL( void )
  147. {
  148. if ( !g_pFileSystemModule )
  149. return;
  150. Sys_UnloadModule( g_pFileSystemModule );
  151. g_pFileSystemModule = 0;
  152. }
  153. void FileSystem_Init( )
  154. {
  155. if( !FileSystem_LoadDLL() )
  156. {
  157. return;
  158. }
  159. g_pFileSystem->RemoveSearchPath( NULL, "GAME" );
  160. g_pFileSystem->AddSearchPath( "hl2", "GAME", PATH_ADD_TO_HEAD );
  161. }
  162. void FileSystem_Shutdown( void )
  163. {
  164. g_pFileSystem->Shutdown();
  165. FileSystem_UnloadDLL();
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Purpose: Unloads the material system .dll
  169. //-----------------------------------------------------------------------------
  170. void UnloadMaterialSystem( void )
  171. {
  172. if ( !g_MaterialsFactory )
  173. return;
  174. Sys_UnloadModule( g_MaterialsDLL );
  175. g_MaterialsDLL = NULL;
  176. }
  177. //-----------------------------------------------------------------------------
  178. // Purpose: Loads the material system dll
  179. //-----------------------------------------------------------------------------
  180. void LoadMaterialSystem( void )
  181. {
  182. if( g_MaterialsFactory )
  183. {
  184. return;
  185. }
  186. Assert( !g_MaterialsDLL );
  187. g_MaterialsDLL = Sys_LoadModule( "MaterialSystem.dll" );
  188. g_MaterialsFactory = Sys_GetFactory( g_MaterialsDLL );
  189. if ( !g_MaterialsFactory )
  190. {
  191. DisplayError( "LoadMaterialSystem: Failed to load MaterialSystem.DLL\n" );
  192. return;
  193. }
  194. if ( g_MaterialsFactory )
  195. {
  196. g_pMaterialSystem = (IMaterialSystem *)g_MaterialsFactory( MATERIAL_SYSTEM_INTERFACE_VERSION, NULL );
  197. if ( !g_pMaterialSystem )
  198. {
  199. DisplayError( "Could not get the material system interface from materialsystem.dll (a)" );
  200. }
  201. }
  202. else
  203. {
  204. DisplayError( "Could not find factory interface in library MaterialSystem.dll" );
  205. }
  206. }
  207. void InitMaterialSystemConfig(MaterialSystem_Config_t *pConfig)
  208. {
  209. }
  210. CreateInterfaceFn g_MaterialSystemClientFactory;
  211. void Shader_Init( HWND mainWindow )
  212. {
  213. LoadMaterialSystem();
  214. Assert( g_pMaterialSystem );
  215. // FIXME: Where do we put this?
  216. const char* pDLLName;
  217. pDLLName = "shaderapidx9";
  218. // assume that IFileSystem paths have already been set via g_pFileSystem
  219. g_MaterialSystemClientFactory = g_pMaterialSystem->Init(
  220. pDLLName, &g_DummyMaterialProxyFactory, g_pFileSystemFactory, VStdLib_GetICVarFactory() );
  221. if (!g_MaterialSystemClientFactory)
  222. {
  223. DisplayError( "Unable to init shader system\n" );
  224. }
  225. // Get the adapter from the command line....
  226. MaterialVideoMode_t mode;
  227. memset( &mode, 0, sizeof( mode ) );
  228. mode.m_Width = g_RenderWidth;
  229. mode.m_Height = g_RenderHeight;
  230. mode.m_Format = IMAGE_FORMAT_BGRX8888;
  231. mode.m_RefreshRate = g_RefreshRate;
  232. // bool modeSet = g_pMaterialSystem->SetMode( (void*)mainWindow, mode, modeFlags );
  233. // if (!modeSet)
  234. // {
  235. // DisplayError( "Unable to set mode\n" );
  236. // }
  237. g_pMaterialSystemHardwareConfig = (IMaterialSystemHardwareConfig*)
  238. g_MaterialSystemClientFactory( MATERIALSYSTEM_HARDWARECONFIG_INTERFACE_VERSION, 0 );
  239. if ( !g_pMaterialSystemHardwareConfig )
  240. {
  241. DisplayError( "Could not get the material system hardware config interface!" );
  242. }
  243. MaterialSystem_Config_t config;
  244. InitMaterialSystemConfig(&config);
  245. g_pMaterialSystem->OverrideConfig( config, false );
  246. if( FindCommand( "-stub" ) != -1 )
  247. {
  248. g_pMaterialSystem->SetInStubMode( true );
  249. }
  250. }
  251. void Shader_Shutdown( HWND hwnd )
  252. {
  253. // Recursive shutdown
  254. if ( !g_pMaterialSystem )
  255. return;
  256. g_pMaterialSystem->Shutdown( );
  257. g_pMaterialSystem = NULL;
  258. UnloadMaterialSystem();
  259. }
  260. static void CalcWindowSize( int desiredRenderingWidth, int desiredRenderingHeight,
  261. int *windowWidth, int *windowHeight )
  262. {
  263. int borderX, borderY;
  264. borderX = (GetSystemMetrics(SM_CXFIXEDFRAME) + 1) * 2;
  265. borderY = (GetSystemMetrics(SM_CYFIXEDFRAME) + 1) * 2 + GetSystemMetrics(SM_CYSIZE) + 1;
  266. *windowWidth = desiredRenderingWidth + borderX;
  267. *windowHeight = desiredRenderingHeight + borderY;
  268. }
  269. //-----------------------------------------------------------------------------
  270. // Window create, destroy...
  271. //-----------------------------------------------------------------------------
  272. LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
  273. {
  274. switch( msg )
  275. {
  276. case WM_PAINT:
  277. RenderFrame();
  278. break;
  279. // abort when ESC is hit
  280. case WM_CHAR:
  281. switch(wParam)
  282. {
  283. case VK_ESCAPE:
  284. SendMessage( g_HWnd, WM_CLOSE, 0, 0 );
  285. break;
  286. }
  287. break;
  288. case WM_DESTROY:
  289. g_Exiting = true;
  290. PostQuitMessage( 0 );
  291. return 0;
  292. }
  293. return DefWindowProc( hWnd, msg, wParam, lParam );
  294. }
  295. bool CreateAppWindow( const char* pAppName, int width, int height )
  296. {
  297. // Register the window class
  298. WNDCLASSEX windowClass =
  299. {
  300. sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
  301. GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
  302. pAppName, NULL
  303. };
  304. RegisterClassEx( &windowClass );
  305. // Create the application's window
  306. g_HWnd = CreateWindow( pAppName, pAppName,
  307. WS_OVERLAPPEDWINDOW,
  308. 0, 0, width, height,
  309. GetDesktopWindow(), NULL, windowClass.hInstance, NULL );
  310. ShowWindow (g_HWnd, SW_SHOWDEFAULT);
  311. return (g_HWnd != 0);
  312. }
  313. void DestroyAppWindow()
  314. {
  315. if (g_HWnd)
  316. DestroyWindow( g_HWnd );
  317. }
  318. bool Init( const char* pCommands)
  319. {
  320. // Store off the command line...
  321. SetupCommandLine( pCommands );
  322. FileSystem_Init( );
  323. /* figure out g_Renderwidth and g_RenderHeight */
  324. g_RenderWidth = -1;
  325. g_RenderHeight = -1;
  326. g_RenderWidth = 640;
  327. g_RenderHeight = 480;
  328. int windowWidth, windowHeight;
  329. CalcWindowSize( g_RenderWidth, g_RenderHeight, &windowWidth, &windowHeight );
  330. if( !CreateAppWindow( "matsys_regressiontest", windowWidth, windowHeight ) )
  331. {
  332. return false;
  333. }
  334. Shader_Init( g_HWnd );
  335. g_pMaterialSystem->CacheUsedMaterials();
  336. CreateLightmapPages();
  337. return true;
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Purpose: Return the directory where this .exe is running from
  341. // Output : char
  342. //-----------------------------------------------------------------------------
  343. static char *GetBaseDir( const char *pszBuffer )
  344. {
  345. static char basedir[ MAX_PATH ];
  346. char szBuffer[ MAX_PATH ];
  347. int j;
  348. char *pBuffer = NULL;
  349. Q_strncpy( szBuffer, pszBuffer, sizeof( szBuffer ) );
  350. pBuffer = strrchr( szBuffer,'\\' );
  351. if ( pBuffer )
  352. {
  353. *(pBuffer+1) = '\0';
  354. }
  355. Q_strncpy( basedir, szBuffer, sizeof( basedir ) );
  356. j = strlen( basedir );
  357. if (j > 0)
  358. {
  359. if ( ( basedir[ j-1 ] == '\\' ) ||
  360. ( basedir[ j-1 ] == '/' ) )
  361. {
  362. basedir[ j-1 ] = 0;
  363. }
  364. }
  365. return basedir;
  366. }
  367. //-----------------------------------------------------------------------------
  368. // Shutdown
  369. //-----------------------------------------------------------------------------
  370. void Shutdown()
  371. {
  372. // Close the window
  373. DestroyAppWindow();
  374. Shader_Shutdown( g_HWnd );
  375. }
  376. //-----------------------------------------------------------------------------
  377. // Pump windows messages
  378. //-----------------------------------------------------------------------------
  379. void PumpWindowsMessages ()
  380. {
  381. MSG msg;
  382. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) == TRUE)
  383. {
  384. TranslateMessage(&msg);
  385. DispatchMessage(&msg);
  386. }
  387. InvalidateRect(g_HWnd, NULL, false);
  388. UpdateWindow(g_HWnd);
  389. }
  390. MaterialSystem_SortInfo_t *g_pMaterialSortInfo = NULL;
  391. struct LightmapInfo_t
  392. {
  393. int m_LightmapDims[2];
  394. int m_LightmapPageDims[2];
  395. int m_OffsetIntoLightmapPage[2];
  396. int m_SortID;
  397. };
  398. LightmapInfo_t g_CheckerboardLightmapInfo;
  399. void AllocateLightmap( LightmapInfo_t& lightmapInfo, int width, int height )
  400. {
  401. lightmapInfo.m_LightmapDims[0] = width;
  402. lightmapInfo.m_LightmapDims[1] = height;
  403. // HACK! We don't ever use this material for anything. . just need it for allocating lightmaps.
  404. CMatRenderContextPtr pRenderContext( materials );
  405. IMaterial *pHackMaterial = g_pMaterialSystem->FindMaterial( "shadertest/lightmappedgeneric", TEXTURE_GROUP_OTHER );
  406. pRenderContext->Bind( pHackMaterial );
  407. lightmapInfo.m_SortID =
  408. g_pMaterialSystem->AllocateLightmap( 16, 16, lightmapInfo.m_OffsetIntoLightmapPage, pHackMaterial );
  409. }
  410. void Lightmap_PostAllocation( LightmapInfo_t& lightmapInfo )
  411. {
  412. g_pMaterialSystem->GetLightmapPageSize( lightmapInfo.m_SortID,
  413. &lightmapInfo.m_LightmapPageDims[0], &lightmapInfo.m_LightmapPageDims[1] );
  414. }
  415. void UpdateLightmap( LightmapInfo_t& lightmapInfo, float *data )
  416. {
  417. g_pMaterialSystem->UpdateLightmap( g_pMaterialSortInfo[lightmapInfo.m_SortID].lightmapPageID,
  418. lightmapInfo.m_LightmapDims, lightmapInfo.m_OffsetIntoLightmapPage, data, NULL, NULL, NULL );
  419. }
  420. void CreateLightmapPages( void )
  421. {
  422. g_pMaterialSystem->BeginLightmapAllocation();
  423. AllocateLightmap( g_CheckerboardLightmapInfo, CHECKERBOARD_DIMS, CHECKERBOARD_DIMS );
  424. g_pMaterialSystem->EndLightmapAllocation();
  425. int numSortIDs = g_pMaterialSystem->GetNumSortIDs();
  426. g_pMaterialSortInfo = new MaterialSystem_SortInfo_t[numSortIDs];
  427. g_pMaterialSystem->GetSortInfo( g_pMaterialSortInfo );
  428. Lightmap_PostAllocation( g_CheckerboardLightmapInfo );
  429. float checkerboardImage[CHECKERBOARD_DIMS*CHECKERBOARD_DIMS*4];
  430. int x, y;
  431. for( y = 0; y < CHECKERBOARD_DIMS; y++ )
  432. {
  433. for( x = 0; x < CHECKERBOARD_DIMS; x++ )
  434. {
  435. if( ( x + y ) & 1 )
  436. {
  437. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+0] = 1.0f;
  438. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+1] = 1.0f;
  439. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+2] = 1.0f;
  440. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+3] = 1.0f;
  441. }
  442. else
  443. {
  444. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+0] = 0.0f;
  445. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+1] = 0.0f;
  446. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+2] = 0.0f;
  447. checkerboardImage[(y*CHECKERBOARD_DIMS+x)*4+3] = 1.0f;
  448. }
  449. }
  450. }
  451. UpdateLightmap( g_CheckerboardLightmapInfo, checkerboardImage );
  452. }
  453. void LightmapTexCoord( CMeshBuilder& meshBuilder, LightmapInfo_t lightmapInfo, float s, float t )
  454. {
  455. // add a one texel border.
  456. float newS = ( s * ( lightmapInfo.m_LightmapDims[0] - 2 ) ) + 1;
  457. float newT = ( t * ( lightmapInfo.m_LightmapDims[1] - 2 ) ) + 1;
  458. newS += lightmapInfo.m_OffsetIntoLightmapPage[0];
  459. newT += lightmapInfo.m_OffsetIntoLightmapPage[1];
  460. newS *= 1.0f / lightmapInfo.m_LightmapPageDims[0];
  461. newT *= 1.0f / lightmapInfo.m_LightmapPageDims[1];
  462. meshBuilder.TexCoord2f( 1, newS, newT );
  463. }
  464. //-----------------------------------------------------------------------------
  465. // Update
  466. //-----------------------------------------------------------------------------
  467. bool Update()
  468. {
  469. PumpWindowsMessages();
  470. return g_Exiting;
  471. }
  472. void ScreenShot( const char *pFilename )
  473. {
  474. // bitmap bits
  475. unsigned char *pImage = ( unsigned char * )malloc( g_RenderWidth * 3 * g_RenderHeight );
  476. // Get Bits from the material system
  477. CMatRenderContextPtr pRenderContext( materials );
  478. pRenderContext->ReadPixels( 0, 0, g_RenderWidth, g_RenderHeight, pImage, IMAGE_FORMAT_RGB888 );
  479. CUtlBuffer outBuf;
  480. if( !TGAWriter::WriteToBuffer( pImage, outBuf, g_RenderWidth, g_RenderHeight, IMAGE_FORMAT_RGB888,
  481. IMAGE_FORMAT_RGB888 ) )
  482. {
  483. Error( "Couldn't write %s\n", pFilename );
  484. }
  485. if ( !g_pFullFileSystem->WriteFile( pFilename, NULL, outBuf ) )
  486. {
  487. Error( "Couldn't write %s\n", pFilename );
  488. }
  489. free( pImage );
  490. }
  491. void SetVar( const char *pVarName, const char *pStringValue )
  492. {
  493. IMaterialVar *pVar = g_pProceduralMaterial->FindVar( pVarName, NULL );
  494. if( pStringValue )
  495. {
  496. pVar->SetStringValue( pStringValue );
  497. }
  498. else
  499. {
  500. pVar->SetUndefined();
  501. }
  502. }
  503. void SetVar( const char *pVarName, int val )
  504. {
  505. IMaterialVar *pVar = g_pProceduralMaterial->FindVar( pVarName, NULL );
  506. pVar->SetIntValue( val );
  507. }
  508. void SetFlag( MaterialVarFlags_t flag, int val )
  509. {
  510. g_pProceduralMaterial->SetMaterialVarFlag( flag, val ? true : false );
  511. }
  512. void DrawBackground( void )
  513. {
  514. CMatRenderContextPtr pRenderContext( materials );
  515. IMaterial *pMaterial = g_pMaterialSystem->FindMaterial( "matsys_regressiontest/background", TEXTURE_GROUP_OTHER );
  516. pRenderContext->Bind( pMaterial );
  517. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  518. CMeshBuilder meshBuilder;
  519. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  520. #define X 500.0f
  521. #define Y 500.0f
  522. #define Z -500.0f
  523. meshBuilder.Position3f( -X, Y, Z );
  524. meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
  525. meshBuilder.AdvanceVertex();
  526. meshBuilder.Position3f( X, Y, Z );
  527. meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
  528. meshBuilder.AdvanceVertex();
  529. meshBuilder.Position3f( X, -Y, Z );
  530. meshBuilder.TexCoord2f( 0, 1.0f, 1.0f );
  531. meshBuilder.AdvanceVertex();
  532. meshBuilder.Position3f( -X, -Y, Z );
  533. meshBuilder.TexCoord2f( 0, 0.0f, 1.0f );
  534. meshBuilder.AdvanceVertex();
  535. meshBuilder.End();
  536. pMesh->Draw();
  537. #undef X
  538. #undef Y
  539. #undef Z
  540. }
  541. void BeginFrame( void )
  542. {
  543. g_pMaterialSystem->BeginFrame( 0 );
  544. CMatRenderContextPtr pRenderContext( materials );
  545. pRenderContext->ClearColor3ub( 255, 0, 0 );
  546. pRenderContext->ClearBuffers( true, true );
  547. pRenderContext->Viewport( 0, 0, g_RenderWidth, g_RenderHeight );
  548. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  549. pRenderContext->LoadIdentity();
  550. pRenderContext->PerspectiveX( 90.0f, ( g_RenderWidth / g_RenderHeight), 1.0f, 500000.0f );
  551. pRenderContext->MatrixMode( MATERIAL_VIEW );
  552. pRenderContext->LoadIdentity();
  553. pRenderContext->MatrixMode( MATERIAL_MODEL );
  554. pRenderContext->LoadIdentity();
  555. }
  556. void EndFrame( void )
  557. {
  558. g_pMaterialSystem->EndFrame();
  559. g_pMaterialSystem->SwapBuffers();
  560. }
  561. void DrawQuad( const LightmapInfo_t& lightmapInfo )
  562. {
  563. CMatRenderContextPtr pRenderContext( materials );
  564. pRenderContext->BindLightmapPage( g_pMaterialSortInfo[lightmapInfo.m_SortID].lightmapPageID );
  565. pRenderContext->Bind( g_pProceduralMaterial );
  566. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  567. CMeshBuilder meshBuilder;
  568. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  569. #define X 350.0f
  570. #define Y (X*(4.0f/3.0f))
  571. #define Z -500.0f
  572. meshBuilder.Position3f( -X, Y, Z );
  573. meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
  574. LightmapTexCoord( meshBuilder, lightmapInfo, 0.0f, 0.0f );
  575. meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
  576. meshBuilder.Color4f( 1.0f, 0.0f, 0.0f, 1.0f );
  577. meshBuilder.AdvanceVertex();
  578. meshBuilder.Position3f( X, Y, Z );
  579. meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
  580. LightmapTexCoord( meshBuilder, lightmapInfo, 1.0f, 0.0f );
  581. meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
  582. meshBuilder.Color4f( 1.0f, 1.0f, 0.0f, 1.0f );
  583. meshBuilder.AdvanceVertex();
  584. meshBuilder.Position3f( X, -Y, Z );
  585. meshBuilder.TexCoord2f( 0, 1.0f, 1.0f );
  586. LightmapTexCoord( meshBuilder, lightmapInfo, 1.0f, 1.0f );
  587. meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
  588. meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, 0.0f );
  589. meshBuilder.AdvanceVertex();
  590. meshBuilder.Position3f( -X, -Y, Z );
  591. meshBuilder.TexCoord2f( 0, 0.0f, 1.0f );
  592. LightmapTexCoord( meshBuilder, lightmapInfo, 0.0f, 1.0f );
  593. meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
  594. meshBuilder.Color4f( 0.0f, 1.0f, 1.0f, 1.0f );
  595. meshBuilder.AdvanceVertex();
  596. meshBuilder.End();
  597. pMesh->Draw();
  598. #undef X
  599. #undef Y
  600. #undef Z
  601. }
  602. void TestLightmappedGeneric_dx80( void )
  603. {
  604. /*
  605. based on lightmappedgeneric_vs11.fxc:
  606. // STATIC: "DETAIL" "0..1"
  607. // STATIC: "ENVMAP" "0..1"
  608. // STATIC: "ENVMAPCAMERASPACE" "0..1"
  609. // STATIC: "ENVMAPSPHERE" "0..1"
  610. // STATIC: "VERTEXCOLOR" "0..1"
  611. // DYNAMIC: "FOGTYPE" "0..1"
  612. // SKIP: $ENVMAPCAMERASPACE && $ENVMAPSPHERE
  613. // SKIP: !$ENVMAP && ( $ENVMAPCAMERASPACE || $ENVMAPSPHERE )
  614. based on lightmappedgeneric_ps11.fxc:
  615. // STATIC: "BASETEXTURE" "0..1"
  616. // STATIC: "ENVMAP" "0..1"
  617. // STATIC: "ENVMAPMASK" "0..1"
  618. // STATIC: "SELFILLUM" "0..1"
  619. // STATIC: "BASEALPHAENVMAPMASK" "0..1"
  620. // SKIP: !$ENVMAP && ( $BASEALPHAENVMAPMASK || $ENVMAPMASK )
  621. // SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK
  622. // SKIP: $BASEALPHAENVMAPMASK && $ENVMAPMASK
  623. // SKIP: !$BASETEXTURE && $BASEALPHAENVMAPMASK
  624. // SKIP: $SELFILLUM && $BASEALPHAENVMAPMASK
  625. // SKIP: !$BASETEXTURE && $SELFILLUM
  626. Versions with DETAIL aren't implemented yet in HLSL, but we'll go ahead and test those.
  627. */
  628. // The following are shader combos from lightmappedgeneric_ps20
  629. for( int BUMPMAP = 0; BUMPMAP <= 1; BUMPMAP++ )
  630. {
  631. for( int NORMALMAPALPHAENVMAPMASK = 0; NORMALMAPALPHAENVMAPMASK <= 1; NORMALMAPALPHAENVMAPMASK++ )
  632. {
  633. // The following are shader combos from lightmappedgeneric_ps11 (that aren't in lightmappedgenerc_vs11)
  634. for( int BASETEXTURE = 0; BASETEXTURE <= 1; BASETEXTURE++ )
  635. {
  636. for( int ENVMAPMASK = 0; ENVMAPMASK <= 1; ENVMAPMASK++ )
  637. {
  638. for( int SELFILLUM = 0; SELFILLUM <= 1; SELFILLUM++ )
  639. {
  640. for( int BASEALPHAENVMAPMASK = 0; BASEALPHAENVMAPMASK <= 1; BASEALPHAENVMAPMASK++ )
  641. {
  642. // The following are shader combos from lightmappedgeneric_vs11
  643. for( int DETAIL = 0; DETAIL <= 1; DETAIL++ )
  644. {
  645. for( int ENVMAP = 0; ENVMAP <= 1; ENVMAP++ )
  646. {
  647. for( int ENVMAPCAMERASPACE = 0; ENVMAPCAMERASPACE <= 1; ENVMAPCAMERASPACE++ )
  648. {
  649. for( int ENVMAPSPHERE = 0; ENVMAPSPHERE <= 1; ENVMAPSPHERE++ )
  650. {
  651. for( int VERTEXCOLOR = 0; VERTEXCOLOR <= 1; VERTEXCOLOR++ )
  652. {
  653. // for( int FOGTYPE = 0; FOGTYPE <= 1; FOGTYPE++ )
  654. {
  655. // conditional beneath here are flags, not shader combos
  656. for( int ALPHATEST = 0; ALPHATEST <= 1; ALPHATEST++ )
  657. {
  658. for( int TRANSLUCENT = 0; TRANSLUCENT <= 1; TRANSLUCENT++ )
  659. {
  660. for( int COLORMODULATE = 0; COLORMODULATE <= 1; COLORMODULATE++ )
  661. {
  662. for( int ALPHAMODULATE = 0; ALPHAMODULATE <= 1; ALPHAMODULATE++ )
  663. {
  664. #if 0
  665. BUMPMAP = 0;
  666. NORMALMAPALPHAENVMAPMASK = 0;
  667. BASETEXTURE = 1;
  668. ENVMAPMASK = 0;
  669. SELFILLUM = 0;
  670. BASEALPHAENVMAPMASK = 1;
  671. DETAIL = 0;
  672. ENVMAP = 1;
  673. ENVMAPCAMERASPACE = 0;
  674. ENVMAPSPHERE = 0;
  675. VERTEXCOLOR = 0;
  676. ALPHATEST = 0;
  677. TRANSLUCENT = 0;
  678. COLORMODULATE = 0;
  679. ALPHAMODULATE = 0;
  680. #endif
  681. // skip commands from shader lightmappedgeneric_vs11
  682. if( ENVMAPCAMERASPACE && ENVMAPSPHERE ) continue;
  683. if( !ENVMAP && ( ENVMAPCAMERASPACE || ENVMAPSPHERE ) ) continue;
  684. // skip commands from shader lihgtmappedgeneric_ps11
  685. if( !ENVMAP && ( BASEALPHAENVMAPMASK || ENVMAPMASK ) ) continue;
  686. if( !BASETEXTURE && BASEALPHAENVMAPMASK ) continue;
  687. if( BASEALPHAENVMAPMASK && ENVMAPMASK ) continue;
  688. if( !BASETEXTURE && BASEALPHAENVMAPMASK ) continue;
  689. if( SELFILLUM && BASEALPHAENVMAPMASK ) continue;
  690. if( !BASETEXTURE && SELFILLUM ) continue;
  691. // skip commands from shader lightmappedgeneric_ps20
  692. if( DETAIL && BUMPMAP ) continue;
  693. if( ENVMAPMASK && BUMPMAP ) continue;
  694. if( NORMALMAPALPHAENVMAPMASK && BASEALPHAENVMAPMASK ) continue;
  695. if( NORMALMAPALPHAENVMAPMASK && ENVMAPMASK ) continue;
  696. if( BASEALPHAENVMAPMASK && ENVMAPMASK ) continue;
  697. if( BASEALPHAENVMAPMASK && SELFILLUM ) continue;
  698. // skip commands from flags that don't make sense (or we don't want to test)
  699. if( !BASETEXTURE && ( ALPHATEST || TRANSLUCENT ) ) continue;
  700. if( TRANSLUCENT && ALPHATEST ) continue;
  701. KeyValues *pKeyValues = new KeyValues( "lightmappedgeneric" );
  702. if ( BASETEXTURE )
  703. {
  704. pKeyValues->SetString( "$basetexture", "matsys_regressiontest/basetexture" );
  705. }
  706. if ( ENVMAPMASK )
  707. {
  708. pKeyValues->SetString( "$envmapmask", "matsys_regressiontest/specularmask" );
  709. }
  710. if ( SELFILLUM )
  711. {
  712. pKeyValues->SetInt( "$selfillum", 1 );
  713. }
  714. if ( BASEALPHAENVMAPMASK )
  715. {
  716. pKeyValues->SetInt( "$basealphaenvmapmask", 1 );
  717. }
  718. if ( BUMPMAP )
  719. {
  720. pKeyValues->SetString( "$bumpmap", "matsys_regressiontest/normalmap_normal" );
  721. }
  722. if ( DETAIL )
  723. {
  724. pKeyValues->SetString( "$detail", "matsys_regressiontest/detail" );
  725. pKeyValues->SetFloat( "$detailscale", 0.5f );
  726. }
  727. if ( ENVMAP )
  728. {
  729. pKeyValues->SetString( "$envmap", "matsys_regressiontest/cubemap" );
  730. }
  731. if ( BASEALPHAENVMAPMASK )
  732. {
  733. pKeyValues->SetInt( "$basealphaenvmapmask", 1 );
  734. }
  735. if ( NORMALMAPALPHAENVMAPMASK )
  736. {
  737. pKeyValues->SetInt( "$normalmapalphaenvmapmask", 1 );
  738. }
  739. if ( TRANSLUCENT )
  740. {
  741. pKeyValues->SetInt( "$translucent", 1 );
  742. }
  743. if ( ENVMAPCAMERASPACE )
  744. {
  745. pKeyValues->SetInt( "$envmapcameraspace", 1 );
  746. }
  747. if ( ENVMAPSPHERE )
  748. {
  749. pKeyValues->SetInt( "$envmapsphere", 1 );
  750. }
  751. if ( VERTEXCOLOR )
  752. {
  753. pKeyValues->SetInt( "$vertexcolor", 1 );
  754. }
  755. if ( ALPHATEST )
  756. {
  757. pKeyValues->SetInt( "$alphatest", 1 );
  758. }
  759. if ( COLORMODULATE )
  760. {
  761. pKeyValues->SetString( "$color", "[1.0 0.8 0.5]" );
  762. }
  763. if ( ALPHAMODULATE )
  764. {
  765. pKeyValues->SetFloat( "$alpha", 0.6f );
  766. }
  767. // FIXME: ignoring fogtype for now.
  768. // hack hack - LEAK - need to figure out how to clear a material out.
  769. g_pProceduralMaterial = g_pMaterialSystem->CreateMaterial( "test", pKeyValues );
  770. g_pProceduralMaterial->Refresh();
  771. BeginFrame();
  772. DrawBackground();
  773. DrawQuad( g_CheckerboardLightmapInfo );
  774. EndFrame();
  775. char filename[MAX_PATH];
  776. sprintf( filename, "%s\\lightmappedgeneric_dx80", CommandLine()->ParmValue( "-targetdir" ) );
  777. if( BUMPMAP ) Q_strcat( filename, "_BUMPMAP", sizeof(filename) );
  778. if( NORMALMAPALPHAENVMAPMASK ) Q_strcat( filename, "_NORMALMAPALPHAENVMAPMASK", sizeof(filename) );
  779. if( BASETEXTURE ) Q_strcat( filename, "_BASE", sizeof(filename) );
  780. if( ENVMAPMASK ) Q_strcat( filename, "_ENVMAPMASK", sizeof(filename) );
  781. if( SELFILLUM ) Q_strcat( filename, "_SELFILLUM", sizeof(filename) );
  782. if( BASEALPHAENVMAPMASK ) Q_strcat( filename, "_BASEALPHAENVMAPMASK", sizeof(filename) );
  783. if( DETAIL ) Q_strcat( filename, "_DETAIL", sizeof(filename) );
  784. if( ENVMAP ) Q_strcat( filename, "_ENVMAP", sizeof(filename) );
  785. if( ENVMAPCAMERASPACE ) Q_strcat( filename, "_ENVMAPCAMERASPACE", sizeof(filename) );
  786. if( ENVMAPSPHERE ) Q_strcat( filename, "_ENVMAPSPHERE", sizeof(filename) );
  787. if( VERTEXCOLOR ) Q_strcat( filename, "_VERTEXCOLOR", sizeof(filename) );
  788. // if( FOGTYPE ) Q_strcat( filename, "_FOGTYPE", sizeof(filename) );
  789. if( ALPHATEST ) Q_strcat( filename, "_ALPHATEST", sizeof(filename) );
  790. if( TRANSLUCENT ) Q_strcat( filename, "_TRANSLUCENT", sizeof(filename) );
  791. if( COLORMODULATE ) Q_strcat( filename, "_COLORMODULATE", sizeof(filename) );
  792. if( ALPHAMODULATE ) Q_strcat( filename, "_ALPHAMODULATE", sizeof(filename) );
  793. if( BUMPMAP ) Q_strcat( filename, "_BUMPMAP", sizeof(filename) );
  794. Q_strcat( filename, ".tga", sizeof(filename) );
  795. ScreenShot( filename );
  796. g_pProceduralMaterial->DecrementReferenceCount();
  797. }
  798. }
  799. }
  800. }
  801. }
  802. }
  803. }
  804. }
  805. }
  806. }
  807. }
  808. }
  809. }
  810. }
  811. }
  812. }
  813. }
  814. //-----------------------------------------------------------------------------
  815. // Render a frame
  816. //-----------------------------------------------------------------------------
  817. void RenderFrame( void )
  818. {
  819. TestLightmappedGeneric_dx80();
  820. }
  821. INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE hInstance, LPSTR pCommands, INT )
  822. {
  823. SpewOutputFunc( SpewFunc );
  824. CommandLine()->CreateCmdLine( ::GetCommandLine() );
  825. InitDefaultFileSystem();
  826. if( !CommandLine()->ParmValue( "-targetdir" ) )
  827. {
  828. Error( "Must specify -targetdir on command line!\n" );
  829. }
  830. struct _stat statbuf;
  831. if( 0 != _stat( CommandLine()->ParmValue( "-targetdir" ), &statbuf ) )
  832. {
  833. if( 0 != _mkdir( CommandLine()->ParmValue( "-targetdir" ) ) )
  834. {
  835. Error( "Couldn't create path %s\n", CommandLine()->ParmValue( "-targetdir" ) );
  836. }
  837. }
  838. // Must add 'bin' to the path....
  839. char* pPath = getenv("PATH");
  840. // Use the .EXE name to determine the root directory
  841. char moduleName[ MAX_PATH ];
  842. char szBuffer[ 4096 ];
  843. if ( !GetModuleFileName( hInstance, moduleName, MAX_PATH ) )
  844. {
  845. MessageBox( 0, "Failed calling GetModuleFileName", "Launcher Error", MB_OK );
  846. return 0;
  847. }
  848. // Get the root directory the .exe is in
  849. char* pRootDir = GetBaseDir( moduleName );
  850. #ifdef DBGFLAG_ASSERT
  851. int len =
  852. #endif
  853. Q_snprintf( szBuffer, sizeof( szBuffer ), "PATH=%s;%s", pRootDir, pPath );
  854. Assert( len < 4096 );
  855. _putenv( szBuffer );
  856. MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f );
  857. if (!Init( pCommands ) )
  858. return false;
  859. /*
  860. bool done = false;
  861. while( !done )
  862. {
  863. done = Update();
  864. }
  865. */
  866. RenderFrame();
  867. Shutdown();
  868. return 0;
  869. }