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.
3380 lines
94 KiB
3380 lines
94 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
|
|
#include "client_pch.h" |
|
#include "ivideomode.h" |
|
#include "client_class.h" |
|
#include "icliententitylist.h" |
|
#include "vgui_basepanel.h" |
|
#include <vgui_controls/Controls.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IScheme.h> |
|
#include <vgui/IVGui.h> |
|
#include <vgui_controls/Frame.h> |
|
#include <vgui_controls/TreeView.h> |
|
#include <vgui_controls/ListPanel.h> |
|
#include <vgui_controls/ListViewPanel.h> |
|
#include <vgui_controls/TreeViewListControl.h> |
|
#include <vgui/ISystem.h> |
|
#include "tier0/vprof.h" |
|
#include "KeyValues.h" |
|
#include "vgui_helpers.h" |
|
#include "utlsymbol.h" |
|
#include "tier1/UtlStringMap.h" |
|
#include "bitvec.h" |
|
#include "utldict.h" |
|
#include "vgui/ILocalize.h" |
|
#include "con_nprint.h" |
|
#include "gl_matsysiface.h" |
|
|
|
#include "VGuiMatSurface/IMatSystemSurface.h" |
|
#include "materialsystem/imaterial.h" |
|
#include "materialsystem/imaterialvar.h" |
|
#include "materialsystem/imesh.h" |
|
#include "materialsystem/idebugtextureinfo.h" |
|
#include "materialsystem/itexture.h" |
|
#include "vtf/vtf.h" |
|
#include "tier2/tier2.h" |
|
#include "smartptr.h" |
|
|
|
#include "igame.h" |
|
|
|
#include "client.h" |
|
|
|
#include "tier2/p4helpers.h" |
|
#include "p4lib/ip4.h" |
|
#include "ivtex.h" |
|
#include "tier2/fileutils.h" |
|
|
|
// For character manipulations isupper/tolower |
|
#include <ctype.h> |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
#define KEYNAME_NAME "Name" |
|
#define KEYNAME_PATH "Path" |
|
#define KEYNAME_BINDS_MAX "BindsMax" |
|
#define KEYNAME_BINDS_FRAME "BindsFrame" |
|
#define KEYNAME_SIZE "Size" |
|
#define KEYNAME_FORMAT "Format" |
|
#define KEYNAME_WIDTH "Width" |
|
#define KEYNAME_HEIGHT "Height" |
|
#define KEYNAME_TEXTURE_GROUP "TexGroup" |
|
|
|
#define COPYTOCLIPBOARD_CMDNAME "CopyToClipboard" |
|
|
|
#if defined( _X360 ) |
|
CON_COMMAND( mat_get_textures, "VXConsole command" ) |
|
{ |
|
g_pMaterialSystemDebugTextureInfo->EnableDebugTextureList( true ); |
|
g_pMaterialSystemDebugTextureInfo->EnableGetAllTextures( args.ArgC() >= 2 && ( Q_stricmp( args[1], "all" ) == 0 ) ); |
|
} |
|
#endif |
|
|
|
static ConVar mat_texture_list( "mat_texture_list", "0", FCVAR_CHEAT, "For debugging, show a list of used textures per frame" ); |
|
|
|
static enum TxListPanelRequest |
|
{ |
|
TXR_NONE, |
|
TXR_SHOW, |
|
TXR_RUNNING, |
|
TXR_HIDE |
|
} s_eTxListPanelRequest = TXR_NONE; |
|
|
|
IVTex* VTex_Load( CSysModule** pModule ); |
|
void VTex_Unload( CSysModule *pModule ); |
|
void* CubemapsFSFactory( const char *pName, int *pReturnCode ); |
|
bool StripDirName( char *pFilename ); |
|
|
|
// These are here so you can bind a key to +mat_texture_list and toggle it on and off. |
|
void mat_texture_list_on_f(); |
|
void mat_texture_list_off_f(); |
|
|
|
ConCommand mat_texture_list_on( "+mat_texture_list", mat_texture_list_on_f ); |
|
ConCommand mat_texture_list_off( "-mat_texture_list", mat_texture_list_off_f ); |
|
|
|
ConVar mat_texture_list_all( "mat_texture_list_all", "0", FCVAR_NEVER_AS_STRING|FCVAR_CHEAT, "If this is nonzero, then the texture list panel will show all currently-loaded textures." ); |
|
|
|
ConVar mat_texture_list_view( "mat_texture_list_view", "1", FCVAR_NEVER_AS_STRING|FCVAR_CHEAT, "If this is nonzero, then the texture list panel will render thumbnails of currently-loaded textures." ); |
|
|
|
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." ); |
|
|
|
|
|
static int g_warn_texkbytes = 1499; |
|
static int g_warn_texdimensions = 1024; |
|
static bool g_warn_enable = true; |
|
static bool g_cursorset = false; |
|
|
|
class CTextureListPanel; |
|
static CTextureListPanel *g_pTextureListPanel = NULL; |
|
static bool g_bRecursiveRequestToShowTextureList = false; |
|
static int g_nSaveQueueState = INT_MIN; |
|
|
|
|
|
// |
|
// A class to mimic a list view |
|
// |
|
|
|
namespace vgui |
|
{ |
|
|
|
|
|
class TileViewPanelEx : public Panel |
|
{ |
|
DECLARE_CLASS_SIMPLE( TileViewPanelEx, Panel ); |
|
|
|
public: |
|
TileViewPanelEx( Panel *parent, const char *panelName ); |
|
~TileViewPanelEx(); |
|
|
|
public: |
|
virtual void SetFont( HFont hFont ); |
|
virtual HFont GetFont(); |
|
|
|
public: |
|
enum HitTest_t |
|
{ |
|
HT_NOTHING = 0, |
|
HT_TILE |
|
}; |
|
virtual int HitTest( int x, int y, int &iTile ); |
|
virtual bool GetTileOrg( int iTile, int &x, int &y ); |
|
|
|
protected: // Overrides for contents |
|
virtual int GetNumTiles() = 0; |
|
virtual void GetTileSize( int &wide, int &tall ) = 0; |
|
virtual void RenderTile( int iTile, int x, int y ) = 0; |
|
|
|
protected: |
|
// Handlers |
|
virtual void OnMouseWheeled( int delta ); |
|
virtual void OnSizeChanged( int wide, int tall ); |
|
virtual void PerformLayout(); |
|
virtual void Paint(); |
|
virtual void ApplySchemeSettings( IScheme *pScheme ); |
|
MESSAGE_FUNC( OnSliderMoved, "ScrollBarSliderMoved" ); |
|
|
|
protected: |
|
virtual bool ComputeLayoutInfo(); |
|
int m_li_numTiles; //!< Total number of tiles |
|
int m_li_numVisibleTiles; //!< Number of tiles fitting in the client area |
|
int m_li_wide, m_li_tall; //!< Tile area width/height |
|
int m_li_wideItem, m_li_tallItem; //!< Every item width/height |
|
int m_li_colVisible, m_li_rowVisible; //!< Num columns/rows fitting in the client area |
|
int m_li_rowNeeded; //!< Num rows required to fit all numTiles |
|
int m_li_startTile, m_li_endTile; //!< Start/end tile that are rendered in the client area |
|
|
|
private: |
|
ScrollBar *m_hbar; |
|
HFont m_hFont; |
|
}; |
|
|
|
|
|
|
|
// |
|
// Implementation details |
|
// |
|
|
|
TileViewPanelEx::TileViewPanelEx( Panel *parent, const char *panelName ) : |
|
Panel( parent, panelName ), |
|
m_hbar( NULL ), |
|
m_hFont( INVALID_FONT ) |
|
{ |
|
m_hbar = new ScrollBar( this, "VerticalScrollBar", true ); |
|
m_hbar->AddActionSignalTarget( this ); |
|
m_hbar->SetVisible( true ); |
|
} |
|
|
|
TileViewPanelEx::~TileViewPanelEx() |
|
{ |
|
delete m_hbar; |
|
} |
|
|
|
void TileViewPanelEx::SetFont( HFont hFont ) |
|
{ |
|
m_hFont = hFont; |
|
Repaint(); |
|
} |
|
|
|
HFont TileViewPanelEx::GetFont() |
|
{ |
|
return m_hFont; |
|
} |
|
|
|
int TileViewPanelEx::HitTest( int x, int y, int &iTile ) |
|
{ |
|
iTile = -1; |
|
|
|
if ( !ComputeLayoutInfo() ) |
|
return HT_NOTHING; |
|
|
|
int hitCol = ( x / m_li_wideItem ); |
|
int hitRow = ( y / m_li_tallItem ); |
|
|
|
if ( hitCol >= m_li_colVisible ) |
|
return HT_NOTHING; |
|
if ( hitRow > m_li_rowVisible ) |
|
return HT_NOTHING; |
|
|
|
int hitTile = m_li_startTile + hitCol + hitRow * m_li_colVisible; |
|
if ( hitTile >= m_li_endTile ) |
|
return HT_NOTHING; |
|
|
|
// Hit tile |
|
iTile = hitTile; |
|
return HT_TILE; |
|
} |
|
|
|
bool TileViewPanelEx::GetTileOrg( int iTile, int &x, int &y ) |
|
{ |
|
if ( m_li_colVisible <= 0 ) |
|
return false; |
|
if ( iTile < m_li_startTile || iTile >= m_li_endTile ) |
|
return false; |
|
|
|
x = 0 + ( ( iTile - m_li_startTile ) % m_li_colVisible ) * m_li_wideItem; |
|
y = 0 + ( ( iTile - m_li_startTile ) / m_li_colVisible ) * m_li_tallItem; |
|
|
|
return true; |
|
} |
|
|
|
void TileViewPanelEx::OnMouseWheeled( int delta ) |
|
{ |
|
if ( m_hbar->IsVisible() ) |
|
{ |
|
int val = m_hbar->GetValue(); |
|
val -= delta; |
|
m_hbar->SetValue( val ); |
|
} |
|
} |
|
|
|
void TileViewPanelEx::OnSizeChanged( int wide, int tall ) |
|
{ |
|
BaseClass::OnSizeChanged( wide, tall ); |
|
InvalidateLayout(); |
|
Repaint(); |
|
} |
|
|
|
void TileViewPanelEx::PerformLayout() |
|
{ |
|
int numTiles = GetNumTiles(); |
|
m_hbar->SetVisible( false ); |
|
|
|
int wide, tall; |
|
GetSize( wide, tall ); |
|
wide -= m_hbar->GetWide(); |
|
|
|
m_hbar->SetPos( wide - 2, 0 ); |
|
m_hbar->SetTall( tall ); |
|
|
|
if ( !numTiles ) |
|
return; |
|
|
|
int wideItem = 1, tallItem = 1; |
|
GetTileSize( wideItem, tallItem ); |
|
if ( !wideItem || !tallItem ) |
|
return; |
|
|
|
int colVisible = wide / wideItem; |
|
int rowVisible = tall / tallItem; |
|
if ( rowVisible <= 0 || colVisible <= 0 ) |
|
return; |
|
|
|
int rowNeeded = ( numTiles + colVisible - 1 ) / colVisible; |
|
|
|
int startTile = 0; |
|
if ( rowNeeded > rowVisible ) |
|
{ |
|
m_hbar->SetRange( 0, rowNeeded ); |
|
m_hbar->SetRangeWindow( rowVisible ); |
|
m_hbar->SetButtonPressedScrollValue( 1 ); |
|
|
|
m_hbar->SetVisible( true ); |
|
m_hbar->InvalidateLayout(); |
|
|
|
int val = m_hbar->GetValue(); |
|
startTile = val * colVisible; |
|
} |
|
} |
|
|
|
bool TileViewPanelEx::ComputeLayoutInfo() |
|
{ |
|
m_li_numTiles = GetNumTiles(); |
|
if ( !m_li_numTiles ) |
|
return false; |
|
|
|
GetSize( m_li_wide, m_li_tall ); |
|
m_li_wide -= m_hbar->GetWide(); |
|
|
|
m_li_wideItem = 1, m_li_tallItem = 1; |
|
GetTileSize( m_li_wideItem, m_li_tallItem ); |
|
if ( !m_li_wideItem || !m_li_tallItem ) |
|
return false; |
|
|
|
m_li_colVisible = m_li_wide / m_li_wideItem; |
|
m_li_rowVisible = m_li_tall / m_li_tallItem; |
|
if ( m_li_rowVisible <= 0 || m_li_colVisible <= 0 ) |
|
return false; |
|
|
|
m_li_rowNeeded = ( m_li_numTiles + m_li_colVisible - 1 ) / m_li_colVisible; |
|
m_li_numVisibleTiles = m_li_colVisible * m_li_rowVisible; |
|
|
|
m_li_startTile = 0; |
|
if ( m_li_rowNeeded > m_li_rowVisible ) |
|
{ |
|
int val = m_hbar->GetValue(); |
|
m_li_startTile = val * m_li_colVisible; |
|
} |
|
|
|
if ( m_li_startTile >= m_li_numTiles ) |
|
m_li_startTile = m_li_numTiles - m_li_numVisibleTiles; |
|
if ( m_li_startTile < 0 ) |
|
m_li_startTile = 0; |
|
|
|
m_li_endTile = m_li_startTile + m_li_numVisibleTiles + m_li_colVisible; // draw the partly visible items |
|
if ( m_li_endTile > m_li_numTiles ) |
|
m_li_endTile = m_li_numTiles; |
|
|
|
return true; |
|
} |
|
|
|
void TileViewPanelEx::Paint() |
|
{ |
|
BaseClass::Paint(); |
|
|
|
// Now render all our tiles |
|
if ( !ComputeLayoutInfo() ) |
|
return; |
|
|
|
for ( int iRenderTile = m_li_startTile; iRenderTile < m_li_endTile; ++ iRenderTile ) |
|
{ |
|
int x = 0 + ( ( iRenderTile - m_li_startTile ) % m_li_colVisible ) * m_li_wideItem; |
|
int y = 0 + ( ( iRenderTile - m_li_startTile ) / m_li_colVisible ) * m_li_tallItem; |
|
RenderTile( iRenderTile, x, y ); |
|
} |
|
} |
|
|
|
void TileViewPanelEx::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
SetBgColor( GetSchemeColor( "ListPanel.BgColor", pScheme ) ); |
|
SetBorder( pScheme->GetBorder("ButtonDepressedBorder" ) ); |
|
|
|
SetFont( pScheme->GetFont( "Default", IsProportional() ) ); |
|
} |
|
|
|
void TileViewPanelEx::OnSliderMoved() |
|
{ |
|
InvalidateLayout(); |
|
Repaint(); |
|
} |
|
|
|
|
|
|
|
}; // namespace vgui |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Material access |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
class CAutoMatSysDebugMode |
|
{ |
|
public: |
|
CAutoMatSysDebugMode(); |
|
~CAutoMatSysDebugMode(); |
|
|
|
void ScheduleCleanupTextureVar( IMaterialVar *pVar ); |
|
|
|
protected: |
|
bool bOldDebugMode; |
|
CUtlRBTree< IMaterialVar * > arrCleanupVars; |
|
}; |
|
|
|
CAutoMatSysDebugMode::CAutoMatSysDebugMode() : |
|
arrCleanupVars( DefLessFunc(IMaterialVar *) ) |
|
{ |
|
g_pMaterialSystem->Flush(); |
|
bOldDebugMode = g_pMaterialSystemDebugTextureInfo->SetDebugTextureRendering( true ); |
|
} |
|
|
|
CAutoMatSysDebugMode::~CAutoMatSysDebugMode() |
|
{ |
|
g_pMaterialSystem->Flush(); |
|
g_pMaterialSystemDebugTextureInfo->SetDebugTextureRendering( bOldDebugMode ); |
|
|
|
for ( uint32 k = 0; k < arrCleanupVars.Count(); ++ k ) |
|
{ |
|
IMaterialVar *pVar = arrCleanupVars.Element( k ); |
|
pVar->SetUndefined(); |
|
} |
|
} |
|
|
|
void CAutoMatSysDebugMode::ScheduleCleanupTextureVar( IMaterialVar *pVar ) |
|
{ |
|
if ( !pVar ) |
|
return; |
|
|
|
arrCleanupVars.InsertIfNotFound( pVar ); |
|
} |
|
|
|
static IMaterial * UseDebugMaterial( char const *szMaterial, ITexture *pMatTexture, CAutoMatSysDebugMode *pRestoreVars ) |
|
{ |
|
if ( !szMaterial || !pMatTexture ) |
|
return NULL; |
|
|
|
bool foundVar; |
|
|
|
IMaterial *pMaterial = materials->FindMaterial( szMaterial, TEXTURE_GROUP_OTHER, false ); |
|
// IMaterial *pMaterial = materials->FindMaterial( "debug/debugempty", TEXTURE_GROUP_OTHER, false ); |
|
if ( !pMaterial ) |
|
return NULL; |
|
|
|
IMaterialVar *BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); |
|
// IMaterialVar *BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); |
|
if ( !foundVar || !BaseTextureVar ) |
|
return NULL; |
|
|
|
IMaterialVar *FrameVar = pMaterial->FindVar( "$frame", &foundVar, false ); |
|
if ( foundVar && FrameVar ) |
|
{ |
|
int numAnimFrames = pMatTexture->GetNumAnimationFrames(); |
|
|
|
if ( pMatTexture->IsRenderTarget() || pMatTexture->IsProcedural() ) |
|
numAnimFrames = 0; // Cannot use the stencil parts of the render targets and shouldn't use the other frames of procedural textures |
|
|
|
FrameVar->SetIntValue( ( numAnimFrames > 0 ) ? ( g_ClientGlobalVariables.tickcount % numAnimFrames ) : 0 ); |
|
} |
|
|
|
BaseTextureVar->SetTextureValue( pMatTexture ); |
|
|
|
if ( pRestoreVars ) |
|
{ |
|
pRestoreVars->ScheduleCleanupTextureVar( BaseTextureVar ); |
|
} |
|
|
|
return pMaterial; |
|
} |
|
|
|
static void RenderTexturedRect( vgui::Panel *pPanel, IMaterial *pMaterial, int x, int y, int x1, int y1, int xoff = 0, int yoff = 0 ) |
|
{ |
|
CAutoMatSysDebugMode auto_matsysdebugmode; |
|
|
|
int tall = pPanel->GetTall(); |
|
float fHeightUV = 1.0f; |
|
if ( y1 > tall ) |
|
{ |
|
fHeightUV = float( tall - y ) / float( y1 - y ); |
|
y1 = tall; |
|
} |
|
if ( y1 <= y ) |
|
return; |
|
|
|
pPanel->LocalToScreen( x, y ); |
|
pPanel->LocalToScreen( x1, y1 ); |
|
|
|
x += xoff; x1 += xoff; y += yoff; y1 += yoff; |
|
|
|
CMatRenderContextPtr pRenderContext( materials ); |
|
pRenderContext->Bind( pMaterial ); |
|
IMesh* pMesh = pRenderContext->GetDynamicMesh( true ); |
|
|
|
CMeshBuilder meshBuilder; |
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); |
|
|
|
meshBuilder.Position3f( x, y, 0.0f ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, 0.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( x1, y, 0.0f ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, 0.0f ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( x1, y1, 0.0f ); |
|
meshBuilder.TexCoord2f( 0, 1.0f, fHeightUV ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Position3f( x, y1, 0.0f ); |
|
meshBuilder.TexCoord2f( 0, 0.0f, fHeightUV ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.End(); |
|
pMesh->Draw(); |
|
} |
|
|
|
static bool ShallWarnTx( KeyValues *kv, ITexture *tx ) |
|
{ |
|
if ( !tx ) |
|
{ |
|
return false; |
|
} |
|
|
|
if ( tx->GetFlags() & ( TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA ) ) |
|
return true; |
|
|
|
if ( stricmp( "DXT1", kv->GetString( KEYNAME_FORMAT ) ) && stricmp( "DXT5", kv->GetString( KEYNAME_FORMAT ) ) && |
|
stricmp( "ATI1N", kv->GetString( KEYNAME_FORMAT ) ) && stricmp( "ATI2N", kv->GetString( KEYNAME_FORMAT ) ) && |
|
stricmp( "DXT5_RUNTIME", kv->GetString( KEYNAME_FORMAT ) ) ) |
|
return true; |
|
|
|
if ( kv->GetInt( KEYNAME_SIZE ) > g_warn_texkbytes ) |
|
return true; |
|
|
|
if ( kv->GetInt( KEYNAME_WIDTH ) > g_warn_texdimensions ) |
|
return true; |
|
|
|
if ( kv->GetInt( KEYNAME_HEIGHT ) > g_warn_texdimensions ) |
|
return true; |
|
|
|
return false; |
|
} |
|
|
|
static void FmtCommaNumber( char *pchBuffer, unsigned int uiNumber ) |
|
{ |
|
pchBuffer[0] = 0; |
|
for ( unsigned int uiDivisor = 1000 * 1000 * 1000; uiDivisor > 0; uiDivisor /= 1000 ) |
|
{ |
|
if ( uiNumber > uiDivisor ) |
|
{ |
|
unsigned int uiPrint = ( uiNumber / uiDivisor ) % 1000; |
|
sprintf( pchBuffer + strlen( pchBuffer ), ( uiNumber / uiDivisor < 1000 ) ? "%d," : "%03d,", uiPrint ); |
|
} |
|
} |
|
|
|
int len = strlen( pchBuffer ); |
|
if ( !len ) |
|
sprintf( pchBuffer, "0" ); |
|
else if ( pchBuffer[ len - 1 ] == ',' ) |
|
pchBuffer[ len - 1 ] = 0; |
|
} |
|
|
|
namespace |
|
{ |
|
|
|
char s_chLastViewedTextureBuffer[ 0x200 ] = {0}; |
|
|
|
}; // end `anonymous` namespace |
|
|
|
bool CanAdjustTextureSize( char const *szTextureName, bool bMoveSizeUp ) |
|
{ |
|
ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false ); |
|
if ( !pMatTexture ) |
|
return false; |
|
|
|
// Determine the texture current size |
|
if ( !bMoveSizeUp ) |
|
{ |
|
return ( pMatTexture->GetActualWidth() > 4 || pMatTexture->GetActualHeight() > 4 ); |
|
} |
|
else |
|
{ |
|
return ( pMatTexture->GetActualWidth() < pMatTexture->GetMappingWidth() || |
|
pMatTexture->GetActualHeight() < pMatTexture->GetMappingHeight() ); |
|
} |
|
} |
|
|
|
bool AdjustTextureSize( char const *szTextureName, bool bMoveSizeUp ) |
|
{ |
|
ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false ); |
|
|
|
if ( !pMatTexture ) |
|
return false; |
|
|
|
pMatTexture->ForceLODOverride( bMoveSizeUp ? +1 : -1 ); |
|
return true; |
|
} |
|
|
|
CON_COMMAND_F( mat_texture_list_txlod, "Adjust LOD of the last viewed texture +1 to inc resolution, -1 to dec resolution", FCVAR_DONTRECORD ) |
|
{ |
|
if ( args.ArgC() == 2 ) |
|
{ |
|
int iAdjustment = atoi( args.Arg( 1 ) ); |
|
switch ( iAdjustment ) |
|
{ |
|
case 1: |
|
case -1: |
|
if ( !CanAdjustTextureSize( s_chLastViewedTextureBuffer, iAdjustment > 0 ) ) |
|
Warning( "mat_texture_list_txlod cannot adjust lod for '%s'\n", s_chLastViewedTextureBuffer ); |
|
else if ( !AdjustTextureSize( s_chLastViewedTextureBuffer, iAdjustment > 0 ) ) |
|
Warning( "mat_texture_list_txlod failed adjusting lod for '%s'\n", s_chLastViewedTextureBuffer ); |
|
else |
|
Msg( "mat_texture_list_txlod adjusted lod %c1 for '%s'\n", ( iAdjustment > 0 ) ? '+' : '-' , s_chLastViewedTextureBuffer ); |
|
return; |
|
default: |
|
break; |
|
|
|
} |
|
} |
|
Warning( "Usage: 'mat_texture_list_txlod +1' to inc lod | 'mat_texture_list_txlod -1' to dec lod\n" ); |
|
} |
|
|
|
static bool SaveTextureImage( char const *szTextureName ) |
|
{ |
|
bool bRet; |
|
char fileName[ MAX_PATH ]; |
|
char baseName[ MAX_PATH ]; |
|
ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false ); |
|
|
|
if ( !pMatTexture ) |
|
{ |
|
Msg( "materials->FindTexture( '%s' ) failed.\n", szTextureName ); |
|
return false; |
|
} |
|
|
|
V_FileBase( szTextureName, baseName, ARRAYSIZE( baseName ) ); |
|
Q_snprintf( fileName, ARRAYSIZE( fileName ), "//MOD/tex_%s.tga", baseName ); |
|
|
|
bRet = pMatTexture->SaveToFile( fileName ); |
|
|
|
Msg( "SaveTextureImage( '%s' ): %s\n", fileName, bRet ? "succeeded" : "failed" ); |
|
return bRet; |
|
} |
|
|
|
namespace MatViewOverride |
|
{ |
|
|
|
|
|
// |
|
// View override parameters request |
|
// |
|
struct ViewParamsReq |
|
{ |
|
CUtlVector< UtlSymId_t > lstMaterials; |
|
} |
|
s_viewParamsReq; |
|
|
|
void RequestSelectNone( void ) |
|
{ |
|
s_viewParamsReq.lstMaterials.RemoveAll(); |
|
} |
|
void RequestSelected( int nCount, UtlSymId_t const *pNameIds ) |
|
{ |
|
s_viewParamsReq.lstMaterials.AddMultipleToTail( nCount, pNameIds ); |
|
} |
|
|
|
// |
|
// View override last parameters |
|
// |
|
struct ViewParamsLast |
|
{ |
|
ViewParamsLast() : lstMaterials( DefLessFunc( UtlSymId_t ) ), flTime( 0.f ), bHighlighted( false ) {} |
|
|
|
float flTime; |
|
bool bHighlighted; |
|
|
|
struct TxInfo |
|
{ |
|
ITexture *pTx; |
|
CUtlSymbol name; |
|
}; |
|
|
|
struct VarMap : public CUtlMap< UtlSymId_t, TxInfo > |
|
{ |
|
VarMap() : CUtlMap< UtlSymId_t, TxInfo >( DefLessFunc( UtlSymId_t ) ) {} |
|
VarMap( VarMap const &x ) { const_cast< VarMap & >( x ).Swap( *this ); m_matInfo = x.m_matInfo; } // Fast-swap data |
|
|
|
struct MatInfo |
|
{ |
|
// MatInfo() : ignorez( false ) {} |
|
// bool ignorez; |
|
MatInfo() {} |
|
} m_matInfo; |
|
}; |
|
|
|
CUtlMap< UtlSymId_t, VarMap > lstMaterials; |
|
} |
|
s_viewParamsLast; |
|
|
|
// |
|
// DisplaySelectedTextures |
|
// Executed every frame to toggle the selected/unselected |
|
// textures for a list of materials. |
|
// |
|
void DisplaySelectedTextures() |
|
{ |
|
// Nothing selected |
|
if ( !s_viewParamsLast.lstMaterials.Count() && |
|
!s_viewParamsReq.lstMaterials.Count() ) |
|
return; |
|
|
|
if ( !s_viewParamsLast.lstMaterials.Count() && |
|
s_viewParamsReq.lstMaterials.Count() ) |
|
{ |
|
// First time selection |
|
s_viewParamsLast.flTime = Plat_FloatTime(); |
|
s_viewParamsLast.bHighlighted = false; |
|
} |
|
else |
|
{ |
|
// Wait for the flash-time |
|
float fCurTime = Plat_FloatTime(); |
|
if ( fCurTime >= s_viewParamsLast.flTime && |
|
fCurTime < s_viewParamsLast.flTime + 0.4 ) |
|
return; |
|
|
|
s_viewParamsLast.flTime = fCurTime; |
|
s_viewParamsLast.bHighlighted = !s_viewParamsLast.bHighlighted; |
|
} |
|
|
|
// Find the empty texture |
|
ITexture *txEmpty = materials->FindTexture( "debugempty", "", false ); |
|
|
|
typedef unsigned short MapIdx; |
|
|
|
// Now walk over all the materials in the req list and push them to the params |
|
for ( int k = 0, kEnd = s_viewParamsReq.lstMaterials.Count(); k < kEnd; ++ k ) |
|
{ |
|
UtlSymId_t idMat = s_viewParamsReq.lstMaterials[ k ]; |
|
MapIdx idx = s_viewParamsLast.lstMaterials.Find( idMat ); |
|
if ( idx == s_viewParamsLast.lstMaterials.InvalidIndex() ) |
|
{ |
|
// Insert the new material |
|
idx = s_viewParamsLast.lstMaterials.Insert( idMat ); |
|
ViewParamsLast::VarMap &vars = s_viewParamsLast.lstMaterials.Element( idx ); |
|
|
|
// Locate the material |
|
char const *szMaterialName = CUtlSymbol( idMat ).String(); |
|
IMaterial *pMat = materials->FindMaterial( szMaterialName, TEXTURE_GROUP_OTHER, false ); |
|
if ( pMat ) |
|
{ |
|
int numParams = pMat->ShaderParamCount(); |
|
IMaterialVar **arrVars = pMat->GetShaderParams(); |
|
for ( int idxParam = 0; idxParam < numParams; ++ idxParam ) |
|
{ |
|
// if ( !stricmp( arrVars[ idxParam ]->GetName(), "$ignorez" ) ) |
|
// { |
|
// vars.m_matInfo.ignorez = arrVars[ idxParam ]->GetIntValue() ? true : false; |
|
// arrVars[ idxParam ]->SetIntValue( 1 ); |
|
// continue; |
|
// } |
|
|
|
if ( !arrVars[ idxParam ]->IsTexture() ) |
|
continue; |
|
|
|
ITexture *pTex = arrVars[ idxParam ]->GetTextureValue(); |
|
if ( !pTex || pTex->IsError() ) |
|
continue; |
|
|
|
ViewParamsLast::TxInfo txinfo; |
|
txinfo.name = CUtlSymbol( pTex->GetName() ); |
|
txinfo.pTx = pTex; |
|
vars.Insert( CUtlSymbol( arrVars[ idxParam ]->GetName() ), txinfo ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Now walk over all the materials that we have to highlight or unhighlight |
|
for ( MapIdx idx = s_viewParamsLast.lstMaterials.FirstInorder(); |
|
idx != s_viewParamsLast.lstMaterials.InvalidIndex(); |
|
/* advance inside */ ) |
|
{ |
|
UtlSymId_t idMat = s_viewParamsLast.lstMaterials.Key( idx ); |
|
ViewParamsLast::VarMap &vars = s_viewParamsLast.lstMaterials.Element( idx ); |
|
|
|
bool bRemovedSelection = ( s_viewParamsReq.lstMaterials.Find( idMat ) < 0 ); |
|
|
|
char const *szMaterialName = CUtlSymbol( idMat ).String(); |
|
IMaterial *pMat = materials->FindMaterial( szMaterialName, TEXTURE_GROUP_OTHER, false ); |
|
if ( pMat ) |
|
{ |
|
int numParams = pMat->ShaderParamCount(); |
|
IMaterialVar **arrVars = pMat->GetShaderParams(); |
|
for ( int idxParam = 0; idxParam < numParams; ++ idxParam ) |
|
{ |
|
// if ( bRemovedSelection && !stricmp( arrVars[ idxParam ]->GetName(), "$ignorez" ) ) |
|
// { |
|
// arrVars[ idxParam ]->SetIntValue( vars.m_matInfo.ignorez ? 1 : 0 ); |
|
// continue; |
|
// } |
|
|
|
char const *szVarName = arrVars[ idxParam ]->GetName(); |
|
CUtlSymbol symVarName( szVarName ); |
|
MapIdx idxVarsTxInfo = vars.Find( symVarName ); |
|
if ( idxVarsTxInfo != vars.InvalidIndex() ) |
|
{ |
|
ViewParamsLast::TxInfo &ti = vars.Element( idxVarsTxInfo ); |
|
|
|
ITexture *pTx = ( s_viewParamsLast.bHighlighted && !bRemovedSelection ) ? txEmpty : ti.pTx; |
|
Assert( ti.pTx && !ti.pTx->IsError() ); |
|
|
|
arrVars[ idxParam ]->SetTextureValue( pTx ); |
|
} |
|
} |
|
} |
|
|
|
// Index advance |
|
if ( bRemovedSelection ) |
|
{ |
|
MapIdx idxRemove = idx; |
|
idx = s_viewParamsLast.lstMaterials.NextInorder( idx ); |
|
s_viewParamsLast.lstMaterials.RemoveAt( idxRemove ); |
|
} |
|
else |
|
{ |
|
idx = s_viewParamsLast.lstMaterials.NextInorder( idx ); |
|
} |
|
} |
|
} |
|
|
|
}; // end namespace MatViewOverride |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Custom text entry with "Open" for vmt's |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
class CVmtTextEntry : public vgui::TextEntry |
|
{ |
|
DECLARE_CLASS_SIMPLE( CVmtTextEntry, vgui::TextEntry ); |
|
|
|
public: |
|
CVmtTextEntry( vgui::Panel *parent, char const *szName ) : BaseClass( parent, szName ) {} |
|
|
|
public: |
|
MESSAGE_FUNC( OpenVmtSelected, "DoOpenVmtSelected" ); |
|
|
|
virtual void OpenEditMenu(); |
|
}; |
|
|
|
void CVmtTextEntry::OpenEditMenu() |
|
{ |
|
vgui::Menu *pEditMenu = BaseClass::GetEditMenu(); |
|
|
|
int pos = pEditMenu->AddMenuItem( "Open VMT", new KeyValues("DoOpenVmtSelected"), this ); |
|
pEditMenu->MoveMenuItem( pos, 0 ); |
|
|
|
int x0, x1; |
|
pEditMenu->SetItemEnabled( "Open VMT", GetSelectedRange(x0, x1) ); |
|
|
|
BaseClass::OpenEditMenu(); |
|
} |
|
|
|
void CVmtTextEntry::OpenVmtSelected() |
|
{ |
|
int x0, x1; |
|
if ( !GetSelectedRange(x0, x1) ) |
|
return; |
|
|
|
CUtlVector<char> buf; |
|
buf.SetCount( x1 - x0 + 1 ); |
|
GetTextRange( buf.Base(), x0, x1 - x0 ); |
|
|
|
for ( char *pchName = buf.Base(), *pchNext = NULL; pchName; pchName = pchNext ) |
|
{ |
|
if ( ( pchNext = strchr( pchName, '\n' ) ) != NULL ) |
|
*( pchNext ++ ) = 0; |
|
|
|
char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0}; |
|
Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vmt", pchName ); |
|
char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 ); |
|
|
|
if ( szResolvedName ) |
|
vgui::system()->ShellExecuteEx( "open", szResolvedName, "" ); |
|
} |
|
} |
|
|
|
#ifdef IS_WINDOWS_PC |
|
bool IsSpaceOrQuote( char val ) |
|
{ |
|
return (isspace(val) || val == '\"'); |
|
} |
|
|
|
static bool SetBufferValue( char *chTxtFileBuffer, char const *szLookupKey, char const *szNewValue ) |
|
{ |
|
bool bResult = false; |
|
|
|
size_t lenTmp = strlen( szNewValue ); |
|
size_t nTxtFileBufferLen = strlen( chTxtFileBuffer ); |
|
|
|
for ( char *pch = chTxtFileBuffer; |
|
( NULL != ( pch = strstr( pch, szLookupKey ) ) ); |
|
++ pch ) |
|
{ |
|
char *val = pch + strlen( szLookupKey ); |
|
if ( !IsSpaceOrQuote( *val ) ) |
|
continue; |
|
else |
|
++ val; |
|
|
|
// Skip over the whitespace and quotes |
|
while ( *val && IsSpaceOrQuote( *val ) ) |
|
++ val; |
|
char *pValStart = val; |
|
|
|
// Okay, here comes the value |
|
while ( *val && IsSpaceOrQuote( *val ) ) |
|
++ val; |
|
while ( *val && !IsSpaceOrQuote( *val ) ) |
|
++ val; |
|
|
|
char *pValEnd = val; // Okay, here ends the value |
|
|
|
memmove( pValStart + lenTmp, pValEnd, chTxtFileBuffer + nTxtFileBufferLen + 1 - pValEnd ); |
|
memcpy( pValStart, szNewValue, lenTmp ); |
|
|
|
nTxtFileBufferLen += ( lenTmp - ( pValEnd - pValStart ) ); |
|
bResult = true; |
|
} |
|
|
|
if ( !bResult ) |
|
{ |
|
char *pchAdd = chTxtFileBuffer + nTxtFileBufferLen; |
|
strcpy( pchAdd + strlen( pchAdd ), "\n" ); |
|
strcpy( pchAdd + strlen( pchAdd ), szLookupKey ); |
|
strcpy( pchAdd + strlen( pchAdd ), " " ); |
|
strcpy( pchAdd + strlen( pchAdd ), szNewValue ); |
|
strcpy( pchAdd + strlen( pchAdd ), "\n" ); |
|
bResult = true; |
|
} |
|
|
|
return bResult; |
|
} |
|
|
|
// Replaces the first occurrence of "szFindData" with "szNewData" |
|
// Returns the remaining buffer past the replaced data or NULL if |
|
// no replacement occurred. |
|
static char * BufferReplace( char *buf, char const *szFindData, char const *szNewData ) |
|
{ |
|
size_t len = strlen( buf ), lFind = strlen( szFindData ), lNew = strlen( szNewData ); |
|
if ( char *pBegin = strstr( buf, szFindData ) ) |
|
{ |
|
memmove( pBegin + lNew, pBegin + lFind, buf + len - ( pBegin + lFind ) ); |
|
memmove( pBegin, szNewData, lNew ); |
|
return pBegin + lNew; |
|
} |
|
return NULL; |
|
} |
|
|
|
class CP4Requirement |
|
{ |
|
public: |
|
CP4Requirement(); |
|
~CP4Requirement(); |
|
|
|
protected: |
|
bool m_bLoadedModule; |
|
CSysModule *m_pP4Module; |
|
}; |
|
|
|
CP4Requirement::CP4Requirement() : |
|
m_bLoadedModule( false ), |
|
m_pP4Module( NULL ) |
|
{ |
|
#ifdef STAGING_ONLY |
|
if ( p4 ) |
|
return; |
|
|
|
// load the p4 lib |
|
m_pP4Module = Sys_LoadModule( "p4lib" ); |
|
m_bLoadedModule = true; |
|
|
|
if ( m_pP4Module ) |
|
{ |
|
CreateInterfaceFn factory = Sys_GetFactory( m_pP4Module ); |
|
if ( factory ) |
|
{ |
|
p4 = ( IP4 * )factory( P4_INTERFACE_VERSION, NULL ); |
|
|
|
if ( p4 ) |
|
{ |
|
extern CreateInterfaceFn g_AppSystemFactory; |
|
p4->Connect( g_AppSystemFactory ); |
|
p4->Init(); |
|
} |
|
} |
|
} |
|
#endif // STAGING_ONLY |
|
|
|
if ( !p4 ) |
|
{ |
|
Warning( "Can't load p4lib.dll\n" ); |
|
} |
|
} |
|
|
|
CP4Requirement::~CP4Requirement() |
|
{ |
|
if ( m_bLoadedModule && m_pP4Module ) |
|
{ |
|
if ( p4 ) |
|
{ |
|
p4->Shutdown(); |
|
p4->Disconnect(); |
|
} |
|
|
|
Sys_UnloadModule( m_pP4Module ); |
|
m_pP4Module = NULL; |
|
p4 = NULL; |
|
} |
|
} |
|
#endif // #ifdef IS_WINDOWS_PC |
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Render textures edit panel |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
class CRenderTextureEditor : public vgui::Frame |
|
{ |
|
DECLARE_CLASS_SIMPLE( CRenderTextureEditor, vgui::Frame ); |
|
|
|
public: |
|
CRenderTextureEditor( vgui::Panel *parent, char const *szName ); |
|
~CRenderTextureEditor(); |
|
|
|
public: |
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); |
|
virtual void PerformLayout(); |
|
virtual void OnCommand( const char *command ); |
|
virtual void SetFont( vgui::HFont hFont ) { m_hFont = hFont; Repaint(); } |
|
virtual vgui::HFont GetFont() { return m_hFont; } |
|
|
|
public: |
|
virtual void OnMousePressed( vgui::MouseCode code ); |
|
virtual void OnMouseDoublePressed( vgui::MouseCode code ) { OnMousePressed( code ); } |
|
virtual void Activate(); |
|
virtual void Close(); |
|
|
|
public: |
|
void SetDispInfo( KeyValues *kv, int iHint ); |
|
void GetDispInfo( KeyValues *&kv, int &iHint ); |
|
|
|
public: |
|
virtual void Paint(); |
|
|
|
enum |
|
{ |
|
TILE_BORDER = 10, |
|
TILE_SIZE = 550, |
|
TILE_TEXTURE_SIZE = 256, |
|
TILE_TEXT = 70 |
|
}; |
|
|
|
protected: |
|
vgui::HFont m_hFont; |
|
CVmtTextEntry *m_pMaterials; |
|
vgui::Button *m_pExplore; |
|
vgui::Button *m_pReload; |
|
vgui::Button *m_pRebuild; |
|
vgui::Button *m_pToggleNoMip; |
|
vgui::Button *m_pCopyTxt; |
|
#ifndef POSIX |
|
vgui::Button *m_pCopyImg; |
|
#endif |
|
vgui::Button *m_pSaveImg; |
|
vgui::Button *m_pSizeControls[2]; |
|
vgui::Button *m_pFlashBtn; |
|
KeyValues *m_pInfo; |
|
CUtlBuffer m_bufInfoText; |
|
CUtlVector< UtlSymId_t > m_lstMaterials; |
|
int m_iInfoHint; |
|
}; |
|
|
|
CRenderTextureEditor::CRenderTextureEditor( vgui::Panel *parent, char const *szName ) : |
|
BaseClass( parent, szName ), |
|
m_pInfo( NULL ), |
|
m_iInfoHint( 0 ), |
|
m_hFont( vgui::INVALID_FONT ), |
|
m_bufInfoText( 0, 0, CUtlBuffer::TEXT_BUFFER ) |
|
{ |
|
m_pMaterials = vgui::SETUP_PANEL( new CVmtTextEntry( this, "Materials" ) ); |
|
m_pMaterials->SetMultiline( true ); |
|
m_pMaterials->SetEditable( false ); |
|
m_pMaterials->SetEnabled( false ); |
|
m_pMaterials->SetVerticalScrollbar( true ); |
|
m_pMaterials->SetVisible( true ); |
|
|
|
m_pExplore = vgui::SETUP_PANEL( new vgui::Button( this, "Explore", "Open", this, "Explore" ) ); |
|
m_pExplore->SetVisible( true ); |
|
|
|
m_pReload = vgui::SETUP_PANEL( new vgui::Button( this, "Reload", "Reload", this, "Reload" ) ); |
|
m_pReload->SetVisible( true ); |
|
|
|
m_pRebuild = vgui::SETUP_PANEL( new vgui::Button( this, "RebuildVTF", "Rebuild VTF", this, "RebuildVTF" ) ); |
|
m_pRebuild->SetVisible( true ); |
|
|
|
m_pToggleNoMip = vgui::SETUP_PANEL( new vgui::Button( this, "ToggleNoMip", "ToggleNoMip", this, "ToggleNoMip" ) ); |
|
m_pToggleNoMip->SetVisible( true ); |
|
|
|
m_pCopyTxt = vgui::SETUP_PANEL( new vgui::Button( this, "CopyTxt", "Copy Text", this, "CopyTxt" ) ); |
|
m_pCopyTxt->SetVisible( true ); |
|
|
|
#ifndef POSIX |
|
m_pCopyImg = vgui::SETUP_PANEL( new vgui::Button( this, "CopyImg", "Copy Image", this, "CopyImg" ) ); |
|
m_pCopyImg->SetVisible( true ); |
|
#endif |
|
|
|
m_pSaveImg = vgui::SETUP_PANEL( new vgui::Button( this, "SaveImg", "Save Image", this, "SaveImg" ) ); |
|
m_pSaveImg->SetVisible( true ); |
|
|
|
m_pFlashBtn = vgui::SETUP_PANEL( new vgui::Button( this, "FlashBtn", "Flash in Game", this, "FlashBtn" ) ); |
|
m_pFlashBtn->SetVisible( true ); |
|
|
|
m_pSizeControls[0] = vgui::SETUP_PANEL( new vgui::Button( this, "--", "--", this, "size-" ) ); |
|
m_pSizeControls[1] = vgui::SETUP_PANEL( new vgui::Button( this, "+", "+", this, "size+" ) ); |
|
} |
|
|
|
CRenderTextureEditor::~CRenderTextureEditor() |
|
{ |
|
SetDispInfo( NULL, 0 ); |
|
} |
|
|
|
void CRenderTextureEditor::GetDispInfo( KeyValues *&kv, int &iHint ) |
|
{ |
|
iHint = m_iInfoHint; |
|
kv = m_pInfo; |
|
} |
|
|
|
void CRenderTextureEditor::SetDispInfo( KeyValues *kv, int iHint ) |
|
{ |
|
m_iInfoHint = iHint; |
|
|
|
if ( m_pInfo ) |
|
m_pInfo->deleteThis(); |
|
|
|
m_pInfo = kv ? kv->MakeCopy() : NULL; |
|
|
|
|
|
CUtlStringMap< bool > arrMaterials, arrMaterialsFullNames; |
|
|
|
if ( kv ) |
|
{ |
|
char const *szTextureName = kv->GetString( KEYNAME_NAME ); |
|
for ( MaterialHandle_t hm = materials->FirstMaterial(); |
|
hm != materials->InvalidMaterial(); hm = materials->NextMaterial( hm ) ) |
|
{ |
|
IMaterial *pMat = materials->GetMaterial( hm ); |
|
if ( !pMat ) |
|
continue; |
|
|
|
int numParams = pMat->ShaderParamCount(); |
|
IMaterialVar **arrVars = pMat->GetShaderParams(); |
|
for ( int idxParam = 0; idxParam < numParams; ++ idxParam ) |
|
{ |
|
if ( !arrVars[ idxParam ]->IsTexture() ) |
|
continue; |
|
|
|
ITexture *pTex = arrVars[ idxParam ]->GetTextureValue(); |
|
if ( !pTex || pTex->IsError() ) |
|
continue; |
|
|
|
if ( !stricmp( pTex->GetName(), szTextureName ) ) |
|
{ |
|
bool bRealMaterial = true; |
|
|
|
if ( StringHasPrefix( pMat->GetName(), "debug/debugtexture" ) ) |
|
bRealMaterial = false; |
|
|
|
if ( StringHasPrefix( pMat->GetName(), "maps/" ) ) |
|
{ |
|
// Format: maps/mapname/[matname]_x_y_z |
|
bRealMaterial = false; |
|
|
|
char chName[ MAX_PATH ]; |
|
Q_strncpy( chName, pMat->GetName() + 5, sizeof( chName ) - 1 ); |
|
|
|
if ( char *szMatName = strchr( chName, '/' ) ) |
|
{ |
|
++ szMatName; |
|
for ( int k = 0; k < 3; ++ k ) |
|
{ |
|
if ( char *rUnderscore = strrchr( szMatName, '_' ) ) |
|
*rUnderscore = 0; |
|
} |
|
|
|
sprintf( szMatName + strlen( szMatName ), " (cubemap)" ); |
|
arrMaterials[ szMatName ] = true; |
|
} |
|
arrMaterialsFullNames[ pMat->GetName() ] = true; |
|
} |
|
|
|
if ( bRealMaterial ) |
|
{ |
|
arrMaterials[ pMat->GetName() ] = true; |
|
arrMaterialsFullNames[ pMat->GetName() ] = true; |
|
} |
|
|
|
break; |
|
} |
|
} |
|
} |
|
} |
|
|
|
// Now that we have a list of materials make a printable version |
|
CUtlBuffer bufText( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
|
|
if ( !arrMaterials.GetNumStrings() ) |
|
{ |
|
bufText.Printf( "-- no materials --" ); |
|
} |
|
else |
|
{ |
|
int c = arrMaterials.GetNumStrings(); |
|
bufText.Printf( " %d material%s:", c, ( c%10 == 1 && c != 11 ) ? "" : "s" ); |
|
} |
|
|
|
for ( int k = 0; k < arrMaterials.GetNumStrings(); ++ k ) |
|
{ |
|
bufText.Printf( "\n%s", arrMaterials.String( k ) ); |
|
} |
|
|
|
m_pSaveImg->SetVisible( false ); |
|
|
|
// Set text except for the cases when m_pInfo and no materials found |
|
if ( !( m_pInfo && !arrMaterials.GetNumStrings() ) ) |
|
{ |
|
if ( kv ) |
|
{ |
|
int iTxWidth = kv->GetInt( KEYNAME_WIDTH ); |
|
int iTxHeight = kv->GetInt( KEYNAME_HEIGHT ); |
|
char const *szTxFormat = kv->GetString( KEYNAME_FORMAT ); |
|
|
|
bufText.Printf( "\n%dx%d Format:%s", iTxWidth, iTxHeight, szTxFormat ); |
|
|
|
// We support saving the 8888 formats right now: "RGBA8888", "ABGR8888", "ARGB8888", "BGRA8888", "BGRX8888" |
|
if( Q_strstr( szTxFormat, "8888" ) ) |
|
{ |
|
m_pSaveImg->SetVisible( true ); |
|
} |
|
} |
|
|
|
m_pMaterials->SetText( ( char const * ) bufText.Base() ); |
|
|
|
m_lstMaterials.RemoveAll(); |
|
m_lstMaterials.EnsureCapacity( arrMaterialsFullNames.GetNumStrings() ); |
|
for ( int k = 0; k < arrMaterialsFullNames.GetNumStrings(); ++ k ) |
|
{ |
|
m_lstMaterials.AddToTail( CUtlSymbol( arrMaterialsFullNames.String( k ) ) ); |
|
} |
|
} |
|
|
|
m_bufInfoText.Clear(); |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
void CRenderTextureEditor::Close() |
|
{ |
|
BaseClass::Close(); |
|
|
|
SetDispInfo( NULL, 0 ); |
|
} |
|
|
|
void CRenderTextureEditor::Activate() |
|
{ |
|
BaseClass::Activate(); |
|
} |
|
|
|
void CRenderTextureEditor::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
int iRenderedHeight = 4 * TILE_BORDER + TILE_TEXT + TILE_SIZE; |
|
|
|
SetSize( 4 * TILE_BORDER + TILE_SIZE, |
|
iRenderedHeight + 90 + TILE_BORDER ); |
|
|
|
m_pMaterials->SetPos( TILE_BORDER, iRenderedHeight + 2 ); |
|
m_pMaterials->SetSize( 2 * TILE_BORDER + TILE_SIZE, 90 ); |
|
|
|
m_pExplore->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50, 2 * TILE_BORDER ); |
|
m_pExplore->SetWide( 50 ); |
|
|
|
m_pReload->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50 - 65, 2 * TILE_BORDER ); |
|
m_pReload->SetWide( 60 ); |
|
m_pReload->SetVisible( m_lstMaterials.Count() > 0 ); |
|
|
|
m_pRebuild->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50 - 65 - 95, 2 * TILE_BORDER ); |
|
m_pRebuild->SetWide( 90 ); |
|
m_pRebuild->SetVisible( m_lstMaterials.Count() > 0 ); |
|
|
|
m_pToggleNoMip->SetPos( 2 * TILE_BORDER + TILE_SIZE - 50 - 95, (2 * TILE_BORDER) + m_pReload->GetTall() + 1 ); |
|
m_pToggleNoMip->SetWide( 90 ); |
|
m_pToggleNoMip->SetVisible( m_lstMaterials.Count() > 0 ); |
|
|
|
m_pExplore->SetVisible( false ); |
|
m_pSizeControls[0]->SetVisible( false ); |
|
m_pSizeControls[1]->SetVisible( false ); |
|
|
|
if ( m_pInfo ) |
|
{ |
|
char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0}; |
|
Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", m_pInfo->GetString( KEYNAME_NAME ) ); |
|
char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 ); |
|
if ( szResolvedName ) |
|
{ |
|
m_pExplore->SetVisible( true ); |
|
} |
|
|
|
if ( !m_pInfo->GetInt( "SpecialTx" ) ) |
|
{ |
|
m_pSizeControls[0]->SetVisible( true ); |
|
m_pSizeControls[1]->SetVisible( true ); |
|
|
|
m_pSizeControls[0]->SetEnabled( CanAdjustTextureSize( m_pInfo->GetString( KEYNAME_NAME ), false ) ); |
|
m_pSizeControls[1]->SetEnabled( CanAdjustTextureSize( m_pInfo->GetString( KEYNAME_NAME ), true ) ); |
|
|
|
int posX, posY; |
|
m_pExplore->GetPos( posX, posY ); |
|
m_pSizeControls[0]->SetPos( posX, posY + m_pExplore->GetTall() + 1 ); |
|
m_pSizeControls[0]->SetWide( m_pExplore->GetWide() / 2 ); |
|
m_pSizeControls[1]->SetPos( posX + m_pSizeControls[0]->GetWide() + 1, posY + m_pExplore->GetTall() + 1 ); |
|
m_pSizeControls[1]->SetWide( m_pExplore->GetWide() - ( m_pSizeControls[0]->GetWide() + 1 ) ); |
|
} |
|
} |
|
|
|
{ |
|
int posX, posY; |
|
m_pExplore->GetPos( posX, posY ); |
|
posY += m_pExplore->GetTall() * 2 + 2; |
|
posX += m_pExplore->GetWide(); |
|
|
|
posX -= 80; |
|
m_pSaveImg->SetPos( posX, posY ); |
|
m_pSaveImg->SetWide( 80 ); |
|
|
|
#ifndef POSIX |
|
posX -= 80 + 5; |
|
m_pCopyImg->SetPos( posX, posY ); |
|
m_pCopyImg->SetWide( 80 ); |
|
#endif |
|
|
|
posX -= 80 + 5; |
|
m_pCopyTxt->SetPos( posX, posY ); |
|
m_pCopyTxt->SetWide( 80 ); |
|
|
|
posX -= 95 + 5; |
|
m_pFlashBtn->SetPos( posX, posY ); |
|
m_pFlashBtn->SetWide( 95 ); |
|
} |
|
} |
|
|
|
#ifdef IS_WINDOWS_PC |
|
bool GetTextureContentPath( const char *pszVTF, char *szTextureContentPath, int nBufSize ) |
|
{ |
|
char vhRelVTF[MAX_PATH]; |
|
Q_snprintf( vhRelVTF, sizeof( vhRelVTF ) - 1, "materials/%s.vtf", pszVTF ); |
|
|
|
ConVarRef mat_texture_list_content_path( "mat_texture_list_content_path" ); |
|
if ( !mat_texture_list_content_path.GetString()[0] ) |
|
{ |
|
szTextureContentPath = const_cast< char * >( g_pFileSystem->RelativePathToFullPath( vhRelVTF, "game", szTextureContentPath, nBufSize - 1 ) ); |
|
|
|
if ( !szTextureContentPath ) |
|
{ |
|
Warning( " texture '%s' is not loaded from file system.\n", pszVTF ); |
|
return false; |
|
} |
|
if ( !BufferReplace( szTextureContentPath, "\\game\\", "\\content\\" ) || |
|
!BufferReplace( szTextureContentPath, "\\materials\\", "\\materialsrc\\" ) ) |
|
{ |
|
Warning( " texture '%s' cannot be mapped to content directory.\n", pszVTF ); |
|
return false; |
|
} |
|
} |
|
else |
|
{ |
|
V_strncpy( szTextureContentPath, mat_texture_list_content_path.GetString(), MAX_PATH ); |
|
V_strncat( szTextureContentPath, "/", MAX_PATH ); |
|
V_strncat( szTextureContentPath, pszVTF, MAX_PATH ); |
|
V_strncat( szTextureContentPath, ".vtf", MAX_PATH ); |
|
} |
|
|
|
return true; |
|
} |
|
#endif // #ifdef IS_WINDOWS_PC |
|
|
|
void CRenderTextureEditor::OnCommand( const char *command ) |
|
{ |
|
BaseClass::OnCommand( command ); |
|
|
|
if ( !stricmp( command, "Explore" ) && m_pInfo ) |
|
{ |
|
char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0}; |
|
Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", m_pInfo->GetString( KEYNAME_NAME ) ); |
|
char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 ); |
|
|
|
char params[256]; |
|
Q_snprintf( params, sizeof( params ) - 1, "/E,/SELECT,%s", szResolvedName ); |
|
vgui::system()->ShellExecuteEx( "open", "explorer.exe", params ); |
|
} |
|
|
|
if ( !stricmp( command, "Reload" ) && m_lstMaterials.Count() ) |
|
{ |
|
CUtlBuffer bufCommand( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
int idxMaterial = 0; |
|
|
|
// |
|
// Issue the console command several times in case we overflow the |
|
// console command buffer size. |
|
// |
|
Cbuf_Execute(); |
|
for ( ; idxMaterial < m_lstMaterials.Count(); ) |
|
{ |
|
int iOldIdx = idxMaterial; |
|
bufCommand.Printf( "mat_reloadmaterial \"" ); |
|
|
|
for ( ; idxMaterial < m_lstMaterials.Count(); ++ idxMaterial ) |
|
{ |
|
int iOldSize = bufCommand.TellPut(); |
|
int const iSizeLimit = CCommand::MaxCommandLength() - 3; |
|
|
|
char const *szString = CUtlSymbol( m_lstMaterials[idxMaterial] ).String(); |
|
bufCommand.Printf( "%s%s", ( idxMaterial > iOldIdx ) ? "*" : "", szString ); |
|
|
|
if ( bufCommand.TellPut() > iSizeLimit && |
|
idxMaterial > iOldIdx ) |
|
{ |
|
bufCommand.SeekPut( CUtlBuffer::SEEK_HEAD, iOldSize ); |
|
break; |
|
} |
|
} |
|
|
|
bufCommand.Printf( "\"\n" ); |
|
bufCommand.PutChar( 0 ); |
|
|
|
Cbuf_AddText( ( char const * ) bufCommand.Base() ); |
|
bufCommand.Clear(); |
|
Cbuf_Execute(); |
|
} |
|
} |
|
|
|
if ( !stricmp( command, "CopyTxt" ) ) |
|
{ |
|
char const *szName = ( char const * ) m_bufInfoText.Base(); |
|
if ( !m_bufInfoText.TellPut() || !szName ) |
|
szName = ""; |
|
vgui::system()->SetClipboardText( szName, strlen( szName ) + 1 ); |
|
} |
|
|
|
if ( !stricmp( command, "CopyImg" ) ) |
|
{ |
|
int x = 0, y = 0; |
|
this->LocalToScreen( x, y ); |
|
|
|
void *pMainWnd = game->GetMainWindow(); |
|
vgui::system()->SetClipboardImage( pMainWnd, x, y, x + GetWide(), y + GetTall() ); |
|
} |
|
|
|
if ( !stricmp( command, "SaveImg" ) ) |
|
{ |
|
SaveTextureImage( m_pInfo->GetString( KEYNAME_NAME ) ); |
|
} |
|
|
|
if ( !stricmp( command, "FlashBtn" ) ) |
|
{ |
|
MatViewOverride::RequestSelectNone(); |
|
MatViewOverride::RequestSelected( m_lstMaterials.Count(), m_lstMaterials.Base() ); |
|
mat_texture_list_off_f(); |
|
} |
|
|
|
if ( ( !stricmp( command, "size-" ) || !stricmp( command, "size+" ) ) && m_pInfo ) |
|
{ |
|
bool bSizeUp = ( command[4] == '+' ); |
|
bool bResult = AdjustTextureSize( m_pInfo->GetString( KEYNAME_NAME ), bSizeUp ); |
|
if ( bResult ) |
|
{ |
|
CAutoPushPop<bool> auto_g_bRecursiveRequestToShowTextureList( g_bRecursiveRequestToShowTextureList, true ); |
|
mat_texture_list_on_f(); |
|
} |
|
|
|
InvalidateLayout(); |
|
} |
|
|
|
if ( !stricmp( command, "ToggleNoMip" ) ) |
|
{ |
|
#ifdef IS_WINDOWS_PC |
|
CP4Requirement p4req; |
|
if ( !p4 ) |
|
g_p4factory->SetDummyMode( true ); |
|
|
|
char const *szTextureFile = m_pInfo->GetString( KEYNAME_NAME ); |
|
char const *szTextureGroup = m_pInfo->GetString( KEYNAME_TEXTURE_GROUP ); |
|
|
|
ITexture *pMatTexture = NULL; |
|
if ( *szTextureFile ) |
|
pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false ); |
|
if ( !pMatTexture ) |
|
pMatTexture = materials->FindTexture( "debugempty", "", false ); |
|
|
|
bool bNewNoMip = !(pMatTexture->GetFlags() & TEXTUREFLAGS_NOMIP); |
|
|
|
char szFileName[MAX_PATH]; |
|
if ( !GetTextureContentPath( szTextureFile, szFileName, sizeof(szFileName) ) ) |
|
return; |
|
|
|
// Figure out what kind of source content is there: |
|
// 1. look for TGA - if found, get the txt file (if txt file missing, create one) |
|
// 2. otherwise look for PSD - affecting psdinfo |
|
// 3. else error |
|
char *pExtPut = szFileName + strlen( szFileName ) - strlen( ".vtf" ); // compensating the TEXTURE_FNAME_EXTENSION(.vtf) extension |
|
|
|
// 1.tga |
|
sprintf( pExtPut, ".tga" ); |
|
if ( g_pFullFileSystem->FileExists( szFileName ) ) |
|
{ |
|
// Have tga - pump in the txt file |
|
sprintf( pExtPut, ".txt" ); |
|
|
|
CUtlBuffer bufTxtFileBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
g_pFullFileSystem->ReadFile( szFileName, 0, bufTxtFileBuffer ); |
|
for ( int k = 0; k < 1024; ++ k ) bufTxtFileBuffer.PutChar( 0 ); |
|
|
|
// Now fix maxwidth/maxheight settings |
|
SetBufferValue( ( char * ) bufTxtFileBuffer.Base(), "nomip", bNewNoMip ? "1" : "0" ); |
|
bufTxtFileBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, strlen( ( char * ) bufTxtFileBuffer.Base() ) ); |
|
|
|
// Check out or add the file |
|
g_p4factory->SetOpenFileChangeList( "Texture LOD Autocheckout" ); |
|
CP4AutoEditFile autop4_edit( szFileName ); |
|
|
|
// Save the file contents |
|
if ( g_pFullFileSystem->WriteFile( szFileName, 0, bufTxtFileBuffer ) ) |
|
{ |
|
Msg(" '%s' : saved.\n", szFileName ); |
|
CP4AutoAddFile autop4_add( szFileName ); |
|
} |
|
else |
|
{ |
|
Warning( " '%s' : failed to save - toggle \"nomip\" manually.\n", |
|
szFileName ); |
|
} |
|
} |
|
else |
|
{ |
|
// 2.psd |
|
sprintf( pExtPut, ".psd" ); |
|
if ( g_pFullFileSystem->FileExists( szFileName ) ) |
|
{ |
|
char chCommand[MAX_PATH]; |
|
char szTxtFileName[MAX_PATH] = {0}; |
|
GetModSubdirectory( "tmp_lod_psdinfo.txt", szTxtFileName, sizeof( szTxtFileName ) ); |
|
sprintf( chCommand, "/C psdinfo \"%s\" > \"%s\"", szFileName, szTxtFileName); |
|
vgui::system()->ShellExecuteEx( "open", "cmd.exe", chCommand ); |
|
Sys_Sleep( 200 ); |
|
|
|
CUtlBuffer bufTxtFileBuffer( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
g_pFullFileSystem->ReadFile( szTxtFileName, 0, bufTxtFileBuffer ); |
|
for ( int k = 0; k < 1024; ++ k ) bufTxtFileBuffer.PutChar( 0 ); |
|
|
|
// Now fix maxwidth/maxheight settings |
|
SetBufferValue( ( char * ) bufTxtFileBuffer.Base(), "nomip", bNewNoMip ? "1" : "0" ); |
|
bufTxtFileBuffer.SeekPut( CUtlBuffer::SEEK_HEAD, strlen( ( char * ) bufTxtFileBuffer.Base() ) ); |
|
|
|
// Check out or add the file |
|
// Save the file contents |
|
if ( g_pFullFileSystem->WriteFile( szTxtFileName, 0, bufTxtFileBuffer ) ) |
|
{ |
|
g_p4factory->SetOpenFileChangeList( "Texture LOD Autocheckout" ); |
|
CP4AutoEditFile autop4_edit( szFileName ); |
|
|
|
sprintf( chCommand, "/C psdinfo -write \"%s\" < \"%s\"", szFileName, szTxtFileName ); |
|
Sys_Sleep( 200 ); |
|
vgui::system()->ShellExecuteEx( "open", "cmd.exe", chCommand ); |
|
Sys_Sleep( 200 ); |
|
|
|
Msg(" '%s' : saved.\n", szFileName ); |
|
CP4AutoAddFile autop4_add( szFileName ); |
|
} |
|
else |
|
{ |
|
Warning( " '%s' : failed to save - toggle \"nomip\" manually.\n", |
|
szFileName ); |
|
} |
|
} |
|
else |
|
{ |
|
// 3. - error |
|
sprintf( pExtPut, "" ); |
|
Warning( " '%s' : doesn't specify a valid TGA or PSD file!\n", szFileName ); |
|
return; |
|
} |
|
} |
|
|
|
// Now reload the texture |
|
OnCommand( "RebuildVTF" ); |
|
#endif // #ifdef IS_WINDOWS_PC |
|
} |
|
|
|
if ( !stricmp( command, "RebuildVTF" ) ) |
|
{ |
|
#ifdef IS_WINDOWS_PC |
|
CP4Requirement p4req; |
|
if ( !p4 ) |
|
g_p4factory->SetDummyMode( true ); |
|
|
|
CSysModule *pModule; |
|
IVTex *pIVTex = VTex_Load( &pModule ); |
|
if ( !pIVTex ) |
|
return; |
|
|
|
char const *szTextureFile = m_pInfo->GetString( KEYNAME_NAME ); |
|
|
|
char szContentFilename[MAX_PATH]; |
|
if ( !GetTextureContentPath( szTextureFile, szContentFilename, sizeof(szContentFilename) ) ) |
|
return; |
|
|
|
char pGameDir[MAX_OSPATH]; |
|
COM_GetGameDir( pGameDir, sizeof( pGameDir ) ); |
|
|
|
// Check out the VTF |
|
char szVTFFilename[MAX_PATH]; |
|
Q_snprintf( szVTFFilename, sizeof( szVTFFilename ) - 1, "%s/materials/%s.vtf", pGameDir, szTextureFile ); |
|
g_p4factory->SetOpenFileChangeList( "Texture LOD Autocheckout" ); |
|
CP4AutoEditFile autop4_edit( szVTFFilename ); |
|
|
|
// Get the directory for the outdir |
|
StripDirName( szVTFFilename ); |
|
|
|
// Now we've modified the source, rebuild the texture |
|
char *argv[64]; |
|
int iArg = 0; |
|
argv[iArg++] = ""; |
|
argv[iArg++] = "-quiet"; |
|
argv[iArg++] = "-UseStandardError"; // These are only here for the -currently released- version of vtex.dll. |
|
argv[iArg++] = "-WarningsAsErrors"; |
|
argv[iArg++] = "-outdir"; |
|
argv[iArg++] = szVTFFilename; |
|
argv[iArg++] = szContentFilename; |
|
pIVTex->VTex( CubemapsFSFactory, pGameDir, iArg, argv ); |
|
|
|
VTex_Unload( pModule ); |
|
|
|
Sys_Sleep( 200 ); |
|
|
|
// Now reload the texture |
|
OnCommand( "Reload" ); |
|
#endif // #ifdef IS_WINDOWS_PC |
|
} |
|
} |
|
|
|
void CRenderTextureEditor::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
SetFont( pScheme->GetFont( "Default", IsProportional() ) ); |
|
} |
|
|
|
void CRenderTextureEditor::OnMousePressed( vgui::MouseCode code ) |
|
{ |
|
Close(); |
|
} |
|
|
|
void CRenderTextureEditor::Paint() |
|
{ |
|
CAutoMatSysDebugMode auto_matsysdebugmode; |
|
|
|
DisableFadeEffect(); |
|
SetBgColor( Color( 10, 50, 10, 255 ) ); |
|
|
|
BaseClass::Paint(); |
|
|
|
KeyValues *kv = m_pInfo; |
|
if ( !kv ) |
|
return; |
|
|
|
char const *szTextureFile = kv->GetString( KEYNAME_NAME ); |
|
Q_strncpy( s_chLastViewedTextureBuffer, szTextureFile, sizeof( s_chLastViewedTextureBuffer ) ); |
|
char const *szTextureGroup = kv->GetString( KEYNAME_TEXTURE_GROUP ); |
|
|
|
ITexture *pMatTexture = NULL; |
|
if ( *szTextureFile ) |
|
pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false ); |
|
if ( !pMatTexture ) |
|
pMatTexture = materials->FindTexture( "debugempty", "", false ); |
|
|
|
// Determine the texture size |
|
int iTxWidth = kv->GetInt( KEYNAME_WIDTH ); |
|
int iTxHeight = kv->GetInt( KEYNAME_HEIGHT ); |
|
int iTxSize = kv->GetInt( KEYNAME_SIZE ); |
|
char const *szTxFormat = kv->GetString( KEYNAME_FORMAT ); |
|
|
|
int x = TILE_BORDER, y = TILE_BORDER; |
|
|
|
// Dimensions to draw |
|
int iDrawWidth = iTxWidth; |
|
int iDrawHeight = iTxHeight; |
|
|
|
if ( pMatTexture && pMatTexture->IsCubeMap() ) |
|
{ |
|
iDrawWidth = 1024; |
|
iDrawHeight = 1024; |
|
} |
|
|
|
if ( iDrawHeight >= iDrawWidth ) |
|
{ |
|
if ( iDrawHeight > TILE_TEXTURE_SIZE ) |
|
{ |
|
iDrawWidth = iDrawWidth * ( float( TILE_TEXTURE_SIZE ) / iDrawHeight ); |
|
iDrawHeight = TILE_TEXTURE_SIZE; |
|
} |
|
|
|
if ( iDrawHeight < 64 ) |
|
{ |
|
iDrawWidth = iDrawWidth * ( float( 64 ) / iDrawHeight ); |
|
iDrawHeight = 64; |
|
} |
|
} |
|
else |
|
{ |
|
if ( iDrawWidth > TILE_TEXTURE_SIZE ) |
|
{ |
|
iDrawHeight = iDrawHeight * ( float( TILE_TEXTURE_SIZE ) / iDrawWidth ); |
|
iDrawWidth = TILE_TEXTURE_SIZE; |
|
} |
|
|
|
if ( iDrawWidth < 64 ) |
|
{ |
|
iDrawHeight = iDrawHeight * ( float( 64 ) / iDrawWidth ); |
|
iDrawWidth = 64; |
|
} |
|
} |
|
|
|
iDrawHeight = iDrawHeight / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) ); |
|
iDrawWidth = iDrawWidth / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) ); |
|
|
|
iDrawHeight = max( iDrawHeight, 4 ); |
|
iDrawWidth = max( iDrawWidth, 4 ); |
|
|
|
// |
|
// Draw frame |
|
// |
|
{ |
|
int tileWidth = 2 * TILE_BORDER + TILE_SIZE; |
|
int tileHeight = 3 * TILE_BORDER + TILE_SIZE + TILE_TEXT; |
|
|
|
g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 ); |
|
g_pMatSystemSurface->DrawOutlinedRect( x + 1, y + 1, |
|
x + tileWidth - 2 , y + tileHeight - 2 ); |
|
} |
|
|
|
// |
|
// Draw all |
|
// |
|
|
|
x += TILE_BORDER; |
|
y += TILE_BORDER; |
|
|
|
char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0}; |
|
Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", szTextureFile ); |
|
char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 ); |
|
|
|
char const *szPrintFilePrefix = szResolvedName ? "" : "[?]/"; |
|
char const *szPrintFileName = szResolvedName ? szResolvedName : szTextureFile; |
|
|
|
char chSizeBuf[20] = { 0 }; |
|
if ( iTxSize >= 0 ) |
|
FmtCommaNumber( chSizeBuf, iTxSize ); |
|
else |
|
chSizeBuf[0] = '-'; |
|
|
|
g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y, TILE_SIZE, TILE_TEXT / 2, |
|
255, 255, 255, 255, |
|
"%s%s\n" |
|
"%s Kb %dx%d %s", |
|
szPrintFilePrefix, szPrintFileName, |
|
chSizeBuf, |
|
iTxWidth, iTxHeight, |
|
szTxFormat |
|
); |
|
|
|
if ( !m_bufInfoText.TellPut() ) |
|
{ |
|
m_bufInfoText.Printf( |
|
"%s%s\r\n" |
|
"%s Kb %dx%d %s", |
|
szPrintFilePrefix, szPrintFileName, |
|
chSizeBuf, |
|
iTxWidth, iTxHeight, |
|
szTxFormat ); |
|
} |
|
|
|
if ( !kv->GetInt( "SpecialTx" ) ) |
|
{ |
|
char chLine1[256] = {0}; |
|
char chLine2[256] = {0}; |
|
|
|
// |
|
// Line 1 |
|
// |
|
if ( iTxSize > g_warn_texkbytes ) |
|
sprintf( chLine1 + strlen( chLine1 ), " Size(%s Kb)", chSizeBuf ); |
|
if ( ( iTxWidth > g_warn_texdimensions ) || |
|
( iTxHeight > g_warn_texdimensions ) ) |
|
sprintf( chLine1 + strlen( chLine1 ), " Dimensions(%dx%d)", iTxWidth, iTxHeight ); |
|
if ( stricmp( szTxFormat, "DXT1" ) && |
|
stricmp( szTxFormat, "DXT5" ) ) |
|
sprintf( chLine1 + strlen( chLine1 ), " Format(%s)", szTxFormat ); |
|
if ( pMatTexture->GetFlags() & TEXTUREFLAGS_NOLOD ) |
|
sprintf( chLine1 + strlen( chLine1 ), " NoLod" ); |
|
if ( pMatTexture->GetFlags() & TEXTUREFLAGS_NOMIP ) |
|
sprintf( chLine1 + strlen( chLine1 ), " NoMip" ); |
|
if ( pMatTexture->GetFlags() & TEXTUREFLAGS_ONEBITALPHA ) |
|
sprintf( chLine1 + strlen( chLine1 ), " OneBitAlpha" ); |
|
|
|
// |
|
// Line 2 |
|
// |
|
// Always show stats for higher/lower mips |
|
{ |
|
int wmap = pMatTexture->GetMappingWidth(), hmap = pMatTexture->GetMappingHeight(), dmap = pMatTexture->GetMappingDepth(); |
|
int wact = pMatTexture->GetActualWidth(), hact = pMatTexture->GetActualHeight(), dact = pMatTexture->GetActualDepth(); |
|
ImageFormat fmt = pMatTexture->GetImageFormat(); |
|
|
|
if ( wact > 4 || hact > 4 ) |
|
{ |
|
char chbuf[50]; |
|
int mem = ImageLoader::GetMemRequired( max( min( wact, 4 ), wact / 2 ), max( min( hact, 4 ), hact / 2 ), max( 1, dact / 2 ), fmt, true ); |
|
mem = ( mem + 511 ) / 1024; |
|
FmtCommaNumber( chbuf, mem ); |
|
|
|
sprintf ( chLine2 + strlen( chLine2 ), " %s Kb @ lower mip", chbuf ); |
|
} |
|
|
|
if ( wmap > wact || hmap > hact || dmap > dact ) |
|
{ |
|
char chbuf[ 50 ]; |
|
int mem = ImageLoader::GetMemRequired( min( wmap, wact * 2 ), min( hmap, hact * 2 ), min( dmap, dact * 2 ), fmt, true ); |
|
mem = ( mem + 511 ) / 1024; |
|
FmtCommaNumber( chbuf, mem ); |
|
|
|
sprintf ( chLine2 + strlen( chLine2 ), " %s Kb @ higher mip", chbuf ); |
|
} |
|
} |
|
|
|
if ( chLine1[0] ) |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 ); |
|
g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y + TILE_TEXT/2, x + TILE_BORDER/2 + (TILE_SIZE * 0.5), y + TILE_TEXT/2 + TILE_TEXT/4 ); |
|
g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y + TILE_TEXT/2, TILE_SIZE, TILE_TEXT / 4, |
|
255, 255, 255, 255, |
|
"%s", chLine1 ); |
|
} |
|
if ( chLine2[0] ) |
|
{ |
|
// g_pMatSystemSurface->DrawSetColor( 200, 0, 0, 255 ); |
|
// g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y + TILE_TEXT/2 + TILE_TEXT/4, x + TILE_BORDER/2 + TILE_SIZE, y + TILE_TEXT ); |
|
g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y + TILE_TEXT/2 + TILE_TEXT/4, TILE_SIZE, TILE_TEXT / 4, |
|
255, 255, 255, 255, |
|
"%s", chLine2 ); |
|
} |
|
} |
|
|
|
y += TILE_TEXT + TILE_BORDER; |
|
|
|
// Images placement |
|
bool bHasAlpha = !!stricmp( szTxFormat, "DXT1" ); |
|
|
|
int extTxWidth = TILE_SIZE; |
|
int extTxHeight = TILE_SIZE; |
|
|
|
int orgTxX = 0, orgTxXA = 0; |
|
int orgTxY = 0, orgTxYA = 0; |
|
|
|
if ( bHasAlpha ) |
|
{ |
|
if ( iTxWidth >= iTxHeight * 2 ) |
|
{ |
|
extTxHeight /= 2; |
|
orgTxYA = extTxHeight + TILE_BORDER/2; |
|
extTxHeight -= 1; |
|
} |
|
else if ( iTxHeight >= iTxWidth * 2 ) |
|
{ |
|
extTxWidth /= 2; |
|
orgTxXA = extTxWidth + TILE_BORDER/2; |
|
extTxWidth -= 3; |
|
} |
|
else |
|
{ |
|
extTxHeight /= 2; |
|
orgTxYA = extTxHeight + TILE_BORDER/2; |
|
orgTxX = extTxWidth / 4; |
|
extTxWidth /= 2; |
|
|
|
if ( iDrawWidth > extTxWidth ) |
|
{ |
|
iDrawWidth /= 2; |
|
iDrawHeight /= 2; |
|
} |
|
extTxWidth -= 1; |
|
extTxHeight -= 1; |
|
} |
|
} |
|
|
|
enum { IMG_FRAME_OFF = 2 }; |
|
if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturecolor", pMatTexture, &auto_matsysdebugmode ) ) |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 ); |
|
g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF ); |
|
RenderTexturedRect( this, pMaterial, |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 ); |
|
|
|
if ( bHasAlpha ) |
|
{ |
|
orgTxX += orgTxXA; |
|
orgTxY += orgTxYA; |
|
if ( IMaterial *pMaterialDebug = UseDebugMaterial( "debug/debugtexturealpha", pMatTexture, &auto_matsysdebugmode ) ) |
|
{ |
|
g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF ); |
|
RenderTexturedRect( this, pMaterialDebug, |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( 255, 0, 255, 100 ); |
|
g_pMatSystemSurface->DrawFilledRect( |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxWidth - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxWidth + iDrawHeight ) / 2 ); |
|
} |
|
|
|
y += TILE_SIZE + TILE_BORDER; |
|
} |
|
|
|
|
|
////////////////////////////////////////////////////////////////////////// |
|
// |
|
// Render textures view panel |
|
// |
|
////////////////////////////////////////////////////////////////////////// |
|
|
|
class CRenderTexturesListViewPanel : public vgui::TileViewPanelEx |
|
{ |
|
DECLARE_CLASS_SIMPLE( CRenderTexturesListViewPanel, vgui::TileViewPanelEx ); |
|
|
|
public: |
|
CRenderTexturesListViewPanel( vgui::Panel *parent, char const *szName ); |
|
~CRenderTexturesListViewPanel(); |
|
|
|
protected: |
|
virtual int GetNumTiles(); |
|
virtual void GetTileSize( int &wide, int &tall ); |
|
virtual void RenderTile( int iTile, int x, int y ); |
|
|
|
protected: |
|
virtual void PerformLayout(); |
|
virtual void OnMousePressed( vgui::MouseCode code ); |
|
virtual void OnMouseDoublePressed( vgui::MouseCode code ) { OnMousePressed( code ); } |
|
|
|
public: |
|
void SetDataListPanel( vgui::ListPanel *pPanel ); |
|
void SetPaintAlpha( bool bPaintAlpha ); |
|
|
|
CRenderTextureEditor * GetRenderTxEditor() const { return m_pRenderTxEditor; } |
|
|
|
protected: |
|
vgui::ListPanel *m_pListPanel; |
|
KeyValues * GetTileData( int iTile ); |
|
|
|
protected: |
|
CRenderTextureEditor *m_pRenderTxEditor; |
|
|
|
protected: |
|
enum |
|
{ |
|
TILE_BORDER = 20, |
|
TILE_SIZE = 192, |
|
TILE_TEXTURE_SIZE = 256, |
|
TILE_TEXT = 35 |
|
}; |
|
|
|
bool m_bPaintAlpha; |
|
}; |
|
|
|
CRenderTexturesListViewPanel::CRenderTexturesListViewPanel( vgui::Panel *parent, char const *szName ) : |
|
vgui::TileViewPanelEx( parent, szName ), |
|
m_pListPanel( NULL ), |
|
m_bPaintAlpha( false ) |
|
{ |
|
m_pRenderTxEditor = new CRenderTextureEditor( this, "TxEdt" ); |
|
m_pRenderTxEditor->SetPos( 10, 10 ); |
|
m_pRenderTxEditor->PerformLayout(); |
|
m_pRenderTxEditor->SetMoveable( true ); |
|
m_pRenderTxEditor->SetSizeable( false ); |
|
m_pRenderTxEditor->SetClipToParent( true ); |
|
m_pRenderTxEditor->SetTitle( "", true ); |
|
m_pRenderTxEditor->SetCloseButtonVisible( false ); |
|
m_pRenderTxEditor->SetVisible( false ); |
|
} |
|
|
|
CRenderTexturesListViewPanel::~CRenderTexturesListViewPanel() |
|
{ |
|
NULL; |
|
} |
|
|
|
void CRenderTexturesListViewPanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
} |
|
|
|
void CRenderTexturesListViewPanel::OnMousePressed( vgui::MouseCode code ) |
|
{ |
|
BaseClass::OnMousePressed( code ); |
|
|
|
// Figure out which tile got hit and pass its data for preview |
|
m_pRenderTxEditor->Close(); |
|
|
|
if ( !m_pListPanel ) |
|
return; |
|
|
|
int x, y; |
|
vgui::input()->GetCursorPos( x, y ); |
|
this->ScreenToLocal( x, y ); |
|
|
|
// Hit test the click |
|
int iTile, tileX, tileY; |
|
int htResult = HitTest( x, y, iTile ); |
|
if ( HT_NOTHING == htResult ) |
|
return; |
|
if ( !GetTileOrg( iTile, tileX, tileY ) ) |
|
return; |
|
|
|
// Now having the tile retrieve the keyvalues |
|
int itemId = m_pListPanel->GetItemIDFromRow( iTile ); |
|
if ( itemId < 0 ) |
|
return; |
|
KeyValues *kv = m_pListPanel->GetItem( itemId ); |
|
if ( !kv ) |
|
return; |
|
|
|
// Display the tx editor |
|
m_pRenderTxEditor->SetDispInfo( kv, itemId ); |
|
|
|
if ( tileX + m_pRenderTxEditor->GetWide() > m_li_wide - 2 ) |
|
tileX -= tileX + m_pRenderTxEditor->GetWide() - ( m_li_wide - 2 ); |
|
if ( tileY + m_pRenderTxEditor->GetTall() > m_li_tall - 2 ) |
|
tileY -= tileY + m_pRenderTxEditor->GetTall() - ( m_li_tall - 2 ); |
|
|
|
int iTopLeftX = 0, iTopLeftY = 0; |
|
for ( vgui::Panel *pPanel = this; ( pPanel = pPanel->GetParent() ) != NULL; ) |
|
{ |
|
iTopLeftX = iTopLeftY = 0; |
|
pPanel->LocalToScreen( iTopLeftX, iTopLeftY ); |
|
} |
|
|
|
LocalToScreen( tileX, tileY ); |
|
if ( tileX < iTopLeftX ) tileX = iTopLeftX; |
|
if ( tileY < iTopLeftY ) tileY = iTopLeftY; |
|
|
|
m_pRenderTxEditor->SetPos( tileX, tileY ); |
|
m_pRenderTxEditor->Activate(); |
|
} |
|
|
|
int CRenderTexturesListViewPanel::GetNumTiles() |
|
{ |
|
return m_pListPanel ? m_pListPanel->GetItemCount() : 0; |
|
} |
|
|
|
void CRenderTexturesListViewPanel::GetTileSize( int &wide, int &tall ) |
|
{ |
|
wide = 2 * TILE_BORDER + TILE_SIZE; |
|
tall = 2 * TILE_BORDER + TILE_SIZE + TILE_TEXT; |
|
}; |
|
|
|
KeyValues * CRenderTexturesListViewPanel::GetTileData( int iTile ) |
|
{ |
|
int iData = m_pListPanel->GetItemIDFromRow( iTile ); |
|
if ( iData < 0 ) |
|
return NULL; |
|
|
|
return m_pListPanel->GetItem( iData ); |
|
} |
|
|
|
void CRenderTexturesListViewPanel::RenderTile( int iTile, int x, int y ) |
|
{ |
|
CAutoMatSysDebugMode auto_matsysdebugmode; |
|
|
|
KeyValues *kv = GetTileData( iTile ); |
|
if ( !kv ) |
|
return; |
|
|
|
char const *szTextureFile = kv->GetString( KEYNAME_NAME ); |
|
char const *szTextureGroup = kv->GetString( KEYNAME_TEXTURE_GROUP ); |
|
ITexture *pMatTexture = NULL; |
|
if ( *szTextureFile ) |
|
pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false ); |
|
if ( !pMatTexture ) |
|
pMatTexture = materials->FindTexture( "debugempty", "", false ); |
|
|
|
// Determine the texture size |
|
int iTxWidth = kv->GetInt( KEYNAME_WIDTH ); |
|
int iTxHeight = kv->GetInt( KEYNAME_HEIGHT ); |
|
int iTxSize = kv->GetInt( KEYNAME_SIZE ); |
|
char const *szTxFormat = kv->GetString( KEYNAME_FORMAT ); |
|
|
|
int iTxFormatLen = strlen( szTxFormat ); |
|
char *szTxFormatSuffix = ""; |
|
if ( iTxFormatLen > 4 ) |
|
{ |
|
fmtlenreduce: |
|
switch ( szTxFormat[ iTxFormatLen - 1 ] ) |
|
{ |
|
case '8': |
|
{ |
|
while ( ( iTxFormatLen > 4 ) && |
|
( szTxFormat[ iTxFormatLen - 2 ] == '8' ) ) |
|
-- iTxFormatLen; |
|
} |
|
break; |
|
case '6': |
|
{ |
|
while ( ( iTxFormatLen > 4 ) && |
|
( szTxFormat[ iTxFormatLen - 2 ] == '1' ) && |
|
( szTxFormat[ iTxFormatLen - 3 ] == '6' ) ) |
|
iTxFormatLen -= 2; |
|
} |
|
break; |
|
case 'F': |
|
if ( !*szTxFormatSuffix ) |
|
{ |
|
iTxFormatLen --; |
|
szTxFormatSuffix = "F"; |
|
goto fmtlenreduce; |
|
} |
|
break; |
|
} |
|
} |
|
|
|
// Dimensions to draw |
|
int iDrawWidth = iTxWidth; |
|
int iDrawHeight = iTxHeight; |
|
|
|
if ( pMatTexture && pMatTexture->IsCubeMap() ) |
|
{ |
|
iDrawWidth = 1024; |
|
iDrawHeight = 1024; |
|
} |
|
|
|
if ( iDrawHeight >= iDrawWidth ) |
|
{ |
|
if ( iDrawHeight > TILE_TEXTURE_SIZE ) |
|
{ |
|
iDrawWidth = iDrawWidth * ( float( TILE_TEXTURE_SIZE ) / iDrawHeight ); |
|
iDrawHeight = TILE_TEXTURE_SIZE; |
|
} |
|
|
|
if ( iDrawHeight < 64 ) |
|
{ |
|
iDrawWidth = iDrawWidth * ( float( 64 ) / iDrawHeight ); |
|
iDrawHeight = 64; |
|
} |
|
} |
|
else |
|
{ |
|
if ( iDrawWidth > TILE_TEXTURE_SIZE ) |
|
{ |
|
iDrawHeight = iDrawHeight * ( float( TILE_TEXTURE_SIZE ) / iDrawWidth ); |
|
iDrawWidth = TILE_TEXTURE_SIZE; |
|
} |
|
|
|
if ( iDrawWidth < 64 ) |
|
{ |
|
iDrawHeight = iDrawHeight * ( float( 64 ) / iDrawWidth ); |
|
iDrawWidth = 64; |
|
} |
|
} |
|
|
|
iDrawHeight = iDrawHeight / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) ); |
|
iDrawWidth = iDrawWidth / ( float( TILE_TEXTURE_SIZE ) / float( TILE_SIZE ) ); |
|
|
|
iDrawHeight = max( iDrawHeight, 4 ); |
|
iDrawWidth = max( iDrawWidth, 4 ); |
|
|
|
// |
|
// Draw frame |
|
// |
|
{ |
|
int tileWidth, tileHeight; |
|
GetTileSize( tileWidth, tileHeight ); |
|
g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 ); |
|
g_pMatSystemSurface->DrawOutlinedRect( x + 1, y + 1, |
|
x + tileWidth - 2 , y + tileHeight - 2 ); |
|
} |
|
|
|
// |
|
// Draw all |
|
// |
|
|
|
x += TILE_BORDER; |
|
y += TILE_BORDER/2; |
|
|
|
int iLenFile = strlen( szTextureFile ); |
|
char const *szPrintFilePrefix = ( iLenFile > 22 ) ? "..." : ""; |
|
char const *szPrintFileName = ( iLenFile > 22 ) ? ( szTextureFile + iLenFile - 22 ) : szTextureFile; |
|
|
|
char chSizeBuf[20] = {0}; |
|
if ( iTxSize >= 0 ) |
|
{ |
|
FmtCommaNumber( chSizeBuf, iTxSize ); |
|
} |
|
else |
|
{ |
|
chSizeBuf[0] = '-'; |
|
} |
|
|
|
static Color clrLblNormal( 25, 50, 25, 255 ); |
|
static Color clrLblWarn( 75, 75, 0, 255 ); |
|
static Color clrLblError( 200, 0, 0, 255 ); |
|
bool bWarnTile = ( !kv->GetInt( "SpecialTx" ) ) && ( g_warn_enable && ShallWarnTx( kv, pMatTexture ) ); |
|
g_pMatSystemSurface->DrawSetColor( bWarnTile ? clrLblWarn : clrLblNormal ); |
|
g_pMatSystemSurface->DrawFilledRect( x - TILE_BORDER/2, y, x + TILE_BORDER/2 + TILE_SIZE, y + TILE_TEXT ); |
|
|
|
char chInfoText[256] = { 0 }; |
|
sprintf( chInfoText, "%s Kb %dx%d %.*s%s %s", |
|
chSizeBuf, |
|
iTxWidth, iTxHeight, |
|
iTxFormatLen, szTxFormat, szTxFormatSuffix, |
|
( pMatTexture->GetFlags() & ( |
|
TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA |
|
) ) ? "***" : "" ); |
|
int iTextMargins[4] = { 0 }; |
|
int iTextHeight = g_pMatSystemSurface->GetFontTall( GetFont() ); |
|
{ |
|
// Compute text extents |
|
int iTextLen[4] = { 0 }; |
|
iTextLen[0] = 5 + strlen( chSizeBuf ); |
|
iTextLen[1] = strchr( chInfoText, 'x' ) + 1 - chInfoText; |
|
while ( chInfoText[ iTextLen[1] ] != ' ' ) |
|
++ iTextLen[1]; |
|
++ iTextLen[1]; |
|
iTextLen[2] = 2 + iTextLen[1] + iTxFormatLen + strlen( szTxFormatSuffix ); |
|
iTextLen[3] = strlen( chInfoText ); |
|
for ( int k = 0; k < 4; ++ k ) |
|
iTextMargins[k] = g_pMatSystemSurface->DrawTextLen( GetFont(), "%.*s", iTextLen[k], chInfoText ); |
|
} |
|
|
|
// Highlights |
|
if ( bWarnTile ) |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( clrLblError ); |
|
if ( iTxSize > g_warn_texkbytes ) |
|
g_pMatSystemSurface->DrawFilledRect( x - 2, y + iTextHeight + 1, x + iTextMargins[0] - 5, y + TILE_TEXT ); |
|
if ( iTxWidth > g_warn_texdimensions || iTxHeight > g_warn_texdimensions ) |
|
g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[0] - 2, y + iTextHeight + 1, x + iTextMargins[1] - 1, y + TILE_TEXT ); |
|
if ( strcmp( szTxFormat, "DXT1" ) && strcmp( szTxFormat, "DXT5" ) ) |
|
g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[1] + 2, y + iTextHeight + 1, x + iTextMargins[2] - 1, y + TILE_TEXT ); |
|
if ( pMatTexture->GetFlags() & ( |
|
TEXTUREFLAGS_NOLOD | TEXTUREFLAGS_NOMIP | TEXTUREFLAGS_ONEBITALPHA |
|
) ) |
|
g_pMatSystemSurface->DrawFilledRect( x + iTextMargins[2] + 3, y + iTextHeight + 1, x + iTextMargins[3] + 2, y + TILE_TEXT ); |
|
} |
|
|
|
g_pMatSystemSurface->DrawColoredTextRect( GetFont(), x, y, TILE_SIZE, TILE_TEXT, |
|
255, 255, 255, 255, |
|
"%s%s\n" |
|
"%s", |
|
szPrintFilePrefix, szPrintFileName, |
|
chInfoText |
|
); |
|
|
|
y += TILE_TEXT + TILE_BORDER/2; |
|
|
|
// Images placement |
|
bool bHasAlpha = m_bPaintAlpha && stricmp( szTxFormat, "DXT1" ); |
|
|
|
int extTxWidth = TILE_SIZE; |
|
int extTxHeight = TILE_SIZE; |
|
|
|
int orgTxX = 0, orgTxXA = 0; |
|
int orgTxY = 0, orgTxYA = 0; |
|
|
|
if ( bHasAlpha ) |
|
{ |
|
if ( iTxWidth >= iTxHeight * 2 ) |
|
{ |
|
extTxHeight /= 2; |
|
orgTxYA = extTxHeight + TILE_BORDER/2; |
|
} |
|
else if ( iTxHeight >= iTxWidth * 2 ) |
|
{ |
|
extTxWidth /= 2; |
|
orgTxXA = extTxWidth + TILE_BORDER/2; |
|
x -= TILE_BORDER/4 + 1; |
|
} |
|
else |
|
{ |
|
extTxHeight /= 2; |
|
orgTxYA = extTxHeight + TILE_BORDER/2; |
|
orgTxX = extTxWidth / 4; |
|
extTxWidth /= 2; |
|
x -= TILE_BORDER/4 + 1; |
|
|
|
if ( iDrawWidth > extTxWidth ) |
|
{ |
|
iDrawWidth /= 2; |
|
iDrawHeight /= 2; |
|
} |
|
} |
|
} |
|
|
|
enum { IMG_FRAME_OFF = 2 }; |
|
if ( IMaterial *pMaterial = UseDebugMaterial( "debug/debugtexturecolor", pMatTexture, &auto_matsysdebugmode ) ) |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( 255, 255, 255, 255 ); |
|
g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF ); |
|
RenderTexturedRect( this, pMaterial, |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2, |
|
2, 1 ); |
|
|
|
if ( bHasAlpha ) |
|
{ |
|
orgTxX += orgTxXA; |
|
orgTxY += orgTxYA; |
|
if ( IMaterial *pMaterialDebug = UseDebugMaterial( "debug/debugtexturealpha", pMatTexture, &auto_matsysdebugmode ) ) |
|
{ |
|
g_pMatSystemSurface->DrawOutlinedRect( x + orgTxX + ( extTxWidth - iDrawWidth ) / 2 - IMG_FRAME_OFF, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2 - IMG_FRAME_OFF, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2 + IMG_FRAME_OFF, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2 + IMG_FRAME_OFF ); |
|
RenderTexturedRect( this, pMaterialDebug, |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxHeight - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxHeight + iDrawHeight ) / 2, |
|
2, 1 ); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
g_pMatSystemSurface->DrawSetColor( 255, 0, 255, 100 ); |
|
g_pMatSystemSurface->DrawFilledRect( |
|
x + orgTxX + ( extTxWidth - iDrawWidth ) / 2, y + orgTxY + ( extTxWidth - iDrawHeight ) / 2, |
|
x + orgTxX + ( extTxWidth + iDrawWidth ) / 2, y + orgTxY + ( extTxWidth + iDrawHeight ) / 2 ); |
|
} |
|
|
|
y += TILE_SIZE + TILE_BORDER; |
|
} |
|
|
|
void CRenderTexturesListViewPanel::SetDataListPanel( vgui::ListPanel *pPanel ) |
|
{ |
|
m_pListPanel = pPanel; |
|
InvalidateLayout(); |
|
} |
|
|
|
void CRenderTexturesListViewPanel::SetPaintAlpha( bool bPaintAlpha ) |
|
{ |
|
m_bPaintAlpha = bPaintAlpha; |
|
Repaint(); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Shows entity status report if cl_entityreport cvar is set |
|
//----------------------------------------------------------------------------- |
|
class CTextureListPanel : public vgui::Frame |
|
{ |
|
DECLARE_CLASS_SIMPLE( CTextureListPanel, vgui::Frame ); |
|
|
|
public: |
|
// Construction |
|
CTextureListPanel( vgui::Panel *parent ); |
|
virtual ~CTextureListPanel( void ); |
|
|
|
// Refresh |
|
virtual void Paint(); |
|
void EndPaint(); // Still inside paint |
|
virtual void ApplySchemeSettings( vgui::IScheme *pScheme ); |
|
virtual bool ShouldDraw(); |
|
virtual void PerformLayout(); |
|
virtual void Close(); |
|
|
|
void OnTurnedOn(); |
|
|
|
private: |
|
|
|
void UpdateTotalUsageLabel(); |
|
virtual void OnCommand( const char *command ); |
|
MESSAGE_FUNC( OnTextChanged, "TextChanged" ); |
|
|
|
int AddListItem( KeyValues *kv ); |
|
|
|
bool UpdateDisplayedItem( KeyValues *pDispData, KeyValues *kv ); |
|
|
|
|
|
private: |
|
|
|
// Font to use for drawing |
|
vgui::HFont m_hFont; |
|
vgui::ListPanel *m_pListPanel; |
|
CRenderTexturesListViewPanel *m_pViewPanel; |
|
|
|
vgui::CheckButton *m_pSpecialTexs; |
|
vgui::CheckButton *m_pResolveTexturePath; |
|
CConVarCheckButton *m_pShowTextureMemoryUsageOption; |
|
CConVarCheckButton *m_pAllTextures; |
|
CConVarCheckButton *m_pViewTextures; |
|
vgui::Button *m_pCopyToClipboardButton; |
|
vgui::ToggleButton *m_pCollapse; |
|
vgui::CheckButton *m_pAlpha; |
|
vgui::CheckButton *m_pThumbWarnings; |
|
|
|
vgui::CheckButton *m_pHideMipped; |
|
vgui::CheckButton *m_pFilteringChk; |
|
vgui::TextEntry *m_pFilteringText; |
|
int m_numDisplayedSizeKB; |
|
|
|
vgui::Button *m_pReloadAllMaterialsButton; |
|
vgui::Button *m_pCommitChangesButton; |
|
vgui::Button *m_pDiscardChangesButton; |
|
|
|
vgui::Label *m_pCVarListLabel; |
|
vgui::Label *m_pTotalUsageLabel; |
|
}; |
|
|
|
|
|
static int __cdecl KilobytesSortFunc( vgui::ListPanel *pPanel, const vgui::ListPanelItem &item1, const vgui::ListPanelItem &item2 ) |
|
{ |
|
// Reverse sort order so the bigger textures show up first |
|
const char *string1 = item1.kv->GetString( KEYNAME_SIZE ); |
|
const char *string2 = item2.kv->GetString( KEYNAME_SIZE ); |
|
int a = atoi( string1 ); |
|
int b = atoi( string2 ); |
|
if( a < b ) |
|
{ |
|
return 1; |
|
} |
|
if( a > b ) |
|
{ |
|
return -1; |
|
} |
|
return 0; |
|
} |
|
|
|
|
|
// |
|
// Smart texture list |
|
// |
|
class CSmartTextureKeyValues |
|
{ |
|
private: |
|
CSmartTextureKeyValues( CSmartTextureKeyValues const &x ); |
|
CSmartTextureKeyValues& operator = ( CSmartTextureKeyValues const &x ); |
|
|
|
public: |
|
CSmartTextureKeyValues() : m_p( NULL ) { if ( KeyValues *p = g_pMaterialSystemDebugTextureInfo->GetDebugTextureList() ) m_p = p->MakeCopy(); } |
|
~CSmartTextureKeyValues() { if ( m_p ) m_p->deleteThis(); m_p = NULL; } |
|
|
|
KeyValues * Get() const { return m_p; }; |
|
|
|
protected: |
|
KeyValues *m_p; |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Instances the entity report panel |
|
// Input : *parent - |
|
//----------------------------------------------------------------------------- |
|
CTextureListPanel::CTextureListPanel( vgui::Panel *parent ) : |
|
BaseClass( parent, "CTextureListPanel" ), |
|
m_numDisplayedSizeKB( 0 ) |
|
{ |
|
// Need parent here, before loading up textures, so getSurfaceBase |
|
// will work on this panel ( it's null otherwise ) |
|
SetSize( videomode->GetModeStereoWidth() - 20, videomode->GetModeStereoHeight() - 20 ); |
|
SetPos( 10, 10 ); |
|
SetVisible( true ); |
|
SetCursor( null ); |
|
|
|
SetTitle( "Texture list", false ); |
|
SetMenuButtonVisible( false ); |
|
|
|
m_hFont = vgui::INVALID_FONT; |
|
|
|
SetFgColor( Color( 0, 0, 0, 255 ) ); |
|
SetPaintBackgroundEnabled( true ); |
|
|
|
// Init the buttons. |
|
m_pCVarListLabel = vgui::SETUP_PANEL( new vgui::Label( this, "m_pCVarListLabel", |
|
"cvars: mat_texture_limit, mat_texture_list, mat_picmip, mat_texture_list_txlod, mat_texture_list_txlod_sync" ) ); |
|
m_pCVarListLabel->SetVisible( false ); // m_pCVarListLabel->SetVisible( true ); |
|
|
|
m_pTotalUsageLabel = vgui::SETUP_PANEL( new vgui::Label( this, "m_pTotalUsageLabel", "" ) ); |
|
m_pTotalUsageLabel->SetVisible( true ); |
|
|
|
m_pSpecialTexs = vgui::SETUP_PANEL( new vgui::CheckButton( this, "service", "Render Targets and Special Textures" ) ); |
|
m_pSpecialTexs->SetVisible( true ); |
|
m_pSpecialTexs->AddActionSignalTarget( this ); |
|
m_pSpecialTexs->SetCommand( "service" ); |
|
|
|
m_pResolveTexturePath = vgui::SETUP_PANEL( new vgui::CheckButton( this, "resolvepath", "Resolve Full Texture Path" ) ); |
|
m_pResolveTexturePath->SetVisible( true ); |
|
m_pResolveTexturePath->AddActionSignalTarget( this ); |
|
m_pResolveTexturePath->SetCommand( "resolvepath" ); |
|
|
|
m_pShowTextureMemoryUsageOption = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pShowTextureMemoryUsageOption", "Show Memory Usage on HUD" ) ); |
|
m_pShowTextureMemoryUsageOption->SetVisible( true ); |
|
m_pShowTextureMemoryUsageOption->SetConVar( &mat_show_texture_memory_usage ); |
|
|
|
m_pAllTextures = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pAllTextures", "Show ALL textures" ) ); |
|
m_pAllTextures->SetVisible( true ); |
|
m_pAllTextures->SetConVar( &mat_texture_list_all ); |
|
m_pAllTextures->AddActionSignalTarget( this ); |
|
m_pAllTextures->SetCommand( "AllTextures" ); |
|
|
|
m_pViewTextures = vgui::SETUP_PANEL( new CConVarCheckButton( this, "m_pViewTextures", "View textures thumbnails" ) ); |
|
m_pViewTextures->SetVisible( true ); |
|
m_pViewTextures->SetConVar( &mat_texture_list_view ); |
|
m_pViewTextures->AddActionSignalTarget( this ); |
|
m_pViewTextures->SetCommand( "ViewThumbnails" ); |
|
|
|
m_pCopyToClipboardButton = vgui::SETUP_PANEL( new vgui::Button( this, "CopyToClipboard", "Copy to Clipboard" ) ); |
|
if ( m_pCopyToClipboardButton ) |
|
{ |
|
m_pCopyToClipboardButton->AddActionSignalTarget( this ); |
|
m_pCopyToClipboardButton->SetCommand( COPYTOCLIPBOARD_CMDNAME ); |
|
} |
|
|
|
m_pCollapse = vgui::SETUP_PANEL( new vgui::ToggleButton( this, "Collapse", " " ) ); |
|
m_pCollapse->AddActionSignalTarget( this ); |
|
m_pCollapse->SetCommand( "Collapse" ); |
|
m_pCollapse->SetSelected( true ); |
|
|
|
m_pAlpha = vgui::SETUP_PANEL( new vgui::CheckButton( this, "ShowAlpha", "Alpha" ) ); |
|
m_pAlpha->AddActionSignalTarget( this ); |
|
m_pAlpha->SetCommand( "ShowAlpha" ); |
|
bool bDefaultTxAlphaOn = true; |
|
m_pAlpha->SetSelected( bDefaultTxAlphaOn ); |
|
|
|
m_pThumbWarnings = vgui::SETUP_PANEL( new vgui::CheckButton( this, "ThumbWarnings", "Warns" ) ); |
|
m_pThumbWarnings->AddActionSignalTarget( this ); |
|
m_pThumbWarnings->SetCommand( "ThumbWarnings" ); |
|
m_pThumbWarnings->SetSelected( g_warn_enable ); |
|
|
|
// Filtering |
|
m_pHideMipped = vgui::SETUP_PANEL( new vgui::CheckButton( this, "HideMipped", "Hide Mipped" ) ); |
|
m_pHideMipped->AddActionSignalTarget( this ); |
|
m_pHideMipped->SetCommand( "HideMipped" ); |
|
m_pHideMipped->SetSelected( false ); |
|
|
|
// Filtering |
|
m_pFilteringChk = vgui::SETUP_PANEL( new vgui::CheckButton( this, "FilteringChk", "Filter: " ) ); |
|
m_pFilteringChk->AddActionSignalTarget( this ); |
|
m_pFilteringChk->SetCommand( "FilteringChk" ); |
|
m_pFilteringChk->SetSelected( true ); |
|
|
|
m_pFilteringText = vgui::SETUP_PANEL( new vgui::TextEntry( this, "FilteringTxt" ) ); |
|
m_pFilteringText->AddActionSignalTarget( this ); |
|
|
|
m_pReloadAllMaterialsButton = vgui::SETUP_PANEL( new vgui::Button( this, "ReloadAllMaterials", "Reload All Materials" ) ); |
|
if ( m_pReloadAllMaterialsButton ) |
|
{ |
|
m_pReloadAllMaterialsButton->AddActionSignalTarget( this ); |
|
m_pReloadAllMaterialsButton->SetCommand( "ReloadAllMaterials" ); |
|
} |
|
m_pCommitChangesButton = vgui::SETUP_PANEL( new vgui::Button( this, "CommitChanges", "Commit Changes" ) ); |
|
if ( m_pCommitChangesButton ) |
|
{ |
|
m_pCommitChangesButton->AddActionSignalTarget( this ); |
|
m_pCommitChangesButton->SetCommand( "CommitChanges" ); |
|
} |
|
m_pDiscardChangesButton = vgui::SETUP_PANEL( new vgui::Button( this, "DiscardChanges", "Discard Changes" ) ); |
|
if ( m_pDiscardChangesButton ) |
|
{ |
|
m_pDiscardChangesButton->AddActionSignalTarget( this ); |
|
m_pDiscardChangesButton->SetCommand( "DiscardChanges" ); |
|
} |
|
|
|
// Create the tree control itself. |
|
m_pListPanel = vgui::SETUP_PANEL( new vgui::ListPanel( this, "List Panel" ) ); |
|
m_pListPanel->SetVisible( !mat_texture_list_view.GetBool() ); |
|
|
|
int col = -1; |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_NAME, "Texture Name", 200, 100, 700, vgui::ListPanel::COLUMN_RESIZEWITHWINDOW ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_PATH, "Path", 50, 50, 300, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_SIZE, "Kilobytes", 50, 50, 50, 0 ); |
|
m_pListPanel->SetSortFunc( col, KilobytesSortFunc ); |
|
m_pListPanel->SetSortColumnEx( col, 0, true ); // advanced sorting setup |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_TEXTURE_GROUP, "Group", 100, 100, 300, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_FORMAT, "Format", 250, 50, 300, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_WIDTH, "Width", 50, 50, 50, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_HEIGHT, "Height", 50, 50, 50, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_BINDS_FRAME, "# Binds", 50, 50, 50, 0 ); |
|
m_pListPanel->AddColumnHeader( ++ col, KEYNAME_BINDS_MAX, "BindsMax", 50, 50, 50, 0 ); |
|
|
|
SetBgColor( Color( 0, 0, 0, 100 ) ); |
|
|
|
m_pListPanel->SetBgColor( Color( 0, 0, 0, 100 ) ); |
|
|
|
// Create the view control itself |
|
m_pViewPanel = vgui::SETUP_PANEL( new CRenderTexturesListViewPanel( this, "View Panel" ) ); |
|
m_pViewPanel->SetVisible( mat_texture_list_view.GetBool() ); |
|
m_pViewPanel->SetBgColor( Color( 0, 0, 0, 255 ) ); |
|
|
|
m_pViewPanel->SetDragEnabled( false ); |
|
m_pViewPanel->SetDropEnabled( false ); |
|
m_pViewPanel->SetPaintAlpha( bDefaultTxAlphaOn ); |
|
|
|
m_pViewPanel->SetDataListPanel( m_pListPanel ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTextureListPanel::~CTextureListPanel( void ) |
|
{ |
|
g_pTextureListPanel = NULL; |
|
} |
|
|
|
void CTextureListPanel::ApplySchemeSettings( vgui::IScheme *pScheme ) |
|
{ |
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
|
|
// If you change this font, be sure to mark it with |
|
// $use_in_fillrate_mode in its .vmt file |
|
m_hFont = pScheme->GetFont( "DefaultVerySmall", false ); |
|
Assert( m_hFont ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Output : Returns true on success, false on failure. |
|
//----------------------------------------------------------------------------- |
|
bool CTextureListPanel::ShouldDraw( void ) |
|
{ |
|
if ( mat_texture_list.GetInt() ) |
|
return true; |
|
if ( s_eTxListPanelRequest == TXR_SHOW || |
|
s_eTxListPanelRequest == TXR_RUNNING ) |
|
return true; |
|
|
|
return false; |
|
} |
|
|
|
void CTextureListPanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
// Put the collapse button in the corner |
|
m_pCollapse->SetPos( 2, 10 ); |
|
m_pCollapse->SetSize( 10, 10 ); |
|
m_pCollapse->SetVisible( true ); |
|
|
|
bool bCollapsed = m_pCollapse->IsSelected(); |
|
|
|
int x, y, w, t; |
|
GetClientArea( x, y, w, t ); |
|
|
|
int yOffset = y; |
|
|
|
// The cvar reminder goes on the top. |
|
m_pCVarListLabel->SetPos( x, yOffset ); |
|
m_pCVarListLabel->SetWide( w ); |
|
NULL; // yOffset += m_pCVarListLabel->GetTall(); |
|
m_pCVarListLabel->SetVisible( false ); // m_pCVarListLabel->SetVisible( !bCollapsed ); |
|
|
|
m_pTotalUsageLabel->SetPos( x, yOffset ); |
|
m_pTotalUsageLabel->SetWide( w ); |
|
yOffset += m_pTotalUsageLabel->GetTall(); |
|
m_pTotalUsageLabel->SetVisible( !bCollapsed ); |
|
|
|
// Align the check boxes. |
|
vgui::Panel *buttons[] = { |
|
m_pSpecialTexs, |
|
m_pShowTextureMemoryUsageOption, |
|
m_pAllTextures, |
|
m_pViewTextures, |
|
m_pFilteringChk, |
|
m_pHideMipped, |
|
m_pResolveTexturePath, |
|
m_pCopyToClipboardButton }; |
|
|
|
for ( int i=0; i < ARRAYSIZE( buttons ); i++ ) |
|
{ |
|
buttons[i]->SetPos( x, yOffset ); |
|
buttons[i]->SetWide( w/2 ); |
|
yOffset += buttons[i]->GetTall(); |
|
buttons[i]->SetVisible( !bCollapsed ); |
|
|
|
if ( buttons[i] == m_pViewTextures ) |
|
{ |
|
m_pViewTextures->SetWide( 170 ); |
|
int accumw = 170; |
|
|
|
m_pAlpha->SetPos( x + accumw + 5, yOffset - m_pViewTextures->GetTall() ); |
|
m_pAlpha->SetWide( (accumw += 85, 85) ); |
|
|
|
m_pThumbWarnings->SetPos( x + accumw + 5, yOffset - m_pViewTextures->GetTall() ); |
|
m_pThumbWarnings->SetWide( (accumw += 85, 85) ); |
|
} |
|
|
|
if ( buttons[i] == m_pFilteringChk ) |
|
{ |
|
m_pFilteringChk->SetWide( 60 ); |
|
int accumw = 60; |
|
|
|
m_pFilteringText->SetPos( x + accumw + 5, yOffset - m_pFilteringChk->GetTall() ); |
|
m_pFilteringText->SetWide( ( accumw += 170, 170 ) ); |
|
m_pFilteringText->SetTall( m_pFilteringChk->GetTall() ); |
|
m_pFilteringText->SetVisible( !bCollapsed ); |
|
} |
|
} |
|
|
|
if ( bCollapsed ) |
|
{ |
|
int xOffset = 85, iWidth; |
|
|
|
struct LayoutHorz_t |
|
{ |
|
vgui::Panel *pPanel; |
|
int iWidth; |
|
} |
|
layout[] = |
|
{ |
|
{ m_pTotalUsageLabel, 290 }, |
|
{ m_pViewTextures, 170 }, |
|
{ m_pAlpha, 60 }, |
|
{ m_pAllTextures, 135 }, |
|
{ m_pHideMipped, 100 }, |
|
{ m_pFilteringChk, 60 }, |
|
{ m_pFilteringText, 130 }, |
|
{ m_pReloadAllMaterialsButton, 130 }, |
|
{ m_pCommitChangesButton, 130 }, |
|
{ m_pDiscardChangesButton, 130 }, |
|
}; |
|
|
|
for ( int k = 0; k < ARRAYSIZE( layout ); ++ k ) |
|
{ |
|
layout[ k ].pPanel->SetPos( xOffset, 2 ); |
|
iWidth = layout[ k ].iWidth; |
|
iWidth = min( w - xOffset - 30, iWidth ); |
|
layout[ k ].pPanel->SetWide( iWidth ); |
|
layout[ k ].pPanel->SetVisible( iWidth > 50 ); |
|
|
|
if ( iWidth > 50 ) |
|
xOffset += iWidth + 5; |
|
} |
|
|
|
yOffset = y; |
|
} |
|
|
|
m_pAlpha->SetVisible( m_pViewTextures->IsSelected() ); |
|
m_pThumbWarnings->SetVisible( !bCollapsed && m_pViewTextures->IsSelected() ); |
|
|
|
m_pListPanel->SetBounds( x, yOffset, w, t - (yOffset - y) ); |
|
m_pViewPanel->SetBounds( x, yOffset, w, t - (yOffset - y) ); |
|
|
|
m_pListPanel->SetVisible( !mat_texture_list_view.GetBool() ); |
|
m_pViewPanel->SetVisible( mat_texture_list_view.GetBool() ); |
|
} |
|
|
|
|
|
bool StripDirName( char *pFilename ) |
|
{ |
|
if ( pFilename[0] == 0 ) |
|
return false; |
|
|
|
char *pLastSlash = pFilename; |
|
while ( 1 ) |
|
{ |
|
char *pTestSlash = strchr( pLastSlash, '/' ); |
|
if ( !pTestSlash ) |
|
{ |
|
pTestSlash = strchr( pLastSlash, '\\' ); |
|
if ( !pTestSlash ) |
|
break; |
|
} |
|
|
|
pTestSlash++; // Skip past the slash. |
|
pLastSlash = pTestSlash; |
|
} |
|
|
|
if ( pLastSlash == pFilename ) |
|
{ |
|
return false; |
|
} |
|
else |
|
{ |
|
Assert( pLastSlash[-1] == '/' || pLastSlash[-1] == '\\' ); |
|
pLastSlash[-1] = 0; |
|
return true; |
|
} |
|
} |
|
|
|
static inline void ToLowerInplace( char *chBuffer ) |
|
{ |
|
for ( char *pch = chBuffer; *pch; ++ pch ) |
|
{ |
|
if ( V_isupper( *pch ) ) |
|
*pch = tolower( *pch ); |
|
} |
|
} |
|
|
|
void KeepSpecialKeys( KeyValues *textureList, bool bServiceKeys ) |
|
{ |
|
KeyValues *pNext; |
|
|
|
for ( KeyValues *pCur = textureList->GetFirstSubKey(); pCur; pCur=pNext ) |
|
{ |
|
pNext = pCur->GetNextKey(); |
|
|
|
bool bIsServiceKey = false; |
|
|
|
char const *szName = pCur->GetString( KEYNAME_NAME ); |
|
if ( StringHasPrefix( szName, "_" ) || |
|
StringHasPrefix( szName, "[" ) || |
|
!stricmp( szName, "backbuffer" ) || |
|
StringHasPrefix( szName, "colorcorrection" ) || |
|
!stricmp( szName, "depthbuffer" ) || |
|
!stricmp( szName, "frontbuffer" ) || |
|
!stricmp( szName, "normalize" ) || |
|
!*szName ) |
|
{ |
|
bIsServiceKey = true; |
|
} |
|
|
|
if ( bIsServiceKey != bServiceKeys ) |
|
{ |
|
textureList->RemoveSubKey( pCur ); |
|
} |
|
else if ( bIsServiceKey ) |
|
{ |
|
pCur->SetInt( "SpecialTx", 1 ); |
|
} |
|
} |
|
} |
|
|
|
void KeepKeysMatchingFilter( KeyValues *textureList, char const *szFilter ) |
|
{ |
|
if ( !szFilter || !*szFilter ) |
|
return; |
|
|
|
char chFilter[MAX_PATH] = {0}, chName[MAX_PATH] = {0}; |
|
|
|
Q_strncpy( chFilter, szFilter, sizeof( chFilter ) - 1 ); |
|
ToLowerInplace( chFilter ); |
|
|
|
KeyValues *pNext; |
|
for ( KeyValues *pCur=textureList->GetFirstSubKey(); pCur; pCur=pNext ) |
|
{ |
|
pNext = pCur->GetNextKey(); |
|
|
|
char const *szName = pCur->GetString( KEYNAME_NAME ); |
|
|
|
Q_strncpy( chName, szName, sizeof( chName ) - 1 ); |
|
ToLowerInplace( chName ); |
|
|
|
if ( !strstr( chName, chFilter ) ) |
|
{ |
|
textureList->RemoveSubKey( pCur ); |
|
} |
|
} |
|
} |
|
|
|
void KeepKeysMarkedNoMip( KeyValues *textureList ) |
|
{ |
|
KeyValues *pNext; |
|
for ( KeyValues *pCur=textureList->GetFirstSubKey(); pCur; pCur=pNext ) |
|
{ |
|
pNext = pCur->GetNextKey(); |
|
|
|
char const *szTextureFile = pCur->GetString( KEYNAME_NAME ); |
|
char const *szTextureGroup = pCur->GetString( KEYNAME_TEXTURE_GROUP ); |
|
if ( *szTextureFile ) |
|
{ |
|
ITexture *pMatTexture = materials->FindTexture( szTextureFile, szTextureGroup, false ); |
|
if ( pMatTexture && !(pMatTexture->GetFlags() & TEXTUREFLAGS_NOMIP) ) |
|
{ |
|
textureList->RemoveSubKey( pCur ); |
|
} |
|
} |
|
} |
|
} |
|
|
|
void CTextureListPanel::UpdateTotalUsageLabel() |
|
{ |
|
char data[1024], kb1[20], kb2[20], kb3[20]; |
|
FmtCommaNumber( kb1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_BOUND_LAST_FRAME ) + 511) / 1024 ); |
|
FmtCommaNumber( kb2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_TOTAL_LOADED ) + 511) / 1024 ); |
|
FmtCommaNumber( kb3, m_numDisplayedSizeKB ); |
|
|
|
if ( bool bCollapsed = m_pCollapse->IsSelected() ) |
|
{ |
|
char const *szTitle = ""; |
|
Q_snprintf( data, sizeof( data ), "%s[F %s Kb] / [T %s Kb] / [S %s Kb]", szTitle, kb1, kb2, kb3 ); |
|
} |
|
else |
|
{ |
|
char const *szTitle = "Texture Memory Usage"; |
|
char kbMip1[ 20 ], kbMip2[ 20 ]; |
|
FmtCommaNumber( kbMip1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_ESTIMATE_PICMIP_1 ) + 511) / 1024 ); |
|
FmtCommaNumber( kbMip2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_ESTIMATE_PICMIP_2 ) + 511) / 1024 ); |
|
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 ); |
|
} |
|
|
|
wchar_t unicodeString[1024]; |
|
g_pVGuiLocalize->ConvertANSIToUnicode( data, unicodeString, sizeof( unicodeString ) ); |
|
|
|
m_pTotalUsageLabel->SetText( unicodeString ); |
|
} |
|
|
|
void CTextureListPanel::OnTextChanged( void ) |
|
{ |
|
OnCommand( "FilteringTxt" ); |
|
} |
|
|
|
void CTextureListPanel::OnCommand( const char *command ) |
|
{ |
|
if ( !Q_stricmp( command, "Close" ) ) |
|
{ |
|
vgui::Frame::OnCommand( command ); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "Collapse" ) ) |
|
{ |
|
InvalidateLayout(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "ShowAlpha" ) ) |
|
{ |
|
m_pViewPanel->SetPaintAlpha( m_pAlpha->IsSelected() ); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "ThumbWarnings" ) ) |
|
{ |
|
g_warn_enable = m_pThumbWarnings->IsSelected(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "ViewThumbnails" ) ) |
|
{ |
|
InvalidateLayout(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, COPYTOCLIPBOARD_CMDNAME ) ) |
|
{ |
|
CopyListPanelToClipboard( m_pListPanel ); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "ReloadAllMaterials" ) ) |
|
{ |
|
Cbuf_AddText( "mat_reloadallmaterials" ); |
|
Cbuf_Execute(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "CommitChanges" ) ) |
|
{ |
|
Cbuf_AddText( "mat_texture_list_txlod_sync save" ); |
|
Cbuf_Execute(); |
|
return; |
|
} |
|
|
|
if ( !Q_stricmp( command, "DiscardChanges" ) ) |
|
{ |
|
Cbuf_AddText( "mat_texture_list_txlod_sync reset" ); |
|
Cbuf_Execute(); |
|
return; |
|
} |
|
|
|
mat_texture_list_on_f(); |
|
InvalidateLayout(); |
|
} |
|
|
|
|
|
bool CTextureListPanel::UpdateDisplayedItem( KeyValues *pDispData, KeyValues *kv ) |
|
{ |
|
// Update the item? |
|
bool bUpdate = false; |
|
|
|
// do the stuff that changes often separately. |
|
if ( pDispData->GetInt( KEYNAME_BINDS_FRAME ) != kv->GetInt( KEYNAME_BINDS_FRAME ) ) |
|
{ |
|
pDispData->SetInt( KEYNAME_BINDS_FRAME, kv->GetInt( KEYNAME_BINDS_FRAME ) ); |
|
bUpdate = true; |
|
} |
|
if ( pDispData->GetInt( KEYNAME_BINDS_MAX ) != kv->GetInt( KEYNAME_BINDS_MAX ) ) |
|
{ |
|
pDispData->SetInt( KEYNAME_BINDS_MAX, kv->GetInt( KEYNAME_BINDS_MAX ) ); |
|
bUpdate = true; |
|
} |
|
|
|
// stuff that changes less frequently |
|
if( pDispData->GetInt( KEYNAME_SIZE ) != kv->GetInt( KEYNAME_SIZE ) || |
|
pDispData->GetInt( KEYNAME_WIDTH ) != kv->GetInt( KEYNAME_WIDTH ) || |
|
pDispData->GetInt( KEYNAME_HEIGHT ) != kv->GetInt( KEYNAME_HEIGHT ) || |
|
Q_stricmp( pDispData->GetString( KEYNAME_FORMAT ), kv->GetString( KEYNAME_FORMAT ) ) != 0 || |
|
Q_stricmp( pDispData->GetString( KEYNAME_PATH ), kv->GetString( KEYNAME_PATH ) ) != 0 || |
|
Q_stricmp( pDispData->GetString( KEYNAME_TEXTURE_GROUP ), kv->GetString( KEYNAME_TEXTURE_GROUP ) ) != 0 ) |
|
{ |
|
pDispData->SetInt( KEYNAME_SIZE, kv->GetInt( KEYNAME_SIZE ) ); |
|
pDispData->SetInt( KEYNAME_WIDTH, kv->GetInt( KEYNAME_WIDTH ) ); |
|
pDispData->SetInt( KEYNAME_HEIGHT, kv->GetInt( KEYNAME_HEIGHT ) ); |
|
pDispData->SetString( KEYNAME_FORMAT, kv->GetString( KEYNAME_FORMAT ) ); |
|
pDispData->SetString( KEYNAME_PATH, kv->GetString( KEYNAME_PATH ) ); |
|
pDispData->SetString( KEYNAME_TEXTURE_GROUP, kv->GetString( KEYNAME_TEXTURE_GROUP ) ); |
|
bUpdate = true; |
|
} |
|
|
|
return bUpdate; |
|
} |
|
|
|
int CTextureListPanel::AddListItem( KeyValues *kv ) |
|
{ |
|
int iItem = m_pListPanel->GetItem( kv->GetString( KEYNAME_NAME ) ); |
|
if ( iItem == -1 ) |
|
{ |
|
// Set this so the GetItem() call above can use the key's name (as opposed to the value of its |
|
// "Name" subkey) to find this texture again. |
|
kv->SetName( kv->GetString( KEYNAME_NAME ) ); |
|
|
|
// Add this one. |
|
iItem = m_pListPanel->AddItem( kv, 0, false, false ); |
|
m_pViewPanel->InvalidateLayout(); |
|
} |
|
else |
|
{ |
|
KeyValues *pValues = m_pListPanel->GetItem( iItem ); |
|
bool bNeedUpdate = UpdateDisplayedItem( pValues, kv ); |
|
|
|
if( bNeedUpdate ) |
|
{ |
|
m_pListPanel->ApplyItemChanges( iItem ); |
|
m_pViewPanel->Repaint(); |
|
} |
|
} |
|
|
|
return iItem; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
|
|
void CTextureListPanel::OnTurnedOn() |
|
{ |
|
if ( g_bRecursiveRequestToShowTextureList ) |
|
return; |
|
|
|
if ( m_pListPanel ) |
|
m_pListPanel->DeleteAllItems(); |
|
|
|
if ( CRenderTextureEditor *pRe = m_pViewPanel->GetRenderTxEditor() ) |
|
pRe->Close(); |
|
|
|
MakePopup( false, false ); |
|
MoveToFront(); |
|
} |
|
|
|
void CTextureListPanel::Close() |
|
{ |
|
mat_texture_list_off_f(); |
|
} |
|
|
|
void CTextureListPanel::EndPaint() |
|
{ |
|
UpdateTotalUsageLabel(); |
|
} |
|
|
|
void CTextureListPanel::Paint() |
|
{ |
|
VPROF( "CTextureListPanel::Paint" ); |
|
|
|
if ( !m_hFont ) |
|
return; |
|
|
|
struct EndPaint_t |
|
{ |
|
CTextureListPanel *m_p; |
|
EndPaint_t( CTextureListPanel *p ) : m_p( p ) {} |
|
~EndPaint_t() |
|
{ |
|
m_p->EndPaint(); |
|
} |
|
} endpaint( this ); |
|
|
|
if ( !mat_texture_list.GetBool() ) |
|
return; |
|
|
|
if ( !g_pMaterialSystemDebugTextureInfo->IsDebugTextureListFresh( 1 ) ) |
|
return; |
|
|
|
CSmartTextureKeyValues textureList; |
|
if ( !textureList.Get() ) |
|
return; |
|
|
|
CRenderTextureEditor *pRte = m_pViewPanel->GetRenderTxEditor(); |
|
if ( ( s_eTxListPanelRequest == TXR_RUNNING ) && |
|
pRte->IsVisible() ) |
|
{ |
|
KeyValues *kv = NULL; |
|
int iHint = 0; |
|
pRte->GetDispInfo( kv, iHint ); |
|
if ( kv && iHint ) |
|
{ |
|
KeyValues *plv = ( m_pListPanel->IsValidItemID( iHint ) ? m_pListPanel->GetItem( iHint ) : NULL ); |
|
if ( plv && !strcmp( plv->GetString( KEYNAME_NAME ), kv->GetString( KEYNAME_NAME ) ) ) |
|
{ |
|
KeyValues *pValData = plv->GetFirstValue(), *pValRendered = kv->GetFirstValue(); |
|
for ( ; pValData && pValRendered; pValData = pValData->GetNextValue(), pValRendered = pValRendered->GetNextValue() ) |
|
{ |
|
if ( strcmp( pValData->GetString(), pValRendered->GetString() ) ) |
|
break; |
|
} |
|
if ( pValData || pValRendered ) // Difference found |
|
pRte->SetDispInfo( plv, iHint ); |
|
} |
|
else |
|
kv = NULL; |
|
} |
|
|
|
if ( 0 ) // if ( !kv ) |
|
{ |
|
pRte->Close(); |
|
pRte->SetDispInfo( NULL, 0 ); |
|
} |
|
} |
|
|
|
// If we are fetching all textures, then stop loading material system: |
|
if ( mat_texture_list_all.GetBool() ) |
|
{ |
|
if ( s_eTxListPanelRequest == TXR_RUNNING ) |
|
{ |
|
mat_texture_list.SetValue( 0 ); |
|
s_eTxListPanelRequest = TXR_SHOW; // Keep displaying our panel |
|
} |
|
else |
|
{ |
|
s_eTxListPanelRequest = TXR_RUNNING; |
|
} |
|
} |
|
else |
|
{ |
|
if ( s_eTxListPanelRequest == TXR_SHOW ) |
|
{ |
|
// Either first show or turned off "all textures" |
|
m_pListPanel->RemoveAll(); |
|
m_pViewPanel->InvalidateLayout(); |
|
s_eTxListPanelRequest = TXR_RUNNING; |
|
return; |
|
} |
|
} |
|
|
|
CBitVec<4096 * 8> itemsTouched; |
|
|
|
// Remove the textures we don't care for |
|
KeepSpecialKeys( textureList.Get(), m_pSpecialTexs->IsSelected() ); |
|
|
|
// If filtering is enabled, then do filtering |
|
if ( m_pFilteringChk->IsSelected() && m_pFilteringText->GetTextLength() ) |
|
{ |
|
char chFilterString[ MAX_PATH ]; |
|
m_pFilteringText->GetText( chFilterString, sizeof( chFilterString ) - 1 ); |
|
chFilterString[ sizeof( chFilterString ) - 1 ] = 0; |
|
KeepKeysMatchingFilter( textureList.Get(), chFilterString ); |
|
} |
|
|
|
// If we're to hide mipped, remove anything that isn't marked nomip |
|
if ( m_pHideMipped->IsSelected() ) |
|
{ |
|
KeepKeysMarkedNoMip( textureList.Get() ); |
|
} |
|
|
|
// Compute the total size of the displayed textures |
|
int cbTotalDisplayedSizeInBytes = 0; |
|
|
|
for ( KeyValues *pCur = textureList.Get()->GetFirstSubKey(); pCur; pCur=pCur->GetNextKey() ) |
|
{ |
|
int sizeInBytes = pCur->GetInt( KEYNAME_SIZE ); |
|
|
|
// Accumulate |
|
cbTotalDisplayedSizeInBytes += sizeInBytes; |
|
|
|
// Factor in frames |
|
int numCount = pCur->GetInt( "Count" ); |
|
if ( numCount > 1 ) |
|
sizeInBytes *= numCount; |
|
|
|
// Size is in kilobytes. |
|
int sizeInKilo = ( sizeInBytes + 511 ) / 1024; |
|
pCur->SetInt( KEYNAME_SIZE, sizeInKilo ); |
|
|
|
if ( m_pResolveTexturePath->IsSelected() ) |
|
{ |
|
char chResolveName[ 256 ] = {0}, chResolveNameArg[ 256 ] = {0}; |
|
Q_snprintf( chResolveNameArg, sizeof( chResolveNameArg ) - 1, "materials/%s.vtf", pCur->GetString( KEYNAME_NAME ) ); |
|
char const *szResolvedName = g_pFileSystem->RelativePathToFullPath( chResolveNameArg, "game", chResolveName, sizeof( chResolveName ) - 1 ); |
|
if ( szResolvedName ) |
|
{ |
|
pCur->SetString( KEYNAME_PATH, szResolvedName ); |
|
} |
|
} |
|
|
|
int iItem = AddListItem( pCur ); |
|
|
|
if ( iItem < itemsTouched.GetNumBits() ) |
|
itemsTouched.Set( iItem ); |
|
} |
|
|
|
// Set the displayed size |
|
m_numDisplayedSizeKB = ( cbTotalDisplayedSizeInBytes + 511 ) / 1024; |
|
|
|
// Now remove from view items that weren't used. |
|
int iNext, numRemoved = 0; |
|
for ( int iCur=m_pListPanel->FirstItem(); iCur != m_pListPanel->InvalidItemID(); iCur=iNext ) |
|
{ |
|
iNext = m_pListPanel->NextItem( iCur ); |
|
|
|
if ( iCur >= itemsTouched.GetNumBits() || !itemsTouched.Get( iCur ) ) |
|
{ |
|
m_pListPanel->RemoveItem( iCur ); |
|
++ numRemoved; |
|
} |
|
} |
|
|
|
// Sorting in list panel |
|
{ |
|
int iPri, iSec; |
|
bool bAsc; |
|
m_pListPanel->GetSortColumnEx( iPri, iSec, bAsc ); |
|
iSec = 0; // always secondary sort by name |
|
m_pListPanel->SetSortColumnEx( iPri, iSec, bAsc ); |
|
m_pListPanel->SortList(); |
|
} |
|
|
|
if ( numRemoved ) |
|
{ |
|
m_pViewPanel->InvalidateLayout(); |
|
} |
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------ // |
|
// Global functions. |
|
// ------------------------------------------------------------------------------ // |
|
|
|
void VGui_UpdateTextureListPanel() |
|
{ |
|
if ( mat_show_texture_memory_usage.GetInt() ) |
|
{ |
|
con_nprint_t info; |
|
info.index = 4; |
|
info.time_to_live = 0.2; |
|
info.color[0] = 1; |
|
info.color[1] = 0.5; |
|
info.color[2] = 0; |
|
info.fixed_width_font = true; |
|
|
|
char kb1[20], kb2[20]; |
|
FmtCommaNumber( kb1, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_BOUND_LAST_FRAME ) + 511) / 1024 ); |
|
FmtCommaNumber( kb2, (g_pMaterialSystemDebugTextureInfo->GetTextureMemoryUsed( IDebugTextureInfo::MEMORY_TOTAL_LOADED ) + 511) / 1024 ); |
|
|
|
Con_NXPrintf( &info, "Texture Memory Usage: %s Kb / %s Kb", kb1, kb2 ); |
|
} |
|
|
|
MatViewOverride::DisplaySelectedTextures(); |
|
|
|
if ( IsX360() ) |
|
return; |
|
|
|
g_pMaterialSystemDebugTextureInfo->EnableGetAllTextures( mat_texture_list_all.GetBool() ); |
|
|
|
g_pMaterialSystemDebugTextureInfo->EnableDebugTextureList( ( mat_texture_list.GetInt() <= 0 ) ? false : true ); |
|
|
|
bool bShouldDrawTxListPanel = g_pTextureListPanel->ShouldDraw(); |
|
if ( g_pTextureListPanel->IsVisible() != bShouldDrawTxListPanel ) |
|
{ |
|
g_pTextureListPanel->SetVisible( bShouldDrawTxListPanel ); |
|
bShouldDrawTxListPanel ? mat_texture_list_on_f() : mat_texture_list_off_f(); |
|
} |
|
} |
|
|
|
|
|
void CL_CreateTextureListPanel( vgui::Panel *parent ) |
|
{ |
|
g_pTextureListPanel = new CTextureListPanel( parent ); |
|
} |
|
|
|
CON_COMMAND( mat_texture_save_fonts, "Save all font textures" ) |
|
{ |
|
for( int i = 0; i < 8192; i++ ) |
|
{ |
|
char szTextureName[ MAX_PATH ]; |
|
|
|
Q_snprintf( szTextureName, ARRAYSIZE( szTextureName ), "__font_page_%d.tga", i ); |
|
|
|
if( !materials->IsTextureLoaded( szTextureName ) ) |
|
break; |
|
|
|
ITexture *pMatTexture = materials->FindTexture( szTextureName, "", false ); |
|
if( pMatTexture && !pMatTexture->IsError() ) |
|
{ |
|
bool bRet = SaveTextureImage( szTextureName ); |
|
Msg( "SaveTextureImage( '%s' ): %s\n", szTextureName, bRet ? "succeeded" : "failed" ); |
|
} |
|
} |
|
} |
|
|
|
void mat_texture_list_on_f() |
|
{ |
|
ConVarRef sv_cheats( "sv_cheats" ); |
|
if ( sv_cheats.IsValid() && !sv_cheats.GetBool() ) |
|
return; |
|
|
|
ConVarRef mat_queue_mode( "mat_queue_mode" ); |
|
|
|
if( mat_queue_mode.IsValid() && ( g_nSaveQueueState == INT_MIN ) ) |
|
{ |
|
g_nSaveQueueState = mat_queue_mode.GetInt(); |
|
mat_queue_mode.SetValue( 0 ); |
|
} |
|
|
|
mat_texture_list.SetValue( 1 ); |
|
s_eTxListPanelRequest = TXR_SHOW; |
|
|
|
g_pTextureListPanel->OnTurnedOn(); |
|
|
|
MatViewOverride::RequestSelectNone(); |
|
|
|
// On Linux, the mouse gets recentered when it's hidden. So if you bring up the texture list |
|
// dialog while the game is running, we need to make sure the mouse is shown. Otherwise it's |
|
// very tough to use when your mouse keeps getting recentered. |
|
if( !g_cursorset && g_pVGuiSurface ) |
|
{ |
|
g_pVGuiSurface->SetCursorAlwaysVisible( true ); |
|
g_cursorset = true; |
|
} |
|
} |
|
void mat_texture_list_off_f() |
|
{ |
|
mat_texture_list.SetValue( 0 ); |
|
s_eTxListPanelRequest = TXR_HIDE; |
|
|
|
if( g_cursorset ) |
|
{ |
|
g_pVGuiSurface->SetCursorAlwaysVisible( false ); |
|
g_cursorset = false; |
|
} |
|
|
|
if( g_nSaveQueueState != INT_MIN ) |
|
{ |
|
ConVarRef mat_queue_mode( "mat_queue_mode" ); |
|
|
|
mat_queue_mode.SetValue( g_nSaveQueueState ); |
|
g_nSaveQueueState = INT_MIN; |
|
} |
|
} |
|
|
|
|
|
|