diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/client/vgui_video_player.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/client/vgui_video_player.cpp')
| -rw-r--r-- | mp/src/game/client/vgui_video_player.cpp | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/mp/src/game/client/vgui_video_player.cpp b/mp/src/game/client/vgui_video_player.cpp new file mode 100644 index 00000000..5e86541d --- /dev/null +++ b/mp/src/game/client/vgui_video_player.cpp @@ -0,0 +1,457 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: VGUI panel which can play back video, in-engine
+//
+//=============================================================================
+
+#include "cbase.h"
+#include <vgui/IVGui.h>
+#include "vgui/IInput.h"
+#include <vgui/ISurface.h>
+#include "ienginevgui.h"
+#include "iclientmode.h"
+#include "vgui_video_player.h"
+#include "engine/IEngineSound.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+VideoPlayerPanel::VideoPlayerPanel( vgui::Panel *parent, const char *panelName, int nXpos, int nYpos, int nWidth, int nHeight, const char *pVideoFile ) :
+ BaseClass( parent, panelName ),
+ m_VideoMaterial( NULL ),
+ m_VideoFileName( NULL ),
+ m_VideoLoaded( false ),
+ m_VideoPlaying( false )
+{
+ Assert( g_pVideo != NULL );
+
+ // init all the video realted member vars
+ ClearVideo();
+
+ SetVisible( false );
+
+ SetKeyBoardInputEnabled( false );
+ SetMouseInputEnabled( false );
+
+ SetProportional( false );
+ SetPaintBackgroundEnabled( false );
+ SetPaintBorderEnabled( false );
+
+ // Set us up
+ SetTall( nHeight );
+ SetWide( nWidth );
+ SetPos( nXpos, nYpos );
+
+ // use defaults for scheme and control settings for now
+
+ // SetScheme( vgui::scheme()->LoadSchemeFromFile( "resource/VideoPlayerPanelScheme.res", "VideoPlayerPanelScheme"));
+ //LoadControlSettings("resource/UI/VideoPlayerPanel.res");
+
+ // Assign video file if supplied
+ SetVideo( pVideoFile );
+
+ SetVisible( true );
+
+}
+
+
+
+
+//-----------------------------------------------------------------------------
+// Properly shutdown out materials
+//-----------------------------------------------------------------------------
+VideoPlayerPanel::~VideoPlayerPanel( void )
+{
+ SetParent( (vgui::Panel *) NULL );
+
+ StopVideo();
+ ClearVideo();
+
+}
+
+
+bool VideoPlayerPanel::SetVideo( const char *pVideoFile )
+{
+ ClearVideo();
+
+ // clearing the video?
+ if ( pVideoFile == NULL || pVideoFile[0] == 0x00 )
+ {
+ return true;
+ }
+
+ // create the material
+ m_VideoMaterial = g_pVideo->CreateVideoMaterial( "VideoPlayerMaterial", pVideoFile, "GAME",
+ VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS,
+ VideoSystem::DETERMINE_FROM_FILE_EXTENSION, true );
+
+ if ( m_VideoMaterial == NULL )
+ {
+ return false;
+ }
+
+ // save filename
+ int sLen = V_strlen( pVideoFile ) + 1;
+ m_VideoFileName = new char[ sLen ];
+ V_strncpy( m_VideoFileName, pVideoFile, sLen );
+
+ // compute Playback dimensions
+
+ int nWidth, nHeight;
+ m_VideoMaterial->GetVideoImageSize( &nWidth, &nHeight );
+ m_VideoMaterial->GetVideoTexCoordRange( &m_flU, &m_flV );
+
+ float flFrameRatio = ( (float) GetWide() / (float) GetTall() );
+ float flVideoRatio = ( (float) nWidth / (float) nHeight );
+
+ if ( flVideoRatio > flFrameRatio )
+ {
+ m_nPlaybackWidth = GetWide();
+ m_nPlaybackHeight = ( GetWide() / flVideoRatio );
+ m_letterBox = 1;
+ }
+ else if ( flVideoRatio < flFrameRatio )
+ {
+ m_nPlaybackWidth = ( GetTall() * flVideoRatio );
+ m_nPlaybackHeight = GetTall();
+ m_letterBox = 2;
+ }
+ else
+ {
+ m_nPlaybackWidth = GetWide();
+ m_nPlaybackHeight = GetTall();
+ m_letterBox = 0;
+ }
+
+ m_pMaterial = m_VideoMaterial->GetMaterial();
+
+ m_VideoDuration = m_VideoMaterial->GetVideoDuration();
+
+ m_VideoLoaded = true;
+ return true;
+}
+
+
+
+void VideoPlayerPanel::ClearVideo()
+{
+ if ( m_VideoPlaying )
+ {
+ StopVideo();
+ }
+
+ // Shut down this video, destroy the video material
+ if ( g_pVideo != NULL && m_VideoMaterial != NULL )
+ {
+ g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
+ m_VideoMaterial = NULL;
+ }
+
+ if ( m_VideoFileName != NULL )
+ {
+ delete[] m_VideoFileName;
+ m_VideoFileName = NULL;
+ }
+
+ m_pMaterial = NULL;
+
+ m_VideoLoaded = false;
+ m_VideoPlaying = false;
+ m_VideoPaused = false;
+ m_nPlaybackHeight = 0;
+ m_nPlaybackWidth = 0;
+ m_letterBox = 0;
+
+ m_flU = 0.0f;
+ m_flV = 0.0f;
+
+ m_VideoDuration = 0.0f;
+
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VideoPlayerPanel::Activate( void )
+{
+ MoveToFront();
+ RequestFocus();
+ SetVisible( true );
+ SetEnabled( true );
+
+ vgui::surface()->SetMinimized( GetVPanel(), false );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void VideoPlayerPanel::OnClose( void )
+{
+ StopVideo();
+
+// enginesound->NotifyEndMoviePlayback();
+
+ vgui::surface()->RestrictPaintToSinglePanel( NULL );
+
+ SetVisible( false );
+ MarkForDeletion();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Update and draw the frame
+//-----------------------------------------------------------------------------
+void VideoPlayerPanel::Paint( void )
+{
+ BaseClass::Paint();
+
+ // Get our dimensions
+ int xpos = 0;
+ int ypos = 0;
+ vgui::ipanel()->GetAbsPos( GetVPanel(), xpos, ypos );
+// GetPanelPos( xpos, ypos );
+ int width = GetWide();
+ int height = GetTall();
+
+
+ // Are we playing the video? Do we even have a video?
+ if ( !m_VideoLoaded || !m_VideoPlaying )
+ {
+ vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
+ vgui::surface()->DrawFilledRect( 0, 0, width, height );
+ return;
+ }
+
+ if ( m_VideoMaterial == NULL )
+ return;
+
+ if ( m_VideoMaterial->Update() == false )
+ {
+ StopVideo();
+ return;
+ }
+
+ // Black out the letterbox ares if we have them
+ if ( m_letterBox != 0 )
+ {
+ vgui::surface()->DrawSetColor( 0, 0, 0, 255 );
+
+ if ( m_letterBox == 1 ) // bars on top, bottom
+ {
+ int excess = ( height - m_nPlaybackHeight );
+ int top = excess /2;
+ int bot = excess - top;
+
+ vgui::surface()->DrawFilledRect( 0, 0, width, top );
+ vgui::surface()->DrawFilledRect( 0, height - bot, width, height );
+ }
+
+ if ( m_letterBox == 2 ) // bars on left, right
+ {
+ int excess = ( width - m_nPlaybackWidth );
+ int left = excess /2;
+ int right = excess - left;
+
+ vgui::surface()->DrawFilledRect( 0, 0, left, height );
+ vgui::surface()->DrawFilledRect( width-right, 0, width, height );
+ }
+ }
+
+ // Draw the polys to draw this out
+ CMatRenderContextPtr pRenderContext( materials );
+
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadIdentity();
+
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->PushMatrix();
+ pRenderContext->LoadIdentity();
+
+ pRenderContext->Bind( m_pMaterial, NULL );
+
+ CMeshBuilder meshBuilder;
+ IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
+ meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
+
+ float flLeftX = xpos;
+ float flRightX = xpos + ( m_nPlaybackWidth-1 );
+
+ float flTopY = ypos;
+ float flBottomY = ypos + ( m_nPlaybackHeight-1 );
+
+ // Map our UVs to cut out just the portion of the video we're interested in
+ float flLeftU = 0.0f;
+ float flTopV = 0.0f;
+
+ // We need to subtract off a pixel to make sure we don't bleed
+ float flRightU = m_flU - ( 1.0f / (float) m_nPlaybackWidth );
+ float flBottomV = m_flV - ( 1.0f / (float) m_nPlaybackHeight );
+
+ // Get the current viewport size
+ int vx, vy, vw, vh;
+ pRenderContext->GetViewport( vx, vy, vw, vh );
+
+ // map from screen pixel coords to -1..1
+ flRightX = FLerp( -1, 1, 0, vw, flRightX );
+ flLeftX = FLerp( -1, 1, 0, vw, flLeftX );
+ flTopY = FLerp( 1, -1, 0, vh ,flTopY );
+ flBottomY = FLerp( 1, -1, 0, vh, flBottomY );
+
+ float alpha = ((float)GetFgColor()[3]/255.0f);
+
+ for ( int corner=0; corner<4; corner++ )
+ {
+ bool bLeft = (corner==0) || (corner==3);
+ meshBuilder.Position3f( (bLeft) ? flLeftX : flRightX, (corner & 2) ? flBottomY : flTopY, 0.0f );
+ meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
+ meshBuilder.TexCoord2f( 0, (bLeft) ? flLeftU : flRightU, (corner & 2) ? flBottomV : flTopV );
+ meshBuilder.TangentS3f( 0.0f, 1.0f, 0.0f );
+ meshBuilder.TangentT3f( 1.0f, 0.0f, 0.0f );
+ meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, alpha );
+ meshBuilder.AdvanceVertex();
+ }
+
+ meshBuilder.End();
+ pMesh->Draw();
+
+ pRenderContext->MatrixMode( MATERIAL_VIEW );
+ pRenderContext->PopMatrix();
+
+ pRenderContext->MatrixMode( MATERIAL_PROJECTION );
+ pRenderContext->PopMatrix();
+
+}
+
+bool VideoPlayerPanel::StartVideo()
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ // already playing?
+ if ( m_VideoPlaying )
+ {
+ // paused?
+ if ( m_VideoPaused )
+ {
+ return UnpauseVideo();
+ }
+ return true;
+ }
+
+ m_VideoPlaying = m_VideoMaterial->StartVideo();
+
+ return m_VideoPlaying;
+
+}
+
+bool VideoPlayerPanel::StopVideo()
+{
+ if ( !m_VideoLoaded || !m_VideoPlaying )
+ return false;
+
+ m_VideoMaterial->StopVideo();
+ m_VideoPlaying = false;
+
+ return true;
+}
+
+bool VideoPlayerPanel::PauseVideo()
+{
+ if ( !m_VideoLoaded || !m_VideoPlaying )
+ return false;
+
+ if ( !m_VideoPaused )
+ {
+ m_VideoMaterial->SetPaused( true );
+ m_VideoPaused = true;
+ }
+
+ return true;
+}
+
+
+bool VideoPlayerPanel::UnpauseVideo()
+{
+ if ( !m_VideoLoaded || !m_VideoPlaying )
+ return false;
+
+ if ( m_VideoPaused )
+ {
+ m_VideoMaterial->SetPaused( false );
+ m_VideoPaused = false;
+ }
+
+ return true;
+}
+
+float VideoPlayerPanel::GetCurrentPlaybackTime()
+{
+ if ( !m_VideoLoaded )
+ {
+ return 0.0f;
+ }
+
+ return m_VideoMaterial->GetCurrentVideoTime();
+}
+
+
+
+bool VideoPlayerPanel::SetCurrentPlaybackTime( float newTime )
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ if ( newTime < 0.0f || newTime > m_VideoDuration )
+ return false;
+
+ return m_VideoMaterial->SetTime( newTime );
+}
+
+
+bool VideoPlayerPanel::HasAudio()
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ return m_VideoMaterial->HasAudio();
+}
+
+bool VideoPlayerPanel::IsMuted()
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ return m_VideoMaterial->IsMuted();
+
+}
+
+
+bool VideoPlayerPanel::SetMute( bool muted )
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ m_VideoMaterial->SetMuted( muted );
+ return true;
+}
+
+float VideoPlayerPanel::GetVolume()
+{
+ if ( !m_VideoLoaded )
+ return 0.0f;
+
+ return m_VideoMaterial->GetVolume();
+}
+
+
+bool VideoPlayerPanel::SetVolume( float newVolume )
+{
+ if ( !m_VideoLoaded )
+ return false;
+
+ return m_VideoMaterial->SetVolume( newVolume );
+}
|