summaryrefslogtreecommitdiff
path: root/movieobjects/dmematerialoverlayfxclip.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'movieobjects/dmematerialoverlayfxclip.cpp')
-rw-r--r--movieobjects/dmematerialoverlayfxclip.cpp270
1 files changed, 270 insertions, 0 deletions
diff --git a/movieobjects/dmematerialoverlayfxclip.cpp b/movieobjects/dmematerialoverlayfxclip.cpp
new file mode 100644
index 0000000..3fb62b1
--- /dev/null
+++ b/movieobjects/dmematerialoverlayfxclip.cpp
@@ -0,0 +1,270 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================
+
+#include "movieobjects/dmematerialoverlayfxclip.h"
+#include "datamodel/dmelementfactoryhelper.h"
+#include "materialsystem/imesh.h"
+#include "materialsystem/imaterial.h"
+#include "tier1/KeyValues.h"
+#include "tier1/convar.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+//-----------------------------------------------------------------------------
+// CDmeClip - common base class for filmclips, soundclips, and channelclips
+//-----------------------------------------------------------------------------
+IMPLEMENT_FX_CLIP_ELEMENT_FACTORY( DmeMaterialOverlayFXClip, CDmeMaterialOverlayFXClip, "Material Overlay Effect" );
+
+void CDmeMaterialOverlayFXClip::OnConstruction()
+{
+ m_Material.Init( this, "material" );
+ m_Color.Init( this, "overlaycolor" );
+ m_nLeft.Init( this, "left" );
+ m_nTop.Init( this, "top" );
+ m_nWidth.Init( this, "width" );
+ m_nHeight.Init( this, "height" );
+ m_bFullScreen.Init( this, "fullscreen" );
+ m_bUseSubRect.Init( this, "useSubRect" );
+ m_flMovementAngle.Init( this, "movementAngle" );
+ m_flMovementSpeed.Init( this, "movementSpeed" );
+ m_nSubRectLeft.Init( this, "subRectLeft" );
+ m_nSubRectTop.Init( this, "subRectTop" );
+ m_nSubRectWidth.Init( this, "subRectWidth" );
+ m_nSubRectHeight.Init( this, "subRectHeight" );
+
+ m_Color.SetColor( 255, 255, 255, 255 );
+ m_bFullScreen = true;
+ m_nLeft = m_nTop = 0;
+ m_nWidth = m_nHeight = 1;
+}
+
+void CDmeMaterialOverlayFXClip::OnDestruction()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Resolve
+//-----------------------------------------------------------------------------
+void CDmeMaterialOverlayFXClip::Resolve()
+{
+ if ( m_Material.IsDirty() )
+ {
+ m_OverlayMaterial.Shutdown();
+ const char *pName = m_Material.Get();
+ if ( pName && pName[0] )
+ {
+ m_OverlayMaterial.Init( pName, NULL, false );
+ }
+ m_Material.GetAttribute()->RemoveFlag( FATTRIB_DIRTY );
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Helper for overlays
+//-----------------------------------------------------------------------------
+void CDmeMaterialOverlayFXClip::SetOverlayEffect( const char *pMaterialName )
+{
+ m_Material = pMaterialName;
+}
+
+void CDmeMaterialOverlayFXClip::SetAlpha( float flAlpha )
+{
+ m_Color.SetAlpha( flAlpha * 255 );
+}
+
+float CDmeMaterialOverlayFXClip::GetAlpha( void )
+{
+ return ( (float)m_Color.a() ) / 255.0f;
+}
+
+bool CDmeMaterialOverlayFXClip::HasOpaqueOverlay( void )
+{
+ if ( m_OverlayMaterial )
+ return ( !m_OverlayMaterial->IsTranslucent() && ( m_Color.a() == 255 ) && m_bFullScreen );
+
+ // no material overlay set
+ return false;
+}
+
+IMaterial *CDmeMaterialOverlayFXClip::GetMaterial()
+{
+ return m_OverlayMaterial;
+}
+
+
+//-----------------------------------------------------------------------------
+// All effects must be able to apply their effect
+//-----------------------------------------------------------------------------
+void CDmeMaterialOverlayFXClip::ApplyEffect( DmeTime_t time, Rect_t &currentRect, Rect_t &totalRect, ITexture *pTextures[MAX_FX_INPUT_TEXTURES] )
+{
+ if ( !m_OverlayMaterial || m_Color.a() == 0 )
+ return;
+
+ time = ToChildMediaTime( time, false );
+
+ // Clip the overlay rectangle to the currently drawn one
+ int x, y, w, h;
+ int tx, ty, tw, th;
+ if ( m_bFullScreen )
+ {
+ x = currentRect.x;
+ y = currentRect.y;
+ w = currentRect.width;
+ h = currentRect.height;
+ tx = ty = 0;
+ tw = totalRect.width;
+ th = totalRect.height;
+ }
+ else
+ {
+ x = clamp( m_nLeft, currentRect.x, currentRect.x + currentRect.width );
+ y = clamp( m_nTop, currentRect.y, currentRect.y + currentRect.height );
+ int x1 = clamp( m_nLeft + m_nWidth, currentRect.x, currentRect.x + currentRect.width );
+ int y1 = clamp( m_nTop + m_nHeight, currentRect.y, currentRect.y + currentRect.height );
+ w = x1 - x;
+ h = y1 - y;
+
+ tx = m_nLeft;
+ ty = m_nTop;
+ tw = m_nWidth;
+ th = m_nHeight;
+
+ // Clipped...
+ if ( w <= 0 || h <= 0 )
+ return;
+ }
+
+ if ( tw == 0 || th == 0 )
+ return;
+
+ // Compute texture coordinate range of the entire texture
+ int mw = m_OverlayMaterial->GetMappingWidth();
+ int mh = m_OverlayMaterial->GetMappingHeight();
+
+ // Compute the texture coords in texels we want over the entire image
+ float uMin = 0;
+ float uMax = mw;
+ float vMin = 0;
+ float vMax = mh;
+
+ if ( m_bUseSubRect )
+ {
+ uMin = m_nSubRectLeft;
+ vMin = m_nSubRectTop;
+ uMax = uMin + m_nSubRectWidth;
+ vMax = vMin + m_nSubRectHeight;
+ }
+
+ if ( m_flMovementSpeed )
+ {
+ float flRadians = M_PI * m_flMovementAngle / 180.0f;
+ float dUdT = -m_flMovementSpeed * cos( flRadians );
+ float dVdT = m_flMovementSpeed * sin( flRadians );
+ float dU = time.GetSeconds() * dUdT;
+ float dV = time.GetSeconds() * dVdT;
+ uMin += dU; uMax += dU;
+ vMin += dV; vMax += dV;
+ }
+
+ // This is the range of normalizes (u,v) coordinates over the *total* image
+ uMin = ( uMin + 0.5f ) / mw;
+ vMin = ( vMin + 0.5f ) / mh;
+ uMax = ( uMax - 0.5f ) / mw;
+ vMax = ( vMax - 0.5f ) / mh;
+
+ // Now determine the subrange we should use given we're rendering a portion of the image
+ float u0, v0, u1, v1, f;
+
+ f = ( x - tx ) / tw;
+ u0 = Lerp( f, uMin, uMax );
+
+ f = ( x + w - tx ) / tw;
+ u1 = Lerp( f, uMin, uMax );
+
+ f = ( y - ty ) / th;
+ v0 = Lerp( f, vMin, vMax );
+
+ f = ( y + h - ty ) / th;
+ v1 = Lerp( f, vMin, vMax );
+
+ x -= currentRect.x;
+ y -= currentRect.y;
+
+ if ( m_OverlayMaterial->NeedsPowerOfTwoFrameBufferTexture() )
+ {
+ CMatRenderContextPtr pRenderContext( materials );
+ ITexture *pTexture = materials->FindTexture( "_rt_PowerOfTwoFB", TEXTURE_GROUP_RENDER_TARGET );
+
+ // forced or only once per frame
+ Rect_t rect;
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = currentRect.width;
+ rect.height = currentRect.height;
+ pRenderContext->CopyRenderTargetToTextureEx( pTexture, 0, &rect, NULL );
+ pRenderContext->SetFrameBufferCopyTexture( pTexture );
+ }
+
+ float r, g, b, a;
+ m_OverlayMaterial->GetColorModulation( &r, &g, &b );
+ a = m_OverlayMaterial->GetAlphaModulation();
+
+ m_OverlayMaterial->ColorModulate( m_Color.r() / 255.0f, m_Color.g() / 255.0f, m_Color.b() / 255.0f );
+ m_OverlayMaterial->AlphaModulate( m_Color.a() / 255.0f );
+
+ CMatRenderContextPtr pRenderContext( materials );
+ pRenderContext->Bind( m_OverlayMaterial );
+
+ IMesh *pMesh = pRenderContext->GetDynamicMesh();
+ CMeshBuilder meshBuilder;
+ meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, 2 );
+
+ meshBuilder.Position3f( x, y, 0.0f );
+ meshBuilder.BoneWeight( 0, 1.0f );
+ meshBuilder.BoneMatrix( 0, 0 );
+ meshBuilder.Color4ub( 255, 255, 255, 255 );
+ meshBuilder.TexCoord2f( 0, u0, v0 );
+ meshBuilder.TexCoord2f( 1, 0.0f, 0.0f );
+ meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x, y+h, 0.0f );
+ meshBuilder.BoneWeight( 0, 1.0f );
+ meshBuilder.BoneMatrix( 0, 0 );
+ meshBuilder.Color4ub( 255, 255, 255, 255 );
+ meshBuilder.TexCoord2f( 0, u0, v1 );
+ meshBuilder.TexCoord2f( 1, 0.0f, 1.0f );
+ meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x+w, y, 0.0f );
+ meshBuilder.BoneWeight( 0, 1.0f );
+ meshBuilder.BoneMatrix( 0, 0 );
+ meshBuilder.Color4ub( 255, 255, 255, 255 );
+ meshBuilder.TexCoord2f( 0, u1, v0 );
+ meshBuilder.TexCoord2f( 1, 1.0f, 0.0f );
+ meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.Position3f( x+w, y+h, 0.0f );
+ meshBuilder.BoneWeight( 0, 1.0f );
+ meshBuilder.BoneMatrix( 0, 0 );
+ meshBuilder.Color4ub( 255, 255, 255, 255 );
+ meshBuilder.TexCoord2f( 0, u1, v1 );
+ meshBuilder.TexCoord2f( 1, 1.0f, 1.0f );
+ meshBuilder.TexCoord2f( 2, 0.0f, 0.0f );
+ meshBuilder.AdvanceVertex();
+
+ meshBuilder.End();
+ pMesh->Draw();
+
+ m_OverlayMaterial->ColorModulate( r, g, b );
+ m_OverlayMaterial->AlphaModulate( a );
+}
+