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.

528 lines
17 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #if !defined( VIEWRENDER_H )
  7. #define VIEWRENDER_H
  8. #ifdef _WIN32
  9. #pragma once
  10. #endif
  11. #include "shareddefs.h"
  12. #include "tier1/utlstack.h"
  13. #include "iviewrender.h"
  14. #include "view_shared.h"
  15. #include "replay/ireplayscreenshotsystem.h"
  16. //-----------------------------------------------------------------------------
  17. // Forward declarations
  18. //-----------------------------------------------------------------------------
  19. class ConVar;
  20. class CClientRenderablesList;
  21. class IClientVehicle;
  22. class C_PointCamera;
  23. class C_EnvProjectedTexture;
  24. class IScreenSpaceEffect;
  25. class CClientViewSetup;
  26. class CViewRender;
  27. struct ClientWorldListInfo_t;
  28. class C_BaseEntity;
  29. struct WriteReplayScreenshotParams_t;
  30. class CReplayScreenshotTaker;
  31. #ifdef HL2_EPISODIC
  32. class CStunEffect;
  33. #endif // HL2_EPISODIC
  34. //-----------------------------------------------------------------------------
  35. // Data specific to intro mode to control rendering.
  36. //-----------------------------------------------------------------------------
  37. struct IntroDataBlendPass_t
  38. {
  39. int m_BlendMode;
  40. float m_Alpha; // in [0.0f,1.0f] This needs to add up to 1.0 for all passes, unless you are fading out.
  41. };
  42. struct IntroData_t
  43. {
  44. bool m_bDrawPrimary;
  45. Vector m_vecCameraView;
  46. QAngle m_vecCameraViewAngles;
  47. float m_playerViewFOV;
  48. CUtlVector<IntroDataBlendPass_t> m_Passes;
  49. // Fade overriding for the intro
  50. float m_flCurrentFadeColor[4];
  51. };
  52. // Robin, make this point at something to get intro mode.
  53. extern IntroData_t *g_pIntroData;
  54. // This identifies the view for certain systems that are unique per view (e.g. pixel visibility)
  55. // NOTE: This is identifying which logical part of the scene an entity is being redered in
  56. // This is not identifying a particular render target necessarily. This is mostly needed for entities that
  57. // can be rendered more than once per frame (pixel vis queries need to be identified per-render call)
  58. enum view_id_t
  59. {
  60. VIEW_ILLEGAL = -2,
  61. VIEW_NONE = -1,
  62. VIEW_MAIN = 0,
  63. VIEW_3DSKY = 1,
  64. VIEW_MONITOR = 2,
  65. VIEW_REFLECTION = 3,
  66. VIEW_REFRACTION = 4,
  67. VIEW_INTRO_PLAYER = 5,
  68. VIEW_INTRO_CAMERA = 6,
  69. VIEW_SHADOW_DEPTH_TEXTURE = 7,
  70. VIEW_SSAO = 8,
  71. VIEW_ID_COUNT
  72. };
  73. view_id_t CurrentViewID();
  74. //-----------------------------------------------------------------------------
  75. // Purpose: Stored pitch drifting variables
  76. //-----------------------------------------------------------------------------
  77. class CPitchDrift
  78. {
  79. public:
  80. float pitchvel;
  81. bool nodrift;
  82. float driftmove;
  83. double laststop;
  84. };
  85. //-----------------------------------------------------------------------------
  86. //
  87. //-----------------------------------------------------------------------------
  88. struct ViewCustomVisibility_t
  89. {
  90. ViewCustomVisibility_t()
  91. {
  92. m_nNumVisOrigins = 0;
  93. m_VisData.m_fDistToAreaPortalTolerance = FLT_MAX;
  94. m_iForceViewLeaf = -1;
  95. }
  96. void AddVisOrigin( const Vector& origin )
  97. {
  98. // Don't allow them to write past array length
  99. AssertMsg( m_nNumVisOrigins < MAX_VIS_LEAVES, "Added more origins than will fit in the array!" );
  100. // If the vis origin count is greater than the size of our array, just fail to add this origin
  101. if ( m_nNumVisOrigins >= MAX_VIS_LEAVES )
  102. return;
  103. m_rgVisOrigins[ m_nNumVisOrigins++ ] = origin;
  104. }
  105. void ForceVisOverride( VisOverrideData_t& visData )
  106. {
  107. m_VisData = visData;
  108. }
  109. void ForceViewLeaf ( int iViewLeaf )
  110. {
  111. m_iForceViewLeaf = iViewLeaf;
  112. }
  113. // Set to true if you want to use multiple origins for doing client side map vis culling
  114. // NOTE: In generaly, you won't want to do this, and by default the 3d origin of the camera, as above,
  115. // will be used as the origin for vis, too.
  116. int m_nNumVisOrigins;
  117. // Array of origins
  118. Vector m_rgVisOrigins[ MAX_VIS_LEAVES ];
  119. // The view data overrides for visibility calculations with area portals
  120. VisOverrideData_t m_VisData;
  121. // The starting leaf to determing which area to start in when performing area portal culling on the engine
  122. // Default behavior is to use the leaf the camera position is in.
  123. int m_iForceViewLeaf;
  124. };
  125. //-----------------------------------------------------------------------------
  126. //
  127. //-----------------------------------------------------------------------------
  128. struct WaterRenderInfo_t
  129. {
  130. bool m_bCheapWater : 1;
  131. bool m_bReflect : 1;
  132. bool m_bRefract : 1;
  133. bool m_bReflectEntities : 1;
  134. bool m_bDrawWaterSurface : 1;
  135. bool m_bOpaqueWater : 1;
  136. };
  137. //-----------------------------------------------------------------------------
  138. //
  139. //-----------------------------------------------------------------------------
  140. class CBase3dView : public CRefCounted<>,
  141. protected CViewSetup
  142. {
  143. DECLARE_CLASS_NOBASE( CBase3dView );
  144. public:
  145. CBase3dView( CViewRender *pMainView );
  146. VPlane * GetFrustum();
  147. virtual int GetDrawFlags() { return 0; }
  148. #ifdef PORTAL
  149. virtual void EnableWorldFog() {};
  150. #endif
  151. protected:
  152. // @MULTICORE (toml 8/11/2006): need to have per-view frustum. Change when move view stack to client
  153. VPlane *m_Frustum;
  154. CViewRender *m_pMainView;
  155. };
  156. //-----------------------------------------------------------------------------
  157. // Base class for 3d views
  158. //-----------------------------------------------------------------------------
  159. class CRendering3dView : public CBase3dView
  160. {
  161. DECLARE_CLASS( CRendering3dView, CBase3dView );
  162. public:
  163. CRendering3dView( CViewRender *pMainView );
  164. virtual ~CRendering3dView() { ReleaseLists(); }
  165. void Setup( const CViewSetup &setup );
  166. // What are we currently rendering? Returns a combination of DF_ flags.
  167. virtual int GetDrawFlags();
  168. virtual void Draw() {};
  169. protected:
  170. // Fog setup
  171. void EnableWorldFog( void );
  172. void SetFogVolumeState( const VisibleFogVolumeInfo_t &fogInfo, bool bUseHeightFog );
  173. // Draw setup
  174. void SetupRenderablesList( int viewID );
  175. void UpdateRenderablesOpacity();
  176. // If iForceViewLeaf is not -1, then it uses the specified leaf as your starting area for setting up area portal culling.
  177. // This is used by water since your reflected view origin is often in solid space, but we still want to treat it as though
  178. // the first portal we're looking out of is a water portal, so our view effectively originates under the water.
  179. void BuildWorldRenderLists( bool bDrawEntities, int iForceViewLeaf = -1, bool bUseCacheIfEnabled = true, bool bShadowDepth = false, float *pReflectionWaterHeight = NULL );
  180. // Purpose: Builds render lists for renderables. Called once for refraction, once for over water
  181. void BuildRenderableRenderLists( int viewID );
  182. // More concise version of the above BuildRenderableRenderLists(). Called for shadow depth map rendering
  183. void BuildShadowDepthRenderableRenderLists();
  184. void DrawWorld( float waterZAdjust );
  185. // Draws all opaque/translucent renderables in leaves that were rendered
  186. void DrawOpaqueRenderables( ERenderDepthMode DepthMode );
  187. void DrawTranslucentRenderables( bool bInSkybox, bool bShadowDepth );
  188. // Renders all translucent entities in the render list
  189. void DrawTranslucentRenderablesNoWorld( bool bInSkybox );
  190. // Draws translucent renderables that ignore the Z buffer
  191. void DrawNoZBufferTranslucentRenderables( void );
  192. // Renders all translucent world surfaces in a particular set of leaves
  193. void DrawTranslucentWorldInLeaves( bool bShadowDepth );
  194. // Renders all translucent world + detail objects in a particular set of leaves
  195. void DrawTranslucentWorldAndDetailPropsInLeaves( int iCurLeaf, int iFinalLeaf, int nEngineDrawFlags, int &nDetailLeafCount, LeafIndex_t* pDetailLeafList, bool bShadowDepth );
  196. // Purpose: Computes the actual world list info based on the render flags
  197. void PruneWorldListInfo();
  198. #ifdef PORTAL
  199. virtual bool ShouldDrawPortals() { return true; }
  200. #endif
  201. void ReleaseLists();
  202. //-----------------------------------------------
  203. // Combination of DF_ flags.
  204. int m_DrawFlags;
  205. int m_ClearFlags;
  206. IWorldRenderList *m_pWorldRenderList;
  207. CClientRenderablesList *m_pRenderablesList;
  208. ClientWorldListInfo_t *m_pWorldListInfo;
  209. ViewCustomVisibility_t *m_pCustomVisibility;
  210. };
  211. //-----------------------------------------------------------------------------
  212. //
  213. //-----------------------------------------------------------------------------
  214. class CRenderExecutor
  215. {
  216. DECLARE_CLASS_NOBASE( CRenderExecutor );
  217. public:
  218. virtual void AddView( CRendering3dView *pView ) = 0;
  219. virtual void Execute() = 0;
  220. protected:
  221. CRenderExecutor( CViewRender *pMainView ) : m_pMainView( pMainView ) {}
  222. CViewRender *m_pMainView;
  223. };
  224. //-----------------------------------------------------------------------------
  225. //
  226. //-----------------------------------------------------------------------------
  227. class CSimpleRenderExecutor : public CRenderExecutor
  228. {
  229. DECLARE_CLASS( CSimpleRenderExecutor, CRenderExecutor );
  230. public:
  231. CSimpleRenderExecutor( CViewRender *pMainView ) : CRenderExecutor( pMainView ) {}
  232. void AddView( CRendering3dView *pView );
  233. void Execute() {}
  234. };
  235. //-----------------------------------------------------------------------------
  236. // Purpose: Implements the interface to view rendering for the client .dll
  237. //-----------------------------------------------------------------------------
  238. class CViewRender : public IViewRender,
  239. public IReplayScreenshotSystem
  240. {
  241. DECLARE_CLASS_NOBASE( CViewRender );
  242. public:
  243. virtual void Init( void );
  244. virtual void Shutdown( void );
  245. const CViewSetup *GetPlayerViewSetup( ) const;
  246. virtual void StartPitchDrift( void );
  247. virtual void StopPitchDrift( void );
  248. virtual float GetZNear();
  249. virtual float GetZFar();
  250. virtual void OnRenderStart();
  251. void DriftPitch (void);
  252. static CViewRender * GetMainView() { return assert_cast<CViewRender *>( view ); }
  253. void AddViewToScene( CRendering3dView *pView ) { m_SimpleExecutor.AddView( pView ); }
  254. protected:
  255. // Sets up the view parameters for all views (left, middle and right eyes).
  256. void SetUpViews();
  257. // Sets up the view parameters of map overview mode (cl_leveloverview)
  258. void SetUpOverView();
  259. // generates a low-res screenshot for save games
  260. virtual void WriteSaveGameScreenshotOfSize( const char *pFilename, int width, int height, bool bCreatePowerOf2Padded = false, bool bWriteVTF = false );
  261. void WriteSaveGameScreenshot( const char *filename );
  262. virtual IReplayScreenshotSystem *GetReplayScreenshotSystem() { return this; }
  263. // IReplayScreenshot implementation
  264. virtual void WriteReplayScreenshot( WriteReplayScreenshotParams_t &params );
  265. virtual void UpdateReplayScreenshotCache();
  266. StereoEye_t GetFirstEye() const;
  267. StereoEye_t GetLastEye() const;
  268. CViewSetup & GetView(StereoEye_t eEye);
  269. const CViewSetup & GetView(StereoEye_t eEye) const ;
  270. // This stores all of the view setup parameters that the engine needs to know about.
  271. // Best way to pick the right one is with ::GetView(), rather than directly.
  272. CViewSetup m_View; // mono <- in stereo mode, this will be between the two eyes and is the "main" view.
  273. CViewSetup m_ViewLeft; // left (unused for mono)
  274. CViewSetup m_ViewRight; // right (unused for mono)
  275. // Pitch drifting data
  276. CPitchDrift m_PitchDrift;
  277. public:
  278. CViewRender();
  279. virtual ~CViewRender( void ) {}
  280. // Implementation of IViewRender interface
  281. public:
  282. void SetupVis( const CViewSetup& view, unsigned int &visFlags, ViewCustomVisibility_t *pCustomVisibility = NULL );
  283. // Render functions
  284. virtual void Render( vrect_t *rect );
  285. virtual void RenderView( const CViewSetup &view, int nClearFlags, int whatToDraw );
  286. virtual void RenderPlayerSprites();
  287. virtual void Render2DEffectsPreHUD( const CViewSetup &view );
  288. virtual void Render2DEffectsPostHUD( const CViewSetup &view );
  289. void DisableFog( void );
  290. // Called once per level change
  291. void LevelInit( void );
  292. void LevelShutdown( void );
  293. // Add entity to transparent entity queue
  294. bool ShouldDrawEntities( void );
  295. bool ShouldDrawBrushModels( void );
  296. const CViewSetup *GetViewSetup( ) const;
  297. void DisableVis( void );
  298. // Sets up the view model position relative to the local player
  299. void MoveViewModels( );
  300. // Gets the abs origin + angles of the view models
  301. void GetViewModelPosition( int nIndex, Vector *pPos, QAngle *pAngle );
  302. void SetCheapWaterStartDistance( float flCheapWaterStartDistance );
  303. void SetCheapWaterEndDistance( float flCheapWaterEndDistance );
  304. void GetWaterLODParams( float &flCheapWaterStartDistance, float &flCheapWaterEndDistance );
  305. virtual void QueueOverlayRenderView( const CViewSetup &view, int nClearFlags, int whatToDraw );
  306. virtual void GetScreenFadeDistances( float *min, float *max );
  307. virtual C_BaseEntity *GetCurrentlyDrawingEntity();
  308. virtual void SetCurrentlyDrawingEntity( C_BaseEntity *pEnt );
  309. virtual bool UpdateShadowDepthTexture( ITexture *pRenderTarget, ITexture *pDepthTexture, const CViewSetup &shadowView );
  310. int GetBaseDrawFlags() { return m_BaseDrawFlags; }
  311. virtual bool ShouldForceNoVis() { return m_bForceNoVis; }
  312. int BuildRenderablesListsNumber() const { return m_BuildRenderableListsNumber; }
  313. int IncRenderablesListsNumber() { return ++m_BuildRenderableListsNumber; }
  314. int BuildWorldListsNumber() const;
  315. int IncWorldListsNumber() { return ++m_BuildWorldListsNumber; }
  316. virtual VPlane* GetFrustum() { return ( m_pActiveRenderer ) ? m_pActiveRenderer->GetFrustum() : m_Frustum; }
  317. // What are we currently rendering? Returns a combination of DF_ flags.
  318. virtual int GetDrawFlags() { return ( m_pActiveRenderer ) ? m_pActiveRenderer->GetDrawFlags() : 0; }
  319. CBase3dView * GetActiveRenderer() { return m_pActiveRenderer; }
  320. CBase3dView * SetActiveRenderer( CBase3dView *pActiveRenderer ) { CBase3dView *pPrevious = m_pActiveRenderer; m_pActiveRenderer = pActiveRenderer; return pPrevious; }
  321. void FreezeFrame( float flFreezeTime );
  322. void SetWaterOverlayMaterial( IMaterial *pMaterial )
  323. {
  324. m_UnderWaterOverlayMaterial.Init( pMaterial );
  325. }
  326. private:
  327. int m_BuildWorldListsNumber;
  328. // General draw methods
  329. // baseDrawFlags is a combination of DF_ defines. DF_MONITOR is passed into here while drawing a monitor.
  330. void ViewDrawScene( bool bDrew3dSkybox, SkyboxVisibility_t nSkyboxVisible, const CViewSetup &view, int nClearFlags, view_id_t viewID, bool bDrawViewModel = false, int baseDrawFlags = 0, ViewCustomVisibility_t *pCustomVisibility = NULL );
  331. void DrawMonitors( const CViewSetup &cameraView );
  332. bool DrawOneMonitor( ITexture *pRenderTarget, int cameraNum, C_PointCamera *pCameraEnt, const CViewSetup &cameraView, C_BasePlayer *localPlayer,
  333. int x, int y, int width, int height );
  334. // Drawing primitives
  335. bool ShouldDrawViewModel( bool drawViewmodel );
  336. void DrawViewModels( const CViewSetup &view, bool drawViewmodel );
  337. void PerformScreenSpaceEffects( int x, int y, int w, int h );
  338. // Overlays
  339. void SetScreenOverlayMaterial( IMaterial *pMaterial );
  340. IMaterial *GetScreenOverlayMaterial( );
  341. void PerformScreenOverlay( int x, int y, int w, int h );
  342. void DrawUnderwaterOverlay( void );
  343. // Water-related methods
  344. void DrawWorldAndEntities( bool drawSkybox, const CViewSetup &view, int nClearFlags, ViewCustomVisibility_t *pCustomVisibility = NULL );
  345. virtual void ViewDrawScene_Intro( const CViewSetup &view, int nClearFlags, const IntroData_t &introData );
  346. #ifdef PORTAL
  347. // Intended for use in the middle of another ViewDrawScene call, this allows stencils to be drawn after opaques but before translucents are drawn in the main view.
  348. void ViewDrawScene_PortalStencil( const CViewSetup &view, ViewCustomVisibility_t *pCustomVisibility );
  349. void Draw3dSkyboxworld_Portal( const CViewSetup &view, int &nClearFlags, bool &bDrew3dSkybox, SkyboxVisibility_t &nSkyboxVisible, ITexture *pRenderTarget = NULL );
  350. #endif // PORTAL
  351. // Determines what kind of water we're going to use
  352. void DetermineWaterRenderInfo( const VisibleFogVolumeInfo_t &fogVolumeInfo, WaterRenderInfo_t &info );
  353. bool UpdateRefractIfNeededByList( CUtlVector< IClientRenderable * > &list );
  354. void DrawRenderablesInList( CUtlVector< IClientRenderable * > &list, int flags = 0 );
  355. // Sets up, cleans up the main 3D view
  356. void SetupMain3DView( const CViewSetup &view, int &nClearFlags );
  357. void CleanupMain3DView( const CViewSetup &view );
  358. // This stores the current view
  359. CViewSetup m_CurrentView;
  360. // VIS Overrides
  361. // Set to true to turn off client side vis ( !!!! rendering will be slow since everything will draw )
  362. bool m_bForceNoVis;
  363. // Some cvars needed by this system
  364. const ConVar *m_pDrawEntities;
  365. const ConVar *m_pDrawBrushModels;
  366. // Some materials used...
  367. CMaterialReference m_TranslucentSingleColor;
  368. CMaterialReference m_ModulateSingleColor;
  369. CMaterialReference m_ScreenOverlayMaterial;
  370. CMaterialReference m_UnderWaterOverlayMaterial;
  371. Vector m_vecLastFacing;
  372. float m_flCheapWaterStartDistance;
  373. float m_flCheapWaterEndDistance;
  374. CViewSetup m_OverlayViewSetup;
  375. int m_OverlayClearFlags;
  376. int m_OverlayDrawFlags;
  377. bool m_bDrawOverlay;
  378. int m_BaseDrawFlags; // Set in ViewDrawScene and OR'd into m_DrawFlags as it goes.
  379. C_BaseEntity *m_pCurrentlyDrawingEntity;
  380. #if defined( CSTRIKE_DLL )
  381. float m_flLastFOV;
  382. #endif
  383. #ifdef PORTAL
  384. friend class CPortalRender; //portal drawing needs muck with views in weird ways
  385. friend class CPortalRenderable;
  386. #endif
  387. int m_BuildRenderableListsNumber;
  388. friend class CBase3dView;
  389. Frustum m_Frustum;
  390. CBase3dView *m_pActiveRenderer;
  391. CSimpleRenderExecutor m_SimpleExecutor;
  392. bool m_rbTakeFreezeFrame[ STEREO_EYE_MAX ];
  393. float m_flFreezeFrameUntil;
  394. #if defined( REPLAY_ENABLED )
  395. CReplayScreenshotTaker *m_pReplayScreenshotTaker;
  396. #endif
  397. };
  398. #endif // VIEWRENDER_H