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.
1309 lines
34 KiB
1309 lines
34 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose: Debugging overlay functions
|
||
|
//
|
||
|
// $Workfile: $
|
||
|
// $Date: $
|
||
|
// $NoKeywords: $
|
||
|
//===========================================================================//
|
||
|
|
||
|
#include "render_pch.h"
|
||
|
#include "edict.h"
|
||
|
#include "client.h"
|
||
|
#include "debugoverlay.h"
|
||
|
#include "cdll_int.h"
|
||
|
#include "ivideomode.h"
|
||
|
#include "materialsystem/imesh.h"
|
||
|
#include "gl_matsysiface.h"
|
||
|
#include "server.h"
|
||
|
#include "client_class.h"
|
||
|
#include "icliententitylist.h"
|
||
|
#include "mathlib/vmatrix.h"
|
||
|
#include "icliententity.h"
|
||
|
#include "overlaytext.h"
|
||
|
#include "engine/ivdebugoverlay.h"
|
||
|
#include "cmodel_engine.h"
|
||
|
#include "vphysics_interface.h"
|
||
|
#include "materialsystem/imaterial.h"
|
||
|
#include "tier2/renderutils.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
extern edict_t *EDICT_NUM(int n);
|
||
|
|
||
|
ConVar enable_debug_overlays( "enable_debug_overlays", "1", FCVAR_GAMEDLL | FCVAR_CHEAT, "Enable rendering of debug overlays" );
|
||
|
|
||
|
int GetOverlayTick()
|
||
|
{
|
||
|
if ( sv.IsActive() )
|
||
|
return sv.m_nTickCount;
|
||
|
|
||
|
return cl.GetClientTickCount();
|
||
|
}
|
||
|
|
||
|
bool OverlayText_t::IsDead()
|
||
|
{
|
||
|
if ( IsXbox() && cl.IsPaused() )
|
||
|
return false;
|
||
|
|
||
|
if ( m_nServerCount != cl.m_nServerCount )
|
||
|
return true;
|
||
|
|
||
|
if ( m_nCreationTick != -1 )
|
||
|
{
|
||
|
if ( GetOverlayTick() > m_nCreationTick )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
return false;
|
||
|
|
||
|
return (cl.GetTime() >= m_flEndTime);
|
||
|
}
|
||
|
|
||
|
void OverlayText_t::SetEndTime( float duration )
|
||
|
{
|
||
|
m_nServerCount = cl.m_nServerCount;
|
||
|
|
||
|
if ( duration <= 0.0f )
|
||
|
{
|
||
|
m_flEndTime = 0.0f;
|
||
|
m_nCreationTick = GetOverlayTick();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( duration == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
{
|
||
|
m_flEndTime = NDEBUG_PERSIST_TILL_NEXT_SERVER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_flEndTime = cl.GetTime() + duration;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace CDebugOverlay
|
||
|
{
|
||
|
|
||
|
enum OverlayType_t
|
||
|
{
|
||
|
OVERLAY_BOX = 0,
|
||
|
OVERLAY_SPHERE,
|
||
|
OVERLAY_LINE,
|
||
|
OVERLAY_TRIANGLE,
|
||
|
OVERLAY_SWEPT_BOX,
|
||
|
OVERLAY_BOX2
|
||
|
};
|
||
|
|
||
|
struct OverlayBase_t
|
||
|
{
|
||
|
OverlayBase_t()
|
||
|
{
|
||
|
m_Type = OVERLAY_BOX;
|
||
|
m_nServerCount = -1;
|
||
|
m_nCreationTick = -1;
|
||
|
m_flEndTime = 0.0f;
|
||
|
m_pNextOverlay = NULL;
|
||
|
}
|
||
|
|
||
|
bool IsDead()
|
||
|
{
|
||
|
if ( IsXbox() && cl.IsPaused() )
|
||
|
return false;
|
||
|
|
||
|
if ( m_nServerCount != cl.m_nServerCount )
|
||
|
return true;
|
||
|
|
||
|
if ( m_nCreationTick != -1 )
|
||
|
{
|
||
|
if ( GetOverlayTick() > m_nCreationTick )
|
||
|
return true;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ( m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
return false;
|
||
|
|
||
|
return (cl.GetTime() >= m_flEndTime) ;
|
||
|
}
|
||
|
|
||
|
void SetEndTime( float duration )
|
||
|
{
|
||
|
m_nServerCount = cl.m_nServerCount;
|
||
|
|
||
|
if ( duration <= 0.0f )
|
||
|
{
|
||
|
m_nCreationTick = GetOverlayTick(); // stay alive for only one frame
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( duration == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
{
|
||
|
m_flEndTime = NDEBUG_PERSIST_TILL_NEXT_SERVER;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_flEndTime = cl.GetTime() + duration;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OverlayType_t m_Type; // What type of overlay is it?
|
||
|
int m_nCreationTick; // Duration -1 means go away after this frame #
|
||
|
int m_nServerCount; // Latch server count, too
|
||
|
float m_flEndTime; // When does this box go away
|
||
|
OverlayBase_t *m_pNextOverlay;
|
||
|
};
|
||
|
|
||
|
struct OverlayBox_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlayBox_t() { m_Type = OVERLAY_BOX; }
|
||
|
|
||
|
Vector origin;
|
||
|
Vector mins;
|
||
|
Vector maxs;
|
||
|
QAngle angles;
|
||
|
int r;
|
||
|
int g;
|
||
|
int b;
|
||
|
int a;
|
||
|
};
|
||
|
|
||
|
struct OverlayBox2_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlayBox2_t() { m_Type = OVERLAY_BOX2; }
|
||
|
|
||
|
Vector origin;
|
||
|
Vector mins;
|
||
|
Vector maxs;
|
||
|
QAngle angles;
|
||
|
Color edgeColor;
|
||
|
Color faceColor;
|
||
|
};
|
||
|
|
||
|
struct OverlaySphere_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlaySphere_t() { m_Type = OVERLAY_SPHERE; }
|
||
|
|
||
|
Vector vOrigin;
|
||
|
float flRadius;
|
||
|
int nTheta;
|
||
|
int nPhi;
|
||
|
int r;
|
||
|
int g;
|
||
|
int b;
|
||
|
int a;
|
||
|
};
|
||
|
|
||
|
struct OverlayLine_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlayLine_t() { m_Type = OVERLAY_LINE; }
|
||
|
|
||
|
Vector origin;
|
||
|
Vector dest;
|
||
|
int r;
|
||
|
int g;
|
||
|
int b;
|
||
|
int a;
|
||
|
bool noDepthTest;
|
||
|
};
|
||
|
|
||
|
struct OverlayTriangle_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlayTriangle_t() { m_Type = OVERLAY_TRIANGLE; }
|
||
|
|
||
|
Vector p1;
|
||
|
Vector p2;
|
||
|
Vector p3;
|
||
|
int r;
|
||
|
int g;
|
||
|
int b;
|
||
|
int a;
|
||
|
bool noDepthTest;
|
||
|
};
|
||
|
|
||
|
struct OverlaySweptBox_t : public OverlayBase_t
|
||
|
{
|
||
|
OverlaySweptBox_t() { m_Type = OVERLAY_SWEPT_BOX; }
|
||
|
|
||
|
Vector start;
|
||
|
Vector end;
|
||
|
Vector mins;
|
||
|
Vector maxs;
|
||
|
QAngle angles;
|
||
|
int r;
|
||
|
int g;
|
||
|
int b;
|
||
|
int a;
|
||
|
};
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Forward declarations
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void DrawOverlays();
|
||
|
void DrawGridOverlay();
|
||
|
void ClearAllOverlays();
|
||
|
void ClearDeadOverlays();
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Init static member variables
|
||
|
//-----------------------------------------------------------------------------
|
||
|
OverlayText_t* s_pOverlayText = NULL; // text is handled differently; for backward compatibility reasons
|
||
|
OverlayBase_t* s_pOverlays = NULL;
|
||
|
Vector s_vGridPosition(0,0,0);
|
||
|
bool s_bDrawGrid = false;
|
||
|
CThreadFastMutex s_OverlayMutex;
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Hack to allow this code to run on a client that's not connected to a server
|
||
|
// (i.e., demo playback, or multiplayer game )
|
||
|
// Input : ent_num -
|
||
|
// origin -
|
||
|
// mins -
|
||
|
// maxs -
|
||
|
// Output : static void
|
||
|
//-----------------------------------------------------------------------------
|
||
|
static bool GetEntityOriginClientOrServer( int ent_num, Vector& origin )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
// Assume failure
|
||
|
origin.Init();
|
||
|
|
||
|
if ( sv.IsActive() )
|
||
|
{
|
||
|
edict_t *e = EDICT_NUM( ent_num );
|
||
|
if ( e )
|
||
|
{
|
||
|
IServerEntity *serverEntity = e->GetIServerEntity();
|
||
|
if ( serverEntity )
|
||
|
{
|
||
|
CM_WorldSpaceCenter( serverEntity->GetCollideable(), &origin );
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
IClientEntity *clent = entitylist->GetClientEntity( ent_num );
|
||
|
if ( clent )
|
||
|
{
|
||
|
CM_WorldSpaceCenter( clent->GetCollideable(), &origin );
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Given a point, return the screen position
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int ScreenPosition(const Vector& point, Vector& screen)
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
CMatRenderContextPtr pRenderContext( materials );
|
||
|
|
||
|
int retval = g_EngineRenderer->ClipTransform(point,&screen);
|
||
|
|
||
|
int x, y, w, h;
|
||
|
pRenderContext->GetViewport( x, y, w, h );
|
||
|
|
||
|
screen[0] = 0.5 * screen[0] * w;
|
||
|
screen[1] = -0.5 * screen[1] * h;
|
||
|
screen[0] += 0.5 * w;
|
||
|
screen[1] += 0.5 * h;
|
||
|
return retval;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Given an xy screen pos (0-1), return the screen position
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
int ScreenPosition(float flXPos, float flYPos, Vector& screen)
|
||
|
{
|
||
|
if (flXPos > 1.0 || flYPos > 1.0 || flXPos < 0.0 || flYPos < 0.0 )
|
||
|
return 1; // Fail
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
CMatRenderContextPtr pRenderContext( materials );
|
||
|
|
||
|
int x, y, w, h;
|
||
|
pRenderContext->GetViewport( x, y, w, h );
|
||
|
|
||
|
screen[0] = flXPos * w;
|
||
|
screen[1] = flYPos * h;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new entity positioned overlay text
|
||
|
// Input : Entity to attach text to
|
||
|
// How many lines to offset text from entity origin
|
||
|
// The text to print
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
Vector myPos, myMins, myMaxs;
|
||
|
|
||
|
GetEntityOriginClientOrServer( ent_index, myPos );
|
||
|
|
||
|
VectorCopy(myPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = line_offset;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = r;
|
||
|
new_overlay->g = g;
|
||
|
new_overlay->b = b;
|
||
|
new_overlay->a = a;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay text
|
||
|
// Input : Position of text & text
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddGridOverlay(const Vector& vPos)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
s_vGridPosition[0] = vPos[0];
|
||
|
s_vGridPosition[1] = vPos[1];
|
||
|
s_vGridPosition[2] = vPos[2];
|
||
|
s_bDrawGrid = true;
|
||
|
}
|
||
|
|
||
|
void AddCoordFrameOverlay(const matrix3x4_t& frame, float flScale, int vColorTable[3][3]/*=NULL*/)
|
||
|
{
|
||
|
static int s_defaultColorTable[3][3] =
|
||
|
{
|
||
|
{ 255, 0, 0 },
|
||
|
{ 0 , 255, 0 },
|
||
|
{ 0 , 0, 255 }
|
||
|
};
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
if ( vColorTable == NULL )
|
||
|
vColorTable = s_defaultColorTable;
|
||
|
|
||
|
Vector startPt, endPt;
|
||
|
MatrixGetColumn( frame, 3, startPt );
|
||
|
|
||
|
for (int k = 0; k < 3; k++)
|
||
|
{
|
||
|
endPt.x = frame[0][3] + frame[0][k] * flScale;
|
||
|
endPt.y = frame[1][3] + frame[1][k] * flScale;
|
||
|
endPt.z = frame[2][3] + frame[2][k] * flScale;
|
||
|
|
||
|
AddLineOverlay(
|
||
|
startPt,
|
||
|
endPt,
|
||
|
vColorTable[k][0], vColorTable[k][1], vColorTable[k][2], 255,
|
||
|
true,
|
||
|
NDEBUG_PERSIST_TILL_NEXT_SERVER
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay text
|
||
|
// Input : Position of text & text
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddTextOverlay(const Vector& textPos, float duration, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
VectorCopy(textPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = 0;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = 255;
|
||
|
new_overlay->g = 255;
|
||
|
new_overlay->b = 255;
|
||
|
new_overlay->a = 255;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay text
|
||
|
// Input : Position of text & text
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddTextOverlay(const Vector& textPos, float duration, float alpha, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
VectorCopy(textPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = 0;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = 255;
|
||
|
new_overlay->g = 255;
|
||
|
new_overlay->b = 255;
|
||
|
new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose :
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//------------------------------------------------------------------------------
|
||
|
void AddScreenTextOverlay(float flXPos, float flYPos, int line_offset, float duration, int r, int g, int b, int a, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->flXPos = flXPos;
|
||
|
new_overlay->flYPos = flYPos;
|
||
|
new_overlay->bUseOrigin = false;
|
||
|
new_overlay->lineOffset = line_offset;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = r;
|
||
|
new_overlay->g = g;
|
||
|
new_overlay->b = b;
|
||
|
new_overlay->a = a;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
void AddScreenTextOverlay( float flXPos, float flYPos, float duration, int r, int g, int b, int a, const char *text )
|
||
|
{
|
||
|
AddScreenTextOverlay( flXPos, flYPos, 0, duration, r, g, b, a, text );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay text
|
||
|
// Input : Position of text
|
||
|
// How many lines to offset text from position
|
||
|
// ext
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddTextOverlay(const Vector& textPos, int line_offset, float duration, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
VectorCopy(textPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = line_offset;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = 255;
|
||
|
new_overlay->g = 255;
|
||
|
new_overlay->b = 255;
|
||
|
new_overlay->a = 255;
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
void AddTextOverlay(const Vector& textPos, int line_offset, float duration, float alpha, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
VectorCopy(textPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = line_offset;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = 255;
|
||
|
new_overlay->g = 255;
|
||
|
new_overlay->b = 255;
|
||
|
new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
void AddTextOverlay(const Vector& textPos, int line_offset, float duration, float r, float g, float b, float alpha, const char *text)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t *new_overlay = new OverlayText_t;
|
||
|
|
||
|
VectorCopy(textPos,new_overlay->origin);
|
||
|
Q_strncpy(new_overlay->text,text, sizeof( new_overlay->text ) );
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
new_overlay->lineOffset = line_offset;
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
new_overlay->r = (int)clamp(r * 255.f,0.f,255.f);
|
||
|
new_overlay->g = (int)clamp(g * 255.f,0.f,255.f);
|
||
|
new_overlay->b = (int)clamp(b * 255.f,0.f,255.f);
|
||
|
new_overlay->a = (int)clamp(alpha * 255.f,0.f,255.f);
|
||
|
new_overlay->bUseOrigin = true;
|
||
|
|
||
|
new_overlay->nextOverlayText = s_pOverlayText;
|
||
|
s_pOverlayText = new_overlay;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay box
|
||
|
// Input : Position of box
|
||
|
// size of box
|
||
|
// angles of box
|
||
|
// color & alpha
|
||
|
// duration
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& angles, int r, int g, int b, int a, float flDuration)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayBox_t *new_overlay = new OverlayBox_t;
|
||
|
|
||
|
new_overlay->origin = origin;
|
||
|
|
||
|
new_overlay->mins[0] = mins[0];
|
||
|
new_overlay->mins[1] = mins[1];
|
||
|
new_overlay->mins[2] = mins[2];
|
||
|
|
||
|
new_overlay->maxs[0] = maxs[0];
|
||
|
new_overlay->maxs[1] = maxs[1];
|
||
|
new_overlay->maxs[2] = maxs[2];
|
||
|
|
||
|
new_overlay->angles = angles;
|
||
|
|
||
|
new_overlay->r = r;
|
||
|
new_overlay->g = g;
|
||
|
new_overlay->b = b;
|
||
|
new_overlay->a = a;
|
||
|
|
||
|
new_overlay->SetEndTime( flDuration );
|
||
|
|
||
|
new_overlay->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = new_overlay;
|
||
|
}
|
||
|
|
||
|
void AddBoxOverlay2( const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& orientation, const Color& faceColor, const Color& edgeColor, float duration )
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayBox2_t *new_overlay = new OverlayBox2_t;
|
||
|
|
||
|
new_overlay->origin = origin;
|
||
|
|
||
|
new_overlay->mins[0] = mins[0];
|
||
|
new_overlay->mins[1] = mins[1];
|
||
|
new_overlay->mins[2] = mins[2];
|
||
|
|
||
|
new_overlay->maxs[0] = maxs[0];
|
||
|
new_overlay->maxs[1] = maxs[1];
|
||
|
new_overlay->maxs[2] = maxs[2];
|
||
|
|
||
|
new_overlay->angles = orientation;
|
||
|
|
||
|
new_overlay->faceColor = faceColor;
|
||
|
new_overlay->edgeColor = edgeColor;
|
||
|
|
||
|
new_overlay->SetEndTime( duration );
|
||
|
|
||
|
new_overlay->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = new_overlay;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay sphere
|
||
|
// Input : Position of sphere
|
||
|
// radius of sphere
|
||
|
// color & alpha
|
||
|
// duration
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlaySphere_t *new_overlay = new OverlaySphere_t;
|
||
|
|
||
|
new_overlay->vOrigin = vOrigin;
|
||
|
new_overlay->flRadius = flRadius;
|
||
|
|
||
|
new_overlay->nTheta = nTheta;
|
||
|
new_overlay->nPhi = nPhi;
|
||
|
|
||
|
new_overlay->r = r;
|
||
|
new_overlay->g = g;
|
||
|
new_overlay->b = b;
|
||
|
new_overlay->a = a;
|
||
|
|
||
|
new_overlay->SetEndTime( flDuration );
|
||
|
|
||
|
new_overlay->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = new_overlay;
|
||
|
}
|
||
|
|
||
|
|
||
|
void AddSweptBoxOverlay(const Vector& start, const Vector& end,
|
||
|
const Vector& mins, const Vector& maxs, QAngle const& angles, int r, int g, int b, int a, float flDuration)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlaySweptBox_t *new_overlay = new OverlaySweptBox_t;
|
||
|
|
||
|
new_overlay->start = start;
|
||
|
new_overlay->end = end;
|
||
|
|
||
|
new_overlay->mins[0] = mins[0];
|
||
|
new_overlay->mins[1] = mins[1];
|
||
|
new_overlay->mins[2] = mins[2];
|
||
|
|
||
|
new_overlay->maxs[0] = maxs[0];
|
||
|
new_overlay->maxs[1] = maxs[1];
|
||
|
new_overlay->maxs[2] = maxs[2];
|
||
|
|
||
|
new_overlay->angles = angles;
|
||
|
|
||
|
new_overlay->r = r;
|
||
|
new_overlay->g = g;
|
||
|
new_overlay->b = b;
|
||
|
new_overlay->a = a;
|
||
|
|
||
|
new_overlay->SetEndTime( flDuration );
|
||
|
|
||
|
new_overlay->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = new_overlay;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new overlay text
|
||
|
// Input : Entity to attach text to
|
||
|
// How many lines to offset text from entity origin
|
||
|
// The text to print
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float flDuration)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayLine_t *new_loverlay = new OverlayLine_t;
|
||
|
|
||
|
new_loverlay->origin[0] = origin[0];
|
||
|
new_loverlay->origin[1] = origin[1];
|
||
|
new_loverlay->origin[2] = origin[2];
|
||
|
|
||
|
new_loverlay->dest[0] = dest[0];
|
||
|
new_loverlay->dest[1] = dest[1];
|
||
|
new_loverlay->dest[2] = dest[2];
|
||
|
|
||
|
new_loverlay->r = r;
|
||
|
new_loverlay->g = g;
|
||
|
new_loverlay->b = b;
|
||
|
new_loverlay->a = a;
|
||
|
|
||
|
new_loverlay->noDepthTest = noDepthTest;
|
||
|
|
||
|
new_loverlay->SetEndTime( flDuration );
|
||
|
|
||
|
new_loverlay->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = new_loverlay;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: Add new triangle overlay
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector &p3,
|
||
|
int r, int g, int b, int a, bool noDepthTest, float flDuration)
|
||
|
{
|
||
|
if ( cl.IsPaused() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayTriangle_t *pTriangle = new OverlayTriangle_t;
|
||
|
pTriangle->p1 = p1;
|
||
|
pTriangle->p2 = p2;
|
||
|
pTriangle->p3 = p3;
|
||
|
|
||
|
pTriangle->r = r;
|
||
|
pTriangle->g = g;
|
||
|
pTriangle->b = b;
|
||
|
pTriangle->a = a;
|
||
|
|
||
|
pTriangle->noDepthTest = noDepthTest;
|
||
|
pTriangle->SetEndTime( flDuration );
|
||
|
|
||
|
pTriangle->m_pNextOverlay = s_pOverlays;
|
||
|
s_pOverlays = pTriangle;
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose : Draw a grid around the s_vGridPosition
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//------------------------------------------------------------------------------
|
||
|
void DrawGridOverlay(void)
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
static int gridSpacing = 100;
|
||
|
static int numHorzSpaces = 16;
|
||
|
static int numVertSpaces = 3;
|
||
|
|
||
|
Vector startGrid;
|
||
|
startGrid[0] = gridSpacing*((int)s_vGridPosition[0]/gridSpacing);
|
||
|
startGrid[1] = gridSpacing*((int)s_vGridPosition[1]/gridSpacing);
|
||
|
startGrid[2] = s_vGridPosition[2];
|
||
|
|
||
|
// Shift to the left
|
||
|
startGrid[0] -= (numHorzSpaces/2)*gridSpacing;
|
||
|
startGrid[1] -= (numHorzSpaces/2)*gridSpacing;
|
||
|
|
||
|
Vector color( 20, 180, 190 );
|
||
|
for (int i=1;i<numVertSpaces+1;i++)
|
||
|
{
|
||
|
// Draw x axis lines
|
||
|
Vector startLine;
|
||
|
VectorCopy(startGrid,startLine);
|
||
|
for (int j=0;j<numHorzSpaces+1;j++)
|
||
|
{
|
||
|
Vector endLine;
|
||
|
VectorCopy(startLine,endLine);
|
||
|
endLine[0] += gridSpacing*numHorzSpaces;
|
||
|
RenderLine( startLine, endLine, Color( color.x, color.y, color.z, 255 ), true );
|
||
|
|
||
|
Vector bottomStartLine;
|
||
|
VectorCopy(startLine,bottomStartLine);
|
||
|
for ( int k=0; k<numHorzSpaces+1; k++ )
|
||
|
{
|
||
|
Vector bottomEndLine;
|
||
|
VectorCopy(bottomStartLine,bottomEndLine);
|
||
|
bottomEndLine[2] -= gridSpacing;
|
||
|
RenderLine( bottomStartLine, bottomEndLine, Color( color.x, color.y, color.z, 255 ), true );
|
||
|
bottomStartLine[0] += gridSpacing;
|
||
|
}
|
||
|
startLine[1] += gridSpacing;
|
||
|
}
|
||
|
|
||
|
// Draw y axis lines
|
||
|
VectorCopy(startGrid,startLine);
|
||
|
for ( int j=0; j<numHorzSpaces+1; j++ )
|
||
|
{
|
||
|
Vector endLine;
|
||
|
VectorCopy(startLine,endLine);
|
||
|
|
||
|
endLine[1] += gridSpacing*numHorzSpaces;
|
||
|
RenderLine( startLine, endLine, Color( color.x, color.y, color.z, 255 ), true );
|
||
|
startLine[0] += gridSpacing;
|
||
|
}
|
||
|
VectorScale( color, 0.7, color );
|
||
|
startGrid[2] -= gridSpacing;
|
||
|
}
|
||
|
s_bDrawGrid = false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Draws a generic overlay
|
||
|
//------------------------------------------------------------------------------
|
||
|
void DrawOverlay( OverlayBase_t *pOverlay )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
switch( pOverlay->m_Type)
|
||
|
{
|
||
|
case OVERLAY_LINE:
|
||
|
{
|
||
|
// Draw the line
|
||
|
OverlayLine_t *pLine = static_cast<OverlayLine_t*>(pOverlay);
|
||
|
RenderLine( pLine->origin, pLine->dest, Color( pLine->r, pLine->g, pLine->b, pLine->a ), !pLine->noDepthTest);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_BOX:
|
||
|
{
|
||
|
// Draw the box
|
||
|
OverlayBox_t *pCurrBox = static_cast<OverlayBox_t*>(pOverlay);
|
||
|
if ( pCurrBox->a > 0 )
|
||
|
{
|
||
|
RenderBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, Color( pCurrBox->r, pCurrBox->g, pCurrBox->b, pCurrBox->a ), false );
|
||
|
}
|
||
|
RenderWireframeBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, Color( pCurrBox->r, pCurrBox->g, pCurrBox->b, 255 ), true );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_BOX2:
|
||
|
{
|
||
|
// Draw the box
|
||
|
OverlayBox2_t *pCurrBox = static_cast<OverlayBox2_t*>(pOverlay);
|
||
|
if ( pCurrBox->faceColor.a() > 0 )
|
||
|
{
|
||
|
RenderBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, pCurrBox->faceColor, false );
|
||
|
}
|
||
|
if ( pCurrBox->edgeColor.a() > 0 )
|
||
|
{
|
||
|
RenderWireframeBox( pCurrBox->origin, pCurrBox->angles, pCurrBox->mins, pCurrBox->maxs, pCurrBox->edgeColor, false );
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_SPHERE:
|
||
|
{
|
||
|
// Draw the sphere
|
||
|
OverlaySphere_t *pSphere = static_cast<OverlaySphere_t*>(pOverlay);
|
||
|
RenderSphere( pSphere->vOrigin, pSphere->flRadius, pSphere->nTheta, pSphere->nPhi, Color( pSphere->r, pSphere->g, pSphere->b, pSphere->a ), g_pMaterialAmbientCube );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_SWEPT_BOX:
|
||
|
{
|
||
|
OverlaySweptBox_t *pBox = static_cast<OverlaySweptBox_t*>(pOverlay);
|
||
|
RenderWireframeSweptBox( pBox->start, pBox->end, pBox->angles, pBox->mins, pBox->maxs, Color( pBox->r, pBox->g, pBox->b, pBox->a ), true );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_TRIANGLE:
|
||
|
{
|
||
|
OverlayTriangle_t *pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
|
||
|
RenderTriangle( pTriangle->p1, pTriangle->p2, pTriangle->p3,
|
||
|
Color( pTriangle->r, pTriangle->g, pTriangle->b, pTriangle->a ), !pTriangle->noDepthTest );
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Assert(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DestroyOverlay( OverlayBase_t *pOverlay )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
switch( pOverlay->m_Type)
|
||
|
{
|
||
|
case OVERLAY_LINE:
|
||
|
{
|
||
|
OverlayLine_t *pCurrLine = static_cast<OverlayLine_t*>(pOverlay);
|
||
|
delete pCurrLine;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_BOX:
|
||
|
{
|
||
|
OverlayBox_t *pCurrBox = static_cast<OverlayBox_t*>(pOverlay);
|
||
|
delete pCurrBox;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
|
||
|
case OVERLAY_BOX2:
|
||
|
{
|
||
|
OverlayBox2_t *pCurrBox = static_cast<OverlayBox2_t*>(pOverlay);
|
||
|
delete pCurrBox;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_SPHERE:
|
||
|
{
|
||
|
OverlaySphere_t *pCurrSphere = static_cast<OverlaySphere_t*>(pOverlay);
|
||
|
delete pCurrSphere;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_SWEPT_BOX:
|
||
|
{
|
||
|
OverlaySweptBox_t *pCurrBox = static_cast<OverlaySweptBox_t*>(pOverlay);
|
||
|
delete pCurrBox;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case OVERLAY_TRIANGLE:
|
||
|
{
|
||
|
OverlayTriangle_t *pTriangle = static_cast<OverlayTriangle_t*>(pOverlay);
|
||
|
delete pTriangle;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Assert(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose :
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//------------------------------------------------------------------------------
|
||
|
void DrawAllOverlays(void)
|
||
|
{
|
||
|
if ( !enable_debug_overlays.GetBool() )
|
||
|
return;
|
||
|
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayBase_t* pCurrOverlay = s_pOverlays;
|
||
|
OverlayBase_t* pPrevOverlay = NULL;
|
||
|
OverlayBase_t* pNextOverlay;
|
||
|
|
||
|
while (pCurrOverlay)
|
||
|
{
|
||
|
// Is it time to kill this overlay?
|
||
|
if ( pCurrOverlay->IsDead() )
|
||
|
{
|
||
|
if (pPrevOverlay)
|
||
|
{
|
||
|
// If I had a last overlay reset it's next pointer
|
||
|
pPrevOverlay->m_pNextOverlay = pCurrOverlay->m_pNextOverlay;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If the first line, reset the s_pOverlays pointer
|
||
|
s_pOverlays = pCurrOverlay->m_pNextOverlay;
|
||
|
}
|
||
|
|
||
|
pNextOverlay = pCurrOverlay->m_pNextOverlay;
|
||
|
DestroyOverlay( pCurrOverlay );
|
||
|
pCurrOverlay = pNextOverlay;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DrawOverlay( pCurrOverlay );
|
||
|
pPrevOverlay = pCurrOverlay;
|
||
|
pCurrOverlay = pCurrOverlay->m_pNextOverlay;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose : Remove from the linkedlist overlays that have the special "until next
|
||
|
// server tick" frametime
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//------------------------------------------------------------------------------
|
||
|
//0.01234f
|
||
|
void PurgeServerOverlays( void )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayBase_t* pCurrOverlay = s_pOverlays;
|
||
|
|
||
|
while (pCurrOverlay)
|
||
|
{
|
||
|
if ( pCurrOverlay->m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
{
|
||
|
pCurrOverlay->m_flEndTime = cl.GetTime() + host_state.interval_per_tick;
|
||
|
}
|
||
|
|
||
|
pCurrOverlay = pCurrOverlay->m_pNextOverlay;
|
||
|
}
|
||
|
|
||
|
OverlayText_t* pCurrText = s_pOverlayText;
|
||
|
while (pCurrText)
|
||
|
{
|
||
|
if ( pCurrText->m_flEndTime == NDEBUG_PERSIST_TILL_NEXT_SERVER )
|
||
|
{
|
||
|
pCurrText->m_flEndTime = cl.GetTime() + host_state.interval_per_tick;
|
||
|
}
|
||
|
|
||
|
pCurrText = pCurrText->nextOverlayText;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void PurgeTextOverlays( void )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t* pCurrOverlay = s_pOverlayText;
|
||
|
while ( pCurrOverlay )
|
||
|
{
|
||
|
if ( pCurrOverlay->m_flEndTime == 0.0f &&
|
||
|
pCurrOverlay->m_nCreationTick != -1 )
|
||
|
{
|
||
|
pCurrOverlay->m_nCreationTick = 0;
|
||
|
}
|
||
|
pCurrOverlay = pCurrOverlay->nextOverlayText;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void Draw3DOverlays(void)
|
||
|
{
|
||
|
// Clear overlays every frame
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
static int previous_servercount = 0;
|
||
|
if ( previous_servercount != cl.m_nServerCount )
|
||
|
{
|
||
|
ClearAllOverlays();
|
||
|
previous_servercount = cl.m_nServerCount;
|
||
|
}
|
||
|
|
||
|
DrawAllOverlays();
|
||
|
|
||
|
if (s_bDrawGrid)
|
||
|
{
|
||
|
DrawGridOverlay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------------------
|
||
|
// Purpose : Deletes all overlays
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//------------------------------------------------------------------------------
|
||
|
void ClearAllOverlays(void)
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
while (s_pOverlays)
|
||
|
{
|
||
|
OverlayBase_t *pOldOverlay = s_pOverlays;
|
||
|
s_pOverlays = s_pOverlays->m_pNextOverlay;
|
||
|
DestroyOverlay( pOldOverlay );
|
||
|
}
|
||
|
|
||
|
while (s_pOverlayText)
|
||
|
{
|
||
|
OverlayText_t *cur_ol = s_pOverlayText;
|
||
|
s_pOverlayText = s_pOverlayText->nextOverlayText;
|
||
|
delete cur_ol;
|
||
|
}
|
||
|
|
||
|
s_bDrawGrid = false;
|
||
|
}
|
||
|
|
||
|
void ClearDeadOverlays( void )
|
||
|
{
|
||
|
AUTO_LOCK( s_OverlayMutex );
|
||
|
OverlayText_t* pCurrText = s_pOverlayText;
|
||
|
OverlayText_t* pLastText = NULL;
|
||
|
OverlayText_t* pNextText = NULL;
|
||
|
while (pCurrText)
|
||
|
{
|
||
|
// Is it time to kill this Text?
|
||
|
if ( pCurrText->IsDead() )
|
||
|
{
|
||
|
// If I had a last Text reset it's next pointer
|
||
|
if (pLastText)
|
||
|
{
|
||
|
pLastText->nextOverlayText = pCurrText->nextOverlayText;
|
||
|
}
|
||
|
// If the first Text, reset the s_pOverlayText pointer
|
||
|
else
|
||
|
{
|
||
|
s_pOverlayText = pCurrText->nextOverlayText;
|
||
|
}
|
||
|
pNextText = pCurrText->nextOverlayText;
|
||
|
delete pCurrText;
|
||
|
pCurrText = pNextText;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pLastText = pCurrText;
|
||
|
pCurrText = pCurrText->nextOverlayText;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
} // end namespace CDebugOverlay
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: export debug overlay to client DLL
|
||
|
// Input :
|
||
|
// Output :
|
||
|
//-----------------------------------------------------------------------------
|
||
|
class CIVDebugOverlay : public IVDebugOverlay, public IVPhysicsDebugOverlay
|
||
|
{
|
||
|
private:
|
||
|
char m_text[1024];
|
||
|
va_list m_argptr;
|
||
|
|
||
|
public:
|
||
|
void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char *format, ...)
|
||
|
{
|
||
|
va_start( m_argptr, format );
|
||
|
Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
|
||
|
va_end( m_argptr );
|
||
|
|
||
|
CDebugOverlay::AddEntityTextOverlay(ent_index, line_offset, duration, r, g, b, a, m_text);
|
||
|
}
|
||
|
|
||
|
void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, QAngle const& angles, int r, int g, int b, int a, float duration)
|
||
|
{
|
||
|
CDebugOverlay::AddBoxOverlay(origin, mins, max, angles, r, g, b, a, duration);
|
||
|
}
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
CDebugOverlay::AddSweptBoxOverlay(start, end, mins, max, angles, r, g, b, a, flDuration);
|
||
|
}
|
||
|
|
||
|
void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration)
|
||
|
{
|
||
|
CDebugOverlay::AddLineOverlay(origin, dest, r, g, b, 255, noDepthTest, duration);
|
||
|
}
|
||
|
|
||
|
void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector &p3, int r, int g, int b, int a, bool noDepthTest, float duration)
|
||
|
{
|
||
|
CDebugOverlay::AddTriangleOverlay(p1, p2, p3, r, g, b, a, noDepthTest, duration);
|
||
|
}
|
||
|
|
||
|
void AddTextOverlay(const Vector& origin, float duration, const char *format, ...)
|
||
|
{
|
||
|
va_start( m_argptr, format );
|
||
|
Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
|
||
|
va_end( m_argptr );
|
||
|
|
||
|
CDebugOverlay::AddTextOverlay(origin, duration, m_text);
|
||
|
}
|
||
|
|
||
|
void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char *format, ...)
|
||
|
{
|
||
|
va_start( m_argptr, format );
|
||
|
Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
|
||
|
va_end( m_argptr );
|
||
|
|
||
|
CDebugOverlay::AddTextOverlay(origin, line_offset, duration, m_text);
|
||
|
}
|
||
|
|
||
|
void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char *format, ...)
|
||
|
{
|
||
|
va_start( m_argptr, format );
|
||
|
Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
|
||
|
va_end( m_argptr );
|
||
|
|
||
|
CDebugOverlay::AddTextOverlay(origin, line_offset, duration, r, g, b, alpha, m_text);
|
||
|
}
|
||
|
|
||
|
void AddTextOverlayRGB(const Vector& origin, int line_offset, float flDuration, int r, int g, int b, int alpha, const char *format, ...)
|
||
|
{
|
||
|
va_start( m_argptr, format );
|
||
|
Q_vsnprintf( m_text, sizeof( m_text ), format, m_argptr );
|
||
|
va_end( m_argptr );
|
||
|
|
||
|
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 );
|
||
|
}
|
||
|
|
||
|
void AddScreenTextOverlay(float flXPos, float flYPos,float flDuration, int r, int g, int b, int a, const char *text)
|
||
|
{
|
||
|
CDebugOverlay::AddScreenTextOverlay( flXPos, flYPos, flDuration, r, g, b, a, text );
|
||
|
}
|
||
|
|
||
|
void AddGridOverlay(const Vector& origin)
|
||
|
{
|
||
|
CDebugOverlay::AddGridOverlay( origin );
|
||
|
}
|
||
|
|
||
|
void AddCoordFrameOverlay(const matrix3x4_t& frame, float flScale, int vColorTable[3][3] = NULL)
|
||
|
{
|
||
|
CDebugOverlay::AddCoordFrameOverlay( frame, flScale, vColorTable );
|
||
|
}
|
||
|
|
||
|
int ScreenPosition(const Vector& point, Vector& screen)
|
||
|
{
|
||
|
return CDebugOverlay::ScreenPosition( point, screen );
|
||
|
}
|
||
|
|
||
|
int ScreenPosition(float flXPos, float flYPos, Vector& screen)
|
||
|
{
|
||
|
return CDebugOverlay::ScreenPosition( flXPos, flYPos, screen );
|
||
|
}
|
||
|
|
||
|
virtual OverlayText_t *GetFirst( void )
|
||
|
{
|
||
|
return CDebugOverlay::s_pOverlayText;
|
||
|
}
|
||
|
|
||
|
virtual OverlayText_t *GetNext( OverlayText_t *current )
|
||
|
{
|
||
|
return current->nextOverlayText;
|
||
|
}
|
||
|
|
||
|
virtual void ClearDeadOverlays( void )
|
||
|
{
|
||
|
CDebugOverlay::ClearDeadOverlays();
|
||
|
}
|
||
|
|
||
|
virtual void ClearAllOverlays()
|
||
|
{
|
||
|
CDebugOverlay::ClearAllOverlays();
|
||
|
}
|
||
|
|
||
|
void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration)
|
||
|
{
|
||
|
CDebugOverlay::AddLineOverlay(origin, dest, r, g, b, a, noDepthTest, duration);
|
||
|
}
|
||
|
|
||
|
void AddBoxOverlay2( const Vector& origin, const Vector& mins, const Vector& maxs, QAngle const& orientation, const Color& faceColor, const Color& edgeColor, float duration )
|
||
|
{
|
||
|
CDebugOverlay::AddBoxOverlay2(origin, mins, maxs, orientation, faceColor, edgeColor, duration );
|
||
|
}
|
||
|
|
||
|
void PurgeTextOverlays()
|
||
|
{
|
||
|
CDebugOverlay::PurgeTextOverlays();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
static CIVDebugOverlay g_DebugOverlay;
|
||
|
|
||
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CIVDebugOverlay, IVDebugOverlay, VDEBUG_OVERLAY_INTERFACE_VERSION, g_DebugOverlay );
|
||
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CIVDebugOverlay, IVPhysicsDebugOverlay, VPHYSICS_DEBUG_OVERLAY_INTERFACE_VERSION, g_DebugOverlay );
|
||
|
|