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.

767 lines
24 KiB

  1. //=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. // $Header: $
  9. // $NoKeywords: $
  10. //
  11. //=============================================================================
  12. #include "gameuisystem.h"
  13. #include "materialsystem/imaterialsystem.h"
  14. #include "materialsystem/imesh.h"
  15. #include "gameuidefinition.h"
  16. #include "gamelayer.h"
  17. #include "tier0/vprof.h"
  18. #include "rendersystem/irenderdevice.h"
  19. #include "rendersystem/irendercontext.h"
  20. #include "gameuisystemsurface.h"
  21. #include "inputgameui.h"
  22. #include "gameuisystemmgr.h"
  23. #include "gameuiscript.h"
  24. // memdbgon must be the last include file in a .cpp file!!!
  25. #include "tier0/memdbgon.h"
  26. #define MAX_LAYERS 10
  27. #define DEBUG_DRAW_REPORT 1
  28. #define HIDE_ALL_TEXT 0
  29. #define HIDE_FONT_TEXTURES 1
  30. // A list of script handles exposed by the system
  31. static int32 g_iSerialHandle = 0;
  32. static CUtlMap< int32, CGameUISystem * > g_mapScriptHandles( DefLessFunc( int32 ) );
  33. CGameUISystem::CGameUISystem() :
  34. m_GameUIDef( this ),
  35. m_iScriptHandle( ++g_iSerialHandle )
  36. {
  37. m_bDrawReport = true;
  38. g_mapScriptHandles.InsertOrReplace( m_iScriptHandle, this );
  39. }
  40. CGameUISystem::~CGameUISystem()
  41. {
  42. g_mapScriptHandles.Remove( m_iScriptHandle );
  43. }
  44. CGameUISystem * CGameUISystem::FromScriptHandle( int32 iScriptHandle )
  45. {
  46. unsigned short usIdx = g_mapScriptHandles.Find( iScriptHandle );
  47. return ( usIdx == g_mapScriptHandles.InvalidIndex() ) ? NULL : g_mapScriptHandles.Element( usIdx );
  48. }
  49. char const * CGameUISystem::GetName()
  50. {
  51. return m_GameUIDef.GetName();
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Init, shutdown
  55. //-----------------------------------------------------------------------------
  56. bool CGameUISystem::Init( KeyValues *kvLoadSettings )
  57. {
  58. DevMsg( "CGameUISystem[%p]::Init( name = %s )\n", this, GetName() );
  59. KeyValuesDumpAsDevMsg( kvLoadSettings );
  60. return true;
  61. }
  62. void CGameUISystem::Release()
  63. {
  64. DevMsg( "CGameUISystem[%p]::Release( name = %s )\n", this, GetName() );
  65. g_pGameUISystemMgrImpl->OnScreenReleased( this );
  66. m_GameUIDef.Shutdown();
  67. delete this;
  68. }
  69. //-----------------------------------------------------------------------------
  70. // Creates an empty game UI.
  71. //-----------------------------------------------------------------------------
  72. void CGameUISystem::LoadEmptyGameUI( const char *pName )
  73. {
  74. m_GameUIDef.Shutdown();
  75. m_GameUIDef.CreateDefault( pName );
  76. }
  77. //-----------------------------------------------------------------------------
  78. // Read the game UI config file from a utlbuffer
  79. //-----------------------------------------------------------------------------
  80. bool CGameUISystem::LoadGameUIDefinition( CUtlBuffer &buf, const char *pFileName )
  81. {
  82. DECLARE_DMX_CONTEXT();
  83. CDmxElement *pRoot = NULL;
  84. if ( !UnserializeDMX( buf, &pRoot, pFileName ) )
  85. {
  86. Warning( "Unable to read game UI config %s! UtlBuffer is the wrong type!\n", pFileName );
  87. return false;
  88. }
  89. bool bOk = m_GameUIDef.Unserialize( pRoot );
  90. CleanupDMX( pRoot );
  91. if ( !bOk )
  92. return false;
  93. m_GameUIDef.InitializeScripts();
  94. // Start the animations all at the same time.
  95. //Start();
  96. //TextTest();
  97. return true;
  98. }
  99. //-----------------------------------------------------------------------------
  100. //
  101. //-----------------------------------------------------------------------------
  102. bool CGameUISystem::ExecuteScript( KeyValues *kvEvent, KeyValues **ppResult )
  103. {
  104. return m_GameUIDef.ExecuteScript( kvEvent, ppResult );
  105. }
  106. //-----------------------------------------------------------------------------
  107. //
  108. //-----------------------------------------------------------------------------
  109. void CGameUISystem::SetStageSize( int nWide, int nTall )
  110. {
  111. m_GameUIDef.SetStageSize( nWide, nTall);
  112. }
  113. //-----------------------------------------------------------------------------
  114. //
  115. //-----------------------------------------------------------------------------
  116. void CGameUISystem::GetStageSize( Vector2D &stageSize )
  117. {
  118. m_GameUIDef.GetStageSize( stageSize );
  119. }
  120. //-----------------------------------------------------------------------------
  121. // 3 draw calls per layer.
  122. // Render in source 1
  123. //-----------------------------------------------------------------------------
  124. void CGameUISystem::Render( const Rect_t &viewport )
  125. {
  126. if ( !m_GameUIDef.GetVisible() )
  127. return;
  128. VPROF_BUDGET( "Render", "Render" );
  129. Assert( g_pMaterialSystem );
  130. m_GameUIDef.UpdateGeometry();
  131. m_GameUIDef.UpdateRenderTransforms( viewport );
  132. CUtlVector< LayerRenderLists_t > renderLists;
  133. m_GameUIDef.GetRenderData( renderLists );
  134. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  135. // Clear back buffer to green. Useful for debugging graphics that you think should be there and are not.
  136. //pRenderContext->ClearColor4ub( 76, 88, 68, 255 );
  137. //pRenderContext->ClearBuffers( true, true );
  138. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  139. pRenderContext->PushMatrix();
  140. pRenderContext->LoadIdentity();
  141. pRenderContext->Scale( 1, -1, 1 );
  142. float flPixelOffsetX = .5;
  143. float flPixelOffsetY = .5;
  144. pRenderContext->Ortho( viewport.x + flPixelOffsetX, viewport.y + flPixelOffsetY, viewport.width + flPixelOffsetX, viewport.height + flPixelOffsetY, -1.0f, 1.0f );
  145. // make sure there is no translation and rotation laying around
  146. pRenderContext->MatrixMode( MATERIAL_MODEL );
  147. pRenderContext->PushMatrix();
  148. pRenderContext->LoadIdentity();
  149. pRenderContext->MatrixMode( MATERIAL_VIEW );
  150. pRenderContext->PushMatrix();
  151. pRenderContext->LoadIdentity();
  152. int nStaticDrawCalls = 0;
  153. int nDynamicDrawCalls = 0;
  154. int nFontDrawCalls = 0;
  155. int nLists = renderLists.Count();
  156. for ( int i = 0; i < nLists; ++i )
  157. {
  158. if ( renderLists[i].m_LayerType == SUBLAYER_STATIC )
  159. {
  160. for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
  161. {
  162. RenderStaticLayer( renderLists[i], j );
  163. nStaticDrawCalls++;
  164. }
  165. }
  166. else if ( renderLists[i].m_LayerType == SUBLAYER_DYNAMIC )
  167. {
  168. // For dynamic texture viewing.
  169. //int x = 900;
  170. //int y = 0;
  171. for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
  172. {
  173. RenderDynamicLayer( renderLists[i], j );
  174. nDynamicDrawCalls++;
  175. // For dynamic texture viewing.
  176. //g_pGameUISystemMgrImpl->DrawDynamicTexture( renderLists[i].m_RenderGeometryLists[j][0].m_pImageAlias, x, y );
  177. //y += 256 + 30;
  178. }
  179. }
  180. else if ( renderLists[i].m_LayerType == SUBLAYER_FONT )
  181. {
  182. // For font texture viewing.
  183. //int x = 900;
  184. //int y = 30;
  185. for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
  186. {
  187. RenderTextLayer( renderLists[i].m_RenderGeometryLists[j] );
  188. nFontDrawCalls++;
  189. // For font texture viewing.
  190. //g_pGameUISystemSurface->DrawFontTexture( renderLists[i].m_RenderGeometryLists[j][0].m_FontTextureID, x, y );
  191. //y += 256 + 30;
  192. }
  193. }
  194. }
  195. #if ( DEBUG_DRAW_REPORT )
  196. if ( m_bDrawReport )
  197. {
  198. m_bDrawReport = false;
  199. Msg( "Total static draw calls in UI: %d\n", nStaticDrawCalls );
  200. Msg( "Total dynamic draw calls in UI: %d\n", nDynamicDrawCalls );
  201. Msg( "Total font draw calls in UI: %d\n", nFontDrawCalls );
  202. Msg( "Total draw calls in UI: %d\n", nStaticDrawCalls + nDynamicDrawCalls + nFontDrawCalls );
  203. }
  204. #endif
  205. // Restore the matrices
  206. pRenderContext->MatrixMode( MATERIAL_PROJECTION );
  207. pRenderContext->PopMatrix();
  208. pRenderContext->MatrixMode( MATERIAL_MODEL );
  209. pRenderContext->PopMatrix();
  210. pRenderContext->MatrixMode( MATERIAL_VIEW );
  211. pRenderContext->PopMatrix();
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Render a static layer in source 1
  215. //-----------------------------------------------------------------------------
  216. void CGameUISystem::RenderStaticLayer( LayerRenderLists_t &renderList, int geometryIndex )
  217. {
  218. // Do not call draw on an empty mesh.
  219. int nTotalTriCount = 0;
  220. for( int i = 0; i < renderList.m_RenderGeometryLists[geometryIndex].Count(); ++i )
  221. {
  222. nTotalTriCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount();
  223. }
  224. if ( nTotalTriCount == 0 )
  225. return;
  226. if ( renderList.m_pSheet == NULL )
  227. {
  228. Assert(0);
  229. return;
  230. }
  231. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  232. pRenderContext->Bind( renderList.m_pMaterial, NULL );
  233. IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
  234. GenerateUIMesh( pRenderContext, pMesh, renderList.m_RenderGeometryLists[geometryIndex],
  235. renderList.m_pSheet );
  236. pMesh->Draw();
  237. }
  238. //-----------------------------------------------------------------------------
  239. // Render a dynamic layer in source 1
  240. //-----------------------------------------------------------------------------
  241. void CGameUISystem::RenderDynamicLayer( LayerRenderLists_t &renderList, int geometryIndex )
  242. {
  243. // Do not call draw on an empty mesh.
  244. int nTotalTriCount = 0;
  245. for( int i = 0; i < renderList.m_RenderGeometryLists[geometryIndex].Count(); ++i )
  246. {
  247. nTotalTriCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount();
  248. }
  249. if ( nTotalTriCount == 0 )
  250. return;
  251. if ( renderList.m_pMaterial == NULL )
  252. return;
  253. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  254. IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, renderList.m_pMaterial ); // this fxn will also bind the material
  255. if ( !pMesh )
  256. return;
  257. CMeshBuilder meshBuilder;
  258. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, nTotalTriCount );
  259. CUtlVector< CRenderGeometry > &renderGeometry = renderList.m_RenderGeometryLists[geometryIndex];
  260. int nGraphicCount = renderGeometry.Count();
  261. int nIndex = 0;
  262. for( int i = 0; i < nGraphicCount; ++i )
  263. {
  264. for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
  265. {
  266. // First anim frame
  267. float flX = renderGeometry[i].m_Positions[j].x;
  268. float flY = renderGeometry[i].m_Positions[j].y;
  269. meshBuilder.Position3f( flX, flY, 0.0f );
  270. color32 c = renderGeometry[i].m_VertexColors[j];
  271. meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
  272. float texCoordX = renderGeometry[i].m_TextureCoords[j].x;
  273. float texCoordY = renderGeometry[i].m_TextureCoords[j].y;
  274. meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
  275. meshBuilder.AdvanceVertex();
  276. }
  277. Assert( renderGeometry[i].m_Positions.Count() == 4 );
  278. // FIXME make this work with generic convex shapes.
  279. // Quads only.
  280. meshBuilder.FastIndex( nIndex );
  281. meshBuilder.FastIndex( nIndex + 1 );
  282. meshBuilder.FastIndex( nIndex + 2 );
  283. meshBuilder.FastIndex( nIndex );
  284. meshBuilder.FastIndex( nIndex + 2 );
  285. meshBuilder.FastIndex( nIndex + 3 );
  286. nIndex += (4);
  287. }
  288. meshBuilder.End();
  289. pMesh->Draw();
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Render a font layer in source 1
  293. //-----------------------------------------------------------------------------
  294. void CGameUISystem::RenderTextLayer( CUtlVector< CRenderGeometry > &renderGeometry )
  295. {
  296. if ( renderGeometry.Count() == 0 )
  297. return;
  298. CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
  299. // get the character texture from the cache
  300. IMaterial *pMaterial = g_pGameUISystemSurface->GetMaterial( renderGeometry[0].m_FontTextureID ); /// Everything in a text rendering layer uses the same font texture, and the texture id is in the seq #
  301. IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); // this fxn will also bind the material
  302. if ( !pMesh )
  303. return;
  304. CMeshBuilder meshBuilder;
  305. meshBuilder.Begin( pMesh, MATERIAL_QUADS, renderGeometry.Count() );
  306. for ( int i = 0; i < renderGeometry.Count(); ++i )
  307. {
  308. Assert( renderGeometry[i].m_Positions.Count() == 4 );
  309. for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
  310. {
  311. meshBuilder.Position3f( renderGeometry[i].m_Positions[j].x, renderGeometry[i].m_Positions[j].y, 0.0f );
  312. meshBuilder.Color4ub( renderGeometry[i].m_VertexColors[j].r, renderGeometry[i].m_VertexColors[j].g, renderGeometry[i].m_VertexColors[j].b, renderGeometry[i].m_VertexColors[j].a );
  313. meshBuilder.TexCoord3f( 0, renderGeometry[i].m_TextureCoords[j].x, renderGeometry[i].m_TextureCoords[j].y, 0 );
  314. meshBuilder.AdvanceVertex();
  315. }
  316. }
  317. meshBuilder.End();
  318. pMesh->Draw();
  319. }
  320. //-----------------------------------------------------------------------------
  321. // Create geometry mesh in source 1
  322. //-----------------------------------------------------------------------------
  323. void CGameUISystem::GenerateUIMesh( IMatRenderContext *pRenderContext,
  324. IMesh* pMesh,
  325. CUtlVector< CRenderGeometry > &renderGeometry,
  326. CSheet *pSheet )
  327. {
  328. int nTotalTriCount = 0;
  329. for( int i = 0; i < renderGeometry.Count(); ++i )
  330. {
  331. nTotalTriCount += renderGeometry[i].GetTriangleCount();
  332. }
  333. Assert( nTotalTriCount != 0 );
  334. CMeshBuilder meshBuilder;
  335. meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, nTotalTriCount * 2 );
  336. int x, y, width, height;
  337. pRenderContext->GetViewport( x, y, width, height);
  338. static long flAge = 0;
  339. {
  340. VPROF_BUDGET( "meshBuilder", "meshBuilder" );
  341. int nGraphicCount = renderGeometry.Count();
  342. int nIndex = 0;
  343. for( int i = 0; i < nGraphicCount; ++i )
  344. {
  345. const SheetSequenceSample_t *pSample = NULL;
  346. int seqNum = renderGeometry[i].m_SheetSequenceNumber;
  347. if ( renderGeometry[i].m_bAnimate )
  348. {
  349. DmeTime_t flStartTime = renderGeometry[i].GetAnimStartTime();
  350. DmeTime_t flAgeInSeconds = ( g_pGameUISystemMgrImpl->GetTime() - flStartTime );
  351. float m_flAnimationRate = renderGeometry[i].m_AnimationRate;
  352. float flAgeScale = m_flAnimationRate * SEQUENCE_SAMPLE_COUNT;
  353. flAgeScale /= pSheet->m_SheetInfo[seqNum].m_flFrameSpan;
  354. pSample = pSheet->GetSampleForSequence( flAgeInSeconds.GetSeconds(), flAgeScale, seqNum, true );
  355. }
  356. else
  357. {
  358. pSample = pSheet->m_SheetInfo[seqNum].m_pSamples;
  359. }
  360. Assert( pSample );
  361. const SequenceSampleTextureCoords_t *pSample0 = &(pSample->m_TextureCoordData[0]);
  362. Assert( pSample0 );
  363. for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
  364. {
  365. // First anim frame
  366. float flX = renderGeometry[i].m_Positions[j].x;
  367. float flY = renderGeometry[i].m_Positions[j].y;
  368. meshBuilder.Position3f( flX, flY, 0.0f );
  369. color32 c = renderGeometry[i].m_VertexColors[j];
  370. c.a *= ( 1 - pSample->m_fBlendFactor );
  371. meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
  372. float sampleWidth = pSample0->m_fRight_U0 - pSample0->m_fLeft_U0;
  373. float sampleHeight = pSample0->m_fBottom_V0 - pSample0->m_fTop_V0;
  374. float texCoordX = pSample0->m_fLeft_U0 + renderGeometry[i].m_TextureCoords[j].x * sampleWidth;
  375. float texCoordY = pSample0->m_fTop_V0 + renderGeometry[i].m_TextureCoords[j].y * sampleHeight;
  376. meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
  377. meshBuilder.AdvanceVertex();
  378. // Ugh, right now we have to do this second frame because of the total triangle count being set before we figure out if we need it.
  379. // Second anim frame
  380. //if ( pSample->m_fBlendFactor < 1.0 )
  381. {
  382. meshBuilder.Position3f( flX, flY, 0.0f );
  383. c = renderGeometry[i].m_VertexColors[j];
  384. c.a *= ( pSample->m_fBlendFactor );
  385. meshBuilder.Color4ub( c.r, c.g, c.b, c.a );
  386. float texCoordX = pSample0->m_fLeft_U1 + renderGeometry[i].m_TextureCoords[j].x * sampleWidth;
  387. float texCoordY = pSample0->m_fTop_V1 + renderGeometry[i].m_TextureCoords[j].y * sampleHeight;
  388. meshBuilder.TexCoord3f( 0, texCoordX, texCoordY, 0 );
  389. meshBuilder.AdvanceVertex();
  390. }
  391. }
  392. //if ( pSample->m_fBlendFactor < 1.0 )
  393. {
  394. // FIME make this work with generic convex shapes.
  395. // Quads only.
  396. meshBuilder.FastIndex( nIndex );
  397. meshBuilder.FastIndex( nIndex + 2 );
  398. meshBuilder.FastIndex( nIndex + 4 );
  399. meshBuilder.FastIndex( nIndex );
  400. meshBuilder.FastIndex( nIndex + 4 );
  401. meshBuilder.FastIndex( nIndex + 6 );
  402. meshBuilder.FastIndex( nIndex + 1 );
  403. meshBuilder.FastIndex( nIndex + 3 );
  404. meshBuilder.FastIndex( nIndex + 5 );
  405. meshBuilder.FastIndex( nIndex + 1 );
  406. meshBuilder.FastIndex( nIndex + 5 );
  407. meshBuilder.FastIndex( nIndex + 7 );
  408. nIndex += (4 * 2);
  409. }
  410. /*
  411. else
  412. {
  413. meshBuilder.FastIndex( nIndex );
  414. meshBuilder.FastIndex( nIndex + 1 );
  415. meshBuilder.FastIndex( nIndex + 2 );
  416. meshBuilder.FastIndex( nIndex );
  417. meshBuilder.FastIndex( nIndex + 2 );
  418. meshBuilder.FastIndex( nIndex + 3 );
  419. nIndex += (4 * 1);
  420. }
  421. */
  422. }
  423. }
  424. meshBuilder.End();
  425. }
  426. //-----------------------------------------------------------------------------
  427. // 3 draw calls per layer.
  428. // Render the UI in source 2
  429. //-----------------------------------------------------------------------------
  430. void CGameUISystem::Render( IRenderContext *pRenderContext, const Rect_t &viewport )
  431. {
  432. if ( !m_GameUIDef.GetVisible() )
  433. return;
  434. m_GameUIDef.UpdateGeometry();
  435. m_GameUIDef.UpdateRenderTransforms( viewport );
  436. CUtlVector< LayerRenderLists_t > renderLists;
  437. m_GameUIDef.GetRenderData( renderLists );
  438. // Note this is not scaling correctly!
  439. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_NONE );
  440. pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
  441. pRenderContext->BindVertexShader( g_pGameUISystemMgrImpl->m_hVertexShader, g_pGameUISystemMgrImpl->m_hInputLayout );
  442. pRenderContext->BindShader( RENDER_PIXEL_SHADER, g_pGameUISystemMgrImpl->m_hPixelShader );
  443. float pViewportInfo[4] = { viewport.x + 0.5f, viewport.y + 0.5f, viewport.width, viewport.height };
  444. pRenderContext->SetConstantBufferData( g_pGameUISystemMgrImpl->m_hConstBuffer, pViewportInfo, 4 * sizeof( float ) );
  445. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, g_pGameUISystemMgrImpl->m_hConstBuffer, 0, 0 );
  446. int nLists = renderLists.Count();
  447. for ( int i = 0; i < nLists; ++i )
  448. {
  449. if ( renderLists[i].m_LayerType == SUBLAYER_STATIC )
  450. {
  451. for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
  452. {
  453. RenderStaticLayer( pRenderContext, renderLists[i], j );
  454. }
  455. }
  456. else if ( renderLists[i].m_LayerType == SUBLAYER_FONT )
  457. {
  458. for ( int j = 0; j < renderLists[i].m_RenderGeometryLists.Count(); ++j )
  459. {
  460. RenderTextLayer( pRenderContext, renderLists[i].m_RenderGeometryLists[j] );
  461. }
  462. }
  463. }
  464. }
  465. //-----------------------------------------------------------------------------
  466. // Render a font layer in source 2
  467. //-----------------------------------------------------------------------------
  468. void CGameUISystem::RenderTextLayer( IRenderContext *pRenderContext, CUtlVector< CRenderGeometry > &renderGeometry )
  469. {
  470. if ( renderGeometry.Count() == 0 )
  471. return;
  472. // get the character texture from the cache
  473. HRenderTexture fontTextureHandle = g_pGameUISystemSurface->GetTextureHandle( renderGeometry[0].m_FontTextureID );
  474. pRenderContext->BindTexture( 0, fontTextureHandle );
  475. CDynamicVertexData< GameUIVertex_t > vb( pRenderContext, renderGeometry.Count() * 4, "gamelayer", "game_controls" );
  476. vb.Lock();
  477. for ( int i = 0; i < renderGeometry.Count(); ++i )
  478. {
  479. Assert( renderGeometry[i].m_Positions.Count() == 4 );
  480. for ( int j = 0; j < renderGeometry[i].m_Positions.Count(); ++j )
  481. {
  482. vb->m_vecPosition.Init( renderGeometry[i].m_Positions[j].x, renderGeometry[i].m_Positions[j].y, 0.0f );
  483. vb->m_color = renderGeometry[i].m_VertexColors[j];
  484. vb->m_vecTexCoord.Init( renderGeometry[i].m_TextureCoords[j].x, renderGeometry[i].m_TextureCoords[j].y );
  485. vb.AdvanceVertex();
  486. }
  487. }
  488. vb.Unlock();
  489. vb.Bind( 0, 0 );
  490. CDynamicIndexData< uint16 > ib( pRenderContext, renderGeometry.Count() * 6, "gamelayer", "game_controls" );
  491. ib.Lock();
  492. int nIndex = 0;
  493. for( int i = 0; i < renderGeometry.Count(); ++i )
  494. {
  495. ib.Index( nIndex );
  496. ib.Index( nIndex + 1 );
  497. ib.Index( nIndex + 2 );
  498. ib.Index( nIndex );
  499. ib.Index( nIndex + 2 );
  500. ib.Index( nIndex + 3 );
  501. nIndex += 4;
  502. }
  503. ib.Unlock();
  504. ib.Bind( 0 );
  505. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, renderGeometry.Count() * 6 );
  506. // For debugging.
  507. //int x = 300;
  508. //int y = 300;
  509. //g_pGameUISystemSurface->DrawFontTexture( pRenderContext, renderGeometry[0].m_FontTextureID, x, y );
  510. //x += 256;
  511. }
  512. //-----------------------------------------------------------------------------
  513. // Renders the static layer in source 2
  514. //-----------------------------------------------------------------------------
  515. void CGameUISystem::RenderStaticLayer( IRenderContext *pRenderContext, LayerRenderLists_t &renderList, int geometryIndex )
  516. {
  517. int nGraphicCount = renderList.m_RenderGeometryLists[geometryIndex].Count();
  518. if ( !nGraphicCount )
  519. return;
  520. int nTotalIndexCount = 0;
  521. int nTotalVertexCount = 0;
  522. int nGeometryCount = renderList.m_RenderGeometryLists[geometryIndex].Count();
  523. for( int i = 0; i < nGeometryCount; ++i )
  524. {
  525. nTotalIndexCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetTriangleCount() * 3;
  526. nTotalVertexCount += renderList.m_RenderGeometryLists[geometryIndex][i].GetVertexCount();
  527. }
  528. if ( nTotalIndexCount == 0 )
  529. return;
  530. pRenderContext->BindTexture( 0, renderList.m_hTexture );
  531. CDynamicVertexData< GameUIVertex_t > vb( pRenderContext, nTotalVertexCount * 2, "gamelayer", "game_controls" );
  532. vb.Lock();
  533. for( int i = 0; i < nGeometryCount; ++i )
  534. {
  535. CRenderGeometry *pGeometry = &renderList.m_RenderGeometryLists[geometryIndex][i];
  536. const SheetSequenceSample_t *pSample = NULL;
  537. int seqNum = pGeometry->m_SheetSequenceNumber;
  538. if ( pGeometry->m_bAnimate )
  539. {
  540. DmeTime_t flStartTime = pGeometry->GetAnimStartTime();
  541. DmeTime_t flAgeInSeconds = ( g_pGameUISystemMgrImpl->GetTime() - flStartTime );
  542. float m_flAnimationRate = pGeometry->m_AnimationRate;
  543. float flAgeScale = m_flAnimationRate * SEQUENCE_SAMPLE_COUNT;
  544. flAgeScale /= renderList.m_pSheet->m_SheetInfo[seqNum].m_flFrameSpan;
  545. pSample = renderList.m_pSheet->GetSampleForSequence( flAgeInSeconds.GetSeconds(), flAgeScale, seqNum, true );
  546. }
  547. else
  548. {
  549. pSample = renderList.m_pSheet->m_SheetInfo[seqNum].m_pSamples;
  550. }
  551. Assert( pSample );
  552. const SequenceSampleTextureCoords_t *pSample0 = &(pSample->m_TextureCoordData[0]);
  553. Assert( pSample0 );
  554. for ( int j = 0; j < pGeometry->m_Positions.Count(); ++j )
  555. {
  556. // First anim frame
  557. float flX = pGeometry->m_Positions[j].x;
  558. float flY = pGeometry->m_Positions[j].y;
  559. vb->m_vecPosition.Init( flX, flY, 0.0f );
  560. color32 c = pGeometry->m_VertexColors[j];
  561. c.a *= ( 1 - pSample->m_fBlendFactor );
  562. vb->m_color = c;
  563. float sampleWidth = pSample0->m_fRight_U0 - pSample0->m_fLeft_U0;
  564. float sampleHeight = pSample0->m_fBottom_V0 - pSample0->m_fTop_V0;
  565. float texCoordX = pSample0->m_fLeft_U0 + pGeometry->m_TextureCoords[j].x * sampleWidth;
  566. float texCoordY = pSample0->m_fTop_V0 + pGeometry->m_TextureCoords[j].y * sampleHeight;
  567. vb->m_vecTexCoord.Init( texCoordX, texCoordY );
  568. vb.AdvanceVertex();
  569. // Second anim frame
  570. //if ( pSample->m_fBlendFactor < 1.0 )
  571. {
  572. c = pGeometry->m_VertexColors[j];
  573. c.a *= ( pSample->m_fBlendFactor );
  574. vb->m_color = c;
  575. float texCoordX = pSample0->m_fLeft_U1 + pGeometry->m_TextureCoords[j].x * sampleWidth;
  576. float texCoordY = pSample0->m_fTop_V1 + pGeometry->m_TextureCoords[j].y * sampleHeight;
  577. vb->m_vecTexCoord.Init( texCoordX, texCoordY );
  578. vb.AdvanceVertex();
  579. }
  580. }
  581. }
  582. vb.Unlock();
  583. vb.Bind( 0, 0 );
  584. CDynamicIndexData< uint16 > ib( pRenderContext, nTotalIndexCount * 2, "gamelayer", "game_controls" );
  585. ib.Lock();
  586. int nIndex = 0;
  587. for( int i = 0; i < nGeometryCount; ++i )
  588. {
  589. ib.Index( nIndex );
  590. ib.Index( nIndex + 2 );
  591. ib.Index( nIndex + 4 );
  592. ib.Index( nIndex );
  593. ib.Index( nIndex + 4 );
  594. ib.Index( nIndex + 6 );
  595. ib.Index( nIndex + 1 );
  596. ib.Index( nIndex + 3 );
  597. ib.Index( nIndex + 5 );
  598. ib.Index( nIndex + 1 );
  599. ib.Index( nIndex + 5 );
  600. ib.Index( nIndex + 7 );
  601. nIndex += (4 * 2);
  602. /*
  603. // FIXME: Deal with sometimes only rendering 1 triangle above
  604. CGeometry *pGeometry = geometry[i];
  605. int nTriangleCount = pGeometry->m_Triangles.Count();
  606. for ( int j = 0; j < nTriangleCount; ++j )
  607. {
  608. CTriangle *pTriangle = &pGeometry->m_Triangles[j];
  609. //if ( pSample->m_fBlendFactor < 1.0 )
  610. {
  611. ib.Index( nIndex + pTriangle->m_PointIndex[0] * 2 );
  612. ib.Index( nIndex + pTriangle->m_PointIndex[1] * 2 );
  613. ib.Index( nIndex + pTriangle->m_PointIndex[2] * 2 );
  614. ib.Index( nIndex + pTriangle->m_PointIndex[0] * 2 + 1 );
  615. ib.Index( nIndex + pTriangle->m_PointIndex[1] * 2 + 1 );
  616. ib.Index( nIndex + pTriangle->m_PointIndex[2] * 2 + 1 );
  617. }
  618. else
  619. {
  620. //ib.Index( nIndex + pTriangle->m_PointIndex[0] );
  621. //ib.Index( nIndex + pTriangle->m_PointIndex[1] );
  622. //ib.Index( nIndex + pTriangle->m_PointIndex[2] );
  623. //nIndex += 3;
  624. }
  625. }
  626. nIndex += (3 * 2) * nTriangleCount;
  627. */
  628. }
  629. ib.Unlock();
  630. ib.Bind( 0 );
  631. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nTotalIndexCount * 2 );
  632. }