Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/game/client/baseclientrendertargets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ ITexture* CBaseClientRenderTargets::CreateCameraTexture( IMaterialSystem* pMater
CREATERENDERTARGETFLAGS_HDR );
}

ITexture *CBaseClientRenderTargets::CreateViewmodelTexture( IMaterialSystem *pMaterialSystem )
{
return pMaterialSystem->CreateNamedRenderTargetTextureEx2(
"_rt_viewmodel",
1, 1, RT_SIZE_FULL_FRAME_BUFFER,
IMAGE_FORMAT_BGRA8888,
MATERIAL_RT_DEPTH_SHARED,
TEXTUREFLAGS_CLAMPS | TEXTUREFLAGS_CLAMPT | TEXTUREFLAGS_EIGHTBITALPHA,
CREATERENDERTARGETFLAGS_HDR );
}

//-----------------------------------------------------------------------------
// Purpose: Called by the engine in material system init and shutdown.
// Clients should override this in their inherited version, but the base
Expand All @@ -60,6 +71,8 @@ void CBaseClientRenderTargets::InitClientRenderTargets( IMaterialSystem* pMateri

// Monitors
m_CameraTexture.Init( CreateCameraTexture( pMaterialSystem, iCameraTextureSize ) );

m_ViewmodelTexture.Init( CreateViewmodelTexture( pMaterialSystem ) );
}

//-----------------------------------------------------------------------------
Expand All @@ -75,4 +88,6 @@ void CBaseClientRenderTargets::ShutdownClientRenderTargets()

// Monitors
m_CameraTexture.Shutdown();

m_ViewmodelTexture.Shutdown();
}
4 changes: 4 additions & 0 deletions src/game/client/baseclientrendertargets.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ class CBaseClientRenderTargets : public IClientRenderTargets
// Used for the HUD in stereo and head tracking mode
CTextureReference m_UITexture;

// Used for transparent viewmodels
CTextureReference m_ViewmodelTexture;

// Init functions for the common render targets
ITexture* CreateWaterReflectionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
ITexture* CreateWaterRefractionTexture( IMaterialSystem* pMaterialSystem, int iSize = 1024 );
ITexture* CreateCameraTexture( IMaterialSystem* pMaterialSystem, int iSize = 256 );
ITexture *CreateViewmodelTexture( IMaterialSystem *pMaterialSystem );

};

Expand Down
29 changes: 16 additions & 13 deletions src/game/client/c_baseviewmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,19 +316,22 @@ int C_BaseViewModel::DrawModel( int flags )
}
#endif

int ret;
// If the local player's overriding the viewmodel rendering, let him do it
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
{
ret = pPlayer->DrawOverriddenViewmodel( this, flags );
}
else if ( pWeapon && pWeapon->IsOverridingViewmodel() )
int ret = 0;
if ( !(flags & STUDIO_DRAWTRANSLUCENTSUBMODELS) )
{
ret = pWeapon->DrawOverriddenViewmodel( this, flags );
}
else
{
ret = BaseClass::DrawModel( flags );
// If the local player's overriding the viewmodel rendering, let him do it
if ( pPlayer && pPlayer->IsOverridingViewmodel() )
{
ret = pPlayer->DrawOverriddenViewmodel( this, flags );
}
else if ( pWeapon && pWeapon->IsOverridingViewmodel() )
{
ret = pWeapon->DrawOverriddenViewmodel( this, flags );
}
else
{
ret = BaseClass::DrawModel( flags );
}
}

// Now that we've rendered, reset the animation restart flag
Expand All @@ -339,7 +342,7 @@ int C_BaseViewModel::DrawModel( int flags )
m_nOldAnimationParity = m_nAnimationParity;
}
// Tell the weapon itself that we've rendered, in case it wants to do something
if ( pWeapon )
if ( (flags & STUDIO_DRAWTRANSLUCENTSUBMODELS) && pWeapon )
{
pWeapon->ViewModelDrawn( this );
}
Expand Down
3 changes: 3 additions & 0 deletions src/game/client/client_mapbase_hl2.vpc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ $Project
// Original stunstick files are conditional'd out in the HL2 VPCs
$File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.cpp"
$File "$SRCDIR\game\shared\hl2mp\weapon_stunstick.h"
// Rendertargets implementation for HL2
$File "hl2\rendertargets.cpp"
$File "hl2\rendertargets.h"
}

$Folder "HL2MP"
Expand Down
30 changes: 30 additions & 0 deletions src/game/client/hl2/rendertargets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
//
// Purpose: Implements IClientRenderTargets
//
// Author: Nooodles
//
//=============================================================================//
#include "cbase.h"
#include "rendertargets.h"

// shamelessly copied from TF2's rendertargets impl
ConVar hl2_water_resolution( "hl2_water_resolution", "1024", FCVAR_NONE, "Needs to be set at game launch time to override." );
ConVar hl2_monitor_resolution( "hl2_monitor_resolution", "1024", FCVAR_NONE, "Needs to be set at game launch time to override." );

void CRenderTargets::InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig )
{
BaseClass::InitClientRenderTargets( pMaterialSystem, pHardwareConfig,
hl2_water_resolution.GetInt(), hl2_monitor_resolution.GetInt() );
}

//-----------------------------------------------------------------------------
// Purpose: Shutdown client render targets. This gets called during shutdown in the engine
// Input : -
//-----------------------------------------------------------------------------
void CRenderTargets::ShutdownClientRenderTargets()
{
BaseClass::ShutdownClientRenderTargets();
}

EXPOSE_INTERFACE( CRenderTargets, IClientRenderTargets, CLIENTRENDERTARGETS_INTERFACE_VERSION );
24 changes: 24 additions & 0 deletions src/game/client/hl2/rendertargets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//========= Mapbase - https://github.com/mapbase-source/source-sdk-2013 ============//
//
// Purpose: Implements IClientRenderTargets
//
// Author: Nooodles
//
//=============================================================================//

#ifndef RENDERTARGETS_H
#define RENDERTARGETS_H
#ifdef _WIN32
#pragma once
#endif

#include "baseclientrendertargets.h"

class CRenderTargets : public CBaseClientRenderTargets
{
DECLARE_CLASS_GAMEROOT( CRenderTargets, CBaseClientRenderTargets );
public:
virtual void InitClientRenderTargets( IMaterialSystem* pMaterialSystem, IMaterialSystemHardwareConfig* pHardwareConfig );
virtual void ShutdownClientRenderTargets();
};
#endif
7 changes: 7 additions & 0 deletions src/game/client/view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,13 @@ void CViewRender::Init( void )
m_flLastFOV = default_fov.GetFloat();
#endif

KeyValues *pVMTKeyValues = new KeyValues( "UnlitGeneric" );
pVMTKeyValues->SetString( "$basetexture", "_rt_viewmodel" );
pVMTKeyValues->SetInt( "$vertexcolor", 0 );
pVMTKeyValues->SetInt( "$vertexalpha", 0 );
pVMTKeyValues->SetInt( "$translucent", 1 );
pVMTKeyValues->SetInt( "$additive", 0 );
m_transparentVMMaterial.Init( "__viewmodel", TEXTURE_GROUP_RENDER_TARGET, pVMTKeyValues );
}

//-----------------------------------------------------------------------------
Expand Down
127 changes: 125 additions & 2 deletions src/game/client/viewrender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ extern ConVar localplayer_visionflags;
static ConVar r_nearz_skybox( "r_nearz_skybox", "2.0", FCVAR_CHEAT );
#endif

ConVar r_viewmodel_opacity( "r_viewmodel_opacity", "1", FCVAR_ARCHIVE, "", true, 0.f, true, 1.f );
// personal preference to have occlusion disable on TF2 by default
#ifdef TF_CLIENT_DLL
ConVar r_viewmodel_opacity_occlude_effects( "r_viewmodel_opacity_occlude_effects", "0",
#else
ConVar r_viewmodel_opacity_occlude_effects( "r_viewmodel_opacity_occlude_effects", "1",
#endif
FCVAR_ARCHIVE, "When the opacity is less than 1 should it occlude effects rendered with the viewmodel such as particles" );

//-----------------------------------------------------------------------------
// Globals
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1143,6 +1152,7 @@ void CViewRender::DrawViewModels( const CViewSetup &viewRender, bool drawViewmod

CUtlVector< IClientRenderable * > opaqueViewModelList( 32 );
CUtlVector< IClientRenderable * > translucentViewModelList( 32 );
CUtlVector< IClientRenderable * > transparentList( 64 );

ClientLeafSystem()->CollateViewModelRenderables( opaqueViewModelList, translucentViewModelList );

Expand Down Expand Up @@ -1171,15 +1181,106 @@ void CViewRender::DrawViewModels( const CViewSetup &viewRender, bool drawViewmod
}
}

if ( !UpdateRefractIfNeededByList( opaqueViewModelList ) )
if ( r_viewmodel_opacity.GetFloat() >= 1.f )
{
if ( !UpdateRefractIfNeededByList( opaqueViewModelList ) )
{
UpdateRefractIfNeededByList( translucentViewModelList );
}
}
else
{
UpdateRefractIfNeededByList( translucentViewModelList );
// move our vm models to a different list
int nOpaque = opaqueViewModelList.Count();
for ( int i = nOpaque - 1; i >= 0; --i )
{
IClientRenderable *pRenderable = opaqueViewModelList[i];
CBaseEntity *pEntity = pRenderable->GetIClientUnknown()->GetBaseEntity();
if ( pEntity )
{
transparentList.AddToTail( pRenderable );
opaqueViewModelList.FastRemove( i );
}
}

int nTranslucent = translucentViewModelList.Count();
for ( int i = nTranslucent - 1; i >= 0; --i )
{
IClientRenderable *pRenderable = translucentViewModelList[i];
CBaseEntity *pEntity = pRenderable->GetIClientUnknown()->GetBaseEntity();
if ( pEntity )
{
transparentList.AddToTail( pRenderable );
translucentViewModelList.FastRemove( i );
}
}

if ( transparentList.Count() )
{
ITexture *pRenderTarget = materials->FindTexture( "_rt_viewmodel", TEXTURE_GROUP_RENDER_TARGET );
pRenderContext->PushRenderTargetAndViewport( pRenderTarget, viewRender.x, viewRender.y, viewRender.width, viewRender.height );
pRenderContext->ClearColor4ub( 0, 0, 0, 0 );
pRenderContext->ClearBuffers( true, true, true );

// write the stencil and draw the viewmodel for the vm render target
pRenderContext->SetStencilEnable( true );
pRenderContext->SetStencilReferenceValue( 1 );
pRenderContext->SetStencilWriteMask( 0xFF );
pRenderContext->SetStencilTestMask( 0xFF );
pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_ALWAYS );
pRenderContext->SetStencilPassOperation( STENCILOPERATION_REPLACE );
pRenderContext->SetStencilFailOperation( STENCILOPERATION_KEEP );
pRenderContext->SetStencilZFailOperation( STENCILOPERATION_KEEP );
DrawRenderablesInList( transparentList, STUDIO_TRANSPARENCY );

// clear the alpha channel based on what we just drew
float opacity = r_viewmodel_opacity.GetFloat() * 255.f;
pRenderContext->ClearColor4ub( 0, 0, 0, static_cast<int>( opacity ) );

pRenderContext->SetStencilWriteMask( 0 );
pRenderContext->SetStencilReferenceValue( 1 );
pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL );
pRenderContext->ClearBuffersObeyStencilEx( false, true, true );
pRenderContext->PopRenderTargetAndViewport();

// Do we want to occlude rendered effects and particles?
if ( !r_viewmodel_opacity_occlude_effects.GetBool() )
pRenderContext->SetStencilEnable( false );
else
{
// write our stencil for the main render target
pRenderContext->SetStencilEnable( true );
pRenderContext->SetStencilReferenceValue( 1 );
pRenderContext->SetStencilWriteMask( 0x3 );
pRenderContext->SetStencilTestMask( 0x3 );
pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_LESS );
pRenderContext->SetStencilPassOperation( STENCILOPERATION_ZERO );
pRenderContext->SetStencilFailOperation( STENCILOPERATION_REPLACE );
pRenderContext->SetStencilZFailOperation( STENCILOPERATION_REPLACE );

// something about drawing the ItemModelPanel render target ruins everything
// so just don't write colour which mostly works
pRenderContext->OverrideColorWriteEnable( true, false );
DrawRenderablesInList( transparentList, STUDIO_TRANSPARENCY );
pRenderContext->OverrideColorWriteEnable( false, true );

// setup for occlusion
pRenderContext->SetStencilWriteMask( 0 );
pRenderContext->SetStencilReferenceValue( 0 );
pRenderContext->SetStencilCompareFunction( STENCILCOMPARISONFUNCTION_EQUAL );
}
DrawRenderablesInList( transparentList, STUDIO_DRAWTRANSLUCENTSUBMODELS );
}
}

DrawRenderablesInList( opaqueViewModelList );
DrawRenderablesInList( opaqueViewModelList, STUDIO_DRAWTRANSLUCENTSUBMODELS );
DrawRenderablesInList( translucentViewModelList, STUDIO_TRANSPARENCY );
DrawRenderablesInList( translucentViewModelList, STUDIO_TRANSPARENCY | STUDIO_DRAWTRANSLUCENTSUBMODELS );
pRenderContext->SetStencilEnable( false );
}


// Reset the depth range to the original values
if( bUseDepthHack )
pRenderContext->DepthRange( depthmin, depthmax );
Expand Down Expand Up @@ -2484,8 +2585,30 @@ void CViewRender::RenderView( const CViewSetup &viewRender, int nClearFlags, int
DownscaleRect.x, DownscaleRect.y, DownscaleRect.x+DownscaleRect.width-1, DownscaleRect.y+DownscaleRect.height-1,
pFullFrameFB1->GetActualWidth(), pFullFrameFB1->GetActualHeight() );

if ( r_drawviewmodel.GetBool() && r_viewmodel_opacity.GetFloat() < 1.f && r_viewmodel_opacity.GetFloat() > 0.f )
{
m_transparentVMMaterial->IncrementReferenceCount();

pRenderContextUpscale->DrawScreenSpaceRectangle( m_transparentVMMaterial, UpscaleRect.x, UpscaleRect.y, UpscaleRect.width, UpscaleRect.height,
DownscaleRect.x, DownscaleRect.y, DownscaleRect.x + DownscaleRect.width - 1, DownscaleRect.y + DownscaleRect.height - 1,
pFullFrameFB1->GetActualWidth(), pFullFrameFB1->GetActualHeight() );

m_transparentVMMaterial->DecrementReferenceCount();
}

pCopyMaterial->DecrementReferenceCount();
}
else if ( r_drawviewmodel.GetBool() && r_viewmodel_opacity.GetFloat() < 1.f && r_viewmodel_opacity.GetFloat() > 0.f )
{
CMatRenderContextPtr pRenderContextVM( materials );
m_transparentVMMaterial->IncrementReferenceCount();

ITexture *pFullFrameFB1 = materials->FindTexture( "_rt_FullFrameFB1", TEXTURE_GROUP_RENDER_TARGET );
pRenderContextVM->DrawScreenSpaceRectangle( m_transparentVMMaterial, viewRender.x, viewRender.y, viewRender.width, viewRender.height,
viewRender.x, viewRender.y, viewRender.x + viewRender.width - 1, viewRender.y + viewRender.height - 1,
pFullFrameFB1->GetActualWidth(), pFullFrameFB1->GetActualHeight() );
m_transparentVMMaterial->DecrementReferenceCount();
}

// if we're in VR mode we might need to override the render target
if( UseVR() )
Expand Down
2 changes: 2 additions & 0 deletions src/game/client/viewrender.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ class CViewRender : public IViewRender,
CMaterialReference m_ScriptOverlayMaterial;
char m_szCurrentScriptMaterialName[ MAX_PATH ];

CMaterialReference m_transparentVMMaterial;

Vector m_vecLastFacing;
float m_flCheapWaterStartDistance;
float m_flCheapWaterEndDistance;
Expand Down