User:JacobsDevelop/GlowArticle: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
No edit summary
(seems finished)
Tag: Replaced
 
(6 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{WIP|[[User:JacobsDevelop|JacobsDevelop]] ([[User talk:JacobsDevelop|talk]])}}
{{messagebox|text=This was a "prototype" page for grand rework of [[TF2_Glow_Effect_(2013_SDK)|this page]]. Now it's just there}}
{{messagebox|text=This page is candidate to replace contents of [[TF2_Glow_Effect_(2013_SDK)|this page]]. Any suggestions are appreciated [[User talk:JacobsDevelop|here]]}}
 
__FORCETOC__
 
=Activation=
 
* Add {{Key|GLOWS_ENABLE}} to the preprocessor directives on your client and server projects (don't forget to add it for release and debug, too!)
* Add the following line to '''ClientModeShared::DoPostScreenSpaceEffects''':
 
<source lang=cpp>
g_GlowObjectManager.RenderGlowEffects( pSetup, 0 );
</source>
 
 
'''Materials Required:'''
[https://www.dropbox.com/s/ltyomrglekrhriv/sdk2013_tf2_glowoutlinematerials.zip?dl=0 SDK2013_TF2_GlowOutlineMaterials.zip]
 
 
* Precache the effect by placing this code in '''clientmode_shared.cpp''' (search for other references of '''CLIENTEFFECT_REGISTER_BEGIN''' for usage example):
 
<source lang=cpp>
CLIENTEFFECT_REGISTER_BEGIN( PrecachePostProcessingEffectsGlow )
CLIENTEFFECT_MATERIAL( "dev/glow_color" )
CLIENTEFFECT_MATERIAL( "dev/halo_add_to_screen" )
CLIENTEFFECT_REGISTER_END_CONDITIONAL( engine->GetDXSupportLevel() >= 90 )
</source>
 
Don't forget to add the include defintion for the precache system!
<source lang=cpp>
#include "clienteffectprecachesystem.h"
</source>
 
=(Optional) Transferring getters and setters from CBaseCombatCharacter=
{{Important|This part is completely optional if you're okay with how glow works by default you can skip to [[#Usage|usage]] section.}}
By default objects derived from {{Key|CBaseCombatCharacter}} have getters and setters which can be problematic. <br>This section shows how to transfer setters and getters from {{Key|CBaseCombatCharacter}} to {{Key|CBaseAnimating}} since most entities are derived from {{Key|CBaseAnimating}} e.g. {{Key|CBaseCombatCharacter}}, {{Key|CDynamicProp}}, {{Key|CBaseProp}} and more.
 
There are two parts: Server and Client, where we'll start with server first.<br>
Firstly delete this part of code from '''basecombatcharacter.h''' (lines 415-420) and put it into '''baseanimating.h''' (recommended lines 54-58):
<source lang=cpp>
#ifdef GLOWS_ENABLE
public:
void AddGlowEffect(void);
void RemoveGlowEffect(void);
bool IsGlowEffectActive(void);
#endif
</source>
 
After that, do the same thing to this part of code ('''basecombatcharacter.h''', lines 459-462, '''baseanimating.h''' recommended lines 171-174):
<source lang=cpp>
#ifdef GLOWS_ENABLE
protected:
CNetworkVar(bool, m_bGlowEnabled);
#endif
</source>
{{Note|This part of code needs to be in '''protected:''' modifier. If there's no protected modifier make one}}
 
And finally repeat that with this part of code ('''basecombatcharacter.h''', lines 467-468, '''baseanimating.h''' recommended lines 355-356)
<source lang=cpp>
void UpdateGlowEffect( void );
void DestroyGlowEffect( void );
</source>
{{Note|This part of code needs to be in '''private:''' modifier}}
 
Now move to '''basecombatcharacter.cpp''' and '''baseanimating.cpp'''
First part of code to delete from '''basecombatcharacter.cpp''' (lines 193-195) and put it into '''baseanimating.cpp''' (line 230):
<source lang=cpp>
#ifdef GLOWS_ENABLE
SendPropBool( SENDINFO( m_bGlowEnabled ) ),
#endif
</source>
 
Next, from '''basecombatcharacter.cpp''' (lines 744-746) put this part of code into '''baseanimating.cpp''' '''CBaseAnimating::CBaseAnimating'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set( false );
#endif
</source>
 
Lastly delete this from '''basecombatcharacter.cpp''' (lines 3227-3252)
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::AddGlowEffect( void )
{
SetTransmitState( FL_EDICT_ALWAYS );
m_bGlowEnabled.Set( true );
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseCombatCharacter::RemoveGlowEffect( void )
{
m_bGlowEnabled.Set( false );
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseCombatCharacter::IsGlowEffectActive( void )
{
return m_bGlowEnabled;
}
#endif // GLOWS_ENABLE
</source>
 
and put this part somewhere under '''CBaseAnimating::~CBaseAnimating''' in '''baseanimating.cpp'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::AddGlowEffect(void)
{
SetTransmitState(FL_EDICT_ALWAYS);
m_bGlowEnabled.Set(true);
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::RemoveGlowEffect(void)
{
m_bGlowEnabled.Set(false);
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CBaseAnimating::IsGlowEffectActive(void)
{
return m_bGlowEnabled;
}
#endif
</source>
 
This is the end of server part, now onto client part. We'll be mainly operating on two files '''c_baseanimating.cpp/.h''' and '''c_basecombatcharacter.cpp/.h'''
Firstly delete this part from '''c_basecombatcharacter.h''' (lines 17-19) and put at the top of '''c_baseanimating.h'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
#include "glow_outline_effect.h"
#endif
</source>
 
Secondly is to delete this part of code from '''c_basecombatcharacter.h''' (lines 94-97) and put it into '''c_baseanimating.h''' (recommended lines 149-152)
<source lang=cpp>
#ifdef GLOWS_ENABLE
CGlowObject *GetGlowObject( void ){ return m_pGlowEffect; }
virtual void GetGlowEffectColor( float *r, float *g, float *b );
#endif // GLOWS_ENABLE
</source>
Then repeat that for this for this part of code (from '''c_basecombatcharacter.h''', lines 100-103 to '''c_baseanimating.h''', recommended lines 458-461):
<source lang=cpp>
#ifdef GLOWS_ENABLE
virtual void UpdateGlowEffect(void);
virtual void DestroyGlowEffect(void);
#endif // GLOWS_ENABLE
</source>
And this (from '''c_basecombatcharacter.h''', lines 110-114 to '''c_baseanimating.h''', recommended lines 481-485):
<source lang=cpp>
#ifdef GLOWS_ENABLE
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject *m_pGlowEffect;
#endif
</source>
 
Now go into '''c_basecombatcharacter.cpp''' and '''c_baseanimating.cpp'''
Firstly delete this part of code from '''c_basecombatcharacter.cpp''' (lines 33-37) and put it into '''c_baseanimating.cpp''' (recommended lines 737-741):
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE
</source>
Then delete this part of code from '''C_BaseCombatCharacter::~C_BaseCombatCharacter''' and put it into '''C_BaseAnimating::~C_BaseAnimating'''
<source lang=cpp>
#ifdef GLOWS_ENABLE
DestroyGlowEffect();
#endif // GLOWS_ENABLE
</source>
 
and repeat this for this part of code (from '''c_basecombatcharacter.h''', lines 58-60 to '''c_baseanimating.h''', recommended lines 4528-4530):
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_bOldGlowEnabled = m_bGlowEnabled;
#endif // GLOWS_ENABLE
</source>
 
and again (from '''c_basecombatcharacter.h''', lines 66-71 to '''c_baseanimating.h''', recommended lines 4716-4721):
<source lang=cpp>
#ifdef GLOWS_ENABLE
m_bOldGlowEnabled = m_bGlowEnabled;
#endif // GLOWS_ENABLE
</source>
 
Remove this section of code from '''c_basecombatcharacter.h''' (lines 85-128)
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::GetGlowEffectColor( float *r, float *g, float *b )
{
*r = 0.76f;
*g = 0.76f;
*b = 0.76f;
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::UpdateGlowEffect( void )
{
// destroy the existing effect
if ( m_pGlowEffect )
{
DestroyGlowEffect();
}
 
// create a new effect
if ( m_bGlowEnabled )
{
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
 
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
}
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseCombatCharacter::DestroyGlowEffect( void )
{
if ( m_pGlowEffect )
{
delete m_pGlowEffect;
m_pGlowEffect = NULL;
}
}
#endif // GLOWS_ENABLE
</source>
and put this section in '''c_baseanimating.h''' (recommended start on line 4387):
<source lang=cpp>
#ifdef GLOWS_ENABLE
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::GetGlowEffectColor( float *r, float *g, float *b )
{
*r = 0.76f;
*g = 0.76f;
*b = 0.76f;
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::UpdateGlowEffect( void )
{
// destroy the existing effect
if ( m_pGlowEffect )
{
DestroyGlowEffect();
}
 
// create a new effect
if ( m_bGlowEnabled )
{
float r, g, b;
GetGlowEffectColor( &r, &g, &b );
 
m_pGlowEffect = new CGlowObject( this, Vector( r, g, b ), 1.0, true );
}
}
 
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void C_BaseAnimating::DestroyGlowEffect( void )
{
if ( m_pGlowEffect )
{
delete m_pGlowEffect;
m_pGlowEffect = NULL;
}
}
#endif // GLOWS_ENABLE
</source>
 
and lastly get this part of code from '''c_basecombatcharacter.cpp''' (lines 97-99) and put it into '''c_baseanimating.cpp''' (recommended lines 203-205):
<source lang=cpp>
#ifdef GLOWS_ENABLE
RecvPropBool( RECVINFO( m_bGlowEnabled ) ),
#endif // GLOWS_ENABLE
</source>
[[File:glow_tutorial_2013_finalres.png|500px|thumb|left|Expected result]]{{clr}}
And you're done. Now you can create entities with glow (e.g. prop_dynamic, npcs, etc.) as long as they're derived from {{Key|CBaseAnimating}} onwards.
 
{{Todo|I plan to add control by inputs/output and also color control, but it'll take some time}}
===Adding color control for glow===
This subsection will explain how to add glow color control so you can change color in code.
Firstly open '''baseanimating.h''' and add {{Key|void SetGlowEffectColor(float r, float g, float b);}} like this:
<source lang=cpp>
#ifdef GLOWS_ENABLE
void SetGlowEffectColor(float r, float g, float b);
void AddGlowEffect(void);
void RemoveGlowEffect(void);
bool IsGlowEffectActive(void);
#endif
</source>
then add {{Key|CNetworkVar(float, m_flGlowR);}}, {{Key|CNetworkVar(float, m_flGlowG);}}, {{Key|CNetworkVar(float, m_flGlowB);}} like this:
<source lang=cpp>
// this should be around line 172
#ifdef GLOWS_ENABLE
protected:
CNetworkVar(bool, m_bGlowEnabled);
CNetworkVar(float, m_flGlowR);
CNetworkVar(float, m_flGlowG);
CNetworkVar(float, m_flGlowB);
#endif
</source>
Now in '''baseanimating.cpp''' add {{Key|SendPropFloat(SENDINFO(m_flGlowR)),}}, {{Key|SendPropFloat(SENDINFO(m_flGlowG)),}}, {{Key|SendPropFloat(SENDINFO(m_flGlowB)),}} like this:
<source lang=cpp>
// this should be around line 229
IMPLEMENT_SERVERCLASS_ST(CBaseAnimating, DT_BaseAnimating)
#ifdef GLOWS_ENABLE
SendPropBool(SENDINFO(m_bGlowEnabled)),
SendPropFloat(SENDINFO(m_flGlowR)),
SendPropFloat(SENDINFO(m_flGlowG)),
SendPropFloat(SENDINFO(m_flGlowB)),
#endif
</source>
In '''baseanimating.cpp''' add {{Key|m_flGlowR.Set(0.76f);}}, {{Key|m_flGlowG.Set(0.76f);}}, {{Key|m_flGlowB.Set(0.76f);}} like this:
<source lang=cpp>
// this should be around line 299
#ifdef GLOWS_ENABLE
m_bGlowEnabled.Set(false);
m_flGlowR.Set(0.76f);
m_flGlowG.Set(0.76f);
m_flGlowB.Set(0.76f);
#endif
</source>
Add this section of code in '''baseanimating.cpp''' like this:
<source lang=cpp>
// this should be around line 318
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CBaseAnimating::SetGlowEffectColor(float r, float g, float b)
{
m_flGlowR.Set(r);
m_flGlowG.Set(g);
m_flGlowB.Set(b);
}
</source>
That's it for the server side, now it's time for client side.<br>
Firstly, inside '''c_baseanimating.h''' add {{Key|float m_flGlowR}}, {{Key|float m_flGlowG}}, {{Key|float m_flGlowB}} like this:
<source lang=cpp>
// This should be around line 481
#ifdef GLOWS_ENABLE
float m_flGlowR;
float m_flGlowG;
float m_flGlowB;
bool m_bGlowEnabled;
bool m_bOldGlowEnabled;
CGlowObject* m_pGlowEffect;
#endif
</source>
Then in '''c_baseanimating.cpp''' add {{Key|RecvPropFloat(RECVINFO(m_flGlowR)),}}, {{Key|RecvPropFloat(RECVINFO(m_flGlowG)),}}, {{Key|RecvPropFloat(RECVINFO(m_flGlowB)),}} like this:
<source lang=cpp>
// this should be around line 203
#ifdef GLOWS_ENABLE
RecvPropBool(RECVINFO(m_bGlowEnabled)),
RecvPropFloat(RECVINFO(m_flGlowR)),
RecvPropFloat(RECVINFO(m_flGlowG)),
RecvPropFloat(RECVINFO(m_flGlowB)),
#endif // GLOWS_ENABLE
</source>
 
Add {{Key|m_flGlowR = 0.76f;}}, {{Key|m_flGlowG = 0.76f;}}, {{Key|m_flGlowB = 0.76f;}} in '''c_baseanimating.cpp''' like this:
<source lang=cpp>
// this should be around line 742
#ifdef GLOWS_ENABLE
m_flGlowR = 0.76f;
m_flGlowG = 0.76f;
m_flGlowB = 0.76f;
m_pGlowEffect = NULL;
m_bGlowEnabled = false;
m_bOldGlowEnabled = false;
#endif // GLOWS_ENABLE
</source>
 
Now change '''C_BaseAnimating::GetGlowEffectColor''' to look like this:
<source lang=cpp>
void C_BaseAnimating::GetGlowEffectColor(float* r, float* g, float* b)
{
*r = m_flGlowR;
*g = m_flGlowG;
*b = m_flGlowB;
}
</source>
[[File:Glow_tutorial_2013_finalres_color.png|500px|thumb|left|Expected result with red outline as example]]{{clr}}
Now you can change the color of glow from white to any color you want. If you don't what values you should type in I suggest [https://harry7557558.github.io/tools/colorpicker.html|this picker]. Most important is {{Key|RGB (float)}} field, since it's the value we want.
=Usage=
If you have followed [[#.28Optional.29_Transferring_getters_and_setters_from_CBaseCombatCharacter|this step]] then you can use getters, setters and color control with objects derived from {{Key|CBaseAnimating}} onwards, but if you didn't followed it then don't worry nothing bad happens, the only limitation is that you can use getters and setter with objects derived from {{Key|CBaseCombatCharacter}}.
To start a glow, call:
<source lang=cpp>
myObject->AddGlowEffect(); //Make it glow
</source>
 
To update a glow, call:
<source lang=cpp>
myObject->UpdateGlowEffect(); //Update glow
</source>
 
To stop a glow, call:
<source lang=cpp>
myObject->RemoveGlowEffect(); //Make it stop glowing
</source>
 
[[Category:Programming]]
[[Category:Snippets]]

Latest revision as of 20:04, 21 April 2025