2023-10-03 17:23:56 +03:00
//============ Copyright (c) Valve Corporation, All rights reserved. ============
2020-04-22 12:56:21 -04:00
//
// Functionality to render a glowing outline around client renderable objects.
//
//===============================================================================
# include "cbase.h"
# include "glow_outline_effect.h"
# include "model_types.h"
# include "shaderapi/ishaderapi.h"
# include "materialsystem/imaterialvar.h"
# include "view_shared.h"
# define FULL_FRAME_TEXTURE "_rt_FullFrameFB"
2023-10-03 17:23:56 +03:00
ConVar glow_outline_effect_enable ( " glow_outline_effect_enable " , " 1 " , FCVAR_CHEAT , " Enable entity outline glow effects. " ) ;
ConVar glow_outline_effect_width ( " glow_outline_width " , " 6.0f " , FCVAR_CHEAT , " Width of glow outline effect in screen space. " ) ;
2020-04-22 12:56:21 -04:00
CGlowObjectManager g_GlowObjectManager ;
void CGlowObjectManager : : RenderGlowEffects ( const CViewSetup * pSetup , int nSplitScreenSlot )
{
2023-10-03 17:23:56 +03:00
if ( glow_outline_effect_enable . GetBool ( ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
CMatRenderContextPtr pRenderContext ( materials ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
int nX , nY , nWidth , nHeight ;
pRenderContext - > GetViewport ( nX , nY , nWidth , nHeight ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
PIXEvent _pixEvent ( pRenderContext , " EntityGlowEffects " ) ;
ApplyEntityGlowEffects ( pSetup , nSplitScreenSlot , pRenderContext , glow_outline_effect_width . GetFloat ( ) , nX , nY , nWidth , nHeight ) ;
2020-04-22 12:56:21 -04:00
}
}
2023-10-03 17:23:56 +03:00
2020-04-22 12:56:21 -04:00
static void SetRenderTargetAndViewPort ( ITexture * rt , int w , int h )
{
CMatRenderContextPtr pRenderContext ( materials ) ;
pRenderContext - > SetRenderTarget ( rt ) ;
pRenderContext - > Viewport ( 0 , 0 , w , h ) ;
}
2023-10-03 17:23:56 +03:00
// *** Keep in sync with matsys_interface.cpp, where the texture is declared ***
// Resolution for glow target chosen to be the largest that we can fit in EDRAM after 720p color/depth textures.
# define GLOW_360_RT_WIDTH ( MIN( 1120, pSetup->width ) )
# define GLOW_360_RT_HEIGHT ( MIN( 624, pSetup->height ) )
2020-04-22 12:56:21 -04:00
void CGlowObjectManager : : RenderGlowModels ( const CViewSetup * pSetup , int nSplitScreenSlot , CMatRenderContextPtr & pRenderContext )
{
//==========================================================================================//
// This renders solid pixels with the correct coloring for each object that needs the glow. //
// After this function returns, this image will then be blurred and added into the frame //
// buffer with the objects stenciled out. //
//==========================================================================================//
pRenderContext - > PushRenderTargetAndViewport ( ) ;
// Save modulation color and blend
Vector vOrigColor ;
render - > GetColorModulation ( vOrigColor . Base ( ) ) ;
float flOrigBlend = render - > GetBlend ( ) ;
2023-10-03 17:23:56 +03:00
ITexture * pRtFullFrame = materials - > FindTexture ( FULL_FRAME_TEXTURE , TEXTURE_GROUP_RENDER_TARGET ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
if ( IsX360 ( ) )
{
ITexture * pRtGlowTexture360 = materials - > FindTexture ( " _rt_Glows360 " , TEXTURE_GROUP_RENDER_TARGET ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
SetRenderTargetAndViewPort ( pRtGlowTexture360 , GLOW_360_RT_WIDTH , GLOW_360_RT_HEIGHT ) ;
}
else
{
SetRenderTargetAndViewPort ( pRtFullFrame , pSetup - > width , pSetup - > height ) ;
}
2020-04-22 12:56:21 -04:00
pRenderContext - > ClearColor3ub ( 0 , 0 , 0 ) ;
pRenderContext - > ClearBuffers ( true , false , false ) ;
// Set override material for glow color
IMaterial * pMatGlowColor = NULL ;
pMatGlowColor = materials - > FindMaterial ( " dev/glow_color " , TEXTURE_GROUP_OTHER , true ) ;
2023-10-03 17:23:56 +03:00
2020-04-22 12:56:21 -04:00
//==================//
// Draw the objects //
//==================//
for ( int i = 0 ; i < m_GlowObjectDefinitions . Count ( ) ; + + i )
{
if ( m_GlowObjectDefinitions [ i ] . IsUnused ( ) | | ! m_GlowObjectDefinitions [ i ] . ShouldDraw ( nSplitScreenSlot ) )
continue ;
2023-10-03 17:23:56 +03:00
g_pStudioRender - > ForcedMaterialOverride ( pMatGlowColor ) ;
if ( m_GlowObjectDefinitions [ i ] . m_bFullBloomRender )
{
// Disabled because stencil test on off-screen buffers doesn't work with MSAA on.
// Also, the normal model render does not seem to work on the off-screen buffer
//g_pStudioRender->ForcedMaterialOverride( NULL );
// ShaderStencilState_t stencilState;
// stencilState.m_bEnable = true;
// stencilState.m_nReferenceValue = m_GlowObjectDefinitions[i].m_nFullBloomStencilTestValue;
// stencilState.m_nTestMask = 0xFF;
// stencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
// stencilState.m_PassOp = SHADER_STENCILOP_KEEP;
// stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
// stencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
//
// pRenderContext->SetStencilState( stencilState );
}
else
{
// Disabled because stencil test on off-screen buffers doesn't work with MSAA on
// Most features still work, but some (e.g. partial occlusion) don't
// ShaderStencilState_t stencilState;
// stencilState.m_bEnable = true;
// stencilState.m_nReferenceValue = 1;
// stencilState.m_nTestMask = 0x1;
// stencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
// stencilState.m_PassOp = SHADER_STENCILOP_KEEP;
// stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
// stencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
//
// pRenderContext->SetStencilState( stencilState );
}
2020-04-22 12:56:21 -04:00
render - > SetBlend ( m_GlowObjectDefinitions [ i ] . m_flGlowAlpha ) ;
Vector vGlowColor = m_GlowObjectDefinitions [ i ] . m_vGlowColor * m_GlowObjectDefinitions [ i ] . m_flGlowAlpha ;
render - > SetColorModulation ( & vGlowColor [ 0 ] ) ; // This only sets rgb, not alpha
m_GlowObjectDefinitions [ i ] . DrawModel ( ) ;
}
g_pStudioRender - > ForcedMaterialOverride ( NULL ) ;
render - > SetColorModulation ( vOrigColor . Base ( ) ) ;
render - > SetBlend ( flOrigBlend ) ;
ShaderStencilState_t stencilStateDisable ;
stencilStateDisable . m_bEnable = false ;
2023-10-03 17:23:56 +03:00
pRenderContext - > SetStencilState ( stencilStateDisable ) ;
if ( IsX360 ( ) )
{
Rect_t rect ;
rect . x = rect . y = 0 ;
rect . width = GLOW_360_RT_WIDTH ;
rect . height = GLOW_360_RT_HEIGHT ;
pRenderContext - > CopyRenderTargetToTextureEx ( pRtFullFrame , 0 , & rect , & rect ) ;
}
2020-04-22 12:56:21 -04:00
pRenderContext - > PopRenderTargetAndViewport ( ) ;
}
void CGlowObjectManager : : ApplyEntityGlowEffects ( const CViewSetup * pSetup , int nSplitScreenSlot , CMatRenderContextPtr & pRenderContext , float flBloomScale , int x , int y , int w , int h )
{
2023-10-03 17:23:56 +03:00
static bool s_bFirstPass = true ;
2020-04-22 12:56:21 -04:00
//=======================================================//
// Render objects into stencil buffer //
//=======================================================//
2023-10-03 17:23:56 +03:00
2020-04-22 12:56:21 -04:00
// Set override shader to the same simple shader we use to render the glow models
IMaterial * pMatGlowColor = materials - > FindMaterial ( " dev/glow_color " , TEXTURE_GROUP_OTHER , true ) ;
g_pStudioRender - > ForcedMaterialOverride ( pMatGlowColor ) ;
ShaderStencilState_t stencilStateDisable ;
stencilStateDisable . m_bEnable = false ;
float flSavedBlend = render - > GetBlend ( ) ;
// Set alpha to 0 so we don't touch any color pixels
render - > SetBlend ( 0.0f ) ;
pRenderContext - > OverrideDepthEnable ( true , false ) ;
2023-10-03 17:23:56 +03:00
RenderableInstance_t instance ;
instance . m_nAlpha = 255 ;
2020-04-22 12:56:21 -04:00
int iNumGlowObjects = 0 ;
for ( int i = 0 ; i < m_GlowObjectDefinitions . Count ( ) ; + + i )
{
if ( m_GlowObjectDefinitions [ i ] . IsUnused ( ) | | ! m_GlowObjectDefinitions [ i ] . ShouldDraw ( nSplitScreenSlot ) )
continue ;
2023-10-03 17:23:56 +03:00
// Full bloom rendered objects should not be stenciled out here
if ( m_GlowObjectDefinitions [ i ] . m_bFullBloomRender )
{
+ + iNumGlowObjects ;
continue ;
}
2020-04-22 12:56:21 -04:00
if ( m_GlowObjectDefinitions [ i ] . m_bRenderWhenOccluded | | m_GlowObjectDefinitions [ i ] . m_bRenderWhenUnoccluded )
{
if ( m_GlowObjectDefinitions [ i ] . m_bRenderWhenOccluded & & m_GlowObjectDefinitions [ i ] . m_bRenderWhenUnoccluded )
{
ShaderStencilState_t stencilState ;
stencilState . m_bEnable = true ;
stencilState . m_nReferenceValue = 1 ;
2023-10-03 17:23:56 +03:00
stencilState . m_CompareFunc = SHADER_STENCILFUNC_ALWAYS ;
stencilState . m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE ;
stencilState . m_FailOp = SHADER_STENCILOP_KEEP ;
stencilState . m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
pRenderContext - > SetStencilState ( stencilState ) ;
2020-04-22 12:56:21 -04:00
m_GlowObjectDefinitions [ i ] . DrawModel ( ) ;
}
else if ( m_GlowObjectDefinitions [ i ] . m_bRenderWhenOccluded )
{
ShaderStencilState_t stencilState ;
stencilState . m_bEnable = true ;
stencilState . m_nReferenceValue = 1 ;
2023-10-03 17:23:56 +03:00
stencilState . m_CompareFunc = SHADER_STENCILFUNC_ALWAYS ;
stencilState . m_PassOp = SHADER_STENCILOP_KEEP ;
stencilState . m_FailOp = SHADER_STENCILOP_KEEP ;
stencilState . m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
pRenderContext - > SetStencilState ( stencilState ) ;
2020-04-22 12:56:21 -04:00
m_GlowObjectDefinitions [ i ] . DrawModel ( ) ;
}
else if ( m_GlowObjectDefinitions [ i ] . m_bRenderWhenUnoccluded )
{
ShaderStencilState_t stencilState ;
stencilState . m_bEnable = true ;
stencilState . m_nReferenceValue = 2 ;
stencilState . m_nTestMask = 0x1 ;
stencilState . m_nWriteMask = 0x3 ;
2023-10-03 17:23:56 +03:00
stencilState . m_CompareFunc = SHADER_STENCILFUNC_EQUAL ;
stencilState . m_PassOp = SHADER_STENCILOP_INCREMENT_CLAMP ;
stencilState . m_FailOp = SHADER_STENCILOP_KEEP ;
stencilState . m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
pRenderContext - > SetStencilState ( stencilState ) ;
2020-04-22 12:56:21 -04:00
m_GlowObjectDefinitions [ i ] . DrawModel ( ) ;
}
}
iNumGlowObjects + + ;
}
// Need to do a 2nd pass to warm stencil for objects which are rendered only when occluded
for ( int i = 0 ; i < m_GlowObjectDefinitions . Count ( ) ; + + i )
{
if ( m_GlowObjectDefinitions [ i ] . IsUnused ( ) | | ! m_GlowObjectDefinitions [ i ] . ShouldDraw ( nSplitScreenSlot ) )
continue ;
2023-10-03 17:23:56 +03:00
// Full bloom rendered objects should not be stenciled out here
if ( m_GlowObjectDefinitions [ i ] . m_bFullBloomRender )
continue ;
2020-04-22 12:56:21 -04:00
if ( m_GlowObjectDefinitions [ i ] . m_bRenderWhenOccluded & & ! m_GlowObjectDefinitions [ i ] . m_bRenderWhenUnoccluded )
{
ShaderStencilState_t stencilState ;
stencilState . m_bEnable = true ;
stencilState . m_nReferenceValue = 2 ;
2023-10-03 17:23:56 +03:00
stencilState . m_CompareFunc = SHADER_STENCILFUNC_ALWAYS ;
stencilState . m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE ;
stencilState . m_FailOp = SHADER_STENCILOP_KEEP ;
stencilState . m_ZFailOp = SHADER_STENCILOP_KEEP ;
pRenderContext - > SetStencilState ( stencilState ) ;
2020-04-22 12:56:21 -04:00
m_GlowObjectDefinitions [ i ] . DrawModel ( ) ;
}
}
pRenderContext - > OverrideDepthEnable ( false , false ) ;
render - > SetBlend ( flSavedBlend ) ;
2023-10-03 17:23:56 +03:00
pRenderContext - > SetStencilState ( stencilStateDisable ) ;
2020-04-22 12:56:21 -04:00
g_pStudioRender - > ForcedMaterialOverride ( NULL ) ;
// If there aren't any objects to glow, don't do all this other stuff
// this fixes a bug where if there are glow objects in the list, but none of them are glowing,
// the whole screen blooms.
if ( iNumGlowObjects < = 0 )
return ;
//=============================================
// Render the glow colors to _rt_FullFrameFB
//=============================================
{
PIXEvent pixEvent ( pRenderContext , " RenderGlowModels " ) ;
RenderGlowModels ( pSetup , nSplitScreenSlot , pRenderContext ) ;
}
2023-10-03 17:23:56 +03:00
//===================================
// Setup state for downsample/bloom
//===================================
# if defined( _X360 )
pRenderContext - > PushVertexShaderGPRAllocation ( 16 ) ; // Max out pixel shader threads
# endif
pRenderContext - > PushRenderTargetAndViewport ( ) ;
2020-04-22 12:56:21 -04:00
// Get viewport
int nSrcWidth = pSetup - > width ;
int nSrcHeight = pSetup - > height ;
int nViewportX , nViewportY , nViewportWidth , nViewportHeight ;
pRenderContext - > GetViewport ( nViewportX , nViewportY , nViewportWidth , nViewportHeight ) ;
// Get material and texture pointers
2023-10-03 17:23:56 +03:00
IMaterial * pMatDownsample = materials - > FindMaterial ( " dev/glow_downsample " , TEXTURE_GROUP_OTHER , true ) ;
IMaterial * pMatBlurX = materials - > FindMaterial ( " dev/glow_blur_x " , TEXTURE_GROUP_OTHER , true ) ;
IMaterial * pMatBlurY = materials - > FindMaterial ( " dev/glow_blur_y " , TEXTURE_GROUP_OTHER , true ) ;
ITexture * pRtFullFrame = materials - > FindTexture ( FULL_FRAME_TEXTURE , TEXTURE_GROUP_RENDER_TARGET ) ;
ITexture * pRtQuarterSize0 = materials - > FindTexture ( " _rt_SmallFB0 " , TEXTURE_GROUP_RENDER_TARGET ) ;
2020-04-22 12:56:21 -04:00
ITexture * pRtQuarterSize1 = materials - > FindTexture ( " _rt_SmallFB1 " , TEXTURE_GROUP_RENDER_TARGET ) ;
2023-10-03 17:23:56 +03:00
//============================================
// Downsample _rt_FullFrameFB to _rt_SmallFB0
//============================================
// First clear the full target to black if we're not going to touch every pixel
if ( ( pRtQuarterSize0 - > GetActualWidth ( ) ! = ( pSetup - > width / 4 ) ) | | ( pRtQuarterSize0 - > GetActualHeight ( ) ! = ( pSetup - > height / 4 ) ) )
{
SetRenderTargetAndViewPort ( pRtQuarterSize0 , pRtQuarterSize0 - > GetActualWidth ( ) , pRtQuarterSize0 - > GetActualHeight ( ) ) ;
pRenderContext - > ClearColor3ub ( 0 , 0 , 0 ) ;
pRenderContext - > ClearBuffers ( true , false , false ) ;
}
// Set the viewport
SetRenderTargetAndViewPort ( pRtQuarterSize0 , pSetup - > width / 4 , pSetup - > height / 4 ) ;
IMaterialVar * pbloomexpvar = pMatDownsample - > FindVar ( " $bloomexp " , null ) ;
if ( pbloomexpvar ! = NULL )
{
pbloomexpvar - > SetFloatValue ( 2.5f ) ;
}
IMaterialVar * pbloomsaturationvar = pMatDownsample - > FindVar ( " $bloomsaturation " , null ) ;
if ( pbloomsaturationvar ! = NULL )
{
pbloomsaturationvar - > SetFloatValue ( 1.0f ) ;
}
// note the -2's below. Thats because we are downsampling on each axis and the shader
// accesses pixels on both sides of the source coord
int nFullFbWidth = nSrcWidth ;
int nFullFbHeight = nSrcHeight ;
if ( IsX360 ( ) )
{
nFullFbWidth = GLOW_360_RT_WIDTH ;
nFullFbHeight = GLOW_360_RT_HEIGHT ;
}
pRenderContext - > DrawScreenSpaceRectangle ( pMatDownsample , 0 , 0 , nSrcWidth / 4 , nSrcHeight / 4 ,
0 , 0 , nFullFbWidth - 4 , nFullFbHeight - 4 ,
pRtFullFrame - > GetActualWidth ( ) , pRtFullFrame - > GetActualHeight ( ) ) ;
if ( IsX360 ( ) )
{
// Need to reset viewport to full size so we can also copy the cleared black pixels around the border
SetRenderTargetAndViewPort ( pRtQuarterSize0 , pRtQuarterSize0 - > GetActualWidth ( ) , pRtQuarterSize0 - > GetActualHeight ( ) ) ;
pRenderContext - > CopyRenderTargetToTextureEx ( pRtQuarterSize0 , 0 , NULL , NULL ) ;
}
//============================//
// Guassian blur x rt0 to rt1 //
//============================//
// First clear the full target to black if we're not going to touch every pixel
if ( s_bFirstPass | | ( pRtQuarterSize1 - > GetActualWidth ( ) ! = ( pSetup - > width / 4 ) ) | | ( pRtQuarterSize1 - > GetActualHeight ( ) ! = ( pSetup - > height / 4 ) ) )
{
// On the first render, this viewport may require clearing
s_bFirstPass = false ;
SetRenderTargetAndViewPort ( pRtQuarterSize1 , pRtQuarterSize1 - > GetActualWidth ( ) , pRtQuarterSize1 - > GetActualHeight ( ) ) ;
pRenderContext - > ClearColor3ub ( 0 , 0 , 0 ) ;
pRenderContext - > ClearBuffers ( true , false , false ) ;
}
// Set the viewport
SetRenderTargetAndViewPort ( pRtQuarterSize1 , pSetup - > width / 4 , pSetup - > height / 4 ) ;
pRenderContext - > DrawScreenSpaceRectangle ( pMatBlurX , 0 , 0 , nSrcWidth / 4 , nSrcHeight / 4 ,
0 , 0 , nSrcWidth / 4 - 1 , nSrcHeight / 4 - 1 ,
pRtQuarterSize0 - > GetActualWidth ( ) , pRtQuarterSize0 - > GetActualHeight ( ) ) ;
if ( IsX360 ( ) )
{
pRenderContext - > CopyRenderTargetToTextureEx ( pRtQuarterSize1 , 0 , NULL , NULL ) ;
}
//============================//
// Gaussian blur y rt1 to rt0 //
//============================//
SetRenderTargetAndViewPort ( pRtQuarterSize0 , pSetup - > width / 4 , pSetup - > height / 4 ) ;
IMaterialVar * pBloomAmountVar = pMatBlurY - > FindVar ( " $bloomamount " , NULL ) ;
pBloomAmountVar - > SetFloatValue ( flBloomScale ) ;
pRenderContext - > DrawScreenSpaceRectangle ( pMatBlurY , 0 , 0 , nSrcWidth / 4 , nSrcHeight / 4 ,
0 , 0 , nSrcWidth / 4 - 1 , nSrcHeight / 4 - 1 ,
pRtQuarterSize1 - > GetActualWidth ( ) , pRtQuarterSize1 - > GetActualHeight ( ) ) ;
if ( IsX360 ( ) )
{
pRenderContext - > CopyRenderTargetToTextureEx ( pRtQuarterSize1 , 0 , NULL , NULL ) ; // copy to rt1 instead of rt0 because rt1 has linear reads enabled and works more easily with screenspace_general to fix 360 bloom issues
}
// Pop RT
pRenderContext - > PopRenderTargetAndViewport ( ) ;
2020-04-22 12:56:21 -04:00
{
//=======================================================================================================//
// At this point, pRtQuarterSize0 is filled with the fully colored glow around everything as solid glowy //
// blobs. Now we need to stencil out the original objects by only writing pixels that have no //
// stencil bits set in the range we care about. //
//=======================================================================================================//
IMaterial * pMatHaloAddToScreen = materials - > FindMaterial ( " dev/halo_add_to_screen " , TEXTURE_GROUP_OTHER , true ) ;
// Do not fade the glows out at all (weight = 1.0)
IMaterialVar * pDimVar = pMatHaloAddToScreen - > FindVar ( " $C0_X " , NULL ) ;
pDimVar - > SetFloatValue ( 1.0f ) ;
ShaderStencilState_t stencilState ;
stencilState . m_bEnable = true ;
stencilState . m_nWriteMask = 0x0 ; // We're not changing stencil
2023-10-03 17:23:56 +03:00
stencilState . m_nTestMask = 0x3 ;
2020-04-22 12:56:21 -04:00
stencilState . m_nReferenceValue = 0x0 ;
2023-10-03 17:23:56 +03:00
stencilState . m_CompareFunc = SHADER_STENCILFUNC_EQUAL ;
stencilState . m_PassOp = SHADER_STENCILOP_KEEP ;
stencilState . m_FailOp = SHADER_STENCILOP_KEEP ;
stencilState . m_ZFailOp = SHADER_STENCILOP_KEEP ;
pRenderContext - > SetStencilState ( stencilState ) ;
2020-04-22 12:56:21 -04:00
// Draw quad
pRenderContext - > DrawScreenSpaceRectangle ( pMatHaloAddToScreen , 0 , 0 , nViewportWidth , nViewportHeight ,
0.0f , - 0.5f , nSrcWidth / 4 - 1 , nSrcHeight / 4 - 1 ,
pRtQuarterSize1 - > GetActualWidth ( ) ,
pRtQuarterSize1 - > GetActualHeight ( ) ) ;
2023-10-03 17:23:56 +03:00
// Disable stencil
pRenderContext - > SetStencilState ( stencilStateDisable ) ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
# if defined( _X360 )
pRenderContext - > PopVertexShaderGPRAllocation ( ) ;
# endif
2020-04-22 12:56:21 -04:00
}
void CGlowObjectManager : : GlowObjectDefinition_t : : DrawModel ( )
{
2023-10-03 17:23:56 +03:00
RenderableInstance_t instance ;
instance . m_nAlpha = ( uint8 ) ( m_flGlowAlpha * 255.0f ) ;
m_pEntity - > DrawModel ( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS , instance ) ;
C_BaseEntity * pAttachment = m_pEntity - > FirstMoveChild ( ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
while ( pAttachment ! = NULL )
{
if ( pAttachment - > ShouldDraw ( ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
pAttachment - > DrawModel ( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS , instance ) ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
pAttachment = pAttachment - > NextMovePeer ( ) ;
2020-04-22 12:56:21 -04:00
}
2023-10-03 17:23:56 +03:00
}