diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/client/portal/c_func_liquidportal.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/client/portal/c_func_liquidportal.cpp')
| -rw-r--r-- | game/client/portal/c_func_liquidportal.cpp | 630 |
1 files changed, 630 insertions, 0 deletions
diff --git a/game/client/portal/c_func_liquidportal.cpp b/game/client/portal/c_func_liquidportal.cpp new file mode 100644 index 0000000..9365102 --- /dev/null +++ b/game/client/portal/c_func_liquidportal.cpp @@ -0,0 +1,630 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: Rising liquid that acts as a one-way portal +// +// $NoKeywords: $ +//=============================================================================// + +#include "cbase.h" +#include "c_func_liquidportal.h" +#include "debugoverlay_shared.h" +#include "view_scene.h" +#include "view.h" +#include "ScreenSpaceEffects.h" +#include "materialsystem/imaterialvar.h" + + +LINK_ENTITY_TO_CLASS( func_liquidportal, C_Func_LiquidPortal ); + +IMPLEMENT_CLIENTCLASS_DT( C_Func_LiquidPortal, DT_Func_LiquidPortal, CFunc_LiquidPortal ) + RecvPropEHandle( RECVINFO(m_hLinkedPortal) ), + RecvPropFloat( RECVINFO(m_fFillStartTime) ), + RecvPropFloat( RECVINFO(m_fFillEndTime) ), +END_RECV_TABLE() + + +#define LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( vertnum, xtexbase, xtexscale, ytexbase, ytexscale )\ + meshBuilder.Position3fv( &vVertices[vertnum].x );\ + meshBuilder.TexCoord2f( 0, vVertices[vertnum].xtexbase * xtexscale, vVertices[vertnum].ytexbase * ytexscale );\ + meshBuilder.AdvanceVertex(); + + +C_Func_LiquidPortal::C_Func_LiquidPortal( void ) +{ + g_pPortalRender->AddPortal( this ); +} + +C_Func_LiquidPortal::~C_Func_LiquidPortal( void ) +{ + g_pPortalRender->RemovePortal( this ); +} + + +int C_Func_LiquidPortal::DrawModel( int flags ) +{ + if( IsFillingNow() ) + { + DrawPortal(); + return 1; + } + + return 0; +} + +void C_Func_LiquidPortal::OnDataChanged( DataUpdateType_t updateType ) +{ + GetRenderBoundsWorldspace( m_vAABBMins, m_vAABBMaxs ); + m_pLinkedPortal = m_hLinkedPortal.Get(); + ComputeLinkMatrix(); + UpdateBoundingPlanes(); +} + +void C_Func_LiquidPortal::ComputeLinkMatrix( void ) +{ + C_Func_LiquidPortal *pLinkedPortal = m_hLinkedPortal.Get(); + if( pLinkedPortal ) + { + VMatrix matLocalToWorld, matLocalToWorldInv, matRemoteToWorld; + + //matLocalToWorld.Identity(); + //matLocalToWorld.SetTranslation( CollisionProp()->WorldSpaceCenter() ); + matLocalToWorld = EntityToWorldTransform(); + + //matRemoteToWorld.Identity(); + //matRemoteToWorld.SetTranslation( pLinkedPortal->CollisionProp()->WorldSpaceCenter() ); + matRemoteToWorld = pLinkedPortal->EntityToWorldTransform(); + + MatrixInverseTR( matLocalToWorld, matLocalToWorldInv ); + m_matrixThisToLinked = matRemoteToWorld * matLocalToWorldInv; + + MatrixInverseTR( m_matrixThisToLinked, pLinkedPortal->m_matrixThisToLinked ); + } + else + { + m_matrixThisToLinked.Identity(); + } +} + + + + +void CPortalRenderable_Func_LiquidPortal::UpdateBoundingPlanes( void ) +{ + //x min + m_fBoundingPlanes[0][0] = 1.0f; + m_fBoundingPlanes[0][1] = 0.0f; + m_fBoundingPlanes[0][2] = 0.0f; + m_fBoundingPlanes[0][3] = m_vAABBMins.x; + + //x max + m_fBoundingPlanes[1][0] = -1.0f; + m_fBoundingPlanes[1][1] = 0.0f; + m_fBoundingPlanes[1][2] = 0.0f; + m_fBoundingPlanes[1][3] = -m_vAABBMaxs.x; + + + //y min + m_fBoundingPlanes[2][0] = 0.0f; + m_fBoundingPlanes[2][1] = 1.0f; + m_fBoundingPlanes[2][2] = 0.0f; + m_fBoundingPlanes[2][3] = m_vAABBMins.y; + + //y max + m_fBoundingPlanes[3][0] = 0.0f; + m_fBoundingPlanes[3][1] = -1.0f; + m_fBoundingPlanes[3][2] = 0.0f; + m_fBoundingPlanes[3][3] = -m_vAABBMaxs.y; + + + //z min + m_fBoundingPlanes[4][0] = 0.0f; + m_fBoundingPlanes[4][1] = 0.0f; + m_fBoundingPlanes[4][2] = 1.0f; + m_fBoundingPlanes[4][3] = m_vAABBMins.z; + + //z max is too variable to store +} + +void CPortalRenderable_Func_LiquidPortal::DrawPreStencilMask( void ) +{ + // Should we do something here like flatbasic? +} + +void CPortalRenderable_Func_LiquidPortal::DrawStencilMask( void ) +{ + DrawOutwardBox( g_pPortalRender->m_MaterialsAccess.m_WriteZ_Model ); + DrawInnerLiquid( true, 1.0f, g_pPortalRender->m_MaterialsAccess.m_WriteZ_Model ); +} + +void CPortalRenderable_Func_LiquidPortal::DrawPostStencilFixes( void ) +{ + DrawOutwardBox( g_pPortalRender->m_MaterialsAccess.m_WriteZ_Model ); + DrawInnerLiquid( true, 1.0f, g_pPortalRender->m_MaterialsAccess.m_WriteZ_Model ); +} + + +void CPortalRenderable_Func_LiquidPortal::RenderPortalViewToBackBuffer( CViewRender *pViewRender, const CViewSetup &cameraView ) +{ + if( m_pLinkedPortal == NULL ) //not linked to any portal + return; + + Frustum FrustumBackup; + memcpy( FrustumBackup, pViewRender->GetFrustum(), sizeof( Frustum ) ); + + Frustum seeThroughFrustum; + bool bUseSeeThroughFrustum; + + if ( g_pPortalRender->GetViewRecursionLevel() == 0 ) + { + bUseSeeThroughFrustum = CalcFrustumThroughPortal( cameraView.origin, seeThroughFrustum, pViewRender->GetFrustum(), FRUSTUM_NUMPLANES ); + } + else + { + bUseSeeThroughFrustum = CalcFrustumThroughPortal( cameraView.origin, seeThroughFrustum ); + } + + Vector vCameraForward; + AngleVectors( cameraView.angles, &vCameraForward, NULL, NULL ); + + // Setup fog state for the camera. + Vector ptPOVOrigin = m_matrixThisToLinked * cameraView.origin; + Vector vPOVForward = m_matrixThisToLinked.ApplyRotation( vCameraForward ); + + CViewSetup portalView = cameraView; + + QAngle qPOVAngles = TransformAnglesToWorldSpace( cameraView.angles, m_matrixThisToLinked.As3x4() ); + + portalView.width = cameraView.width; + portalView.height = cameraView.height; + portalView.x = 0; + portalView.y = 0; + portalView.origin = ptPOVOrigin; + portalView.angles = qPOVAngles; + portalView.fov = cameraView.fov; + portalView.m_bOrtho = false; + portalView.m_flAspectRatio = cameraView.m_flAspectRatio; //use the screen aspect ratio, 0.0f doesn't work as advertised + + CopyToCurrentView( pViewRender, portalView ); + + CMatRenderContextPtr pRenderContext( materials ); + + { + ViewCustomVisibility_t customVisibility; + m_pLinkedPortal->AddToVisAsExitPortal( &customVisibility ); + render->Push3DView( portalView, 0, NULL, pViewRender->GetFrustum() ); + { + if( bUseSeeThroughFrustum) + memcpy( pViewRender->GetFrustum(), seeThroughFrustum, sizeof( Frustum ) ); + + render->OverrideViewFrustum( pViewRender->GetFrustum() ); + SetViewRecursionLevel( g_pPortalRender->GetViewRecursionLevel() + 1 ); + + CPortalRenderable *pRenderingViewForPortalBackup = g_pPortalRender->GetCurrentViewEntryPortal(); + CPortalRenderable *pRenderingViewExitPortalBackup = g_pPortalRender->GetCurrentViewExitPortal(); + SetViewEntranceAndExitPortals( this, m_pLinkedPortal ); + + //DRAW!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + ViewDrawScene_PortalStencil( pViewRender, portalView, &customVisibility ); + + SetViewEntranceAndExitPortals( pRenderingViewForPortalBackup, pRenderingViewExitPortalBackup ); + + SetViewRecursionLevel( g_pPortalRender->GetViewRecursionLevel() - 1 ); + } + render->PopView( pViewRender->GetFrustum() ); + + //restore old frustum + memcpy( pViewRender->GetFrustum(), FrustumBackup, sizeof( Frustum ) ); + render->OverrideViewFrustum( FrustumBackup ); + } + + //restore old vis data + CopyToCurrentView( pViewRender, cameraView ); +} + +void CPortalRenderable_Func_LiquidPortal::RenderPortalViewToTexture( CViewRender *pViewRender, const CViewSetup &cameraView ) +{ + +} + + +void CPortalRenderable_Func_LiquidPortal::AddToVisAsExitPortal( ViewCustomVisibility_t *pCustomVisibility ) +{ + if ( !pCustomVisibility ) + return; + + VisOverrideData_t visOverride; + Vector vOrigin = (m_vAABBMins + m_vAABBMaxs) * 0.5f; + + visOverride.m_vecVisOrigin = vOrigin; + visOverride.m_fDistToAreaPortalTolerance = 64.0f; + + // Specify which leaf to use for area portal culling + pCustomVisibility->ForceVisOverride( visOverride ); + pCustomVisibility->ForceViewLeaf( enginetrace->GetLeafContainingPoint( vOrigin ) ); + + pCustomVisibility->AddVisOrigin( vOrigin ); +} + +bool CPortalRenderable_Func_LiquidPortal::DoesExitViewIntersectWaterPlane( float waterZ, int leafWaterDataID ) const +{ + return ((m_vAABBMins.z < waterZ) && (m_vAABBMaxs.z > waterZ)); +} + +SkyboxVisibility_t CPortalRenderable_Func_LiquidPortal::SkyBoxVisibleFromPortal( void ) +{ + return SKYBOX_NOT_VISIBLE; +} + + +bool CPortalRenderable_Func_LiquidPortal::CalcFrustumThroughPortal( const Vector &ptCurrentViewOrigin, Frustum OutputFrustum, const VPlane *pInputFrustum, int iInputFrustumPlaneCount ) +{ + return false; +} + + +const Vector& CPortalRenderable_Func_LiquidPortal::GetFogOrigin( void ) const +{ + return vec3_origin; +} + +void CPortalRenderable_Func_LiquidPortal::ShiftFogForExitPortalView() const +{ + +} + + +bool CPortalRenderable_Func_LiquidPortal::ShouldUpdatePortalView_BasedOnView( const CViewSetup ¤tView, Frustum currentFrustum ) +{ + //return false; + return IsFillingNow(); +} + +CPortalRenderable* CPortalRenderable_Func_LiquidPortal::GetLinkedPortal() const +{ + return m_pLinkedPortal; +} + +bool CPortalRenderable_Func_LiquidPortal::ShouldUpdateDepthDoublerTexture( const CViewSetup &viewSetup ) +{ + return false; +} + +void CPortalRenderable_Func_LiquidPortal::DrawPortal( void ) +{ + if( IsFillingNow() ) + { + //"shadertest/gooinglass" + //"glass/glasswindow_refract01" + //IMaterial *pMaterial = materials->FindMaterial( "glass/glasswindow_refract01", TEXTURE_GROUP_OTHER ); + //UpdateFrontBufferTexturesForMaterial( (IMaterial *)pMaterial ); + + DrawOutwardBox(); + //DrawInnerLiquid( pMaterial ); + //DrawInwardBox( pMaterial ); + } +} + +void CPortalRenderable_Func_LiquidPortal::GetToolRecordingState( bool bActive, KeyValues *msg ) +{ + +} + +void CPortalRenderable_Func_LiquidPortal::HandlePortalPlaybackMessage( KeyValues *pKeyValues ) +{ + +} + +void CPortalRenderable_Func_LiquidPortal::DrawOutwardBox( const IMaterial *pMaterial ) +{ + if( pMaterial == NULL ) + pMaterial = materials->FindMaterial( "glass/glasswindow_refract01", TEXTURE_GROUP_OTHER ); + + const float fVerticalTextureScale = 1.0f / 100.0f; + const float fHorizontalTextureScale = 1.0f / 100.0f; + + float fMaxZ = m_vAABBMins.z + ((m_vAABBMaxs.z - m_vAABBMins.z) * GetFillInterpolationAmount()); + + Vector vVertices[8]; + for( int i = 0; i != 8; ++i ) + { + vVertices[i].x = (i&(1<<0)) ? m_vAABBMaxs.x : m_vAABBMins.x; + vVertices[i].y = (i&(1<<1)) ? m_vAABBMaxs.y : m_vAABBMins.y; + vVertices[i].z = (i&(1<<2)) ? fMaxZ : m_vAABBMins.z; + } + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( (IMaterial *)pMaterial, (CPortalRenderable_Func_LiquidPortal*)this ); + + CMeshBuilder meshBuilder; + IMesh* pMesh = pRenderContext->GetDynamicMesh( false ); + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 6 ); + + //x min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //x max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //y min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //y max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + + //z min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + + //z max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + + meshBuilder.End(); + pMesh->Draw(); + pRenderContext->Flush( false ); +} + +void CPortalRenderable_Func_LiquidPortal::DrawInwardBox( const IMaterial *pMaterial ) +{ + if( pMaterial == NULL ) + pMaterial = materials->FindMaterial( "glass/glasswindow_refract01", TEXTURE_GROUP_OTHER ); + + const float fVerticalTextureScale = 1.0f / 100.0f; + const float fHorizontalTextureScale = 1.0f / 100.0f; + + float fMaxZ = m_vAABBMins.z + ((m_vAABBMaxs.z - m_vAABBMins.z) * GetFillInterpolationAmount()); + + Vector vVertices[8]; + for( int i = 0; i != 8; ++i ) + { + vVertices[i].x = (i&(1<<0)) ? m_vAABBMaxs.x : m_vAABBMins.x; + vVertices[i].y = (i&(1<<1)) ? m_vAABBMaxs.y : m_vAABBMins.y; + vVertices[i].z = (i&(1<<2)) ? fMaxZ : m_vAABBMins.z; + } + + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->Bind( (IMaterial *)pMaterial, (CPortalRenderable_Func_LiquidPortal*)this ); + + CMeshBuilder meshBuilder; + IMesh* pMesh = pRenderContext->GetDynamicMesh( false ); + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 6 ); + + //x min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //x max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, y, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //y min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + //y max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, x, fHorizontalTextureScale, z, -fVerticalTextureScale ); + + + //z min + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 0, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 2, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 3, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 1, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + + //z max + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 5, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 7, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 6, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + LIQUIDPORTAL_DYNAMICMESH_BOX_ADDVERTEX( 4, x, fHorizontalTextureScale, y, fVerticalTextureScale ); + + meshBuilder.End(); + pMesh->Draw(); + pRenderContext->Flush( false ); +} + +void CPortalRenderable_Func_LiquidPortal::DrawInnerLiquid( bool bClipToBounds, float fOpacity, const IMaterial *pMaterial ) //quads in front of camera clipped to box dimensions +{ + if( !IsFillingNow() && bClipToBounds ) + return; + + PortalMeshPoint_t WorkVertices[4]; + + //view->GetViewSetup()->zNear; + Vector vForward, vUp, vRight, vOrigin; + vForward = CurrentViewForward(); + vUp = CurrentViewUp(); + vRight = CurrentViewRight(); + + //vOrigin = CurrentViewOrigin() + vForward * (view->GetViewSetup()->zNear + 0.011f); //experimentation has shown this to be the optimal distance on the Nvidia 6800 cards we develop on + vOrigin = CurrentViewOrigin() + vForward * (view->GetViewSetup()->zNear + 1.0f ); + + const float fScalingAmount = 5.0f; + + WorkVertices[0].texCoord.x = fScalingAmount; + WorkVertices[0].texCoord.y = fScalingAmount; + + WorkVertices[1].texCoord.x = fScalingAmount; + WorkVertices[1].texCoord.y = 0.0f; + + WorkVertices[2].texCoord.x = 0.0f; + WorkVertices[2].texCoord.y = 0.0f; + + WorkVertices[3].texCoord.x = 0.0f; + WorkVertices[3].texCoord.y = fScalingAmount; + + + WorkVertices[0].vWorldSpacePosition = vOrigin + (vRight * 40.0f) + (vUp * -40.0f); + WorkVertices[1].vWorldSpacePosition = vOrigin + (vRight * 40.0f) + (vUp * 40.0f); + WorkVertices[2].vWorldSpacePosition = vOrigin + (vRight * -40.0f) + (vUp * 40.0f); + WorkVertices[3].vWorldSpacePosition = vOrigin + (vRight * -40.0f) + (vUp * -40.0f); + + PortalMeshPoint_t *pInVerts = (PortalMeshPoint_t *)stackalloc( 4 * (6) * 2 * sizeof( PortalMeshPoint_t ) ); //really only should need 2x points, but I'm paranoid + PortalMeshPoint_t *pOutVerts = (PortalMeshPoint_t *)stackalloc( 4 * (6) * 2 * sizeof( PortalMeshPoint_t ) ); + + PortalMeshPoint_t *pFinalVerts; + int iVertCount; + if( bClipToBounds ) + { + PortalMeshPoint_t *pTempVerts; + + //clip by first plane and put output into pInVerts + iVertCount = ClipPolyToPlane_LerpTexCoords( WorkVertices, 4, pInVerts, Vector( 0.0f, 0.0f, -1.0f ), -(m_vAABBMins.z + ((m_vAABBMaxs.z - m_vAABBMins.z) * GetFillInterpolationAmount())), 0.01f ); + + //clip by other planes and flipflop in and out pointers + for( int i = 0; i != 5; ++i ) + { + if( iVertCount < 3 ) + return; //nothing to draw + + iVertCount = ClipPolyToPlane_LerpTexCoords( pInVerts, iVertCount, pOutVerts, *(Vector *)m_fBoundingPlanes[i], m_fBoundingPlanes[i][3], 0.01f ); + pTempVerts = pInVerts; pInVerts = pOutVerts; pOutVerts = pTempVerts; //swap vertex pointers + } + + if( iVertCount < 3 ) + return; //nothing to draw + + pFinalVerts = pInVerts; + } + else + { + pFinalVerts = WorkVertices; + iVertCount = 4; + } + + bool bInterpOpacity = false; + if( pMaterial == NULL ) + { + pMaterial = materials->FindMaterial( "glass/glasswindow_refract01", TEXTURE_GROUP_OTHER ); + bInterpOpacity = ( fOpacity != 1.0f ); + } + + if( bInterpOpacity ) + { + IMaterial *pEditMaterial = (IMaterial *)pMaterial; //we'll be making changes, then changing it back + + IMaterialVar *pRefractAmount = pEditMaterial->FindVar( "$refractamount", NULL ); + IMaterialVar *pBlurAmount = pEditMaterial->FindVar( "$bluramount", NULL ); + IMaterialVar *pTint = pEditMaterial->FindVar( "$refracttint", NULL ); + + float fOriginalRefractAmount = pRefractAmount->GetFloatValue(); + float fOriginalBlurAmount = pBlurAmount->GetFloatValue(); + Vector4D vOriginalTint; + pTint->GetVecValue( &vOriginalTint.x, 4 ); + + Vector4D vModdedTint = vOriginalTint; + + pRefractAmount->SetFloatValue( fOriginalRefractAmount * fOpacity ); + pBlurAmount->SetFloatValue( fOriginalBlurAmount * fOpacity ); + vModdedTint.x = 1.0f - ((1.0f - vOriginalTint.x) * fOpacity); + vModdedTint.y = 1.0f - ((1.0f - vOriginalTint.y) * fOpacity); + vModdedTint.z = 1.0f - ((1.0f - vOriginalTint.z) * fOpacity); + pTint->SetVecValue( &vModdedTint.x, 4 ); + + Clip_And_Render_Convex_Polygon( pFinalVerts, iVertCount, pEditMaterial, this ); + materials->Flush(); + + pRefractAmount->SetFloatValue( fOriginalRefractAmount ); + pBlurAmount->SetFloatValue( fOriginalBlurAmount ); + pTint->SetVecValue( &vOriginalTint.x, 4 ); + } + else + { + Clip_And_Render_Convex_Polygon( pFinalVerts, iVertCount, pMaterial, this ); + } + + +} + + + +ADD_SCREENSPACE_EFFECT( CLiquidPortal_InnerLiquidEffect, LiquidPortal_InnerLiquid ); +const float CLiquidPortal_InnerLiquidEffect::s_fFadeBackEffectTime = 5.0f; + + +CLiquidPortal_InnerLiquidEffect::CLiquidPortal_InnerLiquidEffect( void ) +: m_bEnable(true), + m_pImmersionPortal(NULL), + m_bFadeBackToReality(false), + m_fFadeBackTimeLeft(0.0f) +{ +} + + +void CLiquidPortal_InnerLiquidEffect::SetParameters( KeyValues *params ) +{ + /*KeyValues *pImmersionPortal = params->FindKey( "immersion_portal" ); + if( pImmersionPortal ) + m_pImmersionPortal = (C_Func_LiquidPortal *)pImmersionPortal->GetPtr();*/ +} + + +void CLiquidPortal_InnerLiquidEffect::Render( int x, int y, int w, int h ) +{ + if( !m_pImmersionPortal || !m_bEnable ) + return; + + if( m_bFadeBackToReality ) + { + //effect should cover whole screen and have a alpha-like fade back to normal view + m_fFadeBackTimeLeft -= gpGlobals->absoluteframetime; + if( m_fFadeBackTimeLeft > 0.0f ) + { + float fInterp = m_fFadeBackTimeLeft/s_fFadeBackEffectTime; + + //clear depth buffer so we can be all warpy on the view model too + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->ClearBuffers( false, true, false ); + pRenderContext->OverrideDepthEnable( true, false ); + + m_pImmersionPortal->DrawInnerLiquid( false, fInterp ); + + pRenderContext->OverrideDepthEnable( false, true ); + } + else + { + m_bFadeBackToReality = false; + m_pImmersionPortal = NULL; + } + } + else + { + //effect should only cover a portion of the screen and be in full warpiness + + //clear depth buffer so we can be all warpy on the view model too + CMatRenderContextPtr pRenderContext( materials ); + pRenderContext->ClearBuffers( false, true, false ); + pRenderContext->OverrideDepthEnable( true, false ); + + m_pImmersionPortal->DrawInnerLiquid(); + + pRenderContext->OverrideDepthEnable( false, true ); + } +} + + |