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.

1411 lines
37 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Debugging overlay functions
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #include "render_pch.h"
  10. #include "edict.h"
  11. #include "client.h"
  12. #include "debugoverlay.h"
  13. #include "cdll_int.h"
  14. #include "ivideomode.h"
  15. #include "materialsystem/imesh.h"
  16. #include "gl_matsysiface.h"
  17. #include "server.h"
  18. #include "client_class.h"
  19. #include "icliententitylist.h"
  20. #include "mathlib/vmatrix.h"
  21. #include "icliententity.h"
  22. #include "overlaytext.h"
  23. #include "engine/ivdebugoverlay.h"
  24. #include "cmodel_engine.h"
  25. #include "vphysics_interface.h"
  26. #include "materialsystem/imaterial.h"
  27. #include "tier2/renderutils.h"
  28. // memdbgon must be the last include file in a .cpp file!!!
  29. #include "tier0/memdbgon.h"
  30. extern edict_t *EDICT_NUM(int n);
  31. ConVar enable_debug_overlays( "enable_debug_overlays", "1", FCVAR_GAMEDLL | FCVAR_CHEAT, "Enable rendering of debug overlays" );
  32. int GetOverlayTick()
  33. {
  34. if ( sv.IsActive() )
  35. return sv.m_nTickCount;
  36. return GetBaseLocalClient().GetClientTickCount();
  37. }
  38. bool OverlayText_t::IsDead()
  39. {
  40. if ( m_nServerCount != GetBaseLocalClient().m_nServerCount )
  41. return true;
  42. if ( m_nCreationTick != -1 )
  43. {
  44. if ( GetOverlayTick() > m_nCreationTick )
  45. return true;
  46. return false;
  47. }
  48. if ( m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  49. return false;
  50. return (GetBaseLocalClient().GetTime() >= m_flEndTime);
  51. }
  52. void OverlayText_t::SetEndTime( float duration )
  53. {
  54. m_nServerCount = GetBaseLocalClient().m_nServerCount;
  55. if ( duration <= 0.0f )
  56. {
  57. m_flEndTime = 0.0f;
  58. m_nCreationTick = GetOverlayTick();
  59. return;
  60. }
  61. if ( duration == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  62. {
  63. m_flEndTime = NDEBUG_PERSIST_TILL_NEXT_SERVER;
  64. }
  65. else
  66. {
  67. m_flEndTime = GetBaseLocalClient().GetTime() + duration;
  68. }
  69. }
  70. namespace CDebugOverlay
  71. {
  72. enum OverlayType_t
  73. {
  74. OVERLAY_BOX = 0,
  75. OVERLAY_SPHERE,
  76. OVERLAY_LINE,
  77. OVERLAY_TRIANGLE,
  78. OVERLAY_SWEPT_BOX,
  79. OVERLAY_BOX2,
  80. OVERLAY_CAPSULE
  81. };
  82. struct OverlayBase_t
  83. {
  84. OverlayBase_t()
  85. {
  86. m_Type = OVERLAY_BOX;
  87. m_nServerCount = -1;
  88. m_nCreationTick = -1;
  89. m_flEndTime = 0.0f;
  90. m_pNextOverlay = NULL;
  91. }
  92. bool IsDead()
  93. {
  94. if ( m_nServerCount != GetBaseLocalClient().m_nServerCount )
  95. return true;
  96. if ( m_nCreationTick != -1 )
  97. {
  98. if ( GetOverlayTick() > m_nCreationTick )
  99. return true;
  100. return false;
  101. }
  102. if ( m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  103. return false;
  104. return (GetBaseLocalClient().GetTime() >= m_flEndTime) ;
  105. }
  106. void SetEndTime( float duration )
  107. {
  108. m_nServerCount = GetBaseLocalClient().m_nServerCount;
  109. if ( duration <= 0.0f )
  110. {
  111. m_nCreationTick = GetOverlayTick(); // stay alive for only one frame
  112. return;
  113. }
  114. if ( duration == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  115. {
  116. m_flEndTime = NDEBUG_PERSIST_TILL_NEXT_SERVER;
  117. }
  118. else
  119. {
  120. m_flEndTime = GetBaseLocalClient().GetTime() + duration;
  121. }
  122. }
  123. OverlayType_t m_Type; // What type of overlay is it?
  124. int m_nCreationTick; // Duration -1 means go away after this frame #
  125. int m_nServerCount; // Latch server count, too
  126. float m_flEndTime; // When does this box go away
  127. OverlayBase_t *m_pNextOverlay;
  128. };
  129. struct OverlayBox_t : public OverlayBase_t
  130. {
  131. OverlayBox_t() { m_Type = OVERLAY_BOX; }
  132. Vector origin;
  133. Vector mins;
  134. Vector maxs;
  135. QAngle angles;
  136. int r;
  137. int g;
  138. int b;
  139. int a;
  140. };
  141. struct OverlayBox2_t : public OverlayBase_t
  142. {
  143. OverlayBox2_t() { m_Type = OVERLAY_BOX2; }
  144. Vector origin;
  145. Vector mins;
  146. Vector maxs;
  147. QAngle angles;
  148. Color edgeColor;
  149. Color faceColor;
  150. };
  151. struct OverlaySphere_t : public OverlayBase_t
  152. {
  153. OverlaySphere_t() { m_Type = OVERLAY_SPHERE; }
  154. Vector vOrigin;
  155. float flRadius;
  156. int nTheta;
  157. int nPhi;
  158. int r;
  159. int g;
  160. int b;
  161. int a;
  162. bool m_bWireframe;
  163. };
  164. struct OverlayLine_t : public OverlayBase_t
  165. {
  166. OverlayLine_t() { m_Type = OVERLAY_LINE; }
  167. Vector origin;
  168. Vector dest;
  169. int r;
  170. int g;
  171. int b;
  172. int a;
  173. bool noDepthTest;
  174. };
  175. struct OverlayTriangle_t : public OverlayBase_t
  176. {
  177. OverlayTriangle_t() { m_Type = OVERLAY_TRIANGLE; }
  178. Vector p1;
  179. Vector p2;
  180. Vector p3;
  181. int r;
  182. int g;
  183. int b;
  184. int a;
  185. bool noDepthTest;
  186. };
  187. struct OverlaySweptBox_t : public OverlayBase_t
  188. {
  189. OverlaySweptBox_t() { m_Type = OVERLAY_SWEPT_BOX; }
  190. Vector start;
  191. Vector end;
  192. Vector mins;
  193. Vector maxs;
  194. QAngle angles;
  195. int r;
  196. int g;
  197. int b;
  198. int a;
  199. };
  200. struct OverlayCapsule_t : public OverlayBase_t
  201. {
  202. OverlayCapsule_t() { m_Type = OVERLAY_CAPSULE; }
  203. Vector start;
  204. Vector end;
  205. float flRadius;
  206. int r;
  207. int g;
  208. int b;
  209. int a;
  210. bool m_bWireframe;
  211. };
  212. //-----------------------------------------------------------------------------
  213. // Forward declarations
  214. //-----------------------------------------------------------------------------
  215. void DrawOverlays();
  216. void DrawGridOverlay();
  217. void ClearAllOverlays();
  218. void ClearDeadOverlays();
  219. //-----------------------------------------------------------------------------
  220. // Init static member variables
  221. //-----------------------------------------------------------------------------
  222. OverlayText_t* s_pOverlayText = NULL; // text is handled differently; for backward compatibility reasons
  223. OverlayBase_t* s_pOverlays = NULL;
  224. Vector s_vGridPosition(0,0,0);
  225. bool s_bDrawGrid = false;
  226. CThreadFastMutex s_OverlayMutex;
  227. //-----------------------------------------------------------------------------
  228. // Purpose: Hack to allow this code to run on a client that's not connected to a server
  229. // (i.e., demo playback, or multiplayer game )
  230. // Input : ent_num -
  231. // origin -
  232. // mins -
  233. // maxs -
  234. // Output : static void
  235. //-----------------------------------------------------------------------------
  236. static bool GetEntityOriginClientOrServer( int ent_num, Vector& origin )
  237. {
  238. AUTO_LOCK( s_OverlayMutex );
  239. // Assume failure
  240. origin.Init();
  241. if ( sv.IsActive() )
  242. {
  243. edict_t *e = EDICT_NUM( ent_num );
  244. if ( e )
  245. {
  246. IServerEntity *serverEntity = e->GetIServerEntity();
  247. if ( serverEntity )
  248. {
  249. CM_WorldSpaceCenter( serverEntity->GetCollideable(), &origin );
  250. }
  251. return true;
  252. }
  253. }
  254. else
  255. {
  256. IClientEntity *clent = entitylist->GetClientEntity( ent_num );
  257. if ( clent )
  258. {
  259. CM_WorldSpaceCenter( clent->GetCollideable(), &origin );
  260. return true;
  261. }
  262. }
  263. return false;
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Purpose: Given a point, return the screen position
  267. // Input :
  268. // Output :
  269. //-----------------------------------------------------------------------------
  270. int ScreenPosition(const Vector& point, Vector& screen)
  271. {
  272. AUTO_LOCK( s_OverlayMutex );
  273. CMatRenderContextPtr pRenderContext( materials );
  274. int retval = g_EngineRenderer->ClipTransform(point,&screen);
  275. int x, y, w, h;
  276. pRenderContext->GetViewport( x, y, w, h );
  277. screen[0] = 0.5 * screen[0] * w;
  278. screen[1] = -0.5 * screen[1] * h;
  279. screen[0] += 0.5 * w;
  280. screen[1] += 0.5 * h;
  281. return retval;
  282. }
  283. //-----------------------------------------------------------------------------
  284. // Purpose: Given an xy screen pos (0-1), return the screen position
  285. // Input :
  286. // Output :
  287. //-----------------------------------------------------------------------------
  288. int ScreenPosition(float flXPos, float flYPos, Vector& screen)
  289. {
  290. if (flXPos > 1.0 || flYPos > 1.0 || flXPos < 0.0 || flYPos < 0.0 )
  291. return 1; // Fail
  292. AUTO_LOCK( s_OverlayMutex );
  293. CMatRenderContextPtr pRenderContext( materials );
  294. int x, y, w, h;
  295. pRenderContext->GetViewport( x, y, w, h );
  296. screen[0] = flXPos * w;
  297. screen[1] = flYPos * h;
  298. return 0;
  299. }
  300. //-----------------------------------------------------------------------------
  301. // Purpose: Add new entity positioned overlay text
  302. // Input : Entity to attach text to
  303. // How many lines to offset text from entity origin
  304. // The text to print
  305. // Output :
  306. //-----------------------------------------------------------------------------
  307. void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char *text)
  308. {
  309. if ( GetBaseLocalClient().IsPaused() )
  310. return;
  311. #if defined( _X360 ) && defined( _CERT )
  312. return;
  313. #endif
  314. AUTO_LOCK( s_OverlayMutex );
  315. OverlayText_t *new_overlay = new OverlayText_t;
  316. Vector myPos, myMins, myMaxs;
  317. GetEntityOriginClientOrServer( ent_index, myPos );
  318. VectorCopy(myPos,new_overlay->origin);
  319. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  320. new_overlay->bUseOrigin = true;
  321. new_overlay->lineOffset = line_offset;
  322. new_overlay->SetEndTime( duration );
  323. new_overlay->r = r;
  324. new_overlay->g = g;
  325. new_overlay->b = b;
  326. new_overlay->a = a;
  327. new_overlay->nextOverlayText = s_pOverlayText;
  328. s_pOverlayText = new_overlay;
  329. }
  330. //-----------------------------------------------------------------------------
  331. // Purpose: Add new overlay text
  332. // Input : Position of text & text
  333. // Output :
  334. //-----------------------------------------------------------------------------
  335. void AddGridOverlay(const Vector& vPos)
  336. {
  337. if ( GetBaseLocalClient().IsPaused() )
  338. return;
  339. AUTO_LOCK( s_OverlayMutex );
  340. s_vGridPosition[0] = vPos[0];
  341. s_vGridPosition[1] = vPos[1];
  342. s_vGridPosition[2] = vPos[2];
  343. s_bDrawGrid = true;
  344. }
  345. void AddCoordFrameOverlay(const matrix3x4_t& frame, float flScale, int vColorTable[3][3]/*=NULL*/)
  346. {
  347. static int s_defaultColorTable[3][3] =
  348. {
  349. { 255, 0, 0 },
  350. { 0 , 255, 0 },
  351. { 0 , 0, 255 }
  352. };
  353. AUTO_LOCK( s_OverlayMutex );
  354. if ( vColorTable == NULL )
  355. vColorTable = s_defaultColorTable;
  356. Vector startPt, endPt;
  357. MatrixGetColumn( frame, 3, startPt );
  358. for (int k = 0; k < 3; k++)
  359. {
  360. endPt.x = frame[0][3] + frame[0][k] * flScale;
  361. endPt.y = frame[1][3] + frame[1][k] * flScale;
  362. endPt.z = frame[2][3] + frame[2][k] * flScale;
  363. AddLineOverlay(
  364. startPt,
  365. endPt,
  366. vColorTable[k][0], vColorTable[k][1], vColorTable[k][2], 255,
  367. true,
  368. NDEBUG_PERSIST_TILL_NEXT_SERVER
  369. );
  370. }
  371. }
  372. //-----------------------------------------------------------------------------
  373. // Purpose: Add new overlay text
  374. // Input : Position of text & text
  375. // Output :
  376. //-----------------------------------------------------------------------------
  377. void AddTextOverlay(const Vector& textPos, float duration, const char *text)
  378. {
  379. if ( GetBaseLocalClient().IsPaused() )
  380. return;
  381. #if defined( _X360 ) && defined( _CERT )
  382. return;
  383. #endif
  384. AUTO_LOCK( s_OverlayMutex );
  385. OverlayText_t *new_overlay = new OverlayText_t;
  386. VectorCopy(textPos,new_overlay->origin);
  387. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  388. new_overlay->bUseOrigin = true;
  389. new_overlay->lineOffset = 0;
  390. new_overlay->SetEndTime( duration );
  391. new_overlay->r = 255;
  392. new_overlay->g = 255;
  393. new_overlay->b = 255;
  394. new_overlay->a = 255;
  395. new_overlay->nextOverlayText = s_pOverlayText;
  396. s_pOverlayText = new_overlay;
  397. }
  398. //-----------------------------------------------------------------------------
  399. // Purpose: Add new overlay text
  400. // Input : Position of text & text
  401. // Output :
  402. //-----------------------------------------------------------------------------
  403. void AddTextOverlay(const Vector& textPos, float duration, float alpha, const char *text)
  404. {
  405. if ( GetBaseLocalClient().IsPaused() )
  406. return;
  407. #if defined( _X360 ) && defined( _CERT )
  408. return;
  409. #endif
  410. AUTO_LOCK( s_OverlayMutex );
  411. OverlayText_t *new_overlay = new OverlayText_t;
  412. VectorCopy(textPos,new_overlay->origin);
  413. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  414. new_overlay->bUseOrigin = true;
  415. new_overlay->lineOffset = 0;
  416. new_overlay->SetEndTime( duration );
  417. new_overlay->r = 255;
  418. new_overlay->g = 255;
  419. new_overlay->b = 255;
  420. new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
  421. new_overlay->nextOverlayText = s_pOverlayText;
  422. s_pOverlayText = new_overlay;
  423. }
  424. //------------------------------------------------------------------------------
  425. // Purpose :
  426. // Input :
  427. // Output :
  428. //------------------------------------------------------------------------------
  429. void AddScreenTextOverlay(float flXPos, float flYPos, int line_offset, float duration, int r, int g, int b, int a, const char *text)
  430. {
  431. if ( GetBaseLocalClient().IsPaused() )
  432. return;
  433. #if defined( _X360 ) && defined( _CERT )
  434. return;
  435. #endif
  436. AUTO_LOCK( s_OverlayMutex );
  437. OverlayText_t *new_overlay = new OverlayText_t;
  438. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  439. new_overlay->flXPos = flXPos;
  440. new_overlay->flYPos = flYPos;
  441. new_overlay->bUseOrigin = false;
  442. new_overlay->lineOffset = line_offset;
  443. new_overlay->SetEndTime( duration );
  444. new_overlay->r = r;
  445. new_overlay->g = g;
  446. new_overlay->b = b;
  447. new_overlay->a = a;
  448. new_overlay->nextOverlayText = s_pOverlayText;
  449. s_pOverlayText = new_overlay;
  450. }
  451. void AddScreenTextOverlay( float flXPos, float flYPos, float duration, int r, int g, int b, int a, const char *text )
  452. {
  453. AddScreenTextOverlay( flXPos, flYPos, 0, duration, r, g, b, a, text );
  454. }
  455. //-----------------------------------------------------------------------------
  456. // Purpose: Add new overlay text
  457. // Input : Position of text
  458. // How many lines to offset text from position
  459. // ext
  460. // Output :
  461. //-----------------------------------------------------------------------------
  462. void AddTextOverlay(const Vector& textPos, int line_offset, float duration, const char *text)
  463. {
  464. if ( GetBaseLocalClient().IsPaused() )
  465. return;
  466. #if defined( _X360 ) && defined( _CERT )
  467. return;
  468. #endif
  469. AUTO_LOCK( s_OverlayMutex );
  470. OverlayText_t *new_overlay = new OverlayText_t;
  471. VectorCopy(textPos,new_overlay->origin);
  472. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  473. new_overlay->bUseOrigin = true;
  474. new_overlay->lineOffset = line_offset;
  475. new_overlay->SetEndTime( duration );
  476. new_overlay->r = 255;
  477. new_overlay->g = 255;
  478. new_overlay->b = 255;
  479. new_overlay->a = 255;
  480. new_overlay->bUseOrigin = true;
  481. new_overlay->nextOverlayText = s_pOverlayText;
  482. s_pOverlayText = new_overlay;
  483. }
  484. void AddTextOverlay(const Vector& textPos, int line_offset, float duration, float alpha, const char *text)
  485. {
  486. if ( GetBaseLocalClient().IsPaused() )
  487. return;
  488. #if defined( _X360 ) && defined( _CERT )
  489. return;
  490. #endif
  491. AUTO_LOCK( s_OverlayMutex );
  492. OverlayText_t *new_overlay = new OverlayText_t;
  493. VectorCopy(textPos,new_overlay->origin);
  494. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  495. new_overlay->bUseOrigin = true;
  496. new_overlay->lineOffset = line_offset;
  497. new_overlay->SetEndTime( duration );
  498. new_overlay->r = 255;
  499. new_overlay->g = 255;
  500. new_overlay->b = 255;
  501. new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
  502. new_overlay->bUseOrigin = true;
  503. new_overlay->nextOverlayText = s_pOverlayText;
  504. s_pOverlayText = new_overlay;
  505. }
  506. void AddTextOverlay(const Vector& textPos, int line_offset, float duration, float r, float g, float b, float alpha, const char *text)
  507. {
  508. if ( GetBaseLocalClient().IsPaused() )
  509. return;
  510. #if defined( _X360 ) && defined( _CERT )
  511. return;
  512. #endif
  513. AUTO_LOCK( s_OverlayMutex );
  514. OverlayText_t *new_overlay = new OverlayText_t;
  515. VectorCopy(textPos,new_overlay->origin);
  516. Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
  517. new_overlay->bUseOrigin = true;
  518. new_overlay->lineOffset = line_offset;
  519. new_overlay->SetEndTime( duration );
  520. new_overlay->r = (int)clamp(r * 255.f,0.f,255.f);
  521. new_overlay->g = (int)clamp(g * 255.f,0.f,255.f);
  522. new_overlay->b = (int)clamp(b * 255.f,0.f,255.f);
  523. new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
  524. new_overlay->bUseOrigin = true;
  525. new_overlay->nextOverlayText = s_pOverlayText;
  526. s_pOverlayText = new_overlay;
  527. }
  528. //-----------------------------------------------------------------------------
  529. // Purpose: Add new overlay box
  530. // Input : Position of box
  531. // size of box
  532. // angles of box
  533. // color & alpha
  534. // duration
  535. // Output :
  536. //-----------------------------------------------------------------------------
  537. void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& angles, int r, int g, int b, int a, float flDuration)
  538. {
  539. if ( GetBaseLocalClient().IsPaused() )
  540. return;
  541. AUTO_LOCK( s_OverlayMutex );
  542. OverlayBox_t *new_overlay = new OverlayBox_t;
  543. new_overlay->origin = origin;
  544. new_overlay->mins[0] = mins[0];
  545. new_overlay->mins[1] = mins[1];
  546. new_overlay->mins[2] = mins[2];
  547. new_overlay->maxs[0] = maxs[0];
  548. new_overlay->maxs[1] = maxs[1];
  549. new_overlay->maxs[2] = maxs[2];
  550. new_overlay->angles = angles;
  551. new_overlay->r = r;
  552. new_overlay->g = g;
  553. new_overlay->b = b;
  554. new_overlay->a = a;
  555. new_overlay->SetEndTime( flDuration );
  556. new_overlay->m_pNextOverlay = s_pOverlays;
  557. s_pOverlays = new_overlay;
  558. }
  559. void AddBoxOverlay2( const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& orientation, const Color& faceColor, const Color& edgeColor, float duration )
  560. {
  561. if ( GetBaseLocalClient().IsPaused() )
  562. return;
  563. AUTO_LOCK( s_OverlayMutex );
  564. OverlayBox2_t *new_overlay = new OverlayBox2_t;
  565. new_overlay->origin = origin;
  566. new_overlay->mins[0] = mins[0];
  567. new_overlay->mins[1] = mins[1];
  568. new_overlay->mins[2] = mins[2];
  569. new_overlay->maxs[0] = maxs[0];
  570. new_overlay->maxs[1] = maxs[1];
  571. new_overlay->maxs[2] = maxs[2];
  572. new_overlay->angles = orientation;
  573. new_overlay->faceColor = faceColor;
  574. new_overlay->edgeColor = edgeColor;
  575. new_overlay->SetEndTime( duration );
  576. new_overlay->m_pNextOverlay = s_pOverlays;
  577. s_pOverlays = new_overlay;
  578. }
  579. void AddCapsuleOverlay( const Vector &vStart, const Vector &vEnd, const float &flRadius, int r, int g, int b, int a, float flDuration)
  580. {
  581. if ( GetBaseLocalClient().IsPaused() )
  582. return;
  583. AUTO_LOCK( s_OverlayMutex );
  584. OverlayCapsule_t *new_overlay = new OverlayCapsule_t;
  585. new_overlay->start = vStart;
  586. new_overlay->end = vEnd;
  587. new_overlay->flRadius = flRadius;
  588. new_overlay->r = r;
  589. new_overlay->g = g;
  590. new_overlay->b = b;
  591. new_overlay->a = a;
  592. new_overlay->SetEndTime( flDuration );
  593. new_overlay->m_pNextOverlay = s_pOverlays;
  594. s_pOverlays = new_overlay;
  595. }
  596. //-----------------------------------------------------------------------------
  597. // Purpose: Add new overlay sphere
  598. // Input : Position of sphere
  599. // radius of sphere
  600. // color & alpha
  601. // duration
  602. // Output :
  603. //-----------------------------------------------------------------------------
  604. void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration, bool bWireframe)
  605. {
  606. if ( GetBaseLocalClient().IsPaused() )
  607. return;
  608. AUTO_LOCK( s_OverlayMutex );
  609. OverlaySphere_t *new_overlay = new OverlaySphere_t;
  610. new_overlay->vOrigin = vOrigin;
  611. new_overlay->flRadius = flRadius;
  612. new_overlay->nTheta = nTheta;
  613. new_overlay->nPhi = nPhi;
  614. new_overlay->r = r;
  615. new_overlay->g = g;
  616. new_overlay->b = b;
  617. new_overlay->a = a;
  618. new_overlay->m_bWireframe = bWireframe;
  619. new_overlay->SetEndTime( flDuration );
  620. new_overlay->m_pNextOverlay = s_pOverlays;
  621. s_pOverlays = new_overlay;
  622. }
  623. void AddSweptBoxOverlay(const Vector& start, const Vector& end,
  624. const Vector& mins, const Vector& maxs, QAngle const& angles, int r, int g, int b, int a, float flDuration)
  625. {
  626. if ( GetBaseLocalClient().IsPaused() )
  627. return;
  628. AUTO_LOCK( s_OverlayMutex );
  629. OverlaySweptBox_t *new_overlay = new OverlaySweptBox_t;
  630. new_overlay->start = start;
  631. new_overlay->end = end;
  632. new_overlay->mins[0] = mins[0];
  633. new_overlay->mins[1] = mins[1];
  634. new_overlay->mins[2] = mins[2];
  635. new_overlay->maxs[0] = maxs[0];
  636. new_overlay->maxs[1] = maxs[1];
  637. new_overlay->maxs[2] = maxs[2];
  638. new_overlay->angles = angles;
  639. new_overlay->r = r;
  640. new_overlay->g = g;
  641. new_overlay->b = b;
  642. new_overlay->a = a;
  643. new_overlay->SetEndTime( flDuration );
  644. new_overlay->m_pNextOverlay = s_pOverlays;
  645. s_pOverlays = new_overlay;
  646. }
  647. //-----------------------------------------------------------------------------
  648. // Purpose: Add new overlay text
  649. // Input : Entity to attach text to
  650. // How many lines to offset text from entity origin
  651. // The text to print
  652. // Output :
  653. //-----------------------------------------------------------------------------
  654. void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float flDuration)
  655. {
  656. if ( GetBaseLocalClient().IsPaused() )
  657. return;
  658. AUTO_LOCK( s_OverlayMutex );
  659. OverlayLine_t *new_loverlay = new OverlayLine_t;
  660. new_loverlay->origin[0] = origin[0];
  661. new_loverlay->origin[1] = origin[1];
  662. new_loverlay->origin[2] = origin[2];
  663. new_loverlay->dest[0] = dest[0];
  664. new_loverlay->dest[1] = dest[1];
  665. new_loverlay->dest[2] = dest[2];
  666. new_loverlay->r = r;
  667. new_loverlay->g = g;
  668. new_loverlay->b = b;
  669. new_loverlay->a = a;
  670. new_loverlay->noDepthTest = noDepthTest;
  671. new_loverlay->SetEndTime( flDuration );
  672. new_loverlay->m_pNextOverlay = s_pOverlays;
  673. s_pOverlays = new_loverlay;
  674. }
  675. //-----------------------------------------------------------------------------
  676. // Purpose: Add new triangle overlay
  677. //-----------------------------------------------------------------------------
  678. void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector &p3,
  679. int r, int g, int b, int a, bool noDepthTest, float flDuration)
  680. {
  681. if ( GetBaseLocalClient().IsPaused() )
  682. return;
  683. AUTO_LOCK( s_OverlayMutex );
  684. OverlayTriangle_t *pTriangle = new OverlayTriangle_t;
  685. pTriangle->p1 = p1;
  686. pTriangle->p2 = p2;
  687. pTriangle->p3 = p3;
  688. pTriangle->r = r;
  689. pTriangle->g = g;
  690. pTriangle->b = b;
  691. pTriangle->a = a;
  692. pTriangle->noDepthTest = noDepthTest;
  693. pTriangle->SetEndTime( flDuration );
  694. pTriangle->m_pNextOverlay = s_pOverlays;
  695. s_pOverlays = pTriangle;
  696. }
  697. //------------------------------------------------------------------------------
  698. // Purpose : Draw a grid around the s_vGridPosition
  699. // Input :
  700. // Output :
  701. //------------------------------------------------------------------------------
  702. void DrawGridOverlay(void)
  703. {
  704. AUTO_LOCK( s_OverlayMutex );
  705. static int gridSpacing = 100;
  706. static int numHorzSpaces = 16;
  707. static int numVertSpaces = 3;
  708. Vector startGrid;
  709. startGrid[0] = gridSpacing*((int)s_vGridPosition[0]/gridSpacing);
  710. startGrid[1] = gridSpacing*((int)s_vGridPosition[1]/gridSpacing);
  711. startGrid[2] = s_vGridPosition[2];
  712. // Shift to the left
  713. startGrid[0] -= (numHorzSpaces/2)*gridSpacing;
  714. startGrid[1] -= (numHorzSpaces/2)*gridSpacing;
  715. Vector color( 20, 180, 190 );
  716. for (int i=1;i<numVertSpaces+1;i++)
  717. {
  718. // Draw x axis lines
  719. Vector startLine;
  720. VectorCopy(startGrid,startLine);
  721. for (int j=0;j<numHorzSpaces+1;j++)
  722. {
  723. Vector endLine;
  724. VectorCopy(startLine,endLine);
  725. endLine[0] += gridSpacing*numHorzSpaces;
  726. RenderLine( startLine, endLine, Color( color.x, color.y, color.z, 255 ), true );
  727. Vector bottomStartLine;
  728. VectorCopy(startLine,bottomStartLine);
  729. for ( int k=0; k<numHorzSpaces+1; k++ )
  730. {
  731. Vector bottomEndLine;
  732. VectorCopy(bottomStartLine,bottomEndLine);
  733. bottomEndLine[2] -= gridSpacing;
  734. RenderLine( bottomStartLine, bottomEndLine, Color( color.x, color.y, color.z, 255 ), true );
  735. bottomStartLine[0] += gridSpacing;
  736. }
  737. startLine[1] += gridSpacing;
  738. }
  739. // Draw y axis lines
  740. VectorCopy(startGrid,startLine);
  741. for ( int j=0; j<numHorzSpaces+1; j++ )
  742. {
  743. Vector endLine;
  744. VectorCopy(startLine,endLine);
  745. endLine[1] += gridSpacing*numHorzSpaces;
  746. RenderLine( startLine, endLine, Color( color.x, color.y, color.z, 255 ), true );
  747. startLine[0] += gridSpacing;
  748. }
  749. VectorScale( color, 0.7, color );
  750. startGrid[2] -= gridSpacing;
  751. }
  752. s_bDrawGrid = false;
  753. }
  754. //------------------------------------------------------------------------------
  755. // Draws a generic overlay
  756. //------------------------------------------------------------------------------
  757. void DrawOverlay( OverlayBase_t *pOverlay )
  758. {
  759. AUTO_LOCK( s_OverlayMutex );
  760. switch( pOverlay->m_Type)
  761. {
  762. case OVERLAY_LINE:
  763. {
  764. // Draw the line
  765. OverlayLine_t *pLine = static_cast<OverlayLine_t*>(pOverlay);
  766. RenderLine( pLine->origin, pLine->dest, Color( pLine->r, pLine->g, pLine->b, pLine->a ), !pLine->noDepthTest);
  767. }
  768. break;
  769. case OVERLAY_BOX:
  770. {
  771. // Draw the box
  772. OverlayBox_t *pCurrBox = static_cast<OverlayBox_t*>(pOverlay);
  773. if ( pCurrBox->a > 0 )
  774. {
  775. RenderBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, Color( pCurrBox->r, pCurrBox->g, pCurrBox->b, pCurrBox->a ), false );
  776. }
  777. if ( pCurrBox->a < 255 )
  778. {
  779. RenderWireframeBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, Color( pCurrBox->r, pCurrBox->g, pCurrBox->b, 255 ), true );
  780. }
  781. }
  782. break;
  783. case OVERLAY_BOX2:
  784. {
  785. // Draw the box
  786. OverlayBox2_t *pCurrBox = static_cast<OverlayBox2_t*>(pOverlay);
  787. if ( pCurrBox->faceColor.a() > 0 )
  788. {
  789. RenderBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, pCurrBox->faceColor, false );
  790. }
  791. if ( pCurrBox->edgeColor.a() > 0 )
  792. {
  793. RenderWireframeBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, pCurrBox->edgeColor, false );
  794. }
  795. }
  796. break;
  797. case OVERLAY_SPHERE:
  798. {
  799. // Draw the sphere
  800. OverlaySphere_t *pSphere = static_cast<OverlaySphere_t*>(pOverlay);
  801. RenderSphere( pSphere->vOrigin, pSphere->flRadius, pSphere->nTheta, pSphere->nPhi, Color( pSphere->r, pSphere->g, pSphere->b, pSphere->a ),
  802. ( pSphere->m_bWireframe ? g_pMaterialWireframeVertexColor : g_pMaterialAmbientCube ) );
  803. }
  804. break;
  805. case OVERLAY_SWEPT_BOX:
  806. {
  807. OverlaySweptBox_t *pBox = static_cast<OverlaySweptBox_t*>(pOverlay);
  808. RenderWireframeSweptBox( pBox->start, pBox->end, pBox->angles, pBox->mins, pBox->maxs, Color( pBox->r, pBox->g, pBox->b, pBox->a ), true );
  809. }
  810. break;
  811. case OVERLAY_TRIANGLE:
  812. {
  813. OverlayTriangle_t *pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
  814. RenderTriangle( pTriangle->p1, pTriangle->p2, pTriangle->p3,
  815. Color( pTriangle->r, pTriangle->g, pTriangle->b, pTriangle->a ), !pTriangle->noDepthTest );
  816. }
  817. break;
  818. case OVERLAY_CAPSULE:
  819. {
  820. OverlayCapsule_t *pCapsule = static_cast<OverlayCapsule_t*>(pOverlay);
  821. RenderCapsule( pCapsule->start, pCapsule->end, pCapsule->flRadius,
  822. Color( pCapsule->r, pCapsule->g, pCapsule->b, pCapsule->a ),
  823. ( pCapsule->m_bWireframe ? g_pMaterialWireframeVertexColor : g_pMaterialAmbientCube ) );
  824. }
  825. break;
  826. default:
  827. Assert(0);
  828. }
  829. }
  830. void DestroyOverlay( OverlayBase_t *pOverlay )
  831. {
  832. AUTO_LOCK( s_OverlayMutex );
  833. switch( pOverlay->m_Type)
  834. {
  835. case OVERLAY_LINE:
  836. {
  837. OverlayLine_t *pCurrLine = static_cast<OverlayLine_t*>(pOverlay);
  838. delete pCurrLine;
  839. }
  840. break;
  841. case OVERLAY_BOX:
  842. {
  843. OverlayBox_t *pCurrBox = static_cast<OverlayBox_t*>(pOverlay);
  844. delete pCurrBox;
  845. }
  846. break;
  847. case OVERLAY_BOX2:
  848. {
  849. OverlayBox2_t *pCurrBox = static_cast<OverlayBox2_t*>(pOverlay);
  850. delete pCurrBox;
  851. }
  852. break;
  853. case OVERLAY_SPHERE:
  854. {
  855. OverlaySphere_t *pCurrSphere = static_cast<OverlaySphere_t*>(pOverlay);
  856. delete pCurrSphere;
  857. }
  858. break;
  859. case OVERLAY_SWEPT_BOX:
  860. {
  861. OverlaySweptBox_t *pCurrBox = static_cast<OverlaySweptBox_t*>(pOverlay);
  862. delete pCurrBox;
  863. }
  864. break;
  865. case OVERLAY_TRIANGLE:
  866. {
  867. OverlayTriangle_t *pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
  868. delete pTriangle;
  869. }
  870. break;
  871. case OVERLAY_CAPSULE:
  872. {
  873. OverlayCapsule_t *pCapsule = static_cast<OverlayCapsule_t*>(pOverlay);
  874. delete pCapsule;
  875. }
  876. break;
  877. default:
  878. Assert(0);
  879. }
  880. }
  881. //------------------------------------------------------------------------------
  882. // Purpose :
  883. // Input :
  884. // Output :
  885. //------------------------------------------------------------------------------
  886. void DrawAllOverlays(void)
  887. {
  888. if ( !enable_debug_overlays.GetBool() )
  889. return;
  890. AUTO_LOCK( s_OverlayMutex );
  891. OverlayBase_t* pCurrOverlay = s_pOverlays;
  892. OverlayBase_t* pPrevOverlay = NULL;
  893. OverlayBase_t* pNextOverlay;
  894. while (pCurrOverlay)
  895. {
  896. // Is it time to kill this overlay?
  897. if ( pCurrOverlay->IsDead() )
  898. {
  899. if (pPrevOverlay)
  900. {
  901. // If I had a last overlay reset it's next pointer
  902. pPrevOverlay->m_pNextOverlay = pCurrOverlay->m_pNextOverlay;
  903. }
  904. else
  905. {
  906. // If the first line, reset the s_pOverlays pointer
  907. s_pOverlays = pCurrOverlay->m_pNextOverlay;
  908. }
  909. pNextOverlay = pCurrOverlay->m_pNextOverlay;
  910. DestroyOverlay( pCurrOverlay );
  911. pCurrOverlay = pNextOverlay;
  912. }
  913. else
  914. {
  915. DrawOverlay( pCurrOverlay );
  916. pPrevOverlay = pCurrOverlay;
  917. pCurrOverlay = pCurrOverlay->m_pNextOverlay;
  918. }
  919. }
  920. }
  921. //------------------------------------------------------------------------------
  922. // Purpose : Remove from the linkedlist overlays that have the special "until next
  923. // server tick" frametime
  924. // Input :
  925. // Output :
  926. //------------------------------------------------------------------------------
  927. //0.01234f
  928. void PurgeServerOverlays( void )
  929. {
  930. AUTO_LOCK( s_OverlayMutex );
  931. OverlayBase_t* pCurrOverlay = s_pOverlays;
  932. while (pCurrOverlay)
  933. {
  934. if ( pCurrOverlay->m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  935. {
  936. pCurrOverlay->m_flEndTime = GetBaseLocalClient().GetTime() + host_state.interval_per_tick;
  937. }
  938. pCurrOverlay = pCurrOverlay->m_pNextOverlay;
  939. }
  940. OverlayText_t* pCurrText = s_pOverlayText;
  941. while (pCurrText)
  942. {
  943. if ( pCurrText->m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
  944. {
  945. pCurrText->m_flEndTime = GetBaseLocalClient().GetTime() + host_state.interval_per_tick;
  946. }
  947. pCurrText = pCurrText->nextOverlayText;
  948. }
  949. }
  950. void PurgeTextOverlays( void )
  951. {
  952. AUTO_LOCK( s_OverlayMutex );
  953. OverlayText_t* pCurrOverlay = s_pOverlayText;
  954. while ( pCurrOverlay )
  955. {
  956. if ( pCurrOverlay->m_flEndTime == 0.0f &&
  957. pCurrOverlay->m_nCreationTick != -1 )
  958. {
  959. pCurrOverlay->m_nCreationTick = 0;
  960. }
  961. pCurrOverlay = pCurrOverlay->nextOverlayText;
  962. }
  963. }
  964. //-----------------------------------------------------------------------------
  965. // Purpose:
  966. // Input :
  967. // Output :
  968. //-----------------------------------------------------------------------------
  969. void Draw3DOverlays(void)
  970. {
  971. // Clear overlays every frame
  972. AUTO_LOCK( s_OverlayMutex );
  973. static int previous_servercount = 0;
  974. if ( previous_servercount != GetBaseLocalClient().m_nServerCount )
  975. {
  976. ClearAllOverlays();
  977. previous_servercount = GetBaseLocalClient().m_nServerCount;
  978. }
  979. DrawAllOverlays();
  980. if (s_bDrawGrid)
  981. {
  982. DrawGridOverlay();
  983. }
  984. }
  985. //------------------------------------------------------------------------------
  986. // Purpose : Deletes all overlays
  987. // Input :
  988. // Output :
  989. //------------------------------------------------------------------------------
  990. void ClearAllOverlays(void)
  991. {
  992. AUTO_LOCK( s_OverlayMutex );
  993. while (s_pOverlays)
  994. {
  995. OverlayBase_t *pOldOverlay = s_pOverlays;
  996. s_pOverlays = s_pOverlays->m_pNextOverlay;
  997. DestroyOverlay( pOldOverlay );
  998. }
  999. while (s_pOverlayText)
  1000. {
  1001. OverlayText_t *cur_ol = s_pOverlayText;
  1002. s_pOverlayText = s_pOverlayText->nextOverlayText;
  1003. delete cur_ol;
  1004. }
  1005. s_bDrawGrid = false;
  1006. }
  1007. void ClearDeadOverlays( void )
  1008. {
  1009. AUTO_LOCK( s_OverlayMutex );
  1010. OverlayText_t* pCurrText = s_pOverlayText;
  1011. OverlayText_t* pLastText = NULL;
  1012. OverlayText_t* pNextText = NULL;
  1013. while (pCurrText)
  1014. {
  1015. // Is it time to kill this Text?
  1016. if ( pCurrText->IsDead() )
  1017. {
  1018. // If I had a last Text reset it's next pointer
  1019. if (pLastText)
  1020. {
  1021. pLastText->nextOverlayText = pCurrText->nextOverlayText;
  1022. }
  1023. // If the first Text, reset the s_pOverlayText pointer
  1024. else
  1025. {
  1026. s_pOverlayText = pCurrText->nextOverlayText;
  1027. }
  1028. pNextText = pCurrText->nextOverlayText;
  1029. delete pCurrText;
  1030. pCurrText = pNextText;
  1031. }
  1032. else
  1033. {
  1034. pLastText = pCurrText;
  1035. pCurrText = pCurrText->nextOverlayText;
  1036. }
  1037. }
  1038. }
  1039. } // end namespace CDebugOverlay
  1040. //-----------------------------------------------------------------------------
  1041. // Purpose: export debug overlay to client DLL
  1042. // Input :
  1043. // Output :
  1044. //-----------------------------------------------------------------------------
  1045. class CIVDebugOverlay : public IVDebugOverlay, public IVPhysicsDebugOverlay
  1046. {
  1047. private:
  1048. char m_text[1024];
  1049. va_list m_argptr;
  1050. public:
  1051. void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char *format, ...)
  1052. {
  1053. va_start( m_argptr, format );
  1054. Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
  1055. va_end( m_argptr );
  1056. CDebugOverlay::AddEntityTextOverlay(ent_index, line_offset, duration, r, g, b, a, m_text);
  1057. }
  1058. void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, QAngle const& angles, int r, int g, int b, int a, float duration)
  1059. {
  1060. CDebugOverlay::AddBoxOverlay(origin, mins, max, angles, r, g, b, a, duration);
  1061. }
  1062. void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration)
  1063. {
  1064. CDebugOverlay::AddSphereOverlay( vOrigin, flRadius, nTheta, nPhi, r, g, b, a, flDuration, true );
  1065. }
  1066. void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const QAngle & angles, int r, int g, int b, int a, float flDuration)
  1067. {
  1068. CDebugOverlay::AddSweptBoxOverlay(start, end, mins, max, angles, r, g, b, a, flDuration);
  1069. }
  1070. void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration)
  1071. {
  1072. CDebugOverlay::AddLineOverlay(origin, dest, r, g, b, 255, noDepthTest, duration);
  1073. }
  1074. void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, int a, float thickness, float duration)
  1075. {
  1076. Vector vecLocal = ( dest - origin );
  1077. Vector max = Vector( vecLocal.Length(), thickness * 0.5, thickness * 0.5 );
  1078. Vector mins = Vector( 0, -thickness * 0.5, -thickness * 0.5 );
  1079. QAngle angles;
  1080. VectorAngles( vecLocal.Normalized(), angles );
  1081. CDebugOverlay::AddBoxOverlay(origin, mins, max, angles, r, g, b, a, duration);
  1082. }
  1083. void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration)
  1084. {
  1085. CDebugOverlay::AddTriangleOverlay(p1, p2, p3, r, g, b, a, noDepthTest, duration);
  1086. }
  1087. void AddTextOverlay(const Vector& origin, float duration, const char *format, ...)
  1088. {
  1089. va_start( m_argptr, format );
  1090. Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
  1091. va_end( m_argptr );
  1092. CDebugOverlay::AddTextOverlay(origin, duration, m_text);
  1093. }
  1094. void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char *format, ...)
  1095. {
  1096. va_start( m_argptr, format );
  1097. Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
  1098. va_end( m_argptr );
  1099. CDebugOverlay::AddTextOverlay(origin, line_offset, duration, m_text);
  1100. }
  1101. void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char *format, ...)
  1102. {
  1103. va_start( m_argptr, format );
  1104. Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
  1105. va_end( m_argptr );
  1106. CDebugOverlay::AddTextOverlay(origin, line_offset, duration, r, g, b, alpha, m_text);
  1107. }
  1108. void AddTextOverlayRGB(const Vector& origin, int line_offset, float flDuration, int r, int g, int b, int alpha, const char *format, ...)
  1109. {
  1110. va_start( m_argptr, format );
  1111. Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
  1112. va_end( m_argptr );
  1113. CDebugOverlay::AddTextOverlay( origin, line_offset, flDuration, r * 1.0f/255.0f, g * 1.0f/255.0f, b * 1.0f/255.0f, alpha * 1.0f/255.0f, m_text );
  1114. }
  1115. void AddScreenTextOverlay(float flXPos, float flYPos,float flDuration, int r, int g, int b, int a, const char *text)
  1116. {
  1117. CDebugOverlay::AddScreenTextOverlay( flXPos, flYPos, flDuration, r, g, b, a, text );
  1118. }
  1119. void AddGridOverlay(const Vector& origin)
  1120. {
  1121. CDebugOverlay::AddGridOverlay( origin );
  1122. }
  1123. void AddCoordFrameOverlay(const matrix3x4_t& frame, float flScale, int vColorTable[3][3] = NULL)
  1124. {
  1125. CDebugOverlay::AddCoordFrameOverlay( frame, flScale, vColorTable );
  1126. }
  1127. int ScreenPosition(const Vector& point, Vector& screen)
  1128. {
  1129. return CDebugOverlay::ScreenPosition( point, screen );
  1130. }
  1131. int ScreenPosition(float flXPos, float flYPos, Vector& screen)
  1132. {
  1133. return CDebugOverlay::ScreenPosition( flXPos, flYPos, screen );
  1134. }
  1135. virtual OverlayText_t *GetFirst( void )
  1136. {
  1137. return CDebugOverlay::s_pOverlayText;
  1138. }
  1139. virtual OverlayText_t *GetNext( OverlayText_t *current )
  1140. {
  1141. return current->nextOverlayText;
  1142. }
  1143. virtual void ClearDeadOverlays( void )
  1144. {
  1145. CDebugOverlay::ClearDeadOverlays();
  1146. }
  1147. virtual void ClearAllOverlays()
  1148. {
  1149. CDebugOverlay::ClearAllOverlays();
  1150. }
  1151. void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration)
  1152. {
  1153. CDebugOverlay::AddLineOverlay(origin, dest, r, g, b, a, noDepthTest, duration);
  1154. }
  1155. void AddBoxOverlay2( const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& orientation, const Color& faceColor, const Color& edgeColor, float duration )
  1156. {
  1157. CDebugOverlay::AddBoxOverlay2(origin, mins, maxs, orientation, faceColor, edgeColor, duration );
  1158. }
  1159. void PurgeTextOverlays()
  1160. {
  1161. CDebugOverlay::PurgeTextOverlays();
  1162. }
  1163. void AddCapsuleOverlay( const Vector &vStart, const Vector &vEnd, const float &flRadius, int r, int g, int b, int a, float flDuration )
  1164. {
  1165. CDebugOverlay::AddCapsuleOverlay( vStart, vEnd, flRadius, r, g, b, a, flDuration );
  1166. }
  1167. };
  1168. static CIVDebugOverlay g_DebugOverlay;
  1169. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CIVDebugOverlay, IVDebugOverlay, VDEBUG_OVERLAY_INTERFACE_VERSION, g_DebugOverlay );
  1170. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CIVDebugOverlay, IVPhysicsDebugOverlay, VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION, g_DebugOverlay );