Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

393 lines
9.7 KiB

//======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ======
//
// CSheetSequencePanel - Panel for selecting one sequence from a sprite sheet
//
//===============================================================================
#include "matsys_controls/sheetsequencepanel.h"
#include "matsys_controls/matsyscontrols.h"
#include "VGuiMatSurface/IMatSystemSurface.h"
#include "materialsystem/imaterial.h"
#include "tier1/keyvalues.h"
#include "bitmap/psheet.h"
#include "vgui/IScheme.h"
#include "vgui/IVGui.h"
#include "materialsystem/imaterialvar.h"
// NOTE: This has to be the last file included!
#include "tier0/memdbgon.h"
//-----------------------------------------------------------------------------
// MOC_TODO: Power of two FB texture - do I really need to do this?
static CTextureReference s_pPowerOfTwoFrameBufferTexture_SheetSeq;
static ITexture *GetPowerOfTwoFrameBufferTexture( void )
{
if ( !s_pPowerOfTwoFrameBufferTexture_SheetSeq )
{
s_pPowerOfTwoFrameBufferTexture_SheetSeq.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
}
return s_pPowerOfTwoFrameBufferTexture_SheetSeq;
}
//-----------------------------------------------------------------------------
// Statics
bool CSheetSequencePanel::m_sMaterialsInitialized = false;
CMaterialReference CSheetSequencePanel::m_sColorMat;
CMaterialReference CSheetSequencePanel::m_sAlphaMat;
const int SEQUENCE_PANEL_BORDER = 2;
const int SEQUENCE_PANEL_MAX_SIZE = 256;
CSheetSequencePanel::CSheetSequencePanel( vgui::Panel *pParent, const char *pPanelName ):
BaseClass(pParent,pPanelName),
m_pSheet(NULL),
m_Material(NULL)
{
m_nHighlightedSequence = -1;
m_bSeparateAlphaColorMaterial = false;
m_bIsSecondSequenceView = false;
EnsureMaterialsExist();
}
void CSheetSequencePanel::EnsureMaterialsExist()
{
if ( !m_sMaterialsInitialized )
{
KeyValues *pKeyValues = new KeyValues( "DebugTextureView" );
pKeyValues->SetString( "$basetexture", "" );
pKeyValues->SetInt( "$ShowAlpha", 1 );
m_sAlphaMat.Init( "SheetSequenceAlphaMaterial", pKeyValues );
m_sAlphaMat->Refresh();
pKeyValues = new KeyValues( "DebugTextureView" );
pKeyValues->SetString( "$basetexture", "" );
pKeyValues->SetInt( "$ShowAlpha", 0 );
m_sColorMat.Init( "SheetSequenceColorMaterial", pKeyValues );
m_sColorMat->Refresh();
m_sMaterialsInitialized = true;
}
}
CSheetSequencePanel::~CSheetSequencePanel()
{
delete m_pSheet;
m_pSheet = NULL;
}
void CSheetSequencePanel::PrepareMaterials()
{
if ( !m_Material )
{
return;
}
m_bSeparateAlphaColorMaterial = CSheetExtended::IsMaterialSeparateAlphaColorMaterial( m_Material );
bool bFound = false;
IMaterialVar *pVar = m_Material->FindVar( "$basetexture", &bFound );
if ( !pVar || !bFound || !pVar->IsDefined() )
return;
ITexture *pTex = pVar->GetTextureValue();
if ( !pTex || pTex->IsError() )
return;
//////////////////////////////
IMaterialVar *BaseTextureVar = m_sAlphaMat->FindVar( "$basetexture", &bFound );
if ( !bFound || !BaseTextureVar )
return;
BaseTextureVar->SetTextureValue( pTex );
//////////////////////////////
BaseTextureVar = m_sColorMat->FindVar( "$basetexture", &bFound );
if ( !bFound || !BaseTextureVar )
return;
BaseTextureVar->SetTextureValue( pTex );
}
void CSheetSequencePanel::SetSecondSequenceView( bool bIsSecondSequenceView )
{
m_bIsSecondSequenceView = bIsSecondSequenceView;
}
void CSheetSequencePanel::SetFromMaterialName( const char* pMaterialName )
{
if ( m_pSheet )
{
delete m_pSheet;
}
m_Material.Init( pMaterialName, "editor material" );
m_pSheet = new CSheetExtended(m_Material);
PrepareMaterials();
PerformLayout();
}
void CSheetSequencePanel::SetFromMaterial( IMaterial* sourceMaterial )
{
if ( m_pSheet )
{
delete m_pSheet;
}
m_Material.Init(sourceMaterial);
m_pSheet = new CSheetExtended(m_Material);
PrepareMaterials();
PerformLayout();
}
void CSheetSequencePanel::PerformLayout()
{
int newWidth = SequenceGridCount() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
int newHeight = SequenceGridRows() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
if ( SequenceGridCount() == 0 )
{
newWidth = 32;
newHeight = 32;
}
SetSize( newWidth, newHeight );
Repaint();
}
void CSheetSequencePanel::OnCursorExited()
{
m_nHighlightedSequence = -1;
}
void CSheetSequencePanel::OnCursorMoved(int x, int y)
{
BaseClass::OnCursorMoved(x,y);
if ( m_pSheet == NULL || m_pSheet->GetSheetSequenceCount() == 0 )
{
m_nHighlightedSequence = -1;
return;
}
int nGridCount = SequenceGridCount();
int nGridSize = SequenceGridSquareSize();
int nGridX = (x - SEQUENCE_PANEL_BORDER) / nGridSize;
int nGridY = (y - SEQUENCE_PANEL_BORDER) / nGridSize;
if ( nGridX >= 0 && nGridY >= 0 &&
nGridX < nGridCount && nGridY < nGridCount )
{
int nSeqIndex = nGridX + nGridY*nGridCount;
if ( nSeqIndex < m_pSheet->GetSheetSequenceCount() )
{
m_nHighlightedSequence = nSeqIndex;
}
else
{
m_nHighlightedSequence = -1;
}
}
else
{
m_nHighlightedSequence = -1;
}
}
int CSheetSequencePanel::SequenceGridCount()
{
return m_pSheet ? Ceil2Int(sqrt((float)m_pSheet->GetSheetSequenceCount())) : 0;
}
int CSheetSequencePanel::SequenceGridSquareSize()
{
int nGridCount = SequenceGridCount();
if ( nGridCount == 0 )
{
return 0;
}
else
{
return (SEQUENCE_PANEL_MAX_SIZE / nGridCount);
}
}
int CSheetSequencePanel::SequenceGridRows()
{
if ( !m_pSheet )
return 0;
int nSequences = m_pSheet->GetSheetSequenceCount();
int nGridCount = SequenceGridCount();
if ( nSequences == 0 )
{
return 0;
}
else
{
// nSequences / nGridCount, rounded up
return (nSequences + nGridCount - 1) / nGridCount;
}
}
void CSheetSequencePanel::OnMouseReleased( vgui::MouseCode mouseCode )
{
if ( m_nHighlightedSequence != -1 )
{
KeyValues *k = new KeyValues("SheetSequenceSelected");
k->SetPtr("panel", this);
k->SetInt("nSequenceNumber", m_nHighlightedSequence);
k->SetBool("bIsSecondSequence", m_bIsSecondSequenceView );
PostActionSignal( k );
}
SetVisible(false);
}
void CSheetSequencePanel::Paint( void )
{
int x, y, w, h;
GetSize(w, h);
GetPos(x,y);
vgui::surface()->DrawSetColor( Color(0,0,0,255) );
vgui::surface()->DrawOutlinedRect( 1, 1, w-1, h-1 );
if ( m_pSheet == NULL || !m_pSheet->ValidSheetData() )
{
return;
}
CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
vgui::MatSystemSurface()->Begin3DPaint( 2, 2, w-2, h-2 );
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
pRenderContext->Ortho( 2, 2, w-2, h-2, -1.0f, 1.0f );
pRenderContext->MatrixMode( MATERIAL_MODEL );
pRenderContext->PushMatrix();
pRenderContext->LoadIdentity();
// Deal with refraction
if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
{
ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
if ( pTexture && !pTexture->IsError() )
{
pRenderContext->CopyRenderTargetToTexture( pTexture );
pRenderContext->SetFrameBufferCopyTexture( pTexture );
}
}
Color bgColor = GetBgColor();
pRenderContext->ClearColor4ub( bgColor.r(), bgColor.g(), bgColor.b(), 255 );
pRenderContext->ClearBuffers( true, true );
pRenderContext->FogMode( MATERIAL_FOG_NONE );
pRenderContext->SetNumBoneWeights( 0 );
bool bOverrideSpriteCard = false;
bool bOnlyColor = false;
bool bOnlyAlpha = false;
if ( m_bSeparateAlphaColorMaterial )
{
if ( !m_bIsSecondSequenceView )
{
pRenderContext->Bind( m_sAlphaMat );
bOnlyAlpha = true;
}
else
{
pRenderContext->Bind( m_sColorMat );
bOnlyColor = true;
}
bOverrideSpriteCard = true;
}
else
{
pRenderContext->Bind( m_Material );
}
IMesh *pMesh = pRenderContext->GetDynamicMesh();
float flAge = fmodf( Plat_FloatTime(), m_pSheet->GetSequenceTimeSpan(0) );
int nGridCount = SequenceGridCount();
float flGridSquareSize = SequenceGridSquareSize();
float flOffset = 0.5f*flGridSquareSize+SEQUENCE_PANEL_BORDER;
int nSequences = m_pSheet->GetSheetSequenceCount();
for ( int i = 0; i < nSequences; ++i )
{
float x = i % nGridCount;
float y = i / nGridCount;
if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
|| bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
{
continue;
}
m_pSheet->DrawSheet( pMesh, Vector(flOffset+x*flGridSquareSize,h-(flOffset+y*flGridSquareSize),0), flGridSquareSize*0.5f, i, flAge, 750.0f, true, -1, bOverrideSpriteCard );
}
pRenderContext->PopMatrix();
pRenderContext->MatrixMode( MATERIAL_PROJECTION );
pRenderContext->PopMatrix();
vgui::MatSystemSurface()->End3DPaint( );
//////////////////////////////////////////////////////////////////////////
flOffset = SEQUENCE_PANEL_BORDER;
for ( int i = 0; i < nSequences; ++i )
{
float x = i % nGridCount;
float y = i / nGridCount;
Color drawColor = Color(0,0,0,255);
if ( m_nHighlightedSequence == i )
{
drawColor = Color(255,255,255,255);
}
vgui::surface()->DrawSetColor(drawColor);
vgui::surface()->DrawSetTextColor(drawColor);
vgui::surface()->DrawOutlinedRect( flOffset+x*flGridSquareSize, flOffset+y*flGridSquareSize, flOffset+(x+1)*flGridSquareSize, flOffset+(y+1)*flGridSquareSize );
wchar_t strBuffer[8];
V_snwprintf( strBuffer, ARRAYSIZE( strBuffer ), L"%d", i );
vgui::surface()->DrawSetTextFont( vgui::scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmall" ) );
vgui::surface()->DrawSetTextPos(flOffset+x*flGridSquareSize+2, flOffset+y*flGridSquareSize+1);
vgui::surface()->DrawUnicodeString( strBuffer );
if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
|| bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
{
vgui::surface()->DrawSetTextColor( Color(255,0,0,255) );
vgui::surface()->DrawSetTextPos(flOffset+(x+0.5f)*flGridSquareSize, flOffset+(y+0.5f)*flGridSquareSize+1);
vgui::surface()->DrawUnicodeString( L"x" );
}
}
}