Team Fortress 2 Source Code as on 22/4/2020
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.

332 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Responsible for drawing the scene
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include "iviewrender.h"
  9. #include "c_dod_player.h"
  10. #include "view_shared.h"
  11. #include "dod_headiconmanager.h"
  12. #include "clienteffectprecachesystem.h"
  13. #include "rendertexture.h"
  14. #include "view_scene.h"
  15. #include "materialsystem/imesh.h"
  16. #include "materialsystem/itexture.h"
  17. #include "materialsystem/imaterial.h"
  18. #include "materialsystem/imaterialvar.h"
  19. #include "colorcorrectionmgr.h"
  20. #include "materialsystem/imaterialsystemhardwareconfig.h"
  21. #include "ScreenSpaceEffects.h"
  22. #include "dod_view_scene.h"
  23. #include "KeyValues.h"
  24. #include "dod_gamerules.h"
  25. // memdbgon must be the last include file in a .cpp file!!!
  26. #include "tier0/memdbgon.h"
  27. static CDODViewRender g_ViewRender;
  28. // Console variable for enabling camera effects
  29. ConVar cl_enablespectatoreffects( "cl_enablespectatoreffects", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Enable/disable spectator camera effects" );
  30. ConVar cl_enabledeatheffects( "cl_enabledeatheffects", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Enable/disable death camera effects" );
  31. ConVar cl_enabledeathfilmgrain( "cl_enabledeathfilmgrain", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Enable/disable the death camera film grain" );
  32. ConVar cl_deatheffect_force_on( "cl_deatheffect_always_on", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE, "Always show the death effect" );
  33. // Console variables to define lookup maps
  34. static void UpdateCameraLookups( IConVar *var, char const *pOldString, float flOldValue )
  35. {
  36. CDODViewRender *pView = static_cast<CDODViewRender*>(view);
  37. pView->InitColorCorrection();
  38. }
  39. static void SetSpectatorLookup( ConVar *var, char const *pOldString );
  40. ConVar cl_spectatorlookup( "cl_spectatorlookup", "materials\\colorcorrection\\bnw_c.raw", FCVAR_CLIENTDLL | FCVAR_CHEAT, "Sets the lookup map to use for spectator cameras", UpdateCameraLookups );
  41. ConVar cl_deathlookup( "cl_deathlookup", "materials\\colorcorrection\\bnw_c.raw", FCVAR_CLIENTDLL | FCVAR_CHEAT, "Sets the lookup map to use for death cameras", UpdateCameraLookups );
  42. CLIENTEFFECT_REGISTER_BEGIN( PrecacheDODViewScene )
  43. CLIENTEFFECT_MATERIAL( "effects/stun" )
  44. CLIENTEFFECT_REGISTER_END()
  45. CDODViewRender::CDODViewRender()
  46. {
  47. view = ( IViewRender * )this;
  48. m_SpectatorLookupHandle = (ClientCCHandle_t)0;
  49. m_DeathLookupHandle = (ClientCCHandle_t)0;
  50. m_bLookupActive = false;
  51. }
  52. struct ConVarFlags
  53. {
  54. const char *name;
  55. int flags;
  56. };
  57. ConVarFlags s_flaggedConVars[] =
  58. {
  59. { "r_screenfademinsize", FCVAR_CHEAT },
  60. { "r_screenfademaxsize", FCVAR_CHEAT },
  61. };
  62. void CDODViewRender::Init()
  63. {
  64. for ( int i=0; i<ARRAYSIZE( s_flaggedConVars ); ++i )
  65. {
  66. ConVar *flaggedConVar = cvar->FindVar( s_flaggedConVars[i].name );
  67. if ( flaggedConVar )
  68. {
  69. flaggedConVar->AddFlags( s_flaggedConVars[i].flags );
  70. }
  71. }
  72. CViewRender::Init();
  73. InitColorCorrection();
  74. }
  75. void CDODViewRender::Shutdown()
  76. {
  77. CViewRender::Shutdown();
  78. ShutdownColorCorrection();
  79. }
  80. void CDODViewRender::PerformStunEffect( const CViewSetup &view )
  81. {
  82. C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer();
  83. if ( pPlayer == NULL )
  84. return;
  85. if ( pPlayer->m_flStunEffectTime < gpGlobals->curtime )
  86. return;
  87. IMaterial *pMaterial = materials->FindMaterial( "effects/stun", TEXTURE_GROUP_CLIENT_EFFECTS, true );
  88. if ( !pMaterial )
  89. return;
  90. byte overlaycolor[4] = { 255, 255, 255, 255 };
  91. CMatRenderContextPtr pRenderContext( materials );
  92. if ( pPlayer->m_flStunAlpha < pPlayer->m_flStunMaxAlpha )
  93. {
  94. // copy current screen content into texture buffer
  95. UpdateScreenEffectTexture( 0, view.x, view.y, view.width, view.height );
  96. pPlayer->m_flStunAlpha += 45;
  97. pPlayer->m_flStunAlpha = MIN( pPlayer->m_flStunAlpha, pPlayer->m_flStunMaxAlpha );
  98. overlaycolor[3] = pPlayer->m_flStunAlpha;
  99. m_pStunTexture = GetFullFrameFrameBufferTexture( 1 );
  100. bool foundVar;
  101. IMaterialVar* m_BaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false );
  102. Rect_t srcRect;
  103. srcRect.x = view.x;
  104. srcRect.y = view.y;
  105. srcRect.width = view.width;
  106. srcRect.height = view.height;
  107. m_BaseTextureVar->SetTextureValue( m_pStunTexture );
  108. pRenderContext->CopyRenderTargetToTextureEx( m_pStunTexture, 0, &srcRect, NULL );
  109. pRenderContext->SetFrameBufferCopyTexture( m_pStunTexture );
  110. render->ViewDrawFade( overlaycolor, pMaterial );
  111. // just do one pass for dxlevel < 80.
  112. if (g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80)
  113. {
  114. pRenderContext->DrawScreenSpaceQuad( pMaterial );
  115. render->ViewDrawFade( overlaycolor, pMaterial );
  116. pRenderContext->DrawScreenSpaceQuad( pMaterial );
  117. }
  118. }
  119. else if ( m_pStunTexture )
  120. {
  121. float flAlpha = pPlayer->m_flStunMaxAlpha * (pPlayer->m_flStunEffectTime - gpGlobals->curtime) / pPlayer->m_flStunDuration;
  122. flAlpha = clamp( flAlpha, 0, pPlayer->m_flStunMaxAlpha );
  123. overlaycolor[3] = flAlpha;
  124. render->ViewDrawFade( overlaycolor, pMaterial );
  125. // just do one pass for dxlevel < 80.
  126. if (g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80)
  127. {
  128. pRenderContext->DrawScreenSpaceQuad( pMaterial );
  129. render->ViewDrawFade( overlaycolor, pMaterial );
  130. pRenderContext->DrawScreenSpaceQuad( pMaterial );
  131. }
  132. }
  133. }
  134. //-----------------------------------------------------------------------------
  135. // Purpose: Initialise the color correction maps for spectator and death cameras
  136. // Input : none
  137. //-----------------------------------------------------------------------------
  138. void CDODViewRender::InitColorCorrection( )
  139. {
  140. m_SpectatorLookupHandle = g_pColorCorrectionMgr->AddColorCorrection( "spectator", cl_spectatorlookup.GetString() );
  141. m_DeathLookupHandle = g_pColorCorrectionMgr->AddColorCorrection( "death", cl_deathlookup.GetString() );
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Cleanup the color correction maps
  145. // Input : none
  146. //-----------------------------------------------------------------------------
  147. void CDODViewRender::ShutdownColorCorrection( )
  148. {
  149. g_pColorCorrectionMgr->RemoveColorCorrection( m_SpectatorLookupHandle );
  150. g_pColorCorrectionMgr->RemoveColorCorrection( m_DeathLookupHandle );
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Purpose: Do the per-frame setup required for the spectator cam color correction
  154. // Input : none
  155. //-----------------------------------------------------------------------------
  156. void CDODViewRender::SetupColorCorrection( )
  157. {
  158. C_DODPlayer *pPlayer = C_DODPlayer::GetLocalDODPlayer();
  159. if( !pPlayer )
  160. return;
  161. bool bResetColorCorrection = true;
  162. int nObsMode = pPlayer->GetObserverMode();
  163. if ( pPlayer->GetTeamNumber() == TEAM_SPECTATOR )
  164. {
  165. if ( cl_enablespectatoreffects.GetBool() )
  166. {
  167. bResetColorCorrection = false;
  168. // Enable spectator color lookup for all other modes except OBS_MODE_NONE
  169. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_SpectatorLookupHandle, 1.0f );
  170. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_DeathLookupHandle, 0.0f );
  171. g_pColorCorrectionMgr->SetResetable( m_SpectatorLookupHandle, false );
  172. g_pColorCorrectionMgr->SetResetable( m_DeathLookupHandle, true );
  173. if ( cl_enabledeathfilmgrain.GetBool() )
  174. {
  175. g_pScreenSpaceEffects->EnableScreenSpaceEffect( "filmgrain" );
  176. KeyValues *kv = new KeyValues( "params" );
  177. kv->SetFloat( "effect_alpha", 1.0f );
  178. g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "filmgrain", kv );
  179. m_bLookupActive = true;
  180. }
  181. }
  182. }
  183. else if ( cl_enabledeatheffects.GetBool() )
  184. {
  185. float flEffectAlpha = 0.0f;
  186. if ( cl_deatheffect_force_on.GetBool() )
  187. {
  188. flEffectAlpha = 1.0f;
  189. }
  190. else if ( nObsMode != OBS_MODE_NONE )
  191. {
  192. flEffectAlpha = MIN( 1.0f, ( gpGlobals->curtime - pPlayer->GetDeathTime() ) / ( 2.0f ) );
  193. }
  194. else
  195. {
  196. DODRoundState roundstate = DODGameRules()->State_Get();
  197. if ( roundstate < STATE_RND_RUNNING )
  198. {
  199. flEffectAlpha = 1.0f;
  200. }
  201. else if ( roundstate == STATE_RND_RUNNING )
  202. {
  203. // fade out of effect at last event: spawn or unfreeze at round start
  204. float flFadeOutStartTime = MAX( DODGameRules()->m_flLastRoundStateChangeTime, pPlayer->m_flLastRespawnTime );
  205. // fade in from round start time
  206. flEffectAlpha = 1.0 - ( gpGlobals->curtime - flFadeOutStartTime ) / ( 2.0f );
  207. flEffectAlpha = MAX( 0.0f, flEffectAlpha );
  208. }
  209. }
  210. if ( flEffectAlpha > 0.0f )
  211. {
  212. bResetColorCorrection = false;
  213. // Enable death camera color lookup
  214. // allow us to reset the weight
  215. g_pColorCorrectionMgr->SetResetable( m_DeathLookupHandle, true );
  216. g_pColorCorrectionMgr->SetResetable( m_SpectatorLookupHandle, true );
  217. // reset weight to 0
  218. g_pColorCorrectionMgr->ResetColorCorrectionWeights();
  219. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_SpectatorLookupHandle, 0.0f );
  220. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_DeathLookupHandle, flEffectAlpha );
  221. if ( cl_enabledeathfilmgrain.GetBool() )
  222. {
  223. g_pScreenSpaceEffects->EnableScreenSpaceEffect( "filmgrain" );
  224. KeyValues *kv = new KeyValues( "params" );
  225. //kv->SetInt( "split_screen", 1 );
  226. kv->SetFloat( "effect_alpha", flEffectAlpha );
  227. g_pScreenSpaceEffects->SetScreenSpaceEffectParams( "filmgrain", kv );
  228. }
  229. m_bLookupActive = true;
  230. }
  231. }
  232. if ( bResetColorCorrection )
  233. {
  234. // Disable color lookups
  235. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_SpectatorLookupHandle, 0.0f );
  236. g_pColorCorrectionMgr->SetColorCorrectionWeight( m_DeathLookupHandle, 0.0f );
  237. g_pColorCorrectionMgr->SetResetable( m_SpectatorLookupHandle, true );
  238. g_pColorCorrectionMgr->SetResetable( m_DeathLookupHandle, true );
  239. if( m_bLookupActive )
  240. g_pScreenSpaceEffects->DisableScreenSpaceEffect( "filmgrain" );
  241. m_bLookupActive = false;
  242. }
  243. }
  244. void CDODViewRender::RenderView( const CViewSetup &view, int nClearFlags, int whatToDraw )
  245. {
  246. // Setup the necessary parameters for color correction
  247. SetupColorCorrection( );
  248. CViewRender::RenderView( view, nClearFlags, whatToDraw );
  249. // Draw screen effects here
  250. PerformStunEffect( view );
  251. }
  252. //-----------------------------------------------------------------------------
  253. // Purpose: Renders voice feedback and other sprites attached to players
  254. // Input : none
  255. //-----------------------------------------------------------------------------
  256. void CDODViewRender::RenderPlayerSprites()
  257. {
  258. CViewRender::RenderPlayerSprites();
  259. // Draw head icons here
  260. HeadIconManager()->DrawHeadIcons();
  261. }