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

  1. //======= Copyright (c) 1996-2009, Valve Corporation, All rights reserved. ======
  2. //
  3. // CSheetSequencePanel - Panel for selecting one sequence from a sprite sheet
  4. //
  5. //===============================================================================
  6. #include "matsys_controls/sheetsequencepanel.h"
  7. #include "matsys_controls/matsyscontrols.h"
  8. #include "VGuiMatSurface/IMatSystemSurface.h"
  9. #include "materialsystem/imaterial.h"
  10. #include "tier1/keyvalues.h"
  11. #include "bitmap/psheet.h"
  12. #include "vgui/IScheme.h"
  13. #include "vgui/IVGui.h"
  14. #include "materialsystem/imaterialvar.h"
  15. // NOTE: This has to be the last file included!
  16. #include "tier0/memdbgon.h"
  17. //-----------------------------------------------------------------------------
  18. // MOC_TODO: Power of two FB texture - do I really need to do this?
  19. static CTextureReference s_pPowerOfTwoFrameBufferTexture_SheetSeq;
  20. static ITexture *GetPowerOfTwoFrameBufferTexture( void )
  21. {
  22. if ( !s_pPowerOfTwoFrameBufferTexture_SheetSeq )
  23. {
  24. s_pPowerOfTwoFrameBufferTexture_SheetSeq.Init( vgui::MaterialSystem()->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET ) );
  25. }
  26. return s_pPowerOfTwoFrameBufferTexture_SheetSeq;
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Statics
  30. bool CSheetSequencePanel::m_sMaterialsInitialized = false;
  31. CMaterialReference CSheetSequencePanel::m_sColorMat;
  32. CMaterialReference CSheetSequencePanel::m_sAlphaMat;
  33. const int SEQUENCE_PANEL_BORDER = 2;
  34. const int SEQUENCE_PANEL_MAX_SIZE = 256;
  35. CSheetSequencePanel::CSheetSequencePanel( vgui::Panel *pParent, const char *pPanelName ):
  36. BaseClass(pParent,pPanelName),
  37. m_pSheet(NULL),
  38. m_Material(NULL)
  39. {
  40. m_nHighlightedSequence = -1;
  41. m_bSeparateAlphaColorMaterial = false;
  42. m_bIsSecondSequenceView = false;
  43. EnsureMaterialsExist();
  44. }
  45. void CSheetSequencePanel::EnsureMaterialsExist()
  46. {
  47. if ( !m_sMaterialsInitialized )
  48. {
  49. KeyValues *pKeyValues = new KeyValues( "DebugTextureView" );
  50. pKeyValues->SetString( "$basetexture", "" );
  51. pKeyValues->SetInt( "$ShowAlpha", 1 );
  52. m_sAlphaMat.Init( "SheetSequenceAlphaMaterial", pKeyValues );
  53. m_sAlphaMat->Refresh();
  54. pKeyValues = new KeyValues( "DebugTextureView" );
  55. pKeyValues->SetString( "$basetexture", "" );
  56. pKeyValues->SetInt( "$ShowAlpha", 0 );
  57. m_sColorMat.Init( "SheetSequenceColorMaterial", pKeyValues );
  58. m_sColorMat->Refresh();
  59. m_sMaterialsInitialized = true;
  60. }
  61. }
  62. CSheetSequencePanel::~CSheetSequencePanel()
  63. {
  64. delete m_pSheet;
  65. m_pSheet = NULL;
  66. }
  67. void CSheetSequencePanel::PrepareMaterials()
  68. {
  69. if ( !m_Material )
  70. {
  71. return;
  72. }
  73. m_bSeparateAlphaColorMaterial = CSheetExtended::IsMaterialSeparateAlphaColorMaterial( m_Material );
  74. bool bFound = false;
  75. IMaterialVar *pVar = m_Material->FindVar( "$basetexture", &bFound );
  76. if ( !pVar || !bFound || !pVar->IsDefined() )
  77. return;
  78. ITexture *pTex = pVar->GetTextureValue();
  79. if ( !pTex || pTex->IsError() )
  80. return;
  81. //////////////////////////////
  82. IMaterialVar *BaseTextureVar = m_sAlphaMat->FindVar( "$basetexture", &bFound );
  83. if ( !bFound || !BaseTextureVar )
  84. return;
  85. BaseTextureVar->SetTextureValue( pTex );
  86. //////////////////////////////
  87. BaseTextureVar = m_sColorMat->FindVar( "$basetexture", &bFound );
  88. if ( !bFound || !BaseTextureVar )
  89. return;
  90. BaseTextureVar->SetTextureValue( pTex );
  91. }
  92. void CSheetSequencePanel::SetSecondSequenceView( bool bIsSecondSequenceView )
  93. {
  94. m_bIsSecondSequenceView = bIsSecondSequenceView;
  95. }
  96. void CSheetSequencePanel::SetFromMaterialName( const char* pMaterialName )
  97. {
  98. if ( m_pSheet )
  99. {
  100. delete m_pSheet;
  101. }
  102. m_Material.Init( pMaterialName, "editor material" );
  103. m_pSheet = new CSheetExtended(m_Material);
  104. PrepareMaterials();
  105. PerformLayout();
  106. }
  107. void CSheetSequencePanel::SetFromMaterial( IMaterial* sourceMaterial )
  108. {
  109. if ( m_pSheet )
  110. {
  111. delete m_pSheet;
  112. }
  113. m_Material.Init(sourceMaterial);
  114. m_pSheet = new CSheetExtended(m_Material);
  115. PrepareMaterials();
  116. PerformLayout();
  117. }
  118. void CSheetSequencePanel::PerformLayout()
  119. {
  120. int newWidth = SequenceGridCount() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
  121. int newHeight = SequenceGridRows() * SequenceGridSquareSize() + SEQUENCE_PANEL_BORDER*2;
  122. if ( SequenceGridCount() == 0 )
  123. {
  124. newWidth = 32;
  125. newHeight = 32;
  126. }
  127. SetSize( newWidth, newHeight );
  128. Repaint();
  129. }
  130. void CSheetSequencePanel::OnCursorExited()
  131. {
  132. m_nHighlightedSequence = -1;
  133. }
  134. void CSheetSequencePanel::OnCursorMoved(int x, int y)
  135. {
  136. BaseClass::OnCursorMoved(x,y);
  137. if ( m_pSheet == NULL || m_pSheet->GetSheetSequenceCount() == 0 )
  138. {
  139. m_nHighlightedSequence = -1;
  140. return;
  141. }
  142. int nGridCount = SequenceGridCount();
  143. int nGridSize = SequenceGridSquareSize();
  144. int nGridX = (x - SEQUENCE_PANEL_BORDER) / nGridSize;
  145. int nGridY = (y - SEQUENCE_PANEL_BORDER) / nGridSize;
  146. if ( nGridX >= 0 && nGridY >= 0 &&
  147. nGridX < nGridCount && nGridY < nGridCount )
  148. {
  149. int nSeqIndex = nGridX + nGridY*nGridCount;
  150. if ( nSeqIndex < m_pSheet->GetSheetSequenceCount() )
  151. {
  152. m_nHighlightedSequence = nSeqIndex;
  153. }
  154. else
  155. {
  156. m_nHighlightedSequence = -1;
  157. }
  158. }
  159. else
  160. {
  161. m_nHighlightedSequence = -1;
  162. }
  163. }
  164. int CSheetSequencePanel::SequenceGridCount()
  165. {
  166. return m_pSheet ? Ceil2Int(sqrt((float)m_pSheet->GetSheetSequenceCount())) : 0;
  167. }
  168. int CSheetSequencePanel::SequenceGridSquareSize()
  169. {
  170. int nGridCount = SequenceGridCount();
  171. if ( nGridCount == 0 )
  172. {
  173. return 0;
  174. }
  175. else
  176. {
  177. return (SEQUENCE_PANEL_MAX_SIZE / nGridCount);
  178. }
  179. }
  180. int CSheetSequencePanel::SequenceGridRows()
  181. {
  182. if ( !m_pSheet )
  183. return 0;
  184. int nSequences = m_pSheet->GetSheetSequenceCount();
  185. int nGridCount = SequenceGridCount();
  186. if ( nSequences == 0 )
  187. {
  188. return 0;
  189. }
  190. else
  191. {
  192. // nSequences / nGridCount, rounded up
  193. return (nSequences + nGridCount - 1) / nGridCount;
  194. }
  195. }
  196. void CSheetSequencePanel::OnMouseReleased( vgui::MouseCode mouseCode )
  197. {
  198. if ( m_nHighlightedSequence != -1 )
  199. {
  200. KeyValues *k = new KeyValues("SheetSequenceSelected");
  201. k->SetPtr("panel", this);
  202. k->SetInt("nSequenceNumber", m_nHighlightedSequence);
  203. k->SetBool("bIsSecondSequence", m_bIsSecondSequenceView );
  204. PostActionSignal( k );
  205. }
  206. SetVisible(false);
  207. }
  208. void CSheetSequencePanel::Paint( void )
  209. {
  210. int x, y, w, h;
  211. GetSize(w, h);
  212. GetPos(x,y);
  213. vgui::surface()->DrawSetColor( Color(0,0,0,255) );
  214. vgui::surface()->DrawOutlinedRect( 1, 1, w-1, h-1 );
  215. if ( m_pSheet == NULL || !m_pSheet->ValidSheetData() )
  216. {
  217. return;
  218. }
  219. CMatRenderContextPtr pRenderContext( vgui::MaterialSystem() );
  220. vgui::MatSystemSurface()->Begin3DPaint( 2, 2, w-2, h-2 );
  221. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  222. pRenderContext->PushMatrix();
  223. pRenderContext->LoadIdentity();
  224. pRenderContext->Ortho( 2, 2, w-2, h-2, -1.0f, 1.0f );
  225. pRenderContext->MatrixMode( MATERIAL_MODEL );
  226. pRenderContext->PushMatrix();
  227. pRenderContext->LoadIdentity();
  228. // Deal with refraction
  229. if ( m_Material->NeedsPowerOfTwoFrameBufferTexture() )
  230. {
  231. ITexture *pTexture = GetPowerOfTwoFrameBufferTexture();
  232. if ( pTexture && !pTexture->IsError() )
  233. {
  234. pRenderContext->CopyRenderTargetToTexture( pTexture );
  235. pRenderContext->SetFrameBufferCopyTexture( pTexture );
  236. }
  237. }
  238. Color bgColor = GetBgColor();
  239. pRenderContext->ClearColor4ub( bgColor.r(), bgColor.g(), bgColor.b(), 255 );
  240. pRenderContext->ClearBuffers( true, true );
  241. pRenderContext->FogMode( MATERIAL_FOG_NONE );
  242. pRenderContext->SetNumBoneWeights( 0 );
  243. bool bOverrideSpriteCard = false;
  244. bool bOnlyColor = false;
  245. bool bOnlyAlpha = false;
  246. if ( m_bSeparateAlphaColorMaterial )
  247. {
  248. if ( !m_bIsSecondSequenceView )
  249. {
  250. pRenderContext->Bind( m_sAlphaMat );
  251. bOnlyAlpha = true;
  252. }
  253. else
  254. {
  255. pRenderContext->Bind( m_sColorMat );
  256. bOnlyColor = true;
  257. }
  258. bOverrideSpriteCard = true;
  259. }
  260. else
  261. {
  262. pRenderContext->Bind( m_Material );
  263. }
  264. IMesh *pMesh = pRenderContext->GetDynamicMesh();
  265. float flAge = fmodf( Plat_FloatTime(), m_pSheet->GetSequenceTimeSpan(0) );
  266. int nGridCount = SequenceGridCount();
  267. float flGridSquareSize = SequenceGridSquareSize();
  268. float flOffset = 0.5f*flGridSquareSize+SEQUENCE_PANEL_BORDER;
  269. int nSequences = m_pSheet->GetSheetSequenceCount();
  270. for ( int i = 0; i < nSequences; ++i )
  271. {
  272. float x = i % nGridCount;
  273. float y = i / nGridCount;
  274. if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
  275. || bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
  276. {
  277. continue;
  278. }
  279. m_pSheet->DrawSheet( pMesh, Vector(flOffset+x*flGridSquareSize,h-(flOffset+y*flGridSquareSize),0), flGridSquareSize*0.5f, i, flAge, 750.0f, true, -1, bOverrideSpriteCard );
  280. }
  281. pRenderContext->PopMatrix();
  282. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  283. pRenderContext->PopMatrix();
  284. vgui::MatSystemSurface()->End3DPaint( );
  285. //////////////////////////////////////////////////////////////////////////
  286. flOffset = SEQUENCE_PANEL_BORDER;
  287. for ( int i = 0; i < nSequences; ++i )
  288. {
  289. float x = i % nGridCount;
  290. float y = i / nGridCount;
  291. Color drawColor = Color(0,0,0,255);
  292. if ( m_nHighlightedSequence == i )
  293. {
  294. drawColor = Color(255,255,255,255);
  295. }
  296. vgui::surface()->DrawSetColor(drawColor);
  297. vgui::surface()->DrawSetTextColor(drawColor);
  298. vgui::surface()->DrawOutlinedRect( flOffset+x*flGridSquareSize, flOffset+y*flGridSquareSize, flOffset+(x+1)*flGridSquareSize, flOffset+(y+1)*flGridSquareSize );
  299. wchar_t strBuffer[8];
  300. V_snwprintf( strBuffer, ARRAYSIZE( strBuffer ), L"%d", i );
  301. vgui::surface()->DrawSetTextFont( vgui::scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmall" ) );
  302. vgui::surface()->DrawSetTextPos(flOffset+x*flGridSquareSize+2, flOffset+y*flGridSquareSize+1);
  303. vgui::surface()->DrawUnicodeString( strBuffer );
  304. if ( bOnlyColor && !m_pSheet->SequenceHasColorData( i )
  305. || bOnlyAlpha && !m_pSheet->SequenceHasAlphaData( i ) )
  306. {
  307. vgui::surface()->DrawSetTextColor( Color(255,0,0,255) );
  308. vgui::surface()->DrawSetTextPos(flOffset+(x+0.5f)*flGridSquareSize, flOffset+(y+0.5f)*flGridSquareSize+1);
  309. vgui::surface()->DrawUnicodeString( L"x" );
  310. }
  311. }
  312. }