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.
215 lines
6.1 KiB
215 lines
6.1 KiB
5 years ago
|
//========= 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;
|
||
|
}
|