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.
214 lines
6.1 KiB
214 lines
6.1 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
#include "cbase.h" |
|
#include "modelimagepanel.h" |
|
#include "iconrenderreceiver.h" |
|
#include "materialsystem/imaterialvar.h" |
|
#include "VGuiMatSurface/IMatSystemSurface.h" |
|
#include "renderparm.h" |
|
|
|
|
|
using namespace vgui; |
|
|
|
const char *g_pszModelImagePanelRTName = "_rt_ModelImagePanel"; |
|
static vgui::DHANDLE<CModelImagePanel> s_hModelImageLockPanel; |
|
|
|
#ifdef STAGING_ONLY |
|
ConVar tf_modelimagepanel_ignore_cache( "tf_modelimagepanel_ignore_cache", "0" ); |
|
#endif |
|
|
|
DECLARE_BUILD_FACTORY( CModelImagePanel ); |
|
|
|
CModelImagePanel::CModelImagePanel( vgui::Panel *pParent, const char *pName ) |
|
: BaseClass( pParent, pName ) |
|
{ |
|
m_pCachedIcon = NULL; |
|
m_pCachedMaterial = NULL; |
|
m_iCachedTextureID = -1; |
|
} |
|
|
|
CModelImagePanel::~CModelImagePanel() |
|
{ |
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::PerformLayout() |
|
{ |
|
BaseClass::PerformLayout(); |
|
|
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::OnSizeChanged( int wide, int tall ) |
|
{ |
|
BaseClass::OnSizeChanged( wide, tall ); |
|
|
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::Paint() |
|
{ |
|
// don't do anything for invalid model |
|
if ( m_RootMDL.m_MDL.GetMDL() == MDLHANDLE_INVALID ) |
|
{ |
|
return; |
|
} |
|
|
|
// check lock panel |
|
if ( s_hModelImageLockPanel ) |
|
{ |
|
// waiting for async copy to finish |
|
if ( s_hModelImageLockPanel->m_pCachedIcon && s_hModelImageLockPanel->m_pCachedIcon->GetTexture() ) |
|
{ |
|
s_hModelImageLockPanel = NULL; |
|
} |
|
} |
|
|
|
if ( m_pCachedIcon ) |
|
{ |
|
if ( m_pCachedIcon->GetTexture() ) |
|
{ |
|
if ( !m_pCachedMaterial && g_pMaterialSystem ) |
|
{ |
|
const char *pszTextureName = m_pCachedIcon->GetTexture()->GetName(); |
|
KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" ); |
|
pVMTKeyValues->SetString( "$basetexture", pszTextureName ); |
|
pVMTKeyValues->SetInt( "$translucent", 1 ); |
|
pVMTKeyValues->SetInt( "$vertexcolor", 1 ); |
|
IMaterial *pMaterial = g_pMaterialSystem->FindProceduralMaterial( pszTextureName, TEXTURE_GROUP_VGUI, pVMTKeyValues ); |
|
SafeAssign( &m_pCachedMaterial, pMaterial ); |
|
|
|
bool bFound = false; |
|
IMaterialVar *pVar = m_pCachedMaterial->FindVar( "$basetexture", &bFound ); |
|
if ( bFound && pVar ) |
|
{ |
|
pVar->SetTextureValue( m_pCachedIcon->GetTexture() ); |
|
m_pCachedMaterial->RefreshPreservingMaterialVars(); |
|
} |
|
} |
|
|
|
if ( m_iCachedTextureID == -1 ) |
|
{ |
|
m_iCachedTextureID = g_pMatSystemSurface->DrawGetTextureId( m_pCachedIcon->GetTexture() ); |
|
g_pMatSystemSurface->DrawSetTextureMaterial( m_iCachedTextureID, m_pCachedMaterial ); |
|
} |
|
} |
|
else |
|
{ |
|
// still waiting for texture |
|
BaseClass::Paint(); |
|
return; |
|
} |
|
} |
|
|
|
// just draw the texture if we got one. |
|
if ( m_iCachedTextureID != -1 ) |
|
{ |
|
surface()->DrawSetTexture( m_iCachedTextureID ); |
|
surface()->DrawSetColor( 255, 255, 255, 255 ); |
|
const int iWidth = GetWide(); |
|
const int iHeight = GetTall(); |
|
const int iMappingWitdh = m_pCachedMaterial->GetMappingWidth(); |
|
const int iMappingHeight = m_pCachedMaterial->GetMappingHeight(); |
|
float flTexW, flTexH; |
|
if ( iWidth > iMappingWitdh || iHeight > iMappingHeight ) |
|
{ |
|
float flScale = iWidth > iHeight ? (float)iMappingWitdh / iWidth : (float)iMappingHeight / iHeight; |
|
flTexW = ( flScale * iWidth ) / iMappingWitdh; |
|
flTexH = ( flScale * iHeight ) / iMappingHeight; |
|
} |
|
else |
|
{ |
|
flTexW = (float)( iWidth - 1 ) / iMappingWitdh; |
|
flTexH = (float)( iHeight - 1 ) / iMappingHeight; |
|
} |
|
surface()->DrawTexturedSubRect( 0, 0, iWidth, iHeight, 0.f, 0.f, flTexW, flTexH ); |
|
return; |
|
} |
|
|
|
// can't find available cache render target, don't do anything |
|
if ( s_hModelImageLockPanel != NULL && s_hModelImageLockPanel != this ) |
|
{ |
|
BaseClass::Paint(); |
|
return; |
|
} |
|
|
|
CMatRenderContextPtr pRenderContext( materials ); |
|
|
|
// Turn off depth-write to dest alpha so that we get white there instead. The code that uses |
|
// the render target needs a mask of where stuff was rendered. |
|
pRenderContext->SetIntRenderingParameter( INT_RENDERPARM_WRITE_DEPTH_TO_DESTALPHA, false ); |
|
|
|
g_pMatSystemSurface->Set3DPaintTempRenderTarget( g_pszModelImagePanelRTName ); |
|
|
|
BaseClass::Paint(); |
|
|
|
// copy the rendered weapon skin from the render target |
|
Assert( m_pCachedIcon == NULL ); |
|
CStudioHdr studioHdr( g_pMDLCache->GetStudioHdr( m_RootMDL.m_MDL.GetMDL() ), g_pMDLCache ); |
|
char buffer[_MAX_PATH]; |
|
CUtlString strMDLName = V_GetFileName( studioHdr.pszName() ); |
|
V_sprintf_safe( buffer, "proc/icon/mdl_%s_body%d_skin%d_w%d_h%d", strMDLName.StripExtension().Get(), m_RootMDL.m_MDL.m_nBody, m_RootMDL.m_MDL.m_nSkin, GetWide(), GetTall() ); |
|
SafeAssign( &m_pCachedIcon, new CIconRenderReceiver() ); |
|
|
|
// If the icon still exists in the material system, don't bother regenerating it. |
|
if ( materials->IsTextureLoaded( buffer ) |
|
#ifdef STAGING_ONLY |
|
&& !tf_modelimagepanel_ignore_cache.GetBool() |
|
#endif |
|
) |
|
{ |
|
ITexture* resTexture = materials->FindTexture( buffer, TEXTURE_GROUP_RUNTIME_COMPOSITE, false, 0 ); |
|
if ( resTexture && resTexture->IsError() == false ) |
|
{ |
|
m_pCachedIcon->OnAsyncCreateComplete( resTexture, NULL ); |
|
} |
|
} |
|
else |
|
{ |
|
// No icon available yet, need to create it. |
|
ITexture *pRenderTarget = g_pMaterialSystem->FindTexture( g_pszModelImagePanelRTName, TEXTURE_GROUP_RENDER_TARGET ); |
|
if ( pRenderTarget ) |
|
{ |
|
pRenderContext->AsyncCreateTextureFromRenderTarget( pRenderTarget, buffer, IMAGE_FORMAT_RGBA8888, false, TEXTUREFLAGS_IMMEDIATE_CLEANUP, m_pCachedIcon, NULL ); |
|
|
|
// make this panel lock the render target |
|
s_hModelImageLockPanel = this; |
|
} |
|
} |
|
|
|
g_pMatSystemSurface->Reset3DPaintTempRenderTarget(); |
|
} |
|
|
|
void CModelImagePanel::SetMDL( MDLHandle_t handle, void *pProxyData /*= NULL*/ ) |
|
{ |
|
BaseClass::SetMDL( handle, pProxyData ); |
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::SetMDL( const char *pMDLName, void *pProxyData /*= NULL*/ ) |
|
{ |
|
BaseClass::SetMDL( pMDLName, pProxyData ); |
|
} |
|
|
|
void CModelImagePanel::SetMDLBody( unsigned int nBody ) |
|
{ |
|
SetBody( nBody ); |
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::SetMDLSkin( int nSkin ) |
|
{ |
|
SetSkin( nSkin ); |
|
InvalidateImage(); |
|
} |
|
|
|
void CModelImagePanel::InvalidateImage() |
|
{ |
|
SafeRelease( &m_pCachedIcon ); |
|
SafeRelease( &m_pCachedMaterial ); |
|
m_iCachedTextureID = -1; |
|
}
|
|
|