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.
457 lines
9.8 KiB
457 lines
9.8 KiB
//========= 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 ); |
|
}
|
|
|