//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //===========================================================================// #ifndef C_FUNC_LIQUIDPORTAL_H #define C_FUNC_LIQUIDPORTAL_H #ifdef _WIN32 #pragma once #endif #include "c_baseentity.h" #include "PortalRender.h" #include "Portal_DynamicMeshRenderingUtils.h" #include "ScreenSpaceEffects.h" class CPortalRenderable_Func_LiquidPortal : public CPortalRenderable { public: virtual void DrawPreStencilMask( void ); virtual void DrawStencilMask( void ); virtual void DrawPostStencilFixes( void ); virtual void RenderPortalViewToBackBuffer( CViewRender *pViewRender, const CViewSetup &cameraView ); virtual void RenderPortalViewToTexture( CViewRender *pViewRender, const CViewSetup &cameraView ); void AddToVisAsExitPortal( ViewCustomVisibility_t *pCustomVisibility ); virtual bool DoesExitViewIntersectWaterPlane( float waterZ, int leafWaterDataID ) const; virtual SkyboxVisibility_t SkyBoxVisibleFromPortal( void ); bool CalcFrustumThroughPortal( const Vector &ptCurrentViewOrigin, Frustum OutputFrustum, const VPlane *pInputFrustum = NULL, int iInputFrustumPlaneCount = 0 ); virtual const Vector& GetFogOrigin( void ) const; virtual void ShiftFogForExitPortalView() const; virtual bool ShouldUpdatePortalView_BasedOnView( const CViewSetup ¤tView, Frustum currentFrustum ); //portal is both visible, and will display at least some portion of a remote view virtual CPortalRenderable* GetLinkedPortal() const; virtual bool ShouldUpdateDepthDoublerTexture( const CViewSetup &viewSetup ); virtual void DrawPortal( void ); //sort of like what you'd expect to happen in C_BaseAnimating::DrawModel() if portals were fully compatible with models virtual void GetToolRecordingState( bool bActive, KeyValues *msg ); virtual void HandlePortalPlaybackMessage( KeyValues *pKeyValues ); void DrawOutwardBox( const IMaterial *pMaterial = NULL ); void DrawInwardBox( const IMaterial *pMaterial = NULL ); void DrawInnerLiquid( bool bClipToBounds = true, float fOpacity = 1.0f, const IMaterial *pMaterial = NULL ); //quads in front of camera clipped to box dimensions float GetFillInterpolationAmount( void ); bool IsFillingNow( void ); void UpdateBoundingPlanes( void ); float m_fFillStartTime; float m_fFillEndTime; Vector m_vAABBMins; Vector m_vAABBMaxs; float m_fBoundingPlanes[5][4]; //top is highly variable and therefore not actually stored CPortalRenderable_Func_LiquidPortal *m_pLinkedPortal; }; inline float CPortalRenderable_Func_LiquidPortal::GetFillInterpolationAmount( void ) { if( m_fFillEndTime < gpGlobals->curtime ) return 0.0f; return ((gpGlobals->curtime - m_fFillStartTime) / (m_fFillEndTime - m_fFillStartTime)); } inline bool CPortalRenderable_Func_LiquidPortal::IsFillingNow( void ) { return ((m_fFillEndTime >= gpGlobals->curtime) && (m_fFillStartTime <= gpGlobals->curtime)); } class C_Func_LiquidPortal : public C_BaseEntity, public CPortalRenderable_Func_LiquidPortal { public: DECLARE_CLASS( C_Func_LiquidPortal, C_BaseEntity ); DECLARE_CLIENTCLASS(); C_Func_LiquidPortal( void ); ~C_Func_LiquidPortal( void ); virtual bool IsTransparent( void ) { return true; }; virtual bool UsesPowerOfTwoFrameBufferTexture() { return true; }; virtual int DrawModel( int flags ); void ComputeLinkMatrix( void ); virtual void OnDataChanged( DataUpdateType_t updateType ); CHandle m_hLinkedPortal; }; class CLiquidPortal_InnerLiquidEffect : public IScreenSpaceEffect { public: CLiquidPortal_InnerLiquidEffect( void ); void Init( void ) { }; void Shutdown( void ) { }; void SetParameters( KeyValues *params ); void Render( int x, int y, int w, int h ); void Enable( bool bEnable ) { m_bEnable = bEnable; }; bool IsEnabled( void ) { return m_bEnable; }; private: bool m_bEnable; public: C_Func_LiquidPortal* m_pImmersionPortal; //portal that did the filling + teleporting bool m_bFadeBackToReality; float m_fFadeBackTimeLeft; static const float s_fFadeBackEffectTime; //how long the effect should take }; #endif //#ifndef C_FUNC_LIQUIDPORTAL_H