Counter Strike : Global Offensive Source Code
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.

3054 lines
85 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "client_pch.h"
  7. #ifdef _PS3
  8. void CL_CreateTextureListPanel( vgui::Panel * ) {}
  9. void CL_TextureListPanel_ClearState() {}
  10. void VGui_UpdateTextureListPanel() {}
  11. #else
  12. #include "ivideomode.h"
  13. #include "client_class.h"
  14. #include "icliententitylist.h"
  15. #include "vgui_basepanel.h"
  16. #include <vgui_controls/Controls.h>
  17. #include <vgui/ISurface.h>
  18. #include <vgui/IScheme.h>
  19. #include <vgui/IVGui.h>
  20. #include <vgui_controls/Frame.h>
  21. #include <vgui_controls/TreeView.h>
  22. #include <vgui_controls/ListPanel.h>
  23. #include <vgui_controls/ListViewPanel.h>
  24. #include <vgui_controls/TreeViewListControl.h>
  25. #include <vgui/ISystem.h>
  26. #include "tier0/vprof.h"
  27. #include "keyvalues.h"
  28. #include "vgui_helpers.h"
  29. #include "utlsymbol.h"
  30. #include "tier1/UtlStringMap.h"
  31. #include "bitvec.h"
  32. #include "utldict.h"
  33. #include "vgui/ILocalize.h"
  34. #include "con_nprint.h"
  35. #include "gl_matsysiface.h"
  36. #include "VGuiMatSurface/IMatSystemSurface.h"
  37. #include "materialsystem/imaterial.h"
  38. #include "materialsystem/imaterialvar.h"
  39. #include "materialsystem/imesh.h"
  40. #include "materialsystem/idebugtextureinfo.h"
  41. #include "materialsystem/itexture.h"
  42. #include "vtf/vtf.h"
  43. #include "tier2/tier2.h"
  44. #include "smartptr.h"
  45. #include "igame.h"
  46. #include "client.h"
  47. // For character manipulations isupper/tolower
  48. #include <ctype.h>
  49. // memdbgon must be the last include file in a .cpp file!!!
  50. #include "tier0/memdbgon.h"
  51. #define KEYNAME_NAME "Name"
  52. #define KEYNAME_PATH "Path"
  53. #define KEYNAME_BINDS_MAX "BindsMax"
  54. #define KEYNAME_BINDS_FRAME "BindsFrame"
  55. #define KEYNAME_SIZE "Size"
  56. #define KEYNAME_FORMAT "Format"
  57. #define KEYNAME_WIDTH "Width"
  58. #define KEYNAME_HEIGHT "Height"
  59. #define KEYNAME_TEXTURE_GROUP "TexGroup"
  60. #define COPYTOCLIPBOARD_CMDNAME "CopyToClipboard"
  61. #if defined( _X360 )
  62. CON_COMMAND( mat_get_textures, "VXConsole command" )
  63. {
  64. g_pMaterialSystemDebugTextureInfo->EnableDebugTextureList( true );
  65. g_pMaterialSystemDebugTextureInfo->EnableGetAllTextures( args.ArgC() >= 2 && ( Q_stricmp( args[1], "all" ) == 0 ) );
  66. }
  67. #endif
  68. static ConVar mat_texture_list( "mat_texture_list", "0", FCVAR_CHEAT, "For debugging, show a list of used textures per frame" );
  69. static inline void MatTextureModificationRecorded()
  70. {
  71. extern void Host_DisallowSecureServers();
  72. Host_DisallowSecureServers();
  73. }
  74. static enum TxListPanelRequest
  75. {
  76. TXR_NONE,
  77. TXR_SHOW,
  78. TXR_RUNNING,
  79. TXR_HIDE
  80. } s_eTxListPanelRequest = TXR_NONE;
  81. // These are here so you can bind a key to +mat_texture_list and toggle it on and off.
  82. void mat_texture_list_on_f();
  83. void mat_texture_list_off_f();
  84. ConCommand mat_texture_list_on( "+mat_texture_list", mat_texture_list_on_f );
  85. ConCommand mat_texture_list_off( "-mat_texture_list", mat_texture_list_off_f );
  86. ConVar mat_texture_list_all( "mat_texture_list_all", "0", FCVAR_NEVER_AS_STRING, "If this is nonzero, then the texture list panel will show all currently-loaded textures." );
  87. ConVar mat_texture_list_all_frames( "mat_texture_list_all_frames", "2", 0, "How many frames to sample texture memory for all textures." );
  88. ConVar mat_texture_list_view( "mat_texture_list_view", "1", FCVAR_NEVER_AS_STRING, "If this is nonzero, then the texture list panel will render thumbnails of currently-loaded textures." );
  89. ConVar mat_show_texture_memory_usage( "mat_show_texture_memory_usage", "0", FCVAR_NEVER_AS_STRING|FCVAR_CHEAT, "Display the texture memory usage on the HUD." );
  90. static int g_warn_texkbytes = 1499;
  91. static int g_warn_texdimensions = 1024;
  92. static bool g_warn_enable = true;
  93. class CTextureListPanel;
  94. static CTextureListPanel *g_pTextureListPanel = NULL;
  95. static bool g_bRecursiveRequestToShowTextureList = false;
  96. //
  97. // A class to mimic a list view
  98. //
  99. namespace vgui
  100. {
  101. class TileViewPanelEx : public Panel
  102. {
  103. DECLARE_CLASS_SIMPLE( TileViewPanelEx, Panel );
  104. public:
  105. TileViewPanelEx( Panel *parent, const char *panelName );
  106. ~TileViewPanelEx();
  107. public:
  108. virtual void SetFont( HFont hFont );
  109. virtual HFont GetFont();
  110. public:
  111. enum HitTest_t
  112. {
  113. HT_NOTHING = 0,
  114. HT_TILE
  115. };
  116. virtual int HitTest( int x, int y, int &iTile );
  117. virtual bool GetTileOrg( int iTile, int &x, int &y );
  118. protected: // Overrides for contents
  119. virtual int GetNumTiles() = 0;
  120. virtual void GetTileSize( int &wide, int &tall ) = 0;
  121. virtual void RenderTile( int iTile, int x, int y ) = 0;
  122. protected:
  123. // Handlers
  124. virtual void OnMouseWheeled( int delta );
  125. virtual void OnSizeChanged( int wide, int tall );
  126. virtual void PerformLayout();
  127. virtual void Paint();
  128. virtual void ApplySchemeSettings( IScheme *pScheme );
  129. MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" );
  130. protected:
  131. virtual bool ComputeLayoutInfo();
  132. int m_li_numTiles; //!< Total number of tiles
  133. int m_li_numVisibleTiles; //!< Number of tiles fitting in the client area
  134. int m_li_wide, m_li_tall; //!< Tile area width/height
  135. int m_li_wideItem, m_li_tallItem; //!< Every item width/height
  136. int m_li_colVisible, m_li_rowVisible; //!< Num columns/rows fitting in the client area
  137. int m_li_rowNeeded; //!< Num rows required to fit all numTiles
  138. int m_li_startTile, m_li_endTile; //!< Start/end tile that are rendered in the client area
  139. private:
  140. ScrollBar *m_hbar;
  141. HFont m_hFont;
  142. };
  143. //
  144. // Implementation details
  145. //
  146. TileViewPanelEx::TileViewPanelEx( Panel *parent, const char *panelName ) :
  147. Panel( parent, panelName ),
  148. m_hbar( NULL ),
  149. m_hFont( INVALID_FONT )
  150. {
  151. m_hbar = new ScrollBar( this, "VerticalScrollBar", true );
  152. m_hbar->AddActionSignalTarget( this );
  153. m_hbar->SetVisible( true );
  154. }
  155. TileViewPanelEx::~TileViewPanelEx()
  156. {
  157. delete m_hbar;
  158. }
  159. void TileViewPanelEx::SetFont( HFont hFont )
  160. {
  161. m_hFont = hFont;
  162. Repaint();
  163. }
  164. HFont TileViewPanelEx::GetFont()
  165. {
  166. return m_hFont;
  167. }
  168. int TileViewPanelEx::HitTest( int x, int y, int &iTile )
  169. {
  170. iTile = -1;
  171. if ( !ComputeLayoutInfo() )
  172. return HT_NOTHING;
  173. int hitCol = ( x / m_li_wideItem );
  174. int hitRow = ( y / m_li_tallItem );
  175. if ( hitCol >= m_li_colVisible )
  176. return HT_NOTHING;
  177. if ( hitRow > m_li_rowVisible )
  178. return HT_NOTHING;
  179. int hitTile = m_li_startTile + hitCol + hitRow * m_li_colVisible;
  180. if ( hitTile >= m_li_endTile )
  181. return HT_NOTHING;
  182. // Hit tile
  183. iTile = hitTile;
  184. return HT_TILE;
  185. }
  186. bool TileViewPanelEx::GetTileOrg( int iTile, int &x, int &y )
  187. {
  188. if ( m_li_colVisible <= 0 )
  189. return false;
  190. if ( iTile < m_li_startTile || iTile >= m_li_endTile )
  191. return false;
  192. x = 0 + ( ( iTile - m_li_startTile ) % m_li_colVisible ) * m_li_wideItem;
  193. y = 0 + ( ( iTile - m_li_startTile ) / m_li_colVisible ) * m_li_tallItem;
  194. return true;
  195. }
  196. void TileViewPanelEx::OnMouseWheeled( int delta )
  197. {
  198. if ( m_hbar->IsVisible() )
  199. {
  200. int val = m_hbar->GetValue();
  201. val -= delta;
  202. m_hbar->SetValue( val );
  203. }
  204. }
  205. void TileViewPanelEx::OnSizeChanged( int wide, int tall )
  206. {
  207. BaseClass::OnSizeChanged( wide, tall );
  208. InvalidateLayout();
  209. Repaint();
  210. }
  211. void TileViewPanelEx::PerformLayout()
  212. {
  213. int numTiles = GetNumTiles();
  214. m_hbar->SetVisible( false );
  215. int wide, tall;
  216. GetSize( wide, tall );
  217. wide -= m_hbar->GetWide();
  218. m_hbar->SetPos( wide - 2, 0 );
  219. m_hbar->SetTall( tall );
  220. if ( !numTiles )
  221. return;
  222. int wideItem = 1, tallItem = 1;
  223. GetTileSize( wideItem, tallItem );
  224. if ( !wideItem || !tallItem )
  225. return;
  226. int colVisible = wide / wideItem;
  227. int rowVisible = tall / tallItem;
  228. if ( rowVisible <= 0 || colVisible <= 0 )
  229. return;
  230. int rowNeeded = ( numTiles + colVisible - 1 ) / colVisible;
  231. int startTile = 0;
  232. if ( rowNeeded > rowVisible )
  233. {
  234. m_hbar->SetRange( 0, rowNeeded );
  235. m_hbar->SetRangeWindow( rowVisible );
  236. m_hbar->SetButtonPressedScrollValue( 1 );
  237. m_hbar->SetVisible( true );
  238. m_hbar->InvalidateLayout();
  239. int val = m_hbar->GetValue();
  240. startTile = val * colVisible;
  241. }
  242. }
  243. bool TileViewPanelEx::ComputeLayoutInfo()
  244. {
  245. m_li_numTiles = GetNumTiles();
  246. if ( !m_li_numTiles )
  247. return false;
  248. GetSize( m_li_wide, m_li_tall );
  249. m_li_wide -= m_hbar->GetWide();
  250. m_li_wideItem = 1, m_li_tallItem = 1;
  251. GetTileSize( m_li_wideItem, m_li_tallItem );
  252. if ( !m_li_wideItem || !m_li_tallItem )
  253. return false;
  254. m_li_colVisible = m_li_wide / m_li_wideItem;
  255. m_li_rowVisible = m_li_tall / m_li_tallItem;
  256. if ( m_li_rowVisible <= 0 || m_li_colVisible <= 0 )
  257. return false;
  258. m_li_rowNeeded = ( m_li_numTiles + m_li_colVisible - 1 ) / m_li_colVisible;
  259. m_li_numVisibleTiles = m_li_colVisible * m_li_rowVisible;
  260. m_li_startTile = 0;
  261. if ( m_li_rowNeeded > m_li_rowVisible )
  262. {
  263. int val = m_hbar->GetValue();
  264. m_li_startTile = val * m_li_colVisible;
  265. }
  266. if ( m_li_startTile >= m_li_numTiles )
  267. m_li_startTile = m_li_numTiles - m_li_numVisibleTiles;
  268. if ( m_li_startTile < 0 )
  269. m_li_startTile = 0;
  270. m_li_endTile = m_li_startTile + m_li_numVisibleTiles + m_li_colVisible; // draw the partly visible items
  271. if ( m_li_endTile > m_li_numTiles )
  272. m_li_endTile = m_li_numTiles;
  273. return true;
  274. }
  275. void TileViewPanelEx::Paint()
  276. {
  277. BaseClass::Paint();
  278. // Now render all our tiles
  279. if ( !ComputeLayoutInfo() )
  280. return;
  281. for ( int iRenderTile = m_li_startTile; iRenderTile < m_li_endTile; ++ iRenderTile )
  282. {
  283. int x = 0 + ( ( iRenderTile - m_li_startTile ) % m_li_colVisible ) * m_li_wideItem;
  284. int y = 0 + ( ( iRenderTile - m_li_startTile ) / m_li_colVisible ) * m_li_tallItem;
  285. RenderTile( iRenderTile, x, y );
  286. }
  287. }
  288. void TileViewPanelEx::ApplySchemeSettings( IScheme *pScheme )
  289. {
  290. BaseClass::ApplySchemeSettings( pScheme );
  291. SetBgColor( GetSchemeColor( "ListPanel.BgColor", pScheme ) );
  292. SetBorder( pScheme->GetBorder("ButtonDepressedBorder" ) );
  293. SetFont( pScheme->GetFont( "Default", IsProportional() ) );
  294. }
  295. void TileViewPanelEx::OnSliderMoved()
  296. {
  297. InvalidateLayout();
  298. Repaint();
  299. }
  300. }; // namespace vgui
  301. //////////////////////////////////////////////////////////////////////////
  302. //
  303. // Material access
  304. //
  305. //////////////////////////////////////////////////////////////////////////
  306. class CAutoMatSysDebugMode
  307. {
  308. public:
  309. CAutoMatSysDebugMode();
  310. ~CAutoMatSysDebugMode();
  311. void ScheduleCleanupTextureVar( IMaterialVar *pVar );
  312. protected:
  313. bool bOldDebugMode;
  314. CUtlRBTree< IMaterialVar * > arrCleanupVars;
  315. };
  316. CAutoMatSysDebugMode::CAutoMatSysDebugMode() :
  317. arrCleanupVars( DefLessFunc(IMaterialVar *) )
  318. {
  319. g_pMaterialSystem->Flush();
  320. bOldDebugMode = g_pMaterialSystemDebugTextureInfo->SetDebugTextureRendering( true );
  321. }
  322. CAutoMatSysDebugMode::~CAutoMatSysDebugMode()
  323. {
  324. g_pMaterialSystem->Flush();
  325. g_pMaterialSystemDebugTextureInfo->SetDebugTextureRendering( bOldDebugMode );
  326. for ( uint32 k = 0; k < arrCleanupVars.Count(); ++ k )
  327. {
  328. IMaterialVar *pVar = arrCleanupVars.Element( k );
  329. pVar->SetUndefined();
  330. }
  331. }
  332. void CAutoMatSysDebugMode::ScheduleCleanupTextureVar( IMaterialVar *pVar )
  333. {
  334. if ( !pVar )
  335. return;
  336. arrCleanupVars.InsertIfNotFound( pVar );
  337. }
  338. static IMaterial * UseDebugMaterial( char const *szMaterial, ITexture *pMatTexture, CAutoMatSysDebugMode *pRestoreVars )
  339. {
  340. if ( !szMaterial || !pMatTexture )
  341. return NULL;
  342. bool foundVar;
  343. IMaterial *pMaterial = materials->FindMaterial( szMaterial, TEXTURE_GROUP_OTHER, false );
  344. // IMaterial *pMaterial = materials->FindMaterial( "debug/debugempty", TEXTURE_GROUP_OTHER, false );
  345. if ( !pMaterial )
  346. return NULL;
  347. IMaterialVar *BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false );
  348. // IMaterialVar *BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false );
  349. if ( !foundVar || !BaseTextureVar )
  350. return NULL;
  351. IMaterialVar *FrameVar = pMaterial->FindVar( "$frame", &foundVar, false );
  352. if ( foundVar && FrameVar )
  353. {
  354. int numAnimFrames = pMatTexture->GetNumAnimationFrames();
  355. if ( pMatTexture->IsRenderTarget() || pMatTexture->IsProcedural() )
  356. numAnimFrames = 0; // Cannot use the stencil parts of the render targets and shouldn't use the other frames of procedural textures
  357. FrameVar->SetIntValue( ( numAnimFrames > 0 ) ? ( g_ClientGlobalVariables.tickcount % numAnimFrames ) : 0 );
  358. }
  359. BaseTextureVar->SetTextureValue( pMatTexture );
  360. if ( pRestoreVars )
  361. {
  362. pRestoreVars->ScheduleCleanupTextureVar( BaseTextureVar );
  363. }
  364. return pMaterial;
  365. }
  366. static void RenderTexturedRect( vgui::Panel *pPanel, IMaterial *pMaterial, int x, int y, int x1, int y1, int xoff = 0, int yoff = 0 )
  367. {
  368. CAutoMatSysDebugMode auto_matsysdebugmode;
  369. int tall = pPanel->GetTall();
  370. float fHeightUV = 1.0f;
  371. if ( y1 > tall )
  372. {
  373. fHeightUV = float( tall - y ) / float( y1 - y );
  374. y1 = tall;
  375. }
  376. if ( y1 <= y )
  377. return;
  378. pPanel->LocalToScreen( x, y );
  379. pPanel->LocalToScreen( x1, y1 );
  380. x += xoff; x1 += xoff; y += yoff; y1 += yoff;
  381. CMatRenderContextPtr pRenderContext( materials );
  382. pRenderContext->Bind( pMaterial );
  383. IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
  384. CMeshBuilder meshBuilder;
  385. meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
  386. meshBuilder.Position3f( x, y, 0.0f );
  387. meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
  388. meshBuilder.AdvanceVertex();
  389. meshBuilder.Position3f( x1, y, 0.0f );
  390. meshBuilder.TexCoord2f( 0, 1.0f, 0.0f );
  391. meshBuilder.AdvanceVertex();
  392. meshBuilder.Position3f( x1, y1, 0.0f );
  393. meshBuilder.TexCoord2f( 0, 1.0f, fHeightUV );
  394. meshBuilder.AdvanceVertex();
  395. meshBuilder.Position3f( x, y1, 0.0f );
  396. meshBuilder.TexCoord2f( 0, 0.0f, fHeightUV );
  397. meshBuilder.AdvanceVertex();
  398. meshBuilder.End();
  399. pMesh->Draw();
  400. }
  401. static bool ShallWarnTx( KeyValues *kv, ITexture *tx )
  402. {
  403. if ( !tx )
  404. {
  405. return false;
  406. }
  407. if ( tx->GetFlags() & ( TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA ) )
  408. return true;
  409. if ( stricmp( "DXT1", kv->GetString( KEYNAME_FORMAT ) ) && stricmp( "DXT5", kv->GetString( KEYNAME_FORMAT ) ) &&
  410. stricmp( "ATI1N", kv->GetString( KEYNAME_FORMAT ) ) && stricmp( "ATI2N", kv->GetString( KEYNAME_FORMAT ) ) )
  411. return true;
  412. if ( kv->GetInt( KEYNAME_SIZE ) > g_warn_texkbytes )
  413. return true;
  414. if ( kv->GetInt( KEYNAME_WIDTH ) > g_warn_texdimensions )
  415. return true;
  416. if ( kv->GetInt( KEYNAME_HEIGHT ) > g_warn_texdimensions )
  417. return true;
  418. return false;
  419. }
  420. static void FmtCommaNumber( char *pchBuffer, unsigned int uiNumber )
  421. {
  422. pchBuffer[0] = 0;
  423. for ( unsigned int uiDivisor = 1000 * 1000 * 1000; uiDivisor > 0; uiDivisor /= 1000 )
  424. {
  425. if ( uiNumber > uiDivisor )
  426. {
  427. unsigned int uiPrint = ( uiNumber / uiDivisor ) % 1000;
  428. sprintf( pchBuffer + strlen( pchBuffer ), ( uiNumber / uiDivisor < 1000 ) ? "%d," : "%03d,", uiPrint );
  429. }
  430. }
  431. int len = strlen( pchBuffer );
  432. if ( !len )
  433. sprintf( pchBuffer, "0" );
  434. else if ( pchBuffer[ len - 1 ] == ',' )
  435. pchBuffer[ len - 1 ] = 0;
  436. }
  437. namespace
  438. {
  439. char s_chLastViewedTextureBuffer[ 0x200 ] = {0};
  440. }; // end `anonymous` namespace
  441. ConVar mat_texture_list_exclude_editing( "mat_texture_list_exclude_editing", "0" );
  442. bool CanAdjustTextureSize( char const *szTextureName, bool bMoveSizeUp )
  443. {
  444. ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false );
  445. if ( !pMatTexture )
  446. return false;
  447. if ( mat_texture_list_exclude_editing.GetInt() > 0 )
  448. {
  449. MaterialTextureInfo_t txInfo;
  450. if ( !materials->GetTextureInformation( szTextureName, txInfo ) )
  451. return false;
  452. if ( txInfo.iExcludeInformation == 0 )
  453. return false;
  454. }
  455. // Determine the texture current size
  456. if ( !bMoveSizeUp )
  457. {
  458. return ( pMatTexture->GetActualWidth() > 4 || pMatTexture->GetActualHeight() > 4 );
  459. }
  460. else
  461. {
  462. return ( pMatTexture->GetActualWidth() < pMatTexture->GetMappingWidth() ||
  463. pMatTexture->GetActualHeight() < pMatTexture->GetMappingHeight() );
  464. }
  465. }
  466. bool AdjustTextureSize( char const *szTextureName, bool bMoveSizeUp )
  467. {
  468. MatTextureModificationRecorded();
  469. ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false );
  470. if ( !pMatTexture )
  471. return false;
  472. if ( mat_texture_list_exclude_editing.GetInt() > 0 )
  473. {
  474. int iOverride = MAX( pMatTexture->GetActualWidth(), pMatTexture->GetActualHeight() );
  475. if ( bMoveSizeUp )
  476. iOverride <<= 1;
  477. else
  478. iOverride >>= 1;
  479. pMatTexture->ForceExcludeOverride( iOverride );
  480. }
  481. else
  482. {
  483. pMatTexture->ForceLODOverride( bMoveSizeUp ? +1 : -1 );
  484. }
  485. return true;
  486. }
  487. bool AdjustTextureExclude( char const *szTextureName, bool bExclude )
  488. {
  489. MatTextureModificationRecorded();
  490. ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false );
  491. if ( !pMatTexture )
  492. return false;
  493. if ( mat_texture_list_exclude_editing.GetInt() > 0 )
  494. {
  495. int iOverride = bExclude ? 0 : -1;
  496. pMatTexture->ForceExcludeOverride( iOverride );
  497. return true;
  498. }
  499. else
  500. {
  501. return false;
  502. }
  503. }
  504. bool CanAdjustTextureExclude( char const *szTextureName )
  505. {
  506. if ( mat_texture_list_exclude_editing.GetInt() <= 0 )
  507. return false;
  508. ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false );
  509. if ( !pMatTexture )
  510. return false;
  511. return true;
  512. }
  513. bool IsTextureExcluded( char const *szTextureName )
  514. {
  515. if ( mat_texture_list_exclude_editing.GetInt() <= 0 )
  516. return false;
  517. ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false );
  518. if ( !pMatTexture )
  519. return false;
  520. MaterialTextureInfo_t txInfo;
  521. if ( !materials->GetTextureInformation( szTextureName, txInfo ) )
  522. return false;
  523. if ( txInfo.iExcludeInformation == 0 )
  524. return true;
  525. else
  526. return false;
  527. }
  528. CON_COMMAND_F( mat_texture_list_txlod, "Adjust LOD of the last viewed texture +1 to inc resolution, -1 to dec resolution", FCVAR_DONTRECORD )
  529. {
  530. if ( args.ArgC() == 2 )
  531. {
  532. char const *szArg = args.Arg( 1 );
  533. if ( !stricmp( szArg, "exclude" ) || !stricmp( szArg, "noexclude" ) )
  534. {
  535. bool bExclude = !stricmp( szArg, "exclude" );
  536. if ( !CanAdjustTextureExclude( s_chLastViewedTextureBuffer ) )
  537. Warning( "mat_texture_list_txlod cannot adjust exclude for '%s'\n", s_chLastViewedTextureBuffer );
  538. else if ( !AdjustTextureExclude( s_chLastViewedTextureBuffer, bExclude ) )
  539. Warning( "mat_texture_list_txlod failed %sexcluding '%s'\n", bExclude ? "" : "no", s_chLastViewedTextureBuffer );
  540. else
  541. Msg( "mat_texture_list_txlod %sexcluded '%s'\n", bExclude ? "" : "no", s_chLastViewedTextureBuffer );
  542. return;
  543. }
  544. int iAdjustment = atoi( szArg );
  545. switch ( iAdjustment )
  546. {
  547. case 1:
  548. case -1:
  549. if ( !CanAdjustTextureSize( s_chLastViewedTextureBuffer, iAdjustment > 0 ) )
  550. Warning( "mat_texture_list_txlod cannot adjust lod for '%s'\n", s_chLastViewedTextureBuffer );
  551. else if ( !AdjustTextureSize( s_chLastViewedTextureBuffer, iAdjustment > 0 ) )
  552. Warning( "mat_texture_list_txlod failed adjusting lod for '%s'\n", s_chLastViewedTextureBuffer );
  553. else
  554. Msg( "mat_texture_list_txlod adjusted lod %c1 for '%s'\n", ( iAdjustment > 0 ) ? '+' : '-' , s_chLastViewedTextureBuffer );
  555. return;
  556. default:
  557. break;
  558. }
  559. }
  560. Warning( "Usage: 'mat_texture_list_txlod +1' to inc lod | 'mat_texture_list_txlod -1' to dec lod\n" );
  561. }
  562. namespace MatViewOverride
  563. {
  564. //
  565. // View override parameters request
  566. //
  567. struct ViewParamsReq
  568. {
  569. CUtlVector< UtlSymId_t > lstMaterials;
  570. }
  571. s_viewParamsReq;
  572. void RequestSelectNone( void )
  573. {
  574. s_viewParamsReq.lstMaterials.RemoveAll();
  575. }
  576. void RequestSelected( int nCount, UtlSymId_t const *pNameIds )
  577. {
  578. s_viewParamsReq.lstMaterials.AddMultipleToTail( nCount, pNameIds );
  579. }
  580. //
  581. // View override last parameters
  582. //
  583. struct ViewParamsLast
  584. {
  585. ViewParamsLast() : lstMaterials( DefLessFunc( UtlSymId_t ) ), flTime( 0.f ), bHighlighted( false ) {}
  586. float flTime;
  587. bool bHighlighted;
  588. struct TxInfo
  589. {
  590. ITexture *pTx;
  591. CUtlSymbol name;
  592. };
  593. struct VarMap : public CUtlMap< UtlSymId_t, TxInfo >
  594. {
  595. VarMap() : CUtlMap< UtlSymId_t, TxInfo >( DefLessFunc( UtlSymId_t ) ) {}
  596. VarMap( VarMap const &x ) { const_cast< VarMap & >( x ).Swap( *this ); m_matInfo = x.m_matInfo; } // Fast-swap data
  597. struct MatInfo
  598. {
  599. // MatInfo() : ignorez( false ) {}
  600. // bool ignorez;
  601. MatInfo() {}
  602. } m_matInfo;
  603. };
  604. CUtlMap< UtlSymId_t, VarMap > lstMaterials;
  605. }
  606. s_viewParamsLast;
  607. //
  608. // DisplaySelectedTextures
  609. // Executed every frame to toggle the selected/unselected
  610. // textures for a list of materials.
  611. //
  612. void DisplaySelectedTextures()
  613. {
  614. // Nothing selected
  615. if ( !s_viewParamsLast.lstMaterials.Count() &&
  616. !s_viewParamsReq.lstMaterials.Count() )
  617. return;
  618. if ( !s_viewParamsLast.lstMaterials.Count() &&
  619. s_viewParamsReq.lstMaterials.Count() )
  620. {
  621. // First time selection
  622. s_viewParamsLast.flTime = Plat_FloatTime();
  623. s_viewParamsLast.bHighlighted = false;
  624. }
  625. else
  626. {
  627. // Wait for the flash-time
  628. float fCurTime = Plat_FloatTime();
  629. if ( fCurTime >= s_viewParamsLast.flTime &&
  630. fCurTime < s_viewParamsLast.flTime + 0.4 &&
  631. s_viewParamsReq.lstMaterials.Count() )
  632. return;
  633. s_viewParamsLast.flTime = fCurTime;
  634. s_viewParamsLast.bHighlighted = !s_viewParamsLast.bHighlighted;
  635. }
  636. // Find the empty texture
  637. ITexture *txEmpty = materials->FindTexture( "debugempty", "", false );
  638. typedef unsigned short MapIdx;
  639. // Now walk over all the materials in the req list and push them to the params
  640. for ( int k = 0, kEnd = s_viewParamsReq.lstMaterials.Count(); k < kEnd; ++ k )
  641. {
  642. UtlSymId_t idMat = s_viewParamsReq.lstMaterials[ k ];
  643. MapIdx idx = s_viewParamsLast.lstMaterials.Find( idMat );
  644. if ( idx == s_viewParamsLast.lstMaterials.InvalidIndex() )
  645. {
  646. // Insert the new material
  647. idx = s_viewParamsLast.lstMaterials.Insert( idMat );
  648. ViewParamsLast::VarMap &vars = s_viewParamsLast.lstMaterials.Element( idx );
  649. // Locate the material
  650. char const *szMaterialName = CUtlSymbol( idMat ).String();
  651. IMaterial *pMat = materials->FindMaterial( szMaterialName, TEXTURE_GROUP_OTHER, false );
  652. if ( pMat )
  653. {
  654. int numParams = pMat->ShaderParamCount();
  655. IMaterialVar **arrVars = pMat->GetShaderParams();
  656. for ( int idxParam = 0; idxParam < numParams; ++ idxParam )
  657. {
  658. // if ( !stricmp( arrVars[ idxParam ]->GetName(), "$ignorez" ) )
  659. // {
  660. // vars.m_matInfo.ignorez = arrVars[ idxParam ]->GetIntValue() ? true : false;
  661. // arrVars[ idxParam ]->SetIntValue( 1 );
  662. // continue;
  663. // }
  664. if ( !arrVars[ idxParam ]->IsTexture() )
  665. continue;
  666. ITexture *pTex = arrVars[ idxParam ]->GetTextureValue();
  667. if ( !pTex || pTex->IsError() )
  668. continue;
  669. ViewParamsLast::TxInfo txinfo;
  670. txinfo.name = CUtlSymbol( pTex->GetName() );
  671. txinfo.pTx = pTex;
  672. vars.Insert( CUtlSymbol( arrVars[ idxParam ]->GetName() ), txinfo );
  673. }
  674. }
  675. }
  676. }
  677. // Now walk over all the materials that we have to highlight or unhighlight
  678. for ( MapIdx idx = s_viewParamsLast.lstMaterials.FirstInorder();
  679. idx != s_viewParamsLast.lstMaterials.InvalidIndex();
  680. /* advance inside */ )
  681. {
  682. UtlSymId_t idMat = s_viewParamsLast.lstMaterials.Key( idx );
  683. ViewParamsLast::VarMap &vars = s_viewParamsLast.lstMaterials.Element( idx );
  684. bool bRemovedSelection = ( s_viewParamsReq.lstMaterials.Find( idMat ) < 0 );
  685. char const *szMaterialName = CUtlSymbol( idMat ).String();
  686. IMaterial *pMat = materials->FindMaterial( szMaterialName, TEXTURE_GROUP_OTHER, false );
  687. if ( pMat )
  688. {
  689. int numParams = pMat->ShaderParamCount();
  690. IMaterialVar **arrVars = pMat->GetShaderParams();
  691. for ( int idxParam = 0; idxParam < numParams; ++ idxParam )
  692. {
  693. // if ( bRemovedSelection && !stricmp( arrVars[ idxParam ]->GetName(), "$ignorez" ) )
  694. // {
  695. // arrVars[ idxParam ]->SetIntValue( vars.m_matInfo.ignorez ? 1 : 0 );
  696. // continue;
  697. // }
  698. char const *szVarName = arrVars[ idxParam ]->GetName();
  699. CUtlSymbol symVarName( szVarName );
  700. MapIdx idxVarsTxInfo = vars.Find( symVarName );
  701. if ( idxVarsTxInfo != vars.InvalidIndex() )
  702. {
  703. ViewParamsLast::TxInfo &ti = vars.Element( idxVarsTxInfo );
  704. ITexture *pTx = ( s_viewParamsLast.bHighlighted && !bRemovedSelection ) ? txEmpty : ti.pTx;
  705. Assert( ti.pTx && !ti.pTx->IsError() );
  706. arrVars[ idxParam ]->SetTextureValue( pTx );
  707. }
  708. }
  709. }
  710. // Index advance
  711. if ( bRemovedSelection )
  712. {
  713. MapIdx idxRemove = idx;
  714. idx = s_viewParamsLast.lstMaterials.NextInorder( idx );
  715. s_viewParamsLast.lstMaterials.RemoveAt( idxRemove );
  716. }
  717. else
  718. {
  719. idx = s_viewParamsLast.lstMaterials.NextInorder( idx );
  720. }
  721. }
  722. }
  723. }; // end namespace MatViewOverride
  724. void CL_TextureListPanel_ClearState()
  725. {
  726. MatViewOverride::RequestSelectNone();
  727. MatViewOverride::DisplaySelectedTextures();
  728. }
  729. //////////////////////////////////////////////////////////////////////////
  730. //
  731. // Custom text entry with "Open" for vmt's
  732. //
  733. //////////////////////////////////////////////////////////////////////////
  734. class CVmtTextEntry : public vgui::TextEntry
  735. {
  736. DECLARE_CLASS_SIMPLE( CVmtTextEntry, vgui::TextEntry );
  737. public:
  738. CVmtTextEntry( vgui::Panel *parent, char const *szName ) : BaseClass( parent, szName ) {}
  739. public:
  740. MESSAGE_FUNC( OpenVmtSelected, "DoOpenVmtSelected" );
  741. virtual void OpenEditMenu();
  742. };
  743. void CVmtTextEntry::OpenEditMenu()
  744. {
  745. vgui::Menu *pEditMenu = BaseClass::GetEditMenu();
  746. int pos = pEditMenu->AddMenuItem( "Open VMT", new KeyValues("DoOpenVmtSelected"), this );
  747. pEditMenu->MoveMenuItem( pos, 0 );
  748. int x0, x1;
  749. pEditMenu->SetItemEnabled( "Open VMT", GetSelectedRange(x0, x1) );
  750. BaseClass::OpenEditMenu();
  751. }
  752. void CVmtTextEntry::OpenVmtSelected()
  753. {
  754. int x0, x1;
  755. if ( !GetSelectedRange(x0, x1) )
  756. return;
  757. CUtlVector<char> buf;
  758. buf.SetCount( x1 - x0 + 1 );
  759. GetTextRange( buf.Base(), x0, x1 - x0 );
  760. for ( char *pchName = buf.Base(), *pchNext = NULL; pchName; pchName = pchNext )
  761. {
  762. if ( ( pchNext = strchr( pchName, '\n' ) ) != NULL )
  763. *( pchNext ++ ) = 0;
  764. char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0};
  765. Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vmt", pchName );
  766. char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 );
  767. if ( szResolvedName )
  768. vgui::system()->ShellExecuteEx( "open", szResolvedName, "" );
  769. }
  770. }
  771. //////////////////////////////////////////////////////////////////////////
  772. //
  773. // Render textures edit panel
  774. //
  775. //////////////////////////////////////////////////////////////////////////
  776. class CRenderTextureEditor : public vgui::Frame
  777. {
  778. DECLARE_CLASS_SIMPLE( CRenderTextureEditor, vgui::Frame );
  779. public:
  780. CRenderTextureEditor( vgui::Panel *parent, char const *szName );
  781. ~CRenderTextureEditor();
  782. public:
  783. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  784. virtual void PerformLayout();
  785. virtual void OnCommand( const char *command );
  786. virtual void SetFont( vgui::HFont hFont ) { m_hFont = hFont; Repaint(); }
  787. virtual vgui::HFont GetFont() { return m_hFont; }
  788. public:
  789. virtual void OnMousePressed( vgui::MouseCode code );
  790. virtual void OnMouseDoublePressed( vgui::MouseCode code ) { OnMousePressed( code ); }
  791. virtual void Activate();
  792. virtual void Close();
  793. public:
  794. void SetDispInfo( KeyValues *kv, int iHint );
  795. void GetDispInfo( KeyValues *&kv, int &iHint );
  796. public:
  797. virtual void Paint();
  798. enum
  799. {
  800. TILE_BORDER = 10,
  801. TILE_SIZE = 550,
  802. TILE_TEXTURE_SIZE = 256,
  803. TILE_TEXT = 70
  804. };
  805. protected:
  806. vgui::HFont m_hFont;
  807. CVmtTextEntry *m_pMaterials;
  808. vgui::Button *m_pExplore;
  809. vgui::Button *m_pReload;
  810. vgui::Button *m_pCopyTxt, *m_pCopyImg;
  811. vgui::Button *m_pSizeControls[3];
  812. vgui::Button *m_pFlashBtn;
  813. KeyValues *m_pInfo;
  814. CUtlBuffer m_bufInfoText;
  815. CUtlVector< UtlSymId_t > m_lstMaterials;
  816. int m_iInfoHint;
  817. };
  818. CRenderTextureEditor::CRenderTextureEditor( vgui::Panel *parent, char const *szName ) :
  819. BaseClass( parent, szName ),
  820. m_pInfo( NULL ),
  821. m_iInfoHint( 0 ),
  822. m_hFont( vgui::INVALID_FONT ),
  823. m_bufInfoText( 0, 0, CUtlBuffer::TEXT_BUFFER )
  824. {
  825. m_pMaterials = vgui::SETUP_PANEL( new CVmtTextEntry( this, "Materials" ) );
  826. m_pMaterials->SetMultiline( true );
  827. m_pMaterials->SetEditable( false );
  828. m_pMaterials->SetEnabled( false );
  829. m_pMaterials->SetVerticalScrollbar( true );
  830. m_pMaterials->SetVisible( true );
  831. m_pExplore = vgui::SETUP_PANEL( new vgui::Button( this, "Explore", "Open", this, "Explore" ) );
  832. m_pExplore->SetVisible( true );
  833. m_pReload = vgui::SETUP_PANEL( new vgui::Button( this, "Reload", "Reload", this, "Reload" ) );
  834. m_pReload->SetVisible( true );
  835. m_pCopyTxt = vgui::SETUP_PANEL( new vgui::Button( this, "CopyTxt", "Copy Text", this, "CopyTxt" ) );
  836. m_pCopyTxt->SetVisible( true );
  837. m_pCopyImg = vgui::SETUP_PANEL( new vgui::Button( this, "CopyImg", "Copy Image", this, "CopyImg" ) );
  838. m_pCopyImg->SetVisible( true );
  839. m_pFlashBtn = vgui::SETUP_PANEL( new vgui::Button( this, "FlashBtn", "Flash in Game", this, "FlashBtn" ) );
  840. m_pFlashBtn->SetVisible( true );
  841. m_pSizeControls[0] = vgui::SETUP_PANEL( new vgui::Button( this, "--", "--", this, "size-" ) );
  842. m_pSizeControls[1] = vgui::SETUP_PANEL( new vgui::Button( this, "+", "+", this, "size+" ) );
  843. m_pSizeControls[2] = vgui::SETUP_PANEL( new vgui::CheckButton( this, "Exclude", "Exclude" ) );
  844. m_pSizeControls[2]->AddActionSignalTarget( this );
  845. m_pSizeControls[2]->SetCommand( "Exclude" );
  846. }
  847. CRenderTextureEditor::~CRenderTextureEditor()
  848. {
  849. SetDispInfo( NULL, 0 );
  850. }
  851. void CRenderTextureEditor::GetDispInfo( KeyValues *&kv, int &iHint )
  852. {
  853. iHint = m_iInfoHint;
  854. kv = m_pInfo;
  855. }
  856. void CRenderTextureEditor::SetDispInfo( KeyValues *kv, int iHint )
  857. {
  858. m_iInfoHint = iHint;
  859. if ( m_pInfo )
  860. m_pInfo->deleteThis();
  861. m_pInfo = kv ? kv->MakeCopy() : NULL;
  862. CUtlStringMap< bool > arrMaterials, arrMaterialsFullNames;
  863. if ( kv )
  864. {
  865. char const *szTextureName = kv->GetString( KEYNAME_NAME );
  866. for ( MaterialHandle_t hm = materials->FirstMaterial();
  867. hm != materials->InvalidMaterial(); hm = materials->NextMaterial( hm ) )
  868. {
  869. IMaterial *pMat = materials->GetMaterial( hm );
  870. if ( !pMat )
  871. continue;
  872. int numParams = pMat->ShaderParamCount();
  873. IMaterialVar **arrVars = pMat->GetShaderParams();
  874. for ( int idxParam = 0; idxParam < numParams; ++ idxParam )
  875. {
  876. if ( !arrVars[ idxParam ]->IsTexture() )
  877. continue;
  878. ITexture *pTex = arrVars[ idxParam ]->GetTextureValue();
  879. if ( !pTex || pTex->IsError() )
  880. continue;
  881. if ( !stricmp( pTex->GetName(), szTextureName ) )
  882. {
  883. bool bRealMaterial = true;
  884. if ( StringHasPrefix( pMat->GetName(), "debug/debugtexture" ) )
  885. bRealMaterial = false;
  886. if ( StringHasPrefix( pMat->GetName(), "maps/" ) )
  887. {
  888. // Format: maps/mapname/[matname]_x_y_z
  889. bRealMaterial = false;
  890. char chName[ MAX_PATH ];
  891. Q_strncpy( chName, pMat->GetName() + 5, sizeof( chName ) - 1 );
  892. if ( char *szMatName = strchr( chName, '/' ) )
  893. {
  894. ++ szMatName;
  895. for ( int k = 0; k < 3; ++ k )
  896. {
  897. if ( char *rUnderscore = strrchr( szMatName, '_' ) )
  898. *rUnderscore = 0;
  899. }
  900. sprintf( szMatName + strlen( szMatName ), " (cubemap)" );
  901. arrMaterials[ szMatName ] = true;
  902. }
  903. arrMaterialsFullNames[ pMat->GetName() ] = true;
  904. }
  905. if ( bRealMaterial )
  906. {
  907. arrMaterials[ pMat->GetName() ] = true;
  908. arrMaterialsFullNames[ pMat->GetName() ] = true;
  909. }
  910. break;
  911. }
  912. }
  913. }
  914. }
  915. // Now that we have a list of materials make a printable version
  916. CUtlBuffer bufText( 0, 0, CUtlBuffer::TEXT_BUFFER );
  917. if ( !arrMaterials.GetNumStrings() )
  918. {
  919. bufText.Printf( "-- no materials --" );
  920. }
  921. else
  922. {
  923. int c = arrMaterials.GetNumStrings();
  924. bufText.Printf( " %d material%s:", c, ( c%10 == 1 && c != 11 ) ? "" : "s" );
  925. }
  926. for ( int k = 0; k < arrMaterials.GetNumStrings(); ++ k )
  927. {
  928. bufText.Printf( "\n%s", arrMaterials.String( k ) );
  929. }
  930. // Set text except for the cases when m_pInfo and no materials found
  931. if ( !( m_pInfo && !arrMaterials.GetNumStrings() ) )
  932. {
  933. m_pMaterials->SetText( ( char const * ) bufText.Base() );
  934. m_lstMaterials.RemoveAll();
  935. m_lstMaterials.EnsureCapacity( arrMaterialsFullNames.GetNumStrings() );
  936. for ( int k = 0; k < arrMaterialsFullNames.GetNumStrings(); ++ k )
  937. {
  938. m_lstMaterials.AddToTail( CUtlSymbol( arrMaterialsFullNames.String( k ) ) );
  939. }
  940. }
  941. m_bufInfoText.Clear();
  942. InvalidateLayout();
  943. }
  944. void CRenderTextureEditor::Close()
  945. {
  946. BaseClass::Close();
  947. SetDispInfo( NULL, 0 );
  948. }
  949. void CRenderTextureEditor::Activate()
  950. {
  951. BaseClass::Activate();
  952. }
  953. void CRenderTextureEditor::PerformLayout()
  954. {
  955. BaseClass::PerformLayout();
  956. int iRenderedHeight = 4 * TILE_BORDER + TILE_TEXT + TILE_SIZE;
  957. SetSize( 4 * TILE_BORDER + TILE_SIZE,
  958. iRenderedHeight + 90 + TILE_BORDER );
  959. m_pMaterials->SetPos( TILE_BORDER, iRenderedHeight + 2 );
  960. m_pMaterials->SetSize( 2 * TILE_BORDER + TILE_SIZE, 90 );
  961. m_pExplore->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50, 2 * TILE_BORDER );
  962. m_pExplore->SetWide( 50 );
  963. m_pReload->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50 - 65, 2 * TILE_BORDER );
  964. m_pReload->SetWide( 60 );
  965. m_pReload->SetVisible( m_lstMaterials.Count() > 0 );
  966. m_pExplore->SetVisible( false );
  967. m_pSizeControls[0]->SetVisible( false );
  968. m_pSizeControls[1]->SetVisible( false );
  969. m_pSizeControls[2]->SetVisible( false );
  970. if ( m_pInfo )
  971. {
  972. char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0};
  973. Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", m_pInfo->GetString( KEYNAME_NAME ) );
  974. char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 );
  975. if ( szResolvedName )
  976. {
  977. m_pExplore->SetVisible( true );
  978. }
  979. char const *szKeyName = m_pInfo->GetString( KEYNAME_NAME );
  980. if ( !m_pInfo->GetInt( "SpecialTx" ) )
  981. {
  982. m_pSizeControls[0]->SetVisible( true );
  983. m_pSizeControls[1]->SetVisible( true );
  984. if ( CanAdjustTextureExclude( szKeyName ) )
  985. {
  986. m_pSizeControls[2]->SetVisible( true );
  987. m_pSizeControls[2]->SetSelected( IsTextureExcluded( szKeyName ) );
  988. }
  989. m_pSizeControls[0]->SetEnabled( CanAdjustTextureSize( szKeyName, false ) );
  990. m_pSizeControls[1]->SetEnabled( CanAdjustTextureSize( szKeyName, true ) );
  991. int posX, posY;
  992. m_pExplore->GetPos( posX, posY );
  993. m_pSizeControls[0]->SetPos( posX, posY + m_pExplore->GetTall() + 1 );
  994. m_pSizeControls[0]->SetWide( m_pExplore->GetWide() / 2 );
  995. m_pSizeControls[1]->SetPos( posX + m_pSizeControls[0]->GetWide() + 1, posY + m_pExplore->GetTall() + 1 );
  996. m_pSizeControls[1]->SetWide( m_pExplore->GetWide() - ( m_pSizeControls[0]->GetWide() + 1 ) );
  997. int iExcludeWidth = 80;
  998. m_pSizeControls[2]->SetPos( posX - iExcludeWidth - 1, posY + m_pExplore->GetTall() + 1 );
  999. m_pSizeControls[2]->SetWide( iExcludeWidth );
  1000. }
  1001. }
  1002. {
  1003. int posX, posY;
  1004. m_pExplore->GetPos( posX, posY );
  1005. posY += m_pExplore->GetTall() * 2 + 2;
  1006. posX += m_pExplore->GetWide();
  1007. posX -= 80;
  1008. m_pCopyImg->SetPos( posX, posY );
  1009. m_pCopyImg->SetWide( 80 );
  1010. posX -= 80 + 5;
  1011. m_pCopyTxt->SetPos( posX, posY );
  1012. m_pCopyTxt->SetWide( 80 );
  1013. posX -= 95 + 5;
  1014. m_pFlashBtn->SetPos( posX, posY );
  1015. m_pFlashBtn->SetWide( 95 );
  1016. }
  1017. }
  1018. void CRenderTextureEditor::OnCommand( const char *command )
  1019. {
  1020. BaseClass::OnCommand( command );
  1021. MatTextureModificationRecorded();
  1022. if ( !stricmp( command, "Explore" ) && m_pInfo )
  1023. {
  1024. char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0};
  1025. Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", m_pInfo->GetString( KEYNAME_NAME ) );
  1026. char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 );
  1027. char params[256];
  1028. Q_snprintf( params, sizeof( params ) - 1, "/E,/SELECT,%s", szResolvedName );
  1029. vgui::system()->ShellExecuteEx( "open", "explorer.exe", params );
  1030. }
  1031. if ( !stricmp( command, "Reload" ) && m_lstMaterials.Count() )
  1032. {
  1033. CUtlBuffer bufCommand( 0, 0, CUtlBuffer::TEXT_BUFFER );
  1034. int idxMaterial = 0;
  1035. //
  1036. // Issue the console command several times in case we overflow the
  1037. // console command buffer size.
  1038. //
  1039. Cbuf_Execute();
  1040. for ( ; idxMaterial < m_lstMaterials.Count(); )
  1041. {
  1042. int iOldIdx = idxMaterial;
  1043. bufCommand.Printf( "mat_reloadmaterial \"" );
  1044. for ( ; idxMaterial < m_lstMaterials.Count(); ++ idxMaterial )
  1045. {
  1046. int iOldSize = bufCommand.TellPut();
  1047. int const iSizeLimit = CCommand::MaxCommandLength() - 3;
  1048. char const *szString = CUtlSymbol( m_lstMaterials[idxMaterial] ).String();
  1049. bufCommand.Printf( "%s%s", ( idxMaterial > iOldIdx ) ? "*" : "", szString );
  1050. if ( bufCommand.TellPut() > iSizeLimit &&
  1051. idxMaterial > iOldIdx )
  1052. {
  1053. bufCommand.SeekPut( CUtlBuffer::SEEK_HEAD, iOldSize );
  1054. break;
  1055. }
  1056. }
  1057. bufCommand.Printf( "\"\n" );
  1058. bufCommand.PutChar( 0 );
  1059. Cbuf_AddText( Cbuf_GetCurrentPlayer(), ( char const * ) bufCommand.Base() );
  1060. bufCommand.Clear();
  1061. Cbuf_Execute();
  1062. }
  1063. }
  1064. if ( !stricmp( command, "CopyTxt" ) )
  1065. {
  1066. char const *szName = ( char const * ) m_bufInfoText.Base();
  1067. if ( !m_bufInfoText.TellPut() || !szName )
  1068. szName = "";
  1069. vgui::system()->SetClipboardText( szName, strlen( szName ) + 1 );
  1070. }
  1071. if ( !stricmp( command, "CopyImg" ) )
  1072. {
  1073. int x = 0, y = 0;
  1074. this->LocalToScreen( x, y );
  1075. void *pMainWnd = game->GetMainWindow();
  1076. vgui::system()->SetClipboardImage( pMainWnd, x, y, x + GetWide(), y + GetTall() );
  1077. }
  1078. if ( !stricmp( command, "FlashBtn" ) )
  1079. {
  1080. MatViewOverride::RequestSelectNone();
  1081. MatViewOverride::RequestSelected( m_lstMaterials.Count(), m_lstMaterials.Base() );
  1082. mat_texture_list_off_f();
  1083. }
  1084. if ( ( !stricmp( command, "size-" ) || !stricmp( command, "size+" ) ) && m_pInfo )
  1085. {
  1086. bool bSizeUp = ( command[4] == '+' );
  1087. bool bResult = AdjustTextureSize( m_pInfo->GetString( KEYNAME_NAME ), bSizeUp );
  1088. if ( bResult )
  1089. {
  1090. CAutoPushPop<bool> auto_g_bRecursiveRequestToShowTextureList( g_bRecursiveRequestToShowTextureList, true );
  1091. mat_texture_list_on_f();
  1092. }
  1093. InvalidateLayout();
  1094. }
  1095. if ( !stricmp( command, "Exclude" ) )
  1096. {
  1097. bool bExclude = m_pSizeControls[2]->IsSelected();
  1098. bool bResult = AdjustTextureExclude( m_pInfo->GetString( KEYNAME_NAME ), bExclude );
  1099. if ( bResult )
  1100. {
  1101. CAutoPushPop<bool> auto_g_bRecursiveRequestToShowTextureList( g_bRecursiveRequestToShowTextureList, true );
  1102. mat_texture_list_on_f();
  1103. }
  1104. InvalidateLayout();
  1105. }
  1106. }
  1107. void CRenderTextureEditor::ApplySchemeSettings( vgui::IScheme *pScheme )
  1108. {
  1109. BaseClass::ApplySchemeSettings( pScheme );
  1110. SetFont( pScheme->GetFont( "Default", IsProportional() ) );
  1111. }
  1112. void CRenderTextureEditor::OnMousePressed( vgui::MouseCode code )
  1113. {
  1114. Close();
  1115. }
  1116. void CRenderTextureEditor::Paint()
  1117. {
  1118. CAutoMatSysDebugMode auto_matsysdebugmode;
  1119. DisableFadeEffect();
  1120. SetBgColor( Color( 10, 50, 10, 255 ) );
  1121. BaseClass::Paint();
  1122. KeyValues *kv = m_pInfo;
  1123. if ( !kv )
  1124. return;
  1125. char const *szTextureFile = kv->GetString( KEYNAME_NAME );
  1126. Q_strncpy( s_chLastViewedTextureBuffer, szTextureFile, sizeof( s_chLastViewedTextureBuffer ) );
  1127. char const *szTextureGroup = kv->GetString( KEYNAME_TEXTURE_GROUP );
  1128. ITexture *pMatTexture = NULL;
  1129. if ( *szTextureFile )
  1130. pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false );
  1131. if ( !pMatTexture )
  1132. pMatTexture = materials->FindTexture( "debugempty", "", false );
  1133. // Determine the texture size
  1134. int iTxWidth = kv->GetInt( KEYNAME_WIDTH );
  1135. int iTxHeight = kv->GetInt( KEYNAME_HEIGHT );
  1136. int iTxSize = kv->GetInt( KEYNAME_SIZE );
  1137. char const *szTxFormat = kv->GetString( KEYNAME_FORMAT );
  1138. int x = TILE_BORDER, y = TILE_BORDER;
  1139. // Dimensions to draw
  1140. int iDrawWidth = iTxWidth;
  1141. int iDrawHeight = iTxHeight;
  1142. if ( pMatTexture && pMatTexture->IsCubeMap() )
  1143. {
  1144. iDrawWidth = 1024;
  1145. iDrawHeight = 1024;
  1146. }
  1147. if ( iDrawHeight >= iDrawWidth )
  1148. {
  1149. if ( iDrawHeight > TILE_TEXTURE_SIZE )
  1150. {
  1151. iDrawWidth = iDrawWidth * ( float( TILE_TEXTURE_SIZE ) / iDrawHeight );
  1152. iDrawHeight = TILE_TEXTURE_SIZE;
  1153. }
  1154. if ( iDrawHeight < 64 )
  1155. {
  1156. iDrawWidth = iDrawWidth * ( float( 64 ) / iDrawHeight );
  1157. iDrawHeight = 64;
  1158. }
  1159. }
  1160. else
  1161. {
  1162. if ( iDrawWidth > TILE_TEXTURE_SIZE )
  1163. {
  1164. iDrawHeight = iDrawHeight * ( float( TILE_TEXTURE_SIZE ) / iDrawWidth );
  1165. iDrawWidth = TILE_TEXTURE_SIZE;
  1166. }
  1167. if ( iDrawWidth < 64 )
  1168. {
  1169. iDrawHeight = iDrawHeight * ( float( 64 ) / iDrawWidth );
  1170. iDrawWidth = 64;
  1171. }
  1172. }
  1173. iDrawHeight = iDrawHeight / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) );
  1174. iDrawWidth = iDrawWidth / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) );
  1175. iDrawHeight = MAX( iDrawHeight, 4 );
  1176. iDrawWidth = MAX( iDrawWidth, 4 );
  1177. //
  1178. // Draw frame
  1179. //
  1180. {
  1181. int tileWidth = 2 * TILE_BORDER + TILE_SIZE;
  1182. int tileHeight = 3 * TILE_BORDER + TILE_SIZE + TILE_TEXT;
  1183. g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 );
  1184. g_pMatSystemSurface->DrawOutlinedRect( x + 1, y + 1,
  1185. x + tileWidth - 2 , y + tileHeight - 2 );
  1186. }
  1187. //
  1188. // Draw all
  1189. //
  1190. x += TILE_BORDER;
  1191. y += TILE_BORDER;
  1192. char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0};
  1193. Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", szTextureFile );
  1194. char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 );
  1195. char const *szPrintFilePrefix = szResolvedName ? "" : "[?]/";
  1196. char const *szPrintFileName = szResolvedName ? szResolvedName : szTextureFile;
  1197. char chSizeBuf[20] = { 0 };
  1198. if ( iTxSize >= 0 )
  1199. FmtCommaNumber( chSizeBuf, iTxSize );
  1200. else
  1201. chSizeBuf[0] = '-';
  1202. g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y, TILE_SIZE, TILE_TEXT / 2,
  1203. 255, 255, 255, 255,
  1204. "%s%s\n"
  1205. "%s Kb %dx%d %s",
  1206. szPrintFilePrefix, szPrintFileName,
  1207. chSizeBuf,
  1208. iTxWidth, iTxHeight,
  1209. szTxFormat
  1210. );
  1211. if ( !m_bufInfoText.TellPut() )
  1212. {
  1213. m_bufInfoText.Printf(
  1214. "%s%s\r\n"
  1215. "%s Kb %dx%d %s",
  1216. szPrintFilePrefix, szPrintFileName,
  1217. chSizeBuf,
  1218. iTxWidth, iTxHeight,
  1219. szTxFormat );
  1220. }
  1221. if ( !kv->GetInt( "SpecialTx" ) )
  1222. {
  1223. char chLine1[256] = {0};
  1224. char chLine2[256] = {0};
  1225. //
  1226. // Line 1
  1227. //
  1228. if ( iTxSize > g_warn_texkbytes )
  1229. sprintf( chLine1 + strlen( chLine1 ), " Size(%s Kb)", chSizeBuf );
  1230. if ( ( iTxWidth > g_warn_texdimensions ) ||
  1231. ( iTxHeight > g_warn_texdimensions ) )
  1232. sprintf( chLine1 + strlen( chLine1 ), " Dimensions(%dx%d)", iTxWidth, iTxHeight );
  1233. if ( stricmp( szTxFormat, "DXT1" ) &&
  1234. stricmp( szTxFormat, "DXT5" ) )
  1235. sprintf( chLine1 + strlen( chLine1 ), " Format(%s)", szTxFormat );
  1236. if ( pMatTexture->GetFlags() & TEXTUREFLAGS_NOLOD )
  1237. sprintf( chLine1 + strlen( chLine1 ), " NoLod" );
  1238. if ( pMatTexture->GetFlags() & TEXTUREFLAGS_NOMIP )
  1239. sprintf( chLine1 + strlen( chLine1 ), " NoMip" );
  1240. if ( pMatTexture->GetFlags() & TEXTUREFLAGS_ONEBITALPHA )
  1241. sprintf( chLine1 + strlen( chLine1 ), " OneBitAlpha" );
  1242. if ( pMatTexture->IsVolumeTexture() )
  1243. sprintf( chLine1 + strlen( chLine1 ), " Volume" );
  1244. //
  1245. // Line 2
  1246. //
  1247. // Always show stats for higher/lower mips
  1248. {
  1249. int wmap = pMatTexture->GetMappingWidth(), hmap = pMatTexture->GetMappingHeight(), dmap = pMatTexture->GetMappingDepth();
  1250. int wact = pMatTexture->GetActualWidth(), hact = pMatTexture->GetActualHeight(), dact = pMatTexture->GetActualDepth();
  1251. ImageFormat fmt = pMatTexture->GetImageFormat();
  1252. if ( wact > 4 || hact > 4 )
  1253. {
  1254. char chbuf[50];
  1255. int mem = ImageLoader::GetMemRequired( MAX( MIN( wact, 4 ), wact / 2 ), MAX( MIN( hact, 4 ), hact / 2 ), MAX( 1, dact / 2 ), fmt, true );
  1256. mem = ( mem + 511 ) / 1024;
  1257. FmtCommaNumber( chbuf, mem );
  1258. sprintf ( chLine2 + strlen( chLine2 ), " %s Kb @ lower mip", chbuf );
  1259. }
  1260. if ( wmap > wact || hmap > hact || dmap > dact )
  1261. {
  1262. char chbuf[ 50 ];
  1263. int mem = ImageLoader::GetMemRequired( MIN( wmap, wact * 2 ), MIN( hmap, hact * 2 ), MIN( dmap, dact * 2 ), fmt, true );
  1264. mem = ( mem + 511 ) / 1024;
  1265. FmtCommaNumber( chbuf, mem );
  1266. sprintf ( chLine2 + strlen( chLine2 ), " %s Kb @ higher mip", chbuf );
  1267. }
  1268. }
  1269. if ( chLine1[0] )
  1270. {
  1271. g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 );
  1272. g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y + TILE_TEXT/2, x + TILE_BORDER/2 + TILE_SIZE, y + TILE_TEXT/2 + TILE_TEXT/4 );
  1273. g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y + TILE_TEXT/2, TILE_SIZE, TILE_TEXT / 4,
  1274. 255, 255, 255, 255,
  1275. "%s", chLine1 );
  1276. }
  1277. if ( chLine2[0] )
  1278. {
  1279. // g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 );
  1280. // g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y + TILE_TEXT/2 + TILE_TEXT/4, x + TILE_BORDER/2 + TILE_SIZE, y + TILE_TEXT );
  1281. g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y + TILE_TEXT/2 + TILE_TEXT/4, TILE_SIZE, TILE_TEXT / 4,
  1282. 255, 255, 255, 255,
  1283. "%s", chLine2 );
  1284. }
  1285. }
  1286. y += TILE_TEXT + TILE_BORDER;
  1287. // Images placement
  1288. bool bHasAlpha = !!stricmp( szTxFormat, "DXT1" );
  1289. int extTxWidth = TILE_SIZE;
  1290. int extTxHeight = TILE_SIZE;
  1291. int orgTxX = 0, orgTxXA = 0;
  1292. int orgTxY = 0, orgTxYA = 0;
  1293. if ( bHasAlpha )
  1294. {
  1295. if ( iTxWidth >= iTxHeight * 2 )
  1296. {
  1297. extTxHeight /= 2;
  1298. orgTxYA = extTxHeight + TILE_BORDER/2;
  1299. extTxHeight -= 1;
  1300. }
  1301. else if ( iTxHeight >= iTxWidth * 2 )
  1302. {
  1303. extTxWidth /= 2;
  1304. orgTxXA = extTxWidth + TILE_BORDER/2;
  1305. extTxWidth -= 3;
  1306. }
  1307. else
  1308. {
  1309. extTxHeight /= 2;
  1310. orgTxYA = extTxHeight + TILE_BORDER/2;
  1311. orgTxX = extTxWidth / 4;
  1312. extTxWidth /= 2;
  1313. if ( iDrawWidth > extTxWidth )
  1314. {
  1315. iDrawWidth /= 2;
  1316. iDrawHeight /= 2;
  1317. }
  1318. extTxWidth -= 1;
  1319. extTxHeight -= 1;
  1320. }
  1321. }
  1322. enum { IMG_FRAME_OFF = 2 };
  1323. if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturecolor", pMatTexture, &auto_matsysdebugmode ) )
  1324. {
  1325. g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 );
  1326. g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1327. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1328. RenderTexturedRect( this, pMaterial,
  1329. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1330. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 );
  1331. if ( bHasAlpha )
  1332. {
  1333. orgTxX += orgTxXA;
  1334. orgTxY += orgTxYA;
  1335. if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturealpha", pMatTexture, &auto_matsysdebugmode ) )
  1336. {
  1337. g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1338. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1339. RenderTexturedRect( this, pMaterial,
  1340. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1341. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 );
  1342. }
  1343. orgTxX -= orgTxXA;
  1344. orgTxY -= orgTxYA;
  1345. }
  1346. }
  1347. else
  1348. {
  1349. g_pMatSystemSurface->DrawSetColor( 255, 0, 255, 100 );
  1350. g_pMatSystemSurface->DrawFilledRect(
  1351. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxWidth - iDrawHeight ) / 2,
  1352. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxWidth + iDrawHeight ) / 2 );
  1353. }
  1354. if ( IsTextureExcluded( szTextureFile ) )
  1355. {
  1356. g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 );
  1357. g_pMatSystemSurface->DrawFilledRect(
  1358. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF,
  1359. y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1360. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF,
  1361. y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1362. g_pMatSystemSurface->DrawColoredTextRect( GetFont(),
  1363. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2,
  1364. y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1365. iDrawWidth,
  1366. iDrawHeight,
  1367. 255, 255, 255, 255,
  1368. "EXCLUDED"
  1369. );
  1370. }
  1371. y += TILE_SIZE + TILE_BORDER;
  1372. }
  1373. //////////////////////////////////////////////////////////////////////////
  1374. //
  1375. // Render textures view panel
  1376. //
  1377. //////////////////////////////////////////////////////////////////////////
  1378. class CRenderTexturesListViewPanel : public vgui::TileViewPanelEx
  1379. {
  1380. DECLARE_CLASS_SIMPLE( CRenderTexturesListViewPanel, vgui::TileViewPanelEx );
  1381. public:
  1382. CRenderTexturesListViewPanel( vgui::Panel *parent, char const *szName );
  1383. ~CRenderTexturesListViewPanel();
  1384. protected:
  1385. virtual int GetNumTiles();
  1386. virtual void GetTileSize( int &wide, int &tall );
  1387. virtual void RenderTile( int iTile, int x, int y );
  1388. protected:
  1389. virtual void PerformLayout();
  1390. virtual void OnMousePressed( vgui::MouseCode code );
  1391. virtual void OnMouseDoublePressed( vgui::MouseCode code ) { OnMousePressed( code ); }
  1392. public:
  1393. void SetDataListPanel( vgui::ListPanel *pPanel );
  1394. void SetPaintAlpha( bool bPaintAlpha );
  1395. CRenderTextureEditor * GetRenderTxEditor() const { return m_pRenderTxEditor; }
  1396. protected:
  1397. vgui::ListPanel *m_pListPanel;
  1398. KeyValues * GetTileData( int iTile );
  1399. protected:
  1400. CRenderTextureEditor *m_pRenderTxEditor;
  1401. protected:
  1402. enum
  1403. {
  1404. TILE_BORDER = 20,
  1405. TILE_SIZE = 192,
  1406. TILE_TEXTURE_SIZE = 256,
  1407. TILE_TEXT = 35
  1408. };
  1409. bool m_bPaintAlpha;
  1410. };
  1411. CRenderTexturesListViewPanel::CRenderTexturesListViewPanel( vgui::Panel *parent, char const *szName ) :
  1412. vgui::TileViewPanelEx( parent, szName ),
  1413. m_pListPanel( NULL ),
  1414. m_bPaintAlpha( false )
  1415. {
  1416. m_pRenderTxEditor = new CRenderTextureEditor( this, "TxEdt" );
  1417. m_pRenderTxEditor->SetPos( 10, 10 );
  1418. m_pRenderTxEditor->PerformLayout();
  1419. m_pRenderTxEditor->SetMoveable( true );
  1420. m_pRenderTxEditor->SetSizeable( false );
  1421. m_pRenderTxEditor->SetClipToParent( true );
  1422. m_pRenderTxEditor->SetTitle( "", true );
  1423. m_pRenderTxEditor->SetCloseButtonVisible( false );
  1424. m_pRenderTxEditor->SetVisible( false );
  1425. }
  1426. CRenderTexturesListViewPanel::~CRenderTexturesListViewPanel()
  1427. {
  1428. NULL;
  1429. }
  1430. void CRenderTexturesListViewPanel::PerformLayout()
  1431. {
  1432. BaseClass::PerformLayout();
  1433. }
  1434. void CRenderTexturesListViewPanel::OnMousePressed( vgui::MouseCode code )
  1435. {
  1436. BaseClass::OnMousePressed( code );
  1437. // Figure out which tile got hit and pass its data for preview
  1438. m_pRenderTxEditor->Close();
  1439. if ( !m_pListPanel )
  1440. return;
  1441. int x, y;
  1442. vgui::input()->GetCursorPos( x, y );
  1443. this->ScreenToLocal( x, y );
  1444. // Hit test the click
  1445. int iTile, tileX, tileY;
  1446. int htResult = HitTest( x, y, iTile );
  1447. if ( HT_NOTHING == htResult )
  1448. return;
  1449. if ( !GetTileOrg( iTile, tileX, tileY ) )
  1450. return;
  1451. // Now having the tile retrieve the keyvalues
  1452. int itemId = m_pListPanel->GetItemIDFromRow( iTile );
  1453. if ( itemId < 0 )
  1454. return;
  1455. KeyValues *kv = m_pListPanel->GetItem( itemId );
  1456. if ( !kv )
  1457. return;
  1458. // Display the tx editor
  1459. m_pRenderTxEditor->SetDispInfo( kv, itemId );
  1460. if ( tileX + m_pRenderTxEditor->GetWide() > m_li_wide - 2 )
  1461. tileX -= tileX + m_pRenderTxEditor->GetWide() - ( m_li_wide - 2 );
  1462. if ( tileY + m_pRenderTxEditor->GetTall() > m_li_tall - 2 )
  1463. tileY -= tileY + m_pRenderTxEditor->GetTall() - ( m_li_tall - 2 );
  1464. int iTopLeftX = 0, iTopLeftY = 0;
  1465. for ( vgui::Panel *pPanel = this; ( pPanel = pPanel->GetParent() ) != NULL; )
  1466. {
  1467. iTopLeftX = iTopLeftY = 0;
  1468. pPanel->LocalToScreen( iTopLeftX, iTopLeftY );
  1469. }
  1470. LocalToScreen( tileX, tileY );
  1471. if ( tileX < iTopLeftX ) tileX = iTopLeftX;
  1472. if ( tileY < iTopLeftY ) tileY = iTopLeftY;
  1473. m_pRenderTxEditor->SetPos( tileX, tileY );
  1474. m_pRenderTxEditor->Activate();
  1475. }
  1476. int CRenderTexturesListViewPanel::GetNumTiles()
  1477. {
  1478. return m_pListPanel ? m_pListPanel->GetItemCount() : 0;
  1479. }
  1480. void CRenderTexturesListViewPanel::GetTileSize( int &wide, int &tall )
  1481. {
  1482. wide = 2 * TILE_BORDER + TILE_SIZE;
  1483. tall = 2 * TILE_BORDER + TILE_SIZE + TILE_TEXT;
  1484. };
  1485. KeyValues * CRenderTexturesListViewPanel::GetTileData( int iTile )
  1486. {
  1487. int iData = m_pListPanel->GetItemIDFromRow( iTile );
  1488. if ( iData < 0 )
  1489. return NULL;
  1490. return m_pListPanel->GetItem( iData );
  1491. }
  1492. void CRenderTexturesListViewPanel::RenderTile( int iTile, int x, int y )
  1493. {
  1494. CAutoMatSysDebugMode auto_matsysdebugmode;
  1495. KeyValues *kv = GetTileData( iTile );
  1496. if ( !kv )
  1497. return;
  1498. char const *szTextureFile = kv->GetString( KEYNAME_NAME );
  1499. char const *szTextureGroup = kv->GetString( KEYNAME_TEXTURE_GROUP );
  1500. ITexture *pMatTexture = NULL;
  1501. if ( *szTextureFile )
  1502. pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false );
  1503. if ( !pMatTexture )
  1504. pMatTexture = materials->FindTexture( "debugempty", "", false );
  1505. // Determine the texture size
  1506. int iTxWidth = kv->GetInt( KEYNAME_WIDTH );
  1507. int iTxHeight = kv->GetInt( KEYNAME_HEIGHT );
  1508. int iTxSize = kv->GetInt( KEYNAME_SIZE );
  1509. char const *szTxFormat = kv->GetString( KEYNAME_FORMAT );
  1510. int iTxFormatLen = strlen( szTxFormat );
  1511. char *szTxFormatSuffix = "";
  1512. if ( iTxFormatLen > 4 )
  1513. {
  1514. fmtlenreduce:
  1515. switch ( szTxFormat[ iTxFormatLen - 1 ] )
  1516. {
  1517. case '8':
  1518. {
  1519. while ( ( iTxFormatLen > 4 ) &&
  1520. ( szTxFormat[ iTxFormatLen - 2 ] == '8' ) )
  1521. -- iTxFormatLen;
  1522. }
  1523. break;
  1524. case '6':
  1525. {
  1526. while ( ( iTxFormatLen > 4 ) &&
  1527. ( szTxFormat[ iTxFormatLen - 2 ] == '1' ) &&
  1528. ( szTxFormat[ iTxFormatLen - 3 ] == '6' ) )
  1529. iTxFormatLen -= 2;
  1530. }
  1531. break;
  1532. case 'F':
  1533. if ( !*szTxFormatSuffix )
  1534. {
  1535. iTxFormatLen --;
  1536. szTxFormatSuffix = "F";
  1537. goto fmtlenreduce;
  1538. }
  1539. break;
  1540. }
  1541. }
  1542. // Dimensions to draw
  1543. int iDrawWidth = iTxWidth;
  1544. int iDrawHeight = iTxHeight;
  1545. if ( pMatTexture && pMatTexture->IsCubeMap() )
  1546. {
  1547. iDrawWidth = 1024;
  1548. iDrawHeight = 1024;
  1549. }
  1550. if ( iDrawHeight >= iDrawWidth )
  1551. {
  1552. if ( iDrawHeight > TILE_TEXTURE_SIZE )
  1553. {
  1554. iDrawWidth = iDrawWidth * ( float( TILE_TEXTURE_SIZE ) / iDrawHeight );
  1555. iDrawHeight = TILE_TEXTURE_SIZE;
  1556. }
  1557. if ( iDrawHeight < 64 )
  1558. {
  1559. iDrawWidth = iDrawWidth * ( float( 64 ) / iDrawHeight );
  1560. iDrawHeight = 64;
  1561. }
  1562. }
  1563. else
  1564. {
  1565. if ( iDrawWidth > TILE_TEXTURE_SIZE )
  1566. {
  1567. iDrawHeight = iDrawHeight * ( float( TILE_TEXTURE_SIZE ) / iDrawWidth );
  1568. iDrawWidth = TILE_TEXTURE_SIZE;
  1569. }
  1570. if ( iDrawWidth < 64 )
  1571. {
  1572. iDrawHeight = iDrawHeight * ( float( 64 ) / iDrawWidth );
  1573. iDrawWidth = 64;
  1574. }
  1575. }
  1576. iDrawHeight = iDrawHeight / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) );
  1577. iDrawWidth = iDrawWidth / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) );
  1578. iDrawHeight = MAX( iDrawHeight, 4 );
  1579. iDrawWidth = MAX( iDrawWidth, 4 );
  1580. //
  1581. // Draw frame
  1582. //
  1583. {
  1584. int tileWidth, tileHeight;
  1585. GetTileSize( tileWidth, tileHeight );
  1586. g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 );
  1587. g_pMatSystemSurface->DrawOutlinedRect( x + 1, y + 1,
  1588. x + tileWidth - 2 , y + tileHeight - 2 );
  1589. }
  1590. //
  1591. // Draw all
  1592. //
  1593. x += TILE_BORDER;
  1594. y += TILE_BORDER/2;
  1595. int iLenFile = strlen( szTextureFile );
  1596. char const *szPrintFilePrefix = ( iLenFile > 22 ) ? "..." : "";
  1597. char const *szPrintFileName = ( iLenFile > 22 ) ? ( szTextureFile + iLenFile - 22 ) : szTextureFile;
  1598. char chSizeBuf[20] = {0};
  1599. if ( iTxSize >= 0 )
  1600. {
  1601. FmtCommaNumber( chSizeBuf, iTxSize );
  1602. }
  1603. else
  1604. {
  1605. chSizeBuf[0] = '-';
  1606. }
  1607. static Color clrLblNormal( 25, 50, 25, 255 );
  1608. static Color clrLblWarn( 75, 75, 0, 255 );
  1609. static Color clrLblError( 200, 0, 0, 255 );
  1610. bool bWarnTile = ( !kv->GetInt( "SpecialTx" ) ) && ( g_warn_enable && ShallWarnTx( kv, pMatTexture ) );
  1611. g_pMatSystemSurface->DrawSetColor( bWarnTile ? clrLblWarn : clrLblNormal );
  1612. g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y, x + TILE_BORDER/2 + TILE_SIZE, y + TILE_TEXT );
  1613. char chInfoText[256] = { 0 };
  1614. sprintf( chInfoText, "%s Kb %dx%d %.*s%s %s",
  1615. chSizeBuf,
  1616. iTxWidth, iTxHeight,
  1617. iTxFormatLen, szTxFormat, szTxFormatSuffix,
  1618. ( pMatTexture->GetFlags() & (
  1619. TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA
  1620. ) ) ? "***" : "" );
  1621. int iTextMargins[4] = { 0 };
  1622. int iTextHeight = g_pMatSystemSurface->GetFontTall( GetFont() );
  1623. {
  1624. // Compute text extents
  1625. int iTextLen[4] = { 0 };
  1626. iTextLen[0] = 5 + strlen( chSizeBuf );
  1627. iTextLen[1] = strchr( chInfoText, 'x' ) + 1 - chInfoText;
  1628. while ( chInfoText[ iTextLen[1] ] != ' ' )
  1629. ++ iTextLen[1];
  1630. ++ iTextLen[1];
  1631. iTextLen[2] = 2 + iTextLen[1] + iTxFormatLen + strlen( szTxFormatSuffix );
  1632. iTextLen[3] = strlen( chInfoText );
  1633. for ( int k = 0; k < 4; ++ k )
  1634. iTextMargins[k] = g_pMatSystemSurface->DrawTextLen( GetFont(), "%.*s", iTextLen[k], chInfoText );
  1635. }
  1636. // Highlights
  1637. if ( bWarnTile )
  1638. {
  1639. g_pMatSystemSurface->DrawSetColor( clrLblError );
  1640. if ( iTxSize > g_warn_texkbytes )
  1641. g_pMatSystemSurface->DrawFilledRect( x - 2, y + iTextHeight + 1, x + iTextMargins[0] - 5, y + TILE_TEXT );
  1642. if ( iTxWidth > g_warn_texdimensions || iTxHeight > g_warn_texdimensions )
  1643. g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[0] - 2, y + iTextHeight + 1, x + iTextMargins[1] - 1, y + TILE_TEXT );
  1644. if ( strcmp( szTxFormat, "DXT1" ) && strcmp( szTxFormat, "DXT5" ) )
  1645. g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[1] + 2, y + iTextHeight + 1, x + iTextMargins[2] - 1, y + TILE_TEXT );
  1646. if ( pMatTexture->GetFlags() & (
  1647. TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA
  1648. ) )
  1649. g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[2] + 3, y + iTextHeight + 1, x + iTextMargins[3] + 2, y + TILE_TEXT );
  1650. }
  1651. g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y, TILE_SIZE, TILE_TEXT,
  1652. 255, 255, 255, 255,
  1653. "%s%s\n"
  1654. "%s",
  1655. szPrintFilePrefix, szPrintFileName,
  1656. chInfoText
  1657. );
  1658. y += TILE_TEXT + TILE_BORDER/2;
  1659. // Images placement
  1660. bool bHasAlpha = m_bPaintAlpha && stricmp( szTxFormat, "DXT1" );
  1661. int extTxWidth = TILE_SIZE;
  1662. int extTxHeight = TILE_SIZE;
  1663. int orgTxX = 0, orgTxXA = 0;
  1664. int orgTxY = 0, orgTxYA = 0;
  1665. if ( bHasAlpha )
  1666. {
  1667. if ( iTxWidth >= iTxHeight * 2 )
  1668. {
  1669. extTxHeight /= 2;
  1670. orgTxYA = extTxHeight + TILE_BORDER/2;
  1671. }
  1672. else if ( iTxHeight >= iTxWidth * 2 )
  1673. {
  1674. extTxWidth /= 2;
  1675. orgTxXA = extTxWidth + TILE_BORDER/2;
  1676. x -= TILE_BORDER/4 + 1;
  1677. }
  1678. else
  1679. {
  1680. extTxHeight /= 2;
  1681. orgTxYA = extTxHeight + TILE_BORDER/2;
  1682. orgTxX = extTxWidth / 4;
  1683. extTxWidth /= 2;
  1684. x -= TILE_BORDER/4 + 1;
  1685. if ( iDrawWidth > extTxWidth )
  1686. {
  1687. iDrawWidth /= 2;
  1688. iDrawHeight /= 2;
  1689. }
  1690. }
  1691. }
  1692. enum { IMG_FRAME_OFF = 2 };
  1693. if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturecolor", pMatTexture, &auto_matsysdebugmode ) )
  1694. {
  1695. g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 );
  1696. g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1697. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1698. RenderTexturedRect( this, pMaterial,
  1699. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1700. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2,
  1701. 2, 1 );
  1702. if ( bHasAlpha )
  1703. {
  1704. orgTxX += orgTxXA;
  1705. orgTxY += orgTxYA;
  1706. if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturealpha", pMatTexture, &auto_matsysdebugmode ) )
  1707. {
  1708. g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1709. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1710. RenderTexturedRect( this, pMaterial,
  1711. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1712. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2,
  1713. 2, 1 );
  1714. }
  1715. orgTxX -= orgTxXA;
  1716. orgTxY -= orgTxYA;
  1717. }
  1718. }
  1719. else
  1720. {
  1721. g_pMatSystemSurface->DrawSetColor( 255, 0, 255, 100 );
  1722. g_pMatSystemSurface->DrawFilledRect(
  1723. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxWidth - iDrawHeight ) / 2,
  1724. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxWidth + iDrawHeight ) / 2 );
  1725. }
  1726. if ( IsTextureExcluded( szTextureFile ) )
  1727. {
  1728. g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 );
  1729. g_pMatSystemSurface->DrawFilledRect(
  1730. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF,
  1731. y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF,
  1732. x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF,
  1733. y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF );
  1734. g_pMatSystemSurface->DrawColoredTextRect( GetFont(),
  1735. x + orgTxX + ( extTxWidth - iDrawWidth ) / 2,
  1736. y + orgTxY + ( extTxHeight - iDrawHeight ) / 2,
  1737. iDrawWidth,
  1738. iDrawHeight,
  1739. 255, 255, 255, 255,
  1740. "-X-"
  1741. );
  1742. }
  1743. y += TILE_SIZE + TILE_BORDER;
  1744. }
  1745. void CRenderTexturesListViewPanel::SetDataListPanel( vgui::ListPanel *pPanel )
  1746. {
  1747. m_pListPanel = pPanel;
  1748. InvalidateLayout();
  1749. }
  1750. void CRenderTexturesListViewPanel::SetPaintAlpha( bool bPaintAlpha )
  1751. {
  1752. m_bPaintAlpha = bPaintAlpha;
  1753. Repaint();
  1754. }
  1755. //-----------------------------------------------------------------------------
  1756. // Purpose: Shows entity status report if cl_entityreport cvar is set
  1757. //-----------------------------------------------------------------------------
  1758. class CTextureListPanel : public vgui::Frame
  1759. {
  1760. DECLARE_CLASS_SIMPLE( CTextureListPanel, vgui::Frame );
  1761. public:
  1762. // Construction
  1763. CTextureListPanel( vgui::Panel *parent );
  1764. virtual ~CTextureListPanel( void );
  1765. // Refresh
  1766. virtual void Paint();
  1767. void EndPaint(); // Still inside paint
  1768. virtual void ApplySchemeSettings( vgui::IScheme *pScheme );
  1769. virtual bool ShouldDraw();
  1770. virtual void PerformLayout();
  1771. virtual void Close();
  1772. void OnTurnedOn();
  1773. private:
  1774. void UpdateTotalUsageLabel();
  1775. virtual void OnCommand( const char *command );
  1776. MESSAGE_FUNC( OnTextChanged, "TextChanged" );
  1777. int AddListItem( KeyValues *kv );
  1778. bool UpdateDisplayedItem( KeyValues *pDispData, KeyValues *kv );
  1779. private:
  1780. // Font to use for drawing
  1781. vgui::HFont m_hFont;
  1782. vgui::ListPanel *m_pListPanel;
  1783. CRenderTexturesListViewPanel *m_pViewPanel;
  1784. vgui::CheckButton *m_pSpecialTexs;
  1785. vgui::CheckButton *m_pResolveTexturePath;
  1786. CConVarCheckButton *m_pShowTextureMemoryUsageOption;
  1787. CConVarCheckButton *m_pAllTextures;
  1788. CConVarCheckButton *m_pViewTextures;
  1789. vgui::Button *m_pCopyToClipboardButton;
  1790. vgui::ToggleButton *m_pCollapse;
  1791. vgui::CheckButton *m_pAlpha;
  1792. vgui::CheckButton *m_pThumbWarnings;
  1793. vgui::CheckButton *m_pFilteringChk;
  1794. vgui::TextEntry *m_pFilteringText;
  1795. int m_numDisplayedSizeKB;
  1796. vgui::Label *m_pCVarListLabel;
  1797. vgui::Label *m_pTotalUsageLabel;
  1798. };
  1799. static int __cdecl KilobytesSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 )
  1800. {
  1801. // Reverse sort order so the bigger textures show up first
  1802. const char *string1 = item1.kv->GetString( KEYNAME_SIZE );
  1803. const char *string2 = item2.kv->GetString( KEYNAME_SIZE );
  1804. int a = atoi( string1 );
  1805. int b = atoi( string2 );
  1806. if( a < b )
  1807. {
  1808. return 1;
  1809. }
  1810. if( a > b )
  1811. {
  1812. return -1;
  1813. }
  1814. return 0;
  1815. }
  1816. //
  1817. // Smart texture list
  1818. //
  1819. class CSmartTextureKeyValues
  1820. {
  1821. private:
  1822. CSmartTextureKeyValues( CSmartTextureKeyValues const &x );
  1823. CSmartTextureKeyValues& operator = ( CSmartTextureKeyValues const &x );
  1824. public:
  1825. CSmartTextureKeyValues() : m_p( NULL )
  1826. {
  1827. // Copy the texture list if it is available. It won't be availabe while it's being
  1828. // constructed on another thread. Remember to release when done.
  1829. if ( KeyValues *p = g_pMaterialSystemDebugTextureInfo->LockDebugTextureList() )
  1830. {
  1831. m_p = p->MakeCopy();
  1832. g_pMaterialSystemDebugTextureInfo->UnlockDebugTextureList();
  1833. }
  1834. }
  1835. ~CSmartTextureKeyValues() { if ( m_p ) m_p->deleteThis(); m_p = NULL; }
  1836. KeyValues * Get() const { return m_p; };
  1837. protected:
  1838. KeyValues *m_p;
  1839. };
  1840. //-----------------------------------------------------------------------------
  1841. // Purpose: Instances the entity report panel
  1842. // Input : *parent -
  1843. //-----------------------------------------------------------------------------
  1844. CTextureListPanel::CTextureListPanel( vgui::Panel *parent ) :
  1845. BaseClass( parent, "CTextureListPanel" ),
  1846. m_numDisplayedSizeKB( 0 )
  1847. {
  1848. // Need parent here, before loading up textures, so getSurfaceBase
  1849. // will work on this panel ( it's 0 otherwise )
  1850. SetSize( videomode->GetModeWidth() - 20, videomode->GetModeHeight() - 20 );
  1851. SetPos( 10, 10 );
  1852. SetVisible( true );
  1853. SetCursor( 0 );
  1854. SetTitle( "Texture list", false );
  1855. SetMenuButtonVisible( false );
  1856. m_hFont = vgui::INVALID_FONT;
  1857. SetFgColor( Color( 0, 0, 0, 255 ) );
  1858. SetPaintBackgroundEnabled( true );
  1859. // Init the buttons.
  1860. m_pCVarListLabel = vgui::SETUP_PANEL( new vgui::Label( this, "m_pCVarListLabel",
  1861. "cvars: mat_texture_limit, mat_texture_list, mat_picmip, mat_texture_list_txlod, mat_texture_list_txlod_sync" ) );
  1862. m_pCVarListLabel->SetVisible( false ); // m_pCVarListLabel->SetVisible( true );
  1863. m_pTotalUsageLabel = vgui::SETUP_PANEL( new vgui::Label( this, "m_pTotalUsageLabel", "" ) );
  1864. m_pTotalUsageLabel->SetVisible( true );
  1865. m_pSpecialTexs = vgui::SETUP_PANEL( new vgui::CheckButton( this, "service", "Render Targets and Special Textures" ) );
  1866. m_pSpecialTexs->SetVisible( true );
  1867. m_pSpecialTexs->AddActionSignalTarget( this );
  1868. m_pSpecialTexs->SetCommand( "service" );
  1869. m_pResolveTexturePath = vgui::SETUP_PANEL( new vgui::CheckButton( this, "resolvepath", "Resolve Full Texture Path" ) );
  1870. m_pResolveTexturePath->SetVisible( true );
  1871. m_pResolveTexturePath->AddActionSignalTarget( this );
  1872. m_pResolveTexturePath->SetCommand( "resolvepath" );
  1873. m_pShowTextureMemoryUsageOption = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pShowTextureMemoryUsageOption", "Show Memory Usage on HUD" ) );
  1874. m_pShowTextureMemoryUsageOption->SetVisible( true );
  1875. m_pShowTextureMemoryUsageOption->SetConVar( &mat_show_texture_memory_usage );
  1876. m_pAllTextures = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pAllTextures", "Show ALL textures" ) );
  1877. m_pAllTextures->SetVisible( true );
  1878. m_pAllTextures->SetConVar( &mat_texture_list_all );
  1879. m_pAllTextures->AddActionSignalTarget( this );
  1880. m_pAllTextures->SetCommand( "AllTextures" );
  1881. m_pViewTextures = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pViewTextures", "View textures thumbnails" ) );
  1882. m_pViewTextures->SetVisible( true );
  1883. m_pViewTextures->SetConVar( &mat_texture_list_view );
  1884. m_pViewTextures->AddActionSignalTarget( this );
  1885. m_pViewTextures->SetCommand( "ViewThumbnails" );
  1886. m_pCopyToClipboardButton = vgui::SETUP_PANEL( new vgui::Button( this, "CopyToClipboard", "Copy to Clipboard" ) );
  1887. if ( m_pCopyToClipboardButton )
  1888. {
  1889. m_pCopyToClipboardButton->AddActionSignalTarget( this );
  1890. m_pCopyToClipboardButton->SetCommand( COPYTOCLIPBOARD_CMDNAME );
  1891. }
  1892. m_pCollapse = vgui::SETUP_PANEL( new vgui::ToggleButton( this, "Collapse", " " ) );
  1893. m_pCollapse->AddActionSignalTarget( this );
  1894. m_pCollapse->SetCommand( "Collapse" );
  1895. m_pCollapse->SetSelected( true );
  1896. m_pAlpha = vgui::SETUP_PANEL( new vgui::CheckButton( this, "ShowAlpha", "Alpha" ) );
  1897. m_pAlpha->AddActionSignalTarget( this );
  1898. m_pAlpha->SetCommand( "ShowAlpha" );
  1899. bool bDefaultTxAlphaOn = true;
  1900. m_pAlpha->SetSelected( bDefaultTxAlphaOn );
  1901. m_pThumbWarnings = vgui::SETUP_PANEL( new vgui::CheckButton( this, "ThumbWarnings", "Warns" ) );
  1902. m_pThumbWarnings->AddActionSignalTarget( this );
  1903. m_pThumbWarnings->SetCommand( "ThumbWarnings" );
  1904. m_pThumbWarnings->SetSelected( g_warn_enable );
  1905. // Filtering
  1906. m_pFilteringChk = vgui::SETUP_PANEL( new vgui::CheckButton( this, "FilteringChk", "Filter: " ) );
  1907. m_pFilteringChk->AddActionSignalTarget( this );
  1908. m_pFilteringChk->SetCommand( "FilteringChk" );
  1909. m_pFilteringChk->SetSelected( true );
  1910. m_pFilteringText = vgui::SETUP_PANEL( new vgui::TextEntry( this, "FilteringTxt" ) );
  1911. m_pFilteringText->AddActionSignalTarget( this );
  1912. // Create the tree control itself.
  1913. m_pListPanel = vgui::SETUP_PANEL( new vgui::ListPanel( this, "List Panel" ) );
  1914. m_pListPanel->SetVisible( !mat_texture_list_view.GetBool() );
  1915. int col = -1;
  1916. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_NAME, "Texture Name", 200, 100, 700, vgui::ListPanel::COLUMN_RESIZEWITHWINDOW );
  1917. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_PATH, "Path", 50, 50, 300, 0 );
  1918. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_SIZE, "Kilobytes", 50, 50, 50, 0 );
  1919. m_pListPanel->SetSortFunc( col, KilobytesSortFunc );
  1920. m_pListPanel->SetSortColumnEx( col, 0, true ); // advanced sorting setup
  1921. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_TEXTURE_GROUP, "Group", 100, 100, 300, 0 );
  1922. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_FORMAT, "Format", 250, 50, 300, 0 );
  1923. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_WIDTH, "Width", 50, 50, 50, 0 );
  1924. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_HEIGHT, "Height", 50, 50, 50, 0 );
  1925. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_BINDS_FRAME, "# Binds", 50, 50, 50, 0 );
  1926. m_pListPanel->AddColumnHeader( ++ col, KEYNAME_BINDS_MAX, "BindsMax", 50, 50, 50, 0 );
  1927. SetBgColor( Color( 0, 0, 0, 100 ) );
  1928. m_pListPanel->SetBgColor( Color( 0, 0, 0, 100 ) );
  1929. // Create the view control itself
  1930. m_pViewPanel = vgui::SETUP_PANEL( new CRenderTexturesListViewPanel( this, "View Panel" ) );
  1931. m_pViewPanel->SetVisible( mat_texture_list_view.GetBool() );
  1932. m_pViewPanel->SetBgColor( Color( 0, 0, 0, 255 ) );
  1933. m_pViewPanel->SetDragEnabled( false );
  1934. m_pViewPanel->SetDropEnabled( false );
  1935. m_pViewPanel->SetPaintAlpha( bDefaultTxAlphaOn );
  1936. m_pViewPanel->SetDataListPanel( m_pListPanel );
  1937. }
  1938. //-----------------------------------------------------------------------------
  1939. // Purpose:
  1940. //-----------------------------------------------------------------------------
  1941. CTextureListPanel::~CTextureListPanel( void )
  1942. {
  1943. g_pTextureListPanel = NULL;
  1944. }
  1945. void CTextureListPanel::ApplySchemeSettings( vgui::IScheme *pScheme )
  1946. {
  1947. BaseClass::ApplySchemeSettings( pScheme );
  1948. // If you change this font, be sure to mark it with
  1949. // $use_in_fillrate_mode in its .vmt file
  1950. m_hFont = pScheme->GetFont( "DefaultVerySmall", false );
  1951. Assert( m_hFont );
  1952. }
  1953. //-----------------------------------------------------------------------------
  1954. // Purpose:
  1955. // Output : Returns true on success, false on failure.
  1956. //-----------------------------------------------------------------------------
  1957. bool CTextureListPanel::ShouldDraw( void )
  1958. {
  1959. if ( mat_texture_list.GetInt() )
  1960. return true;
  1961. if ( s_eTxListPanelRequest == TXR_SHOW ||
  1962. s_eTxListPanelRequest == TXR_RUNNING )
  1963. return true;
  1964. return false;
  1965. }
  1966. void CTextureListPanel::PerformLayout()
  1967. {
  1968. BaseClass::PerformLayout();
  1969. // Put the collapse button in the corner
  1970. m_pCollapse->SetPos( 2, 10 );
  1971. m_pCollapse->SetSize( 10, 10 );
  1972. m_pCollapse->SetVisible( true );
  1973. bool bCollapsed = m_pCollapse->IsSelected();
  1974. int x, y, w, t;
  1975. GetClientArea( x, y, w, t );
  1976. int yOffset = y;
  1977. // The cvar reminder goes on the top.
  1978. m_pCVarListLabel->SetPos( x, yOffset );
  1979. m_pCVarListLabel->SetWide( w );
  1980. NULL; // yOffset += m_pCVarListLabel->GetTall();
  1981. m_pCVarListLabel->SetVisible( false ); // m_pCVarListLabel->SetVisible( !bCollapsed );
  1982. m_pTotalUsageLabel->SetPos( x, yOffset );
  1983. m_pTotalUsageLabel->SetWide( w );
  1984. yOffset += m_pTotalUsageLabel->GetTall();
  1985. m_pTotalUsageLabel->SetVisible( !bCollapsed );
  1986. // Align the check boxes.
  1987. vgui::Panel *buttons[] = {
  1988. m_pSpecialTexs,
  1989. m_pShowTextureMemoryUsageOption,
  1990. m_pAllTextures,
  1991. m_pViewTextures,
  1992. m_pFilteringChk,
  1993. m_pResolveTexturePath,
  1994. m_pCopyToClipboardButton };
  1995. for ( int i=0; i < ARRAYSIZE( buttons ); i++ )
  1996. {
  1997. buttons[i]->SetPos( x, yOffset );
  1998. buttons[i]->SetWide( w/2 );
  1999. yOffset += buttons[i]->GetTall();
  2000. buttons[i]->SetVisible( !bCollapsed );
  2001. if ( buttons[i] == m_pViewTextures )
  2002. {
  2003. m_pViewTextures->SetWide( 170 );
  2004. int accumw = 170;
  2005. m_pAlpha->SetPos( x + accumw + 5, yOffset - m_pViewTextures->GetTall() );
  2006. m_pAlpha->SetWide( (accumw += 85, 85) );
  2007. m_pThumbWarnings->SetPos( x + accumw + 5, yOffset - m_pViewTextures->GetTall() );
  2008. m_pThumbWarnings->SetWide( (accumw += 85, 85) );
  2009. }
  2010. if ( buttons[i] == m_pFilteringChk )
  2011. {
  2012. m_pFilteringChk->SetWide( 60 );
  2013. int accumw = 60;
  2014. m_pFilteringText->SetPos( x + accumw + 5, yOffset - m_pFilteringChk->GetTall() );
  2015. m_pFilteringText->SetWide( ( accumw += 170, 170 ) );
  2016. m_pFilteringText->SetTall( m_pFilteringChk->GetTall() );
  2017. m_pFilteringText->SetVisible( !bCollapsed );
  2018. }
  2019. }
  2020. if ( bCollapsed )
  2021. {
  2022. int xOffset = 85, iWidth;
  2023. struct LayoutHorz_t
  2024. {
  2025. vgui::Panel *pPanel;
  2026. int iWidth;
  2027. }
  2028. layout[] =
  2029. {
  2030. { m_pTotalUsageLabel, 290 },
  2031. { m_pViewTextures, 170 },
  2032. { m_pAlpha, 60 },
  2033. { m_pAllTextures, 135 },
  2034. { m_pFilteringChk, 60 },
  2035. { m_pFilteringText, 130 }
  2036. };
  2037. for ( int k = 0; k < ARRAYSIZE( layout ); ++ k )
  2038. {
  2039. layout[ k ].pPanel->SetPos( xOffset, 2 );
  2040. iWidth = layout[ k ].iWidth;
  2041. iWidth = MIN( w - xOffset - 30, iWidth );
  2042. layout[ k ].pPanel->SetWide( iWidth );
  2043. layout[ k ].pPanel->SetVisible( iWidth > 50 );
  2044. if ( iWidth > 50 )
  2045. xOffset += iWidth + 5;
  2046. }
  2047. yOffset = y;
  2048. }
  2049. m_pAlpha->SetVisible( m_pViewTextures->IsSelected() );
  2050. m_pThumbWarnings->SetVisible( !bCollapsed && m_pViewTextures->IsSelected() );
  2051. m_pListPanel->SetBounds( x, yOffset, w, t - (yOffset - y) );
  2052. m_pViewPanel->SetBounds( x, yOffset, w, t - (yOffset - y) );
  2053. m_pListPanel->SetVisible( !mat_texture_list_view.GetBool() );
  2054. m_pViewPanel->SetVisible( mat_texture_list_view.GetBool() );
  2055. }
  2056. bool StripDirName( char *pFilename )
  2057. {
  2058. if ( pFilename[0] == 0 )
  2059. return false;
  2060. char *pLastSlash = pFilename;
  2061. while ( 1 )
  2062. {
  2063. char *pTestSlash = strchr( pLastSlash, '/' );
  2064. if ( !pTestSlash )
  2065. {
  2066. pTestSlash = strchr( pLastSlash, '\\' );
  2067. if ( !pTestSlash )
  2068. break;
  2069. }
  2070. pTestSlash++; // Skip past the slash.
  2071. pLastSlash = pTestSlash;
  2072. }
  2073. if ( pLastSlash == pFilename )
  2074. {
  2075. return false;
  2076. }
  2077. else
  2078. {
  2079. Assert( pLastSlash[-1] == '/' || pLastSlash[-1] == '\\' );
  2080. pLastSlash[-1] = 0;
  2081. return true;
  2082. }
  2083. }
  2084. static inline void ToLowerInplace( char *chBuffer )
  2085. {
  2086. for ( char *pch = chBuffer; *pch; ++ pch )
  2087. {
  2088. if ( V_isupper( *pch ) )
  2089. *pch = tolower( *pch );
  2090. }
  2091. }
  2092. void KeepSpecialKeys( KeyValues *textureList, bool bServiceKeys )
  2093. {
  2094. KeyValues *pNext;
  2095. for ( KeyValues *pCur=textureList->GetFirstSubKey(); pCur; pCur=pNext )
  2096. {
  2097. pNext = pCur->GetNextKey();
  2098. bool bIsServiceKey = false;
  2099. char const *szName = pCur->GetString( KEYNAME_NAME );
  2100. if ( StringHasPrefix( szName, "_" ) ||
  2101. StringHasPrefix( szName, "[" ) ||
  2102. !stricmp( szName, "backbuffer" ) ||
  2103. StringHasPrefix( szName, "colorcorrection" ) ||
  2104. !stricmp( szName, "depthbuffer" ) ||
  2105. !stricmp( szName, "frontbuffer" ) ||
  2106. !stricmp( szName, "normalize" ) ||
  2107. !*szName )
  2108. {
  2109. bIsServiceKey = true;
  2110. }
  2111. if ( bIsServiceKey != bServiceKeys )
  2112. {
  2113. textureList->RemoveSubKey( pCur );
  2114. }
  2115. else if ( bIsServiceKey )
  2116. {
  2117. pCur->SetInt( "SpecialTx", 1 );
  2118. }
  2119. }
  2120. }
  2121. void KeepKeysMatchingFilter( KeyValues *textureList, char const *szFilter )
  2122. {
  2123. if ( !szFilter || !*szFilter )
  2124. return;
  2125. char chFilter[MAX_PATH] = {0}, chName[MAX_PATH] = {0};
  2126. Q_strncpy( chFilter, szFilter, sizeof( chFilter ) - 1 );
  2127. ToLowerInplace( chFilter );
  2128. KeyValues *pNext;
  2129. for ( KeyValues *pCur=textureList->GetFirstSubKey(); pCur; pCur=pNext )
  2130. {
  2131. pNext = pCur->GetNextKey();
  2132. char const *szName = pCur->GetString( KEYNAME_NAME );
  2133. Q_strncpy( chName, szName, sizeof( chName ) - 1 );
  2134. ToLowerInplace( chName );
  2135. if ( !strstr( chName, chFilter ) )
  2136. {
  2137. textureList->RemoveSubKey( pCur );
  2138. }
  2139. }
  2140. }
  2141. void CTextureListPanel::UpdateTotalUsageLabel()
  2142. {
  2143. char data[1024], kb1[20], kb2[20], kb3[20];
  2144. FmtCommaNumber( kb1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_BOUND_LAST_FRAME ) + 511) / 1024 );
  2145. FmtCommaNumber( kb2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_TOTAL_LOADED ) + 511) / 1024 );
  2146. FmtCommaNumber( kb3, m_numDisplayedSizeKB );
  2147. if ( bool bCollapsed = m_pCollapse->IsSelected() )
  2148. {
  2149. char const *szTitle = "";
  2150. Q_snprintf( data, sizeof( data ), "%s[F %s Kb] / [T %s Kb] / [S %s Kb]", szTitle, kb1, kb2, kb3 );
  2151. }
  2152. else
  2153. {
  2154. char const *szTitle = "Texture Memory Usage";
  2155. char kbMip1[ 20 ], kbMip2[ 20 ];
  2156. FmtCommaNumber( kbMip1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_ESTIMATE_PICMIP_1 ) + 511) / 1024 );
  2157. FmtCommaNumber( kbMip2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_ESTIMATE_PICMIP_2 ) + 511) / 1024 );
  2158. Q_snprintf( data, sizeof( data ), "%s: frame %s Kb / total %s Kb ( picmip1 = %s Kb, picmip2 = %s Kb ) / shown %s Kb", szTitle, kb1, kb2, kbMip1, kbMip2, kb3 );
  2159. }
  2160. wchar_t unicodeString[1024];
  2161. g_pVGuiLocalize->ConvertANSIToUnicode( data, unicodeString, sizeof( unicodeString ) );
  2162. m_pTotalUsageLabel->SetText( unicodeString );
  2163. }
  2164. void CTextureListPanel::OnTextChanged( void )
  2165. {
  2166. OnCommand( "FilteringTxt" );
  2167. }
  2168. void CTextureListPanel::OnCommand( const char *command )
  2169. {
  2170. if ( !Q_stricmp( command, "Close" ) )
  2171. {
  2172. vgui::Frame::OnCommand( command );
  2173. return;
  2174. }
  2175. if ( !Q_stricmp( command, "Collapse" ) )
  2176. {
  2177. InvalidateLayout();
  2178. return;
  2179. }
  2180. if ( !Q_stricmp( command, "ShowAlpha" ) )
  2181. {
  2182. m_pViewPanel->SetPaintAlpha( m_pAlpha->IsSelected() );
  2183. return;
  2184. }
  2185. if ( !Q_stricmp( command, "ThumbWarnings" ) )
  2186. {
  2187. g_warn_enable = m_pThumbWarnings->IsSelected();
  2188. return;
  2189. }
  2190. if ( !Q_stricmp( command, "ViewThumbnails" ) )
  2191. {
  2192. InvalidateLayout();
  2193. return;
  2194. }
  2195. if ( !Q_stricmp( command, COPYTOCLIPBOARD_CMDNAME ) )
  2196. {
  2197. CopyListPanelToClipboard( m_pListPanel );
  2198. return;
  2199. }
  2200. mat_texture_list_on_f();
  2201. InvalidateLayout();
  2202. }
  2203. bool CTextureListPanel::UpdateDisplayedItem( KeyValues *pDispData, KeyValues *kv )
  2204. {
  2205. // Update the item?
  2206. bool bUpdate = false;
  2207. // do the stuff that changes often separately.
  2208. if ( pDispData->GetInt( KEYNAME_BINDS_FRAME ) != kv->GetInt( KEYNAME_BINDS_FRAME ) )
  2209. {
  2210. pDispData->SetInt( KEYNAME_BINDS_FRAME, kv->GetInt( KEYNAME_BINDS_FRAME ) );
  2211. bUpdate = true;
  2212. }
  2213. if ( pDispData->GetInt( KEYNAME_BINDS_MAX ) != kv->GetInt( KEYNAME_BINDS_MAX ) )
  2214. {
  2215. pDispData->SetInt( KEYNAME_BINDS_MAX, kv->GetInt( KEYNAME_BINDS_MAX ) );
  2216. bUpdate = true;
  2217. }
  2218. // stuff that changes less frequently
  2219. if( pDispData->GetInt( KEYNAME_SIZE ) != kv->GetInt( KEYNAME_SIZE ) ||
  2220. pDispData->GetInt( KEYNAME_WIDTH ) != kv->GetInt( KEYNAME_WIDTH ) ||
  2221. pDispData->GetInt( KEYNAME_HEIGHT ) != kv->GetInt( KEYNAME_HEIGHT ) ||
  2222. Q_stricmp( pDispData->GetString( KEYNAME_FORMAT ), kv->GetString( KEYNAME_FORMAT ) ) != 0 ||
  2223. Q_stricmp( pDispData->GetString( KEYNAME_PATH ), kv->GetString( KEYNAME_PATH ) ) != 0 ||
  2224. Q_stricmp( pDispData->GetString( KEYNAME_TEXTURE_GROUP ), kv->GetString( KEYNAME_TEXTURE_GROUP ) ) != 0 )
  2225. {
  2226. pDispData->SetInt( KEYNAME_SIZE, kv->GetInt( KEYNAME_SIZE ) );
  2227. pDispData->SetInt( KEYNAME_WIDTH, kv->GetInt( KEYNAME_WIDTH ) );
  2228. pDispData->SetInt( KEYNAME_HEIGHT, kv->GetInt( KEYNAME_HEIGHT ) );
  2229. pDispData->SetString( KEYNAME_FORMAT, kv->GetString( KEYNAME_FORMAT ) );
  2230. pDispData->SetString( KEYNAME_PATH, kv->GetString( KEYNAME_PATH ) );
  2231. pDispData->SetString( KEYNAME_TEXTURE_GROUP, kv->GetString( KEYNAME_TEXTURE_GROUP ) );
  2232. bUpdate = true;
  2233. }
  2234. return bUpdate;
  2235. }
  2236. int CTextureListPanel::AddListItem( KeyValues *kv )
  2237. {
  2238. int iItem = m_pListPanel->GetItem( kv->GetString( KEYNAME_NAME ) );
  2239. if ( iItem == -1 )
  2240. {
  2241. // Set this so the GetItem() call above can use the key's name (as opposed to the value of its
  2242. // "Name" subkey) to find this texture again.
  2243. kv->SetName( kv->GetString( KEYNAME_NAME ) );
  2244. // Add this one.
  2245. iItem = m_pListPanel->AddItem( kv, 0, false, false );
  2246. m_pViewPanel->InvalidateLayout();
  2247. }
  2248. else
  2249. {
  2250. KeyValues *pValues = m_pListPanel->GetItem( iItem );
  2251. bool bNeedUpdate = UpdateDisplayedItem( pValues, kv );
  2252. if( bNeedUpdate )
  2253. {
  2254. m_pListPanel->ApplyItemChanges( iItem );
  2255. m_pViewPanel->Repaint();
  2256. }
  2257. }
  2258. return iItem;
  2259. }
  2260. //-----------------------------------------------------------------------------
  2261. // Purpose:
  2262. //-----------------------------------------------------------------------------
  2263. void CTextureListPanel::OnTurnedOn()
  2264. {
  2265. if ( g_bRecursiveRequestToShowTextureList )
  2266. return;
  2267. if ( m_pListPanel )
  2268. m_pListPanel->DeleteAllItems();
  2269. if ( CRenderTextureEditor *pRe = m_pViewPanel->GetRenderTxEditor() )
  2270. pRe->Close();
  2271. }
  2272. void CTextureListPanel::Close()
  2273. {
  2274. mat_texture_list_off_f();
  2275. }
  2276. void CTextureListPanel::EndPaint()
  2277. {
  2278. UpdateTotalUsageLabel();
  2279. }
  2280. void CTextureListPanel::Paint()
  2281. {
  2282. VPROF( "CTextureListPanel::Paint" );
  2283. if ( !m_hFont )
  2284. return;
  2285. struct EndPaint_t
  2286. {
  2287. CTextureListPanel *m_p;
  2288. EndPaint_t( CTextureListPanel *p ) : m_p( p ) {}
  2289. ~EndPaint_t()
  2290. {
  2291. m_p->EndPaint();
  2292. }
  2293. } endpaint( this );
  2294. if ( !mat_texture_list.GetBool() )
  2295. return;
  2296. MatTextureModificationRecorded();
  2297. if ( !g_pMaterialSystemDebugTextureInfo->IsDebugTextureListFresh( 1 ) )
  2298. return;
  2299. CSmartTextureKeyValues textureList;
  2300. if ( !textureList.Get() )
  2301. return;
  2302. CRenderTextureEditor *pRte = m_pViewPanel->GetRenderTxEditor();
  2303. if ( ( s_eTxListPanelRequest == TXR_RUNNING ) &&
  2304. pRte->IsVisible() )
  2305. {
  2306. KeyValues *kv = NULL;
  2307. int iHint = 0;
  2308. pRte->GetDispInfo( kv, iHint );
  2309. if ( kv && iHint )
  2310. {
  2311. KeyValues *plv = ( m_pListPanel->IsValidItemID( iHint ) ? m_pListPanel->GetItem( iHint ) : NULL );
  2312. if ( plv && !strcmp( plv->GetString( KEYNAME_NAME ), kv->GetString( KEYNAME_NAME ) ) )
  2313. {
  2314. KeyValues *pValData = plv->GetFirstValue(), *pValRendered = kv->GetFirstValue();
  2315. for ( ; pValData && pValRendered; pValData = pValData->GetNextValue(), pValRendered = pValRendered->GetNextValue() )
  2316. {
  2317. if ( strcmp( pValData->GetString(), pValRendered->GetString() ) )
  2318. break;
  2319. }
  2320. if ( pValData || pValRendered ) // Difference found
  2321. pRte->SetDispInfo( plv, iHint );
  2322. }
  2323. else
  2324. kv = NULL;
  2325. }
  2326. if ( 0 ) // if ( !kv )
  2327. {
  2328. pRte->Close();
  2329. pRte->SetDispInfo( NULL, 0 );
  2330. }
  2331. }
  2332. // If we are fetching all textures, then stop loading material system:
  2333. if ( mat_texture_list_all.GetBool() )
  2334. {
  2335. static int s_nFramesForAllTextures = 0;
  2336. if ( s_eTxListPanelRequest == TXR_RUNNING )
  2337. {
  2338. if ( -- s_nFramesForAllTextures <= 0 )
  2339. {
  2340. mat_texture_list.SetValue( 0 );
  2341. s_eTxListPanelRequest = TXR_SHOW; // Keep displaying our panel
  2342. }
  2343. }
  2344. else
  2345. {
  2346. s_eTxListPanelRequest = TXR_RUNNING;
  2347. s_nFramesForAllTextures = mat_texture_list_all_frames.GetInt();
  2348. }
  2349. }
  2350. else
  2351. {
  2352. if ( s_eTxListPanelRequest == TXR_SHOW )
  2353. {
  2354. // Either first show or turned off "all textures"
  2355. m_pListPanel->RemoveAll();
  2356. m_pViewPanel->InvalidateLayout();
  2357. s_eTxListPanelRequest = TXR_RUNNING;
  2358. return;
  2359. }
  2360. }
  2361. CBitVec<4096 * 8> itemsTouched;
  2362. // Remove the textures we don't care for
  2363. KeepSpecialKeys( textureList.Get(), m_pSpecialTexs->IsSelected() );
  2364. // If filtering is enabled, then do filtering
  2365. if ( m_pFilteringChk->IsSelected() && m_pFilteringText->GetTextLength() )
  2366. {
  2367. char chFilterString[ MAX_PATH ];
  2368. m_pFilteringText->GetText( chFilterString, sizeof( chFilterString ) - 1 );
  2369. chFilterString[ sizeof( chFilterString ) - 1 ] = 0;
  2370. KeepKeysMatchingFilter( textureList.Get(), chFilterString );
  2371. }
  2372. // Remove scaleform texture
  2373. if ( 1 )
  2374. {
  2375. KeyValues *pNext;
  2376. for ( KeyValues *pCur=textureList.Get()->GetFirstSubKey(); pCur; pCur=pNext )
  2377. {
  2378. pNext = pCur->GetNextKey();
  2379. char const *szName = pCur->GetString( KEYNAME_NAME );
  2380. char chName[MAX_PATH] = {0};
  2381. Q_strncpy( chName, szName, sizeof( chName ) - 1 );
  2382. ToLowerInplace( chName );
  2383. if ( V_stristr( chName, "ScaleformDynamic" ) )
  2384. {
  2385. textureList.Get()->RemoveSubKey( pCur );
  2386. }
  2387. }
  2388. }
  2389. // Compute the total size of the displayed textures
  2390. int cbTotalDisplayedSizeInBytes = 0;
  2391. for ( KeyValues *pCur=textureList.Get()->GetFirstSubKey(); pCur; pCur=pCur->GetNextKey() )
  2392. {
  2393. int sizeInBytes = pCur->GetInt( KEYNAME_SIZE );
  2394. // Accumulate
  2395. cbTotalDisplayedSizeInBytes += sizeInBytes;
  2396. // Factor in frames
  2397. int numCount = pCur->GetInt( "Count" );
  2398. if ( numCount > 1 )
  2399. sizeInBytes *= numCount;
  2400. // Size is in kilobytes.
  2401. int sizeInKilo = ( sizeInBytes + 511 ) / 1024;
  2402. pCur->SetInt( KEYNAME_SIZE, sizeInKilo );
  2403. if ( m_pResolveTexturePath->IsSelected() )
  2404. {
  2405. char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0};
  2406. Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", pCur->GetString( KEYNAME_NAME ) );
  2407. char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 );
  2408. if ( szResolvedName )
  2409. {
  2410. pCur->SetString( KEYNAME_PATH, szResolvedName );
  2411. }
  2412. }
  2413. int iItem = AddListItem( pCur );
  2414. if ( iItem < itemsTouched.GetNumBits() )
  2415. itemsTouched.Set( iItem );
  2416. }
  2417. // Set the displayed size
  2418. m_numDisplayedSizeKB = ( cbTotalDisplayedSizeInBytes + 511 ) / 1024;
  2419. // Now remove from view items that weren't used.
  2420. int iNext, numRemoved = 0;
  2421. for ( int iCur=m_pListPanel->FirstItem(); iCur != m_pListPanel->InvalidItemID(); iCur=iNext )
  2422. {
  2423. iNext = m_pListPanel->NextItem( iCur );
  2424. if ( iCur >= itemsTouched.GetNumBits() || !itemsTouched.Get( iCur ) )
  2425. {
  2426. m_pListPanel->RemoveItem( iCur );
  2427. ++ numRemoved;
  2428. }
  2429. }
  2430. // Sorting in list panel
  2431. {
  2432. int iPri, iSec;
  2433. bool bAsc;
  2434. m_pListPanel->GetSortColumnEx( iPri, iSec, bAsc );
  2435. iSec = 0; // always secondary sort by name
  2436. m_pListPanel->SetSortColumnEx( iPri, iSec, bAsc );
  2437. m_pListPanel->SortList();
  2438. }
  2439. if ( numRemoved )
  2440. {
  2441. m_pViewPanel->InvalidateLayout();
  2442. }
  2443. }
  2444. // ------------------------------------------------------------------------------ //
  2445. // Global functions.
  2446. // ------------------------------------------------------------------------------ //
  2447. void VGui_UpdateTextureListPanel()
  2448. {
  2449. if ( mat_show_texture_memory_usage.GetInt() )
  2450. {
  2451. con_nprint_t info;
  2452. info.index = 4;
  2453. info.time_to_live = 0.2;
  2454. info.color[0] = 1;
  2455. info.color[1] = 0.5;
  2456. info.color[2] = 0;
  2457. info.fixed_width_font = true;
  2458. char kb1[20], kb2[20];
  2459. FmtCommaNumber( kb1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_BOUND_LAST_FRAME ) + 511) / 1024 );
  2460. FmtCommaNumber( kb2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_TOTAL_LOADED ) + 511) / 1024 );
  2461. Con_NXPrintf( &info, "Texture Memory Usage: %s Kb / %s Kb", kb1, kb2 );
  2462. }
  2463. MatViewOverride::DisplaySelectedTextures();
  2464. if ( IsX360() )
  2465. return;
  2466. g_pMaterialSystemDebugTextureInfo->EnableGetAllTextures( mat_texture_list_all.GetBool() );
  2467. g_pMaterialSystemDebugTextureInfo->EnableDebugTextureList( ( mat_texture_list.GetInt() <= 0 ) ? false : true );
  2468. bool bShouldDrawTxListPanel = g_pTextureListPanel->ShouldDraw();
  2469. if ( g_pTextureListPanel->IsVisible() != bShouldDrawTxListPanel )
  2470. {
  2471. g_pTextureListPanel->SetVisible( bShouldDrawTxListPanel );
  2472. bShouldDrawTxListPanel ? mat_texture_list_on_f() : mat_texture_list_off_f();
  2473. }
  2474. }
  2475. void CL_CreateTextureListPanel( vgui::Panel *parent )
  2476. {
  2477. g_pTextureListPanel = new CTextureListPanel( parent );
  2478. }
  2479. extern ConVar sv_cheats;
  2480. void mat_texture_list_on_f()
  2481. {
  2482. if ( !sv_cheats.GetBool() )
  2483. return;
  2484. mat_texture_list.SetValue( 1 );
  2485. s_eTxListPanelRequest = TXR_SHOW;
  2486. g_pTextureListPanel->OnTurnedOn();
  2487. MatViewOverride::RequestSelectNone();
  2488. }
  2489. void mat_texture_list_off_f()
  2490. {
  2491. mat_texture_list.SetValue( 0 );
  2492. s_eTxListPanelRequest = TXR_HIDE;
  2493. }
  2494. #endif