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.

317 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #include "cbase.h"
  3. #include "KeyValues.h"
  4. #include "cdll_client_int.h"
  5. #include "view_scene.h"
  6. #include "viewrender.h"
  7. #include "tier0/icommandline.h"
  8. #include "materialsystem/imesh.h"
  9. #include "materialsystem/imaterial.h"
  10. #include "materialsystem/imaterialsystemhardwareconfig.h"
  11. #include "materialsystem/imaterialvar.h"
  12. #include "ScreenSpaceEffects.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. //------------------------------------------------------------------------------
  16. // CScreenSpaceEffectRegistration code
  17. // Used to register and effect with the IScreenSpaceEffectManager
  18. //------------------------------------------------------------------------------
  19. CScreenSpaceEffectRegistration *CScreenSpaceEffectRegistration::s_pHead = NULL;
  20. CScreenSpaceEffectRegistration::CScreenSpaceEffectRegistration( const char *pName, IScreenSpaceEffect *pEffect )
  21. {
  22. m_pEffectName = pName;
  23. m_pEffect = pEffect;
  24. m_pNext = s_pHead;
  25. s_pHead = this;
  26. }
  27. //------------------------------------------------------------------------------
  28. // CScreenSpaceEffectManager - Implementation of IScreenSpaceEffectManager
  29. //------------------------------------------------------------------------------
  30. class CScreenSpaceEffectManager : public IScreenSpaceEffectManager
  31. {
  32. public:
  33. virtual void InitScreenSpaceEffects( );
  34. virtual void ShutdownScreenSpaceEffects( );
  35. virtual IScreenSpaceEffect *GetScreenSpaceEffect( const char *pEffectName );
  36. virtual void SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params );
  37. virtual void SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params );
  38. virtual void EnableScreenSpaceEffect( const char *pEffectName );
  39. virtual void EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
  40. virtual void DisableScreenSpaceEffect( const char *pEffectName );
  41. virtual void DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect );
  42. virtual void DisableAllScreenSpaceEffects( );
  43. virtual void RenderEffects( int x, int y, int w, int h );
  44. };
  45. CScreenSpaceEffectManager g_ScreenSpaceEffectManager;
  46. IScreenSpaceEffectManager *g_pScreenSpaceEffects = &g_ScreenSpaceEffectManager;
  47. //---------------------------------------------------------------------------------------
  48. // CScreenSpaceEffectManager::InitScreenSpaceEffects - Initialise all registered effects
  49. //---------------------------------------------------------------------------------------
  50. void CScreenSpaceEffectManager::InitScreenSpaceEffects( )
  51. {
  52. if ( CommandLine()->FindParm( "-filmgrain" ) )
  53. {
  54. GetScreenSpaceEffect( "filmgrain" )->Enable( true );
  55. }
  56. for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
  57. {
  58. IScreenSpaceEffect *pEffect = pReg->m_pEffect;
  59. if( pEffect )
  60. {
  61. bool bIsEnabled = pEffect->IsEnabled( );
  62. pEffect->Init( );
  63. pEffect->Enable( bIsEnabled );
  64. }
  65. }
  66. }
  67. //----------------------------------------------------------------------------------------
  68. // CScreenSpaceEffectManager::ShutdownScreenSpaceEffects - Shutdown all registered effects
  69. //----------------------------------------------------------------------------------------
  70. void CScreenSpaceEffectManager::ShutdownScreenSpaceEffects( )
  71. {
  72. for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
  73. {
  74. IScreenSpaceEffect *pEffect = pReg->m_pEffect;
  75. if( pEffect )
  76. {
  77. pEffect->Shutdown( );
  78. }
  79. }
  80. }
  81. //---------------------------------------------------------------------------------------
  82. // CScreenSpaceEffectManager::GetScreenSpaceEffect - Returns a point to the named effect
  83. //---------------------------------------------------------------------------------------
  84. IScreenSpaceEffect *CScreenSpaceEffectManager::GetScreenSpaceEffect( const char *pEffectName )
  85. {
  86. for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
  87. {
  88. if( !Q_stricmp( pReg->m_pEffectName, pEffectName ) )
  89. {
  90. IScreenSpaceEffect *pEffect = pReg->m_pEffect;
  91. return pEffect;
  92. }
  93. }
  94. Warning( "Could not find screen space effect %s\n", pEffectName );
  95. return NULL;
  96. }
  97. //---------------------------------------------------------------------------------------
  98. // CScreenSpaceEffectManager::SetScreenSpaceEffectParams
  99. // - Assign parameters to the specified effect
  100. //---------------------------------------------------------------------------------------
  101. void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( const char *pEffectName, KeyValues *params )
  102. {
  103. IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
  104. if( pEffect )
  105. SetScreenSpaceEffectParams( pEffect, params );
  106. }
  107. void CScreenSpaceEffectManager::SetScreenSpaceEffectParams( IScreenSpaceEffect *pEffect, KeyValues *params )
  108. {
  109. if( pEffect )
  110. pEffect->SetParameters( params );
  111. }
  112. //---------------------------------------------------------------------------------------
  113. // CScreenSpaceEffectManager::EnableScreenSpaceEffect
  114. // - Enables the specified effect
  115. //---------------------------------------------------------------------------------------
  116. void CScreenSpaceEffectManager::EnableScreenSpaceEffect( const char *pEffectName )
  117. {
  118. IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
  119. if( pEffect )
  120. EnableScreenSpaceEffect( pEffect );
  121. }
  122. void CScreenSpaceEffectManager::EnableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
  123. {
  124. if( pEffect )
  125. pEffect->Enable( true );
  126. }
  127. //---------------------------------------------------------------------------------------
  128. // CScreenSpaceEffectManager::DisableScreenSpaceEffect
  129. // - Disables the specified effect
  130. //---------------------------------------------------------------------------------------
  131. void CScreenSpaceEffectManager::DisableScreenSpaceEffect( const char *pEffectName )
  132. {
  133. IScreenSpaceEffect *pEffect = GetScreenSpaceEffect( pEffectName );
  134. if( pEffect )
  135. DisableScreenSpaceEffect( pEffect );
  136. }
  137. void CScreenSpaceEffectManager::DisableScreenSpaceEffect( IScreenSpaceEffect *pEffect )
  138. {
  139. if( pEffect )
  140. pEffect->Enable( false );
  141. }
  142. //---------------------------------------------------------------------------------------
  143. // CScreenSpaceEffectManager::DisableAllScreenSpaceEffects
  144. // - Disables all registered screen space effects
  145. //---------------------------------------------------------------------------------------
  146. void CScreenSpaceEffectManager::DisableAllScreenSpaceEffects( )
  147. {
  148. for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
  149. {
  150. IScreenSpaceEffect *pEffect = pReg->m_pEffect;
  151. if( pEffect )
  152. {
  153. pEffect->Enable( false );
  154. }
  155. }
  156. }
  157. //---------------------------------------------------------------------------------------
  158. // CScreenSpaceEffectManager::RenderEffects
  159. // - Renders all registered screen space effects
  160. //---------------------------------------------------------------------------------------
  161. void CScreenSpaceEffectManager::RenderEffects( int x, int y, int w, int h )
  162. {
  163. for( CScreenSpaceEffectRegistration *pReg=CScreenSpaceEffectRegistration::s_pHead; pReg!=NULL; pReg=pReg->m_pNext )
  164. {
  165. IScreenSpaceEffect *pEffect = pReg->m_pEffect;
  166. if( pEffect )
  167. {
  168. pEffect->Render( x, y, w, h );
  169. }
  170. }
  171. }
  172. //------------------------------------------------------------------------------
  173. // Example post-processing effect
  174. //------------------------------------------------------------------------------
  175. class CExampleEffect : public IScreenSpaceEffect
  176. {
  177. public:
  178. CExampleEffect( );
  179. ~CExampleEffect( );
  180. void Init( );
  181. void Shutdown( );
  182. void SetParameters( KeyValues *params );
  183. void Render( int x, int y, int w, int h );
  184. void Enable( bool bEnable );
  185. bool IsEnabled( );
  186. private:
  187. bool m_bEnable;
  188. CMaterialReference m_Material;
  189. };
  190. ADD_SCREENSPACE_EFFECT( CExampleEffect, exampleeffect );
  191. //------------------------------------------------------------------------------
  192. // CExampleEffect constructor
  193. //------------------------------------------------------------------------------
  194. CExampleEffect::CExampleEffect( )
  195. {
  196. m_bEnable = false;
  197. }
  198. //------------------------------------------------------------------------------
  199. // CExampleEffect destructor
  200. //------------------------------------------------------------------------------
  201. CExampleEffect::~CExampleEffect( )
  202. {
  203. }
  204. //------------------------------------------------------------------------------
  205. // CExampleEffect init
  206. //------------------------------------------------------------------------------
  207. void CExampleEffect::Init( )
  208. {
  209. // This is just example code, init your effect material here
  210. //m_Material.Init( "engine/exampleeffect", TEXTURE_GROUP_OTHER );
  211. m_bEnable = false;
  212. }
  213. //------------------------------------------------------------------------------
  214. // CExampleEffect shutdown
  215. //------------------------------------------------------------------------------
  216. void CExampleEffect::Shutdown( )
  217. {
  218. m_Material.Shutdown();
  219. }
  220. //------------------------------------------------------------------------------
  221. // CExampleEffect enable
  222. //------------------------------------------------------------------------------
  223. void CExampleEffect::Enable( bool bEnable )
  224. {
  225. // This is just example code, don't enable it
  226. // m_bEnable = bEnable;
  227. }
  228. bool CExampleEffect::IsEnabled( )
  229. {
  230. return m_bEnable;
  231. }
  232. //------------------------------------------------------------------------------
  233. // CExampleEffect SetParameters
  234. //------------------------------------------------------------------------------
  235. void CExampleEffect::SetParameters( KeyValues *params )
  236. {
  237. if( params->GetDataType( "example_param" ) == KeyValues::TYPE_STRING )
  238. {
  239. // ...
  240. }
  241. }
  242. //------------------------------------------------------------------------------
  243. // CExampleEffect render
  244. //------------------------------------------------------------------------------
  245. void CExampleEffect::Render( int x, int y, int w, int h )
  246. {
  247. if ( !IsEnabled() )
  248. return;
  249. // Render Effect
  250. Rect_t actualRect;
  251. UpdateScreenEffectTexture( 0, x, y, w, h, false, &actualRect );
  252. ITexture *pTexture = GetFullFrameFrameBufferTexture( 0 );
  253. CMatRenderContextPtr pRenderContext( materials );
  254. pRenderContext->DrawScreenSpaceRectangle( m_Material, x, y, w, h,
  255. actualRect.x, actualRect.y, actualRect.x+actualRect.width-1, actualRect.y+actualRect.height-1,
  256. pTexture->GetActualWidth(), pTexture->GetActualHeight() );
  257. }