summaryrefslogtreecommitdiff
path: root/game/client/tf/vgui/modelimagepanel.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/tf/vgui/modelimagepanel.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/client/tf/vgui/modelimagepanel.cpp')
-rw-r--r--game/client/tf/vgui/modelimagepanel.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/game/client/tf/vgui/modelimagepanel.cpp b/game/client/tf/vgui/modelimagepanel.cpp
new file mode 100644
index 0000000..e322282
--- /dev/null
+++ b/game/client/tf/vgui/modelimagepanel.cpp
@@ -0,0 +1,214 @@
+//========= 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;
+}