add RageMovieTexture abstraction
This commit is contained in:
+32
-20
@@ -57,10 +57,10 @@ LINK32=link.exe
|
|||||||
# SUBTRACT LINK32 /verbose /pdb:none
|
# SUBTRACT LINK32 /verbose /pdb:none
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
IntDir=.\../Release6
|
IntDir=.\../Release6
|
||||||
TargetDir=\stepmania\stepmania
|
TargetDir=\temp\stepmania
|
||||||
TargetName=StepMania
|
TargetName=StepMania
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||||
# End Special Build Tool
|
# End Special Build Tool
|
||||||
|
|
||||||
@@ -92,10 +92,10 @@ LINK32=link.exe
|
|||||||
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
|
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
|
||||||
# Begin Special Build Tool
|
# Begin Special Build Tool
|
||||||
IntDir=.\../Debug6
|
IntDir=.\../Debug6
|
||||||
TargetDir=\stepmania\stepmania
|
TargetDir=\temp\stepmania
|
||||||
TargetName=StepMania-debug
|
TargetName=StepMania-debug
|
||||||
SOURCE="$(InputPath)"
|
SOURCE="$(InputPath)"
|
||||||
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
||||||
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
|
||||||
# End Special Build Tool
|
# End Special Build Tool
|
||||||
|
|
||||||
@@ -113,14 +113,6 @@ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania
|
|||||||
# PROP Default_Filter ""
|
# PROP Default_Filter ""
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\RageMovieTextureHelper.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\RageMovieTextureHelper.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\regex.c
|
SOURCE=.\regex.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -219,14 +211,6 @@ SOURCE=.\RageMath.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\RageMovieTexture.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\RageMovieTexture.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\RageSound.cpp
|
SOURCE=.\RageSound.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
@@ -700,6 +684,34 @@ SOURCE=.\arch\InputHandler\InputHandler_Win32_Pump.cpp
|
|||||||
SOURCE=.\arch\InputHandler\InputHandler_Win32_Pump.h
|
SOURCE=.\arch\InputHandler\InputHandler_Win32_Pump.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
# Begin Group "MovieTexture"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture_DShow.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture_DShow.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture_DShowHelper.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\arch\MovieTexture\MovieTexture_DShowHelper.h
|
||||||
|
# End Source File
|
||||||
|
# End Group
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\arch\arch.cpp
|
SOURCE=.\arch\arch.cpp
|
||||||
|
|||||||
@@ -833,6 +833,28 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
|||||||
RelativePath="arch\InputHandler\InputHandler_Win32_Pump.h">
|
RelativePath="arch\InputHandler\InputHandler_Win32_Pump.h">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="MovieTexture"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture_DShow.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture_DShow.h">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture_DShowHelper.cpp">
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="arch\MovieTexture\MovieTexture_DShowHelper.h">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="system"
|
Name="system"
|
||||||
@@ -1362,18 +1384,6 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\
|
|||||||
<File
|
<File
|
||||||
RelativePath="RageMath.h">
|
RelativePath="RageMath.h">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath="RageMovieTexture.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="RageMovieTexture.h">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="RageMovieTextureHelper.cpp">
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath="RageMovieTextureHelper.h">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="RageSound.cpp">
|
RelativePath="RageSound.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "MovieTexture.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "MovieTexture_DShow.h"
|
||||||
|
|
||||||
|
/* Try drivers in order of preference until we find one that works. */
|
||||||
|
/* Well, eventually; for now it's DShow or bust.w */
|
||||||
|
RageMovieTexture *MakeRageMovieTexture(RageTextureID ID)
|
||||||
|
{
|
||||||
|
#if defined(WIN32)
|
||||||
|
return new MovieTexture_DShow(ID);
|
||||||
|
#else
|
||||||
|
RageException::Throw("xxx");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef MOVIE_TEXTURE_H
|
||||||
|
#define MOVIE_TEXTURE_H
|
||||||
|
|
||||||
|
#include "RageTexture.h"
|
||||||
|
|
||||||
|
class RageMovieTexture : public RageTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RageMovieTexture( RageTextureID ID ): RageTexture(ID) { }
|
||||||
|
virtual ~RageMovieTexture() { }
|
||||||
|
void Update(float fDeltaTime) { }
|
||||||
|
|
||||||
|
virtual void Reload() = 0;
|
||||||
|
|
||||||
|
virtual void Play() = 0;
|
||||||
|
virtual void Pause() = 0;
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
virtual void SetPosition( float fSeconds ) = 0;
|
||||||
|
virtual bool IsPlaying() const = 0;
|
||||||
|
virtual void SetLooping(bool looping=true) { }
|
||||||
|
|
||||||
|
bool IsAMovie() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
RageMovieTexture *MakeRageMovieTexture(RageTextureID ID);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
#include "global.h"
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Class: MovieTexture_DShow
|
||||||
|
|
||||||
|
Desc: See header.
|
||||||
|
|
||||||
|
Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved.
|
||||||
|
Chris Danford
|
||||||
|
Glenn Maynard
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma comment(lib, "winmm.lib")
|
||||||
|
|
||||||
|
// Link with the DirectShow base class libraries
|
||||||
|
#if defined(DEBUG)
|
||||||
|
#pragma comment(lib, "baseclasses/debug/strmbasd.lib")
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "baseclasses/release/strmbase.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "MovieTexture_DShowHelper.h"
|
||||||
|
|
||||||
|
#include "MovieTexture_DShow.h"
|
||||||
|
#include "RageUtil.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
#include "RageException.h"
|
||||||
|
#include "RageDisplayInternal.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "SDL_utils.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// MovieTexture_DShow constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
MovieTexture_DShow::MovieTexture_DShow( RageTextureID ID ) :
|
||||||
|
RageMovieTexture( ID )
|
||||||
|
{
|
||||||
|
LOG->Trace( "RageBitmapTexture::RageBitmapTexture()" );
|
||||||
|
|
||||||
|
buffer_changed = false;
|
||||||
|
|
||||||
|
m_uGLTextureID = 0;
|
||||||
|
buffer = NULL;
|
||||||
|
|
||||||
|
Create();
|
||||||
|
|
||||||
|
CreateFrameRects();
|
||||||
|
// flip all frame rects because movies are upside down
|
||||||
|
for( unsigned i=0; i<m_TextureCoordRects.size(); i++ )
|
||||||
|
{
|
||||||
|
float fTemp = m_TextureCoordRects[i].top;
|
||||||
|
m_TextureCoordRects[i].top = m_TextureCoordRects[i].bottom;
|
||||||
|
m_TextureCoordRects[i].bottom = fTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bLoop = true;
|
||||||
|
m_bPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MovieTexture_DShow::~MovieTexture_DShow()
|
||||||
|
{
|
||||||
|
LOG->Trace("MovieTexture_DShow::~MovieTexture_DShow");
|
||||||
|
|
||||||
|
// Shut down the graph
|
||||||
|
if (m_pGB) {
|
||||||
|
Stop();
|
||||||
|
m_pGB.Release ();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
|
|
||||||
|
if(m_uGLTextureID)
|
||||||
|
glDeleteTextures(1, &m_uGLTextureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Reload()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int MovieTexture_DShow::GetGLTextureID()
|
||||||
|
{
|
||||||
|
CheckMovieStatus(); // restart the movie if we reach the end
|
||||||
|
return m_uGLTextureID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Update(float fDeltaTime)
|
||||||
|
{
|
||||||
|
LockMutex L(buffer_mutex);
|
||||||
|
|
||||||
|
if(!buffer_changed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
buffer_changed = false;
|
||||||
|
|
||||||
|
/* Just in case we were invalidated: */
|
||||||
|
CreateTexture();
|
||||||
|
|
||||||
|
DISPLAY->SetTexture(this);
|
||||||
|
glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
/* XXX: We should use m_lVidPitch; we might be padded. However, I can't
|
||||||
|
* find any codec that don't force the width to a multiple of at least
|
||||||
|
* 4 anyway, so I can't test it, so I'll leave it like this for now. */
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, m_iSourceWidth);
|
||||||
|
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
|
0, 0,
|
||||||
|
min(m_iSourceWidth, m_iTextureWidth),
|
||||||
|
min(m_iSourceHeight, m_iTextureHeight),
|
||||||
|
GL_BGR, GL_UNSIGNED_BYTE, buffer);
|
||||||
|
|
||||||
|
/* Must unset PixelStore when we're done! */
|
||||||
|
glPixelStorei(GL_UNPACK_SWAP_BYTES, 0);
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleDivXError(HRESULT hr, CString s)
|
||||||
|
{
|
||||||
|
/* Actually, we might need XviD; we might want to look
|
||||||
|
* at the file and try to figure out if it's something
|
||||||
|
* common: DIV3, DIV4, DIV5, XVID, or maybe even MPEG2. */
|
||||||
|
CString err = hr_ssprintf(hr, "%s", s.GetString());
|
||||||
|
RageException::Throw(
|
||||||
|
ssprintf(
|
||||||
|
"There was an error initializing a movie: %s.\n"
|
||||||
|
"Could not locate the DivX video codec.\n"
|
||||||
|
"DivX is required to movie textures and must\n"
|
||||||
|
"be installed before running the application.\n\n"
|
||||||
|
"Please visit http://www.divx.com to download the latest version.",
|
||||||
|
err.GetString())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Create()
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
m_ActualID.iAlphaBits = 0;
|
||||||
|
|
||||||
|
if( FAILED( hr=CoInitialize(NULL) ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not CoInitialize") );
|
||||||
|
|
||||||
|
// Create the filter graph
|
||||||
|
if( FAILED( hr=m_pGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC) ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not create CLSID_FilterGraph!") );
|
||||||
|
|
||||||
|
// Create the Texture Renderer object
|
||||||
|
CTextureRenderer *pCTR = new CTextureRenderer;
|
||||||
|
|
||||||
|
/* Get a pointer to the IBaseFilter on the TextureRenderer, and add it to the
|
||||||
|
* graph. When m_pGB is released, it will free pFTR. */
|
||||||
|
CComPtr<IBaseFilter> pFTR = pCTR;
|
||||||
|
if( FAILED( hr = m_pGB->AddFilter(pFTR, L"TEXTURERENDERER" ) ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not add renderer filter to graph!") );
|
||||||
|
|
||||||
|
// Add the source filter
|
||||||
|
CComPtr<IBaseFilter> pFSrc; // Source Filter
|
||||||
|
WCHAR wFileName[MAX_PATH];
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, m_ActualID.filename.GetString(), -1, wFileName, MAX_PATH);
|
||||||
|
|
||||||
|
// if this fails, it's probably because the user doesn't have DivX installed
|
||||||
|
if( FAILED( hr = m_pGB->AddSourceFilter( wFileName, L"SOURCE", &pFSrc ) ) )
|
||||||
|
{
|
||||||
|
HandleDivXError(hr, "Could not create source filter to graph!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the source's output and the renderer's input
|
||||||
|
CComPtr<IPin> pFTRPinIn; // Texture Renderer Input Pin
|
||||||
|
if( FAILED( hr = pFTR->FindPin( L"In", &pFTRPinIn ) ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not find input pin!") );
|
||||||
|
|
||||||
|
CComPtr<IPin> pFSrcPinOut; // Source Filter Output Pin
|
||||||
|
if( FAILED( hr = pFSrc->FindPin( L"Output", &pFSrcPinOut ) ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not find output pin!") );
|
||||||
|
|
||||||
|
// Connect these two filters
|
||||||
|
if( FAILED( hr = m_pGB->Connect( pFSrcPinOut, pFTRPinIn ) ) )
|
||||||
|
{
|
||||||
|
HandleDivXError(hr, "Could not connect pins!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass us to our TextureRenderer.
|
||||||
|
pCTR->SetRenderTarget(this);
|
||||||
|
|
||||||
|
// The graph is built, now get the set the output video width and height.
|
||||||
|
// The source and image width will always be the same since we can't scale the video
|
||||||
|
m_iSourceWidth = pCTR->GetVidWidth();
|
||||||
|
m_iSourceHeight = pCTR->GetVidHeight();
|
||||||
|
|
||||||
|
/* image size cannot exceed max size */
|
||||||
|
m_iImageWidth = min( m_iSourceWidth, m_ActualID.iMaxSize );
|
||||||
|
m_iImageHeight = min( m_iSourceHeight, m_ActualID.iMaxSize );
|
||||||
|
|
||||||
|
/* Texture dimensions need to be a power of two; jump to the next. */
|
||||||
|
m_iTextureWidth = power_of_two(m_iImageWidth);
|
||||||
|
m_iTextureHeight = power_of_two(m_iImageHeight);
|
||||||
|
|
||||||
|
if(buffer == NULL)
|
||||||
|
buffer = new char[m_iSourceWidth * m_iSourceHeight * 3];
|
||||||
|
|
||||||
|
/* We've set up the movie, so we know the dimensions we need. Set
|
||||||
|
* up the texture. */
|
||||||
|
CreateTexture();
|
||||||
|
|
||||||
|
// Start the graph running
|
||||||
|
if( !PlayMovie() )
|
||||||
|
RageException::Throw( "Could not run the DirectShow graph." );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::NewData(char *data)
|
||||||
|
{
|
||||||
|
LockMutex L(buffer_mutex);
|
||||||
|
buffer_changed = true;
|
||||||
|
memcpy(buffer, data, m_iSourceWidth * m_iSourceHeight * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::CreateTexture()
|
||||||
|
{
|
||||||
|
if(m_uGLTextureID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
glGenTextures(1, &m_uGLTextureID);
|
||||||
|
|
||||||
|
DISPLAY->SetTexture(this);
|
||||||
|
|
||||||
|
/* Initialize the texture and set it to black. */
|
||||||
|
string buf(m_iTextureWidth*m_iTextureHeight*3, 0);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
|
||||||
|
m_iTextureWidth, m_iTextureHeight, 0, GL_BGR, GL_UNSIGNED_BYTE, buf.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MovieTexture_DShow::PlayMovie()
|
||||||
|
{
|
||||||
|
LOG->Trace("MovieTexture_DShow::PlayMovie()");
|
||||||
|
CComPtr<IMediaControl> pMC;
|
||||||
|
m_pGB.QueryInterface(&pMC);
|
||||||
|
|
||||||
|
// Start the graph running;
|
||||||
|
HRESULT hr;
|
||||||
|
if( FAILED( hr = pMC->Run() ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not run the DirectShow graph.") );
|
||||||
|
|
||||||
|
m_bPlaying = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// CheckMovieStatus: If the movie has ended, rewind to beginning
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void MovieTexture_DShow::CheckMovieStatus()
|
||||||
|
{
|
||||||
|
if(!m_bLoop) return;
|
||||||
|
|
||||||
|
// Check for completion events
|
||||||
|
CComPtr<IMediaEvent> pME;
|
||||||
|
m_pGB.QueryInterface(&pME);
|
||||||
|
|
||||||
|
long lEventCode, lParam1, lParam2;
|
||||||
|
pME->GetEvent( &lEventCode, &lParam1, &lParam2, 0 );
|
||||||
|
if( EC_COMPLETE == lEventCode )
|
||||||
|
SetPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Play()
|
||||||
|
{
|
||||||
|
PlayMovie();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Pause()
|
||||||
|
{
|
||||||
|
CComPtr<IMediaControl> pMC;
|
||||||
|
m_pGB.QueryInterface(&pMC);
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
if( FAILED( hr = pMC->Pause() ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not pause the DirectShow graph.") );
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::Stop()
|
||||||
|
{
|
||||||
|
CComPtr<IMediaControl> pMC;
|
||||||
|
m_pGB.QueryInterface(&pMC);
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
if( FAILED( hr = pMC->Stop() ) )
|
||||||
|
RageException::Throw( hr_ssprintf(hr, "Could not stop the DirectShow graph.") );
|
||||||
|
|
||||||
|
m_bPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovieTexture_DShow::SetPosition( float fSeconds )
|
||||||
|
{
|
||||||
|
CComPtr<IMediaPosition> pMP;
|
||||||
|
m_pGB.QueryInterface(&pMP);
|
||||||
|
pMP->put_CurrentPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MovieTexture_DShow::IsPlaying() const
|
||||||
|
{
|
||||||
|
return m_bPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
#ifndef RAGEMOVIETEXTURE_H
|
||||||
|
#define RAGEMOVIETEXTURE_H
|
||||||
|
/*
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Class: RageMovieTexture
|
||||||
|
|
||||||
|
Desc: Based on the DShowTextures example in the DX8 SDK.
|
||||||
|
|
||||||
|
Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved.
|
||||||
|
Chris Danford
|
||||||
|
Glenn Maynard
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "MovieTexture.h"
|
||||||
|
|
||||||
|
/* Don't know why we need this for the headers ... */
|
||||||
|
typedef char TCHAR, *PTCHAR;
|
||||||
|
|
||||||
|
/* Prevent these from using Dbg stuff, which we don't link in. */
|
||||||
|
#ifdef DEBUG
|
||||||
|
#undef DEBUG
|
||||||
|
#undef _DEBUG
|
||||||
|
#define GIVE_BACK_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <atlbase.h>
|
||||||
|
|
||||||
|
#ifdef GIVE_BACK_DEBUG
|
||||||
|
#undef GIVE_BACK_DEBUG
|
||||||
|
#define _DEBUG
|
||||||
|
#define DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "baseclasses/streams.h"
|
||||||
|
|
||||||
|
#include "RageDisplay.h"
|
||||||
|
#include "RageTexture.h"
|
||||||
|
#include "RageThreads.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// RageMovieTexture Class Declarations
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class MovieTexture_DShow : public RageMovieTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MovieTexture_DShow( RageTextureID ID );
|
||||||
|
virtual ~MovieTexture_DShow();
|
||||||
|
/* only called by RageTextureManager::InvalidateTextures */
|
||||||
|
void Invalidate() { m_uGLTextureID = 0; }
|
||||||
|
void Update(float fDeltaTime);
|
||||||
|
|
||||||
|
virtual void Reload();
|
||||||
|
|
||||||
|
virtual void Play();
|
||||||
|
virtual void Pause();
|
||||||
|
virtual void Stop();
|
||||||
|
virtual void SetPosition( float fSeconds );
|
||||||
|
virtual bool IsPlaying() const;
|
||||||
|
void SetLooping(bool looping=true) { m_bLoop = looping; }
|
||||||
|
|
||||||
|
void NewData(char *buffer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char *buffer;
|
||||||
|
bool buffer_changed;
|
||||||
|
RageMutex buffer_mutex;
|
||||||
|
|
||||||
|
void Create();
|
||||||
|
|
||||||
|
void CreateTexture();
|
||||||
|
bool PlayMovie();
|
||||||
|
void CheckMovieStatus();
|
||||||
|
|
||||||
|
virtual unsigned int GetGLTextureID();
|
||||||
|
unsigned int m_uGLTextureID;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// DirectShow pointers
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
CComPtr<IGraphBuilder> m_pGB; // GraphBuilder
|
||||||
|
bool m_bLoop;
|
||||||
|
bool m_bPlaying;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "MovieTexture_DShowHelper.h"
|
||||||
|
#include "RageUtil.h"
|
||||||
|
#include "RageLog.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Define GUID for Texture Renderer
|
||||||
|
// {71771540-2017-11cf-AE26-0020AFD79767}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) CLSID_TextureRenderer;
|
||||||
|
|
||||||
|
static HRESULT CBV_ret;
|
||||||
|
CTextureRenderer::CTextureRenderer()
|
||||||
|
: CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer),
|
||||||
|
NAME("Texture Renderer"), NULL, &CBV_ret)
|
||||||
|
{
|
||||||
|
if( FAILED(CBV_ret) )
|
||||||
|
RageException::Throw( hr_ssprintf(CBV_ret, "Could not create texture renderer object!") );
|
||||||
|
|
||||||
|
// Store and ARageef the texture for our use.
|
||||||
|
m_pTexture = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTextureRenderer::~CTextureRenderer()
|
||||||
|
{
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT CTextureRenderer::CheckMediaType(const CMediaType *pmt)
|
||||||
|
{
|
||||||
|
VIDEOINFO *pvi;
|
||||||
|
|
||||||
|
// Reject the connection if this is not a video type
|
||||||
|
if( *pmt->FormatType() != FORMAT_VideoInfo )
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
// Force the graph to R8G8B8.
|
||||||
|
pvi = (VIDEOINFO *)pmt->Format();
|
||||||
|
if(IsEqualGUID( *pmt->Type(), MEDIATYPE_Video) &&
|
||||||
|
IsEqualGUID( *pmt->Subtype(), MEDIASUBTYPE_RGB24))
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SetMediaType: Graph connection has been made.
|
||||||
|
HRESULT CTextureRenderer::SetMediaType(const CMediaType *pmt)
|
||||||
|
{
|
||||||
|
// Retrive the size of this media type
|
||||||
|
VIDEOINFO *pviBmp; // Bitmap info header
|
||||||
|
pviBmp = (VIDEOINFO *)pmt->Format();
|
||||||
|
m_lVidWidth = pviBmp->bmiHeader.biWidth;
|
||||||
|
m_lVidHeight = abs(pviBmp->bmiHeader.biHeight);
|
||||||
|
m_lVidPitch = (m_lVidWidth * 3 + 3) + ~3; // We are forcing RGB24
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CTextureRenderer::SetRenderTarget( MovieTexture_DShow* pTexture )
|
||||||
|
{
|
||||||
|
m_pTexture = pTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoRenderSample: A sample has been delivered. Copy it.
|
||||||
|
HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample )
|
||||||
|
{
|
||||||
|
if( m_pTexture == NULL )
|
||||||
|
{
|
||||||
|
LOG->Warn( "DoRenderSample called while m_pTexture was NULL!" );
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE *pBmpBuffer; // Bitmap buffer
|
||||||
|
|
||||||
|
// Get the video bitmap buffer
|
||||||
|
pSample->GetPointer( &pBmpBuffer );
|
||||||
|
|
||||||
|
// Copy the bits
|
||||||
|
m_pTexture->NewData((char *) pBmpBuffer);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef RAGEMOVIETEXTURE_HELPER_H
|
||||||
|
#define RAGEMOVIETEXTURE_HELPER_H
|
||||||
|
|
||||||
|
|
||||||
|
// #include <windows.h>
|
||||||
|
// #include <atlbase.h>
|
||||||
|
|
||||||
|
//#include "baseclasses/streams.h"
|
||||||
|
//#include "baseclasses/streams.h"
|
||||||
|
#include "MovieTexture_DShow.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// CTextureRenderer Class Declarations
|
||||||
|
//
|
||||||
|
// Usage: 1) CheckMediaType is called by the graph
|
||||||
|
// 2) SetMediaType is called by the graph
|
||||||
|
// 3) call GetVidWidth and GetVidHeight to get texture information
|
||||||
|
// 4) call SetRenderTarget
|
||||||
|
// 5) Do RenderSample is called by the graph
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
class CTextureRenderer : public CBaseVideoRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTextureRenderer();
|
||||||
|
~CTextureRenderer();
|
||||||
|
|
||||||
|
// overridden methods
|
||||||
|
HRESULT CheckMediaType(const CMediaType *pmt ); // Format acceptable?
|
||||||
|
HRESULT SetMediaType(const CMediaType *pmt ); // Video format notification
|
||||||
|
HRESULT DoRenderSample(IMediaSample *pMediaSample); // New video sample
|
||||||
|
|
||||||
|
// new methods
|
||||||
|
long GetVidWidth() const { return m_lVidWidth; }
|
||||||
|
long GetVidHeight() const { return m_lVidHeight; }
|
||||||
|
void SetRenderTarget( MovieTexture_DShow* pTexture );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Video width, height, and pitch.
|
||||||
|
long m_lVidWidth, m_lVidHeight, m_lVidPitch;
|
||||||
|
|
||||||
|
char *output;
|
||||||
|
|
||||||
|
MovieTexture_DShow* m_pTexture; // the video surface we will copy new frames to
|
||||||
|
// D3DFORMAT m_TextureFormat; // Texture format
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user