惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Darknet – Hacking Tools, Hacker News & Cyber Security
Jina AI
Jina AI
博客园_首页
J
Java Code Geeks
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
Hugging Face - Blog
Hugging Face - Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Forbes - Security
Forbes - Security
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Y
Y Combinator Blog
Google DeepMind News
Google DeepMind News
The Register - Security
The Register - Security
N
News | PayPal Newsroom
S
Security Archives - TechRepublic
量子位
Cisco Talos Blog
Cisco Talos Blog
V
V2EX
C
Cisco Blogs
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
L
LangChain Blog
Scott Helme
Scott Helme
S
Securelist
Security Latest
Security Latest
爱范儿
爱范儿
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
I
Intezer
L
LINUX DO - 最新话题
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Check Point Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
美团技术团队
Know Your Adversary
Know Your Adversary
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
PCI Perspectives
PCI Perspectives
月光博客
月光博客
T
Tailwind CSS Blog
Cloudbric
Cloudbric
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
K
Kaspersky official blog
D
DataBreaches.Net
博客园 - 【当耐特】
有赞技术团队
有赞技术团队

博客园 - zhucde

一句话的解释 给场景添加一个背景 ATI显卡中不能使用CG的变态原因 ORA-28000: the account is locked Oracle10g, EM中,ERROR: Wrong password for user ActiveX中嵌入Flash, 在IE中调用时, 与Flash的交互问题 Ogre中解决中文路径和中文文件名的方法 子节点(ChildNode)设置WorldPostion [转贴]c/c++ struct union 对齐方式 OpenGL程序 转为Opengl ES 的一点建议glDrawArray和glDrawElements [陆续更新] IPhone中编译Ogre源码及使用 宏定义中"#"的用法 - zhucde - 博客园 Ogre控件在网页中调用的问题 在3D中, 将世界坐标映射为屏幕上的坐标点 更新一下道路的最新效果,处理了边缘, 加入了Shader光照 OGRE中新做的火焰和爆炸 刚刚从CSDN的博客搬家过来, 有些文章的内容逐步完善, 请多多谅解! 新加的一个天空的效果. (已完整) [OGRE]继续完善道路-----道路两侧物体匹配(已完整)
在Ogre中使用DirectShow来播放视频--重新封装并测试通过(已完整)
zhucde · 2009-12-12 · via 博客园 - zhucde
 

在Ogre中使用DirectShow来播放视频,  原文可见官方Wiki中的文章:http://www.ogre3d.org/wiki/index.php/DirectShow_video_in_ogre_texture鉴于该文很多同志无法编译, 而且对于新手使用起来有些小麻烦, 所以简单修改了一下, 并且进行了简单的封装,使用起来更容易, 特别对于新手,  下面先看看效果(视频熟悉吧, 暴雪的):

下面上代码:

h-genutils.h

#ifndef PROG_FILE_HGENUTILS
#define PROG_FILE_HGENUTILS

#include "windows.h"

namespace hGenUtils {
	// convert a char* to a wchar*
	WCHAR* convertCStringToWString(const char* string);
}

#endif // PROG_FILE_HGENUTILS

h-genutils.cpp

代码

#include "stdafx.h"

#include

"h-genutils.h"

#include

<Ogre.h>// convert a char* to a wchar*
// warning: the return value points to a fixed buffer, whose contents change with
// every call to this function.
WCHAR* hGenUtils::convertCStringToWString(const char* string)
{
const int MAX_STRINGZ=500;
static WCHAR wtext[MAX_STRINGZ+2];if (strlen(string)>MAX_STRINGZ)
{
throw("hGenUtils::convertCStringToWString buffer isn't big enough");
}
// convert text to wchar
if (MultiByteToWideChar(
CP_ACP,
// ansi code page
0,// flags
string,// orig string
-1,// calculate len
wtext,// where to put the string
MAX_STRINGZ)// maximum allowed path
==0)
{
throw("hGenUtils::convertCStringToWString failed with no extra error info");
}
return wtext;
}

UtilsOgreDshow_private.h

代码

/// Do not include this file directly, always use UtilsOgreDshow.h instead.
// Ogre Dshow: small wrapper for video reproduction in Ogre, using Direct Show 9.
/*

Wrapper for video reproduction using Direct Show in the Ogre 3d engine.

Coded by H. Hernán Moraldo from Moraldo Games
www.hernan.moraldo.com.ar/pmenglish/field.php

--------------------

Copyright (c) 2007 Horacio Hernan Moraldo

This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

*/

#ifndef __FILE_UTILSOGREDSHOW_PRIVATE_INCLUDED

#define __FILE_UTILSOGREDSHOW_PRIVATE_INCLUDED

#include

<dshow.h>
#include
<Qedit.h>// for sample grabber
#include <windows.h>namespace OgreUtils
{
struct DirectShowData
{
/// Graph object
IGraphBuilder *pGraph;
/// Media control object
IMediaControl *pControl;
/// Media event object
IMediaEvent *pEvent;
/// Grabber filter
IBaseFilter *pGrabberF;
/// Grabber object
ISampleGrabber *pGrabber;
/// Interface for seeking object
IMediaSeeking *pSeeking;
/// Window interface
/** Useful for some configuration
*/
IVideoWindow
*pWindow;/// Video output width
int videoWidth;
/// Video output height
int videoHeight;
};
/// Util function for converting C strings to wide strings
/** (as needed for path in directshow). */
WCHAR
* util_convertCStringToWString(const char* string);
}
#endif // __FILE_UTILSOGREDSHOW_PRIVATE_INCLUDED

UtilsOgreDshow.h

代码

// Ogre Dshow: small wrapper for video reproduction in Ogre, using Direct Show 9.
/*

Wrapper for video reproduction using Direct Show in the Ogre 3d engine.

Coded by H. Hernán Moraldo from Moraldo Games
www.hernan.moraldo.com.ar/pmenglish/field.php

--------------------

Copyright (c) 2007 Horacio Hernan Moraldo

This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

*/

#ifndef __FILE_UTILSOGREDSHOW_INCLUDED

#define __FILE_UTILSOGREDSHOW_INCLUDED#define __FILE_UTILSOGREDSHOW_VERSION "1-30-2007b"

#include

<Ogre.h>
#include
<OgreVector2.h>namespace OgreUtils
{
struct DirectShowData;/// A class for playing movies in an ogre texture
class DirectShowMovieTexture
{
public:
// cons / decons
/// Initializes the dshow object, and creates a texture with the given dimensions.
/**
If dontModifyDimensions is false, the system might modify the texture dimensions
by setting them to the nearest power of two (useful for old computers).
(Ie, 1024x512 if the original dimensions were 640x480).
*/
DirectShowMovieTexture(
int width, int height, bool dontModifyDimensions=true);
/// Destroys the dshow object
virtual ~DirectShowMovieTexture();// basic movie methods
/// Loads a given movie
/**
/param moviePath A string telling the full path of the file to be loaded.
/param horizontalMirroring A bool telling whether the video should be rendered
as if seen through a mirror, or not.
*/
//已经强制在载入视频后重新修改纹理的大小,所以最后一个参数现在已经失效
void loadMovie(const Ogre::String& moviePath, bool horizontalMirroring=false);
/// Obtains the dimensions of the current movie
Ogre::Vector2 getMovieDimensions();
/// Unloads the current movie
void unloadMovie();// methods for movie control
/// Pauses the current movie
void pauseMovie();
/// Starts playing the current movie
void playMovie();
/// Makes the current movie rewind
void rewindMovie();
/// Stops the current movie
void stopMovie();
/// Is the latest video put to play, now playing?
/** (This is an old implementation of mine; I guess I should re-check this) */
bool isPlayingMovie();// methods on movie texture
/// Obtain the ogre texture where the movie is rendered
Ogre::TexturePtr getMovieTexture();
/// Render a movie frame in the ogre texture
void updateMovieTexture();
protected:
/// Texture where to render the movie
Ogre::TexturePtr mTexture;
/// Real texture width
Ogre::Real mTexWidth;
/// Real texture height
Ogre::Real mTexHeight;
/// Direct Show specific data
DirectShowData* dsdata;
/// Do we do horizontal mirroring by software?
bool mHorizontalMirroring;/// Clean the full texture (paint it all black)
void cleanTextureContents();void ResetSize(Ogre::Real w ,Ogre::Real h)
{
mTexWidth
=w;
mTexHeight
=h;
}

};

//对DirectShowTexture进行一次包装, 直接生成Overlay或者材质
class DirectShowControl
{
public:
friend
class DirectShowManager;

DirectShowControl(Ogre::String name,Ogre::String filename,

int width,int height,Ogre::Viewport *vp,bool overlay=true);
~DirectShowControl();void Destroy();
Ogre::MaterialPtr getMaterial();
void PlayMovie();
void StopMovie();protected:
void createOverlay(); //目前先针对全屏, 以后再扩展任意位置,大小
void createMaterial();private:
DirectShowMovieTexture
*mDirectshowTexture;
Ogre::MaterialPtr mMaterial;
int mWidth;
int mHeight;
Ogre::String mFilename;
Ogre::String mName;
Ogre::Overlay
*mOverlay;
bool isOverlay;
Ogre::Viewport
*mVp;

};

typedef std::list

<DirectShowControl*> DirectShowControlList;class DirectShowManager : public Ogre::Singleton<DirectShowManager>,public Ogre::FrameListener
{
public:
DirectShowManager(Ogre::Viewport
*vp);
~DirectShowManager();static DirectShowManager &getSingleton()
{
return *ms_Singleton;
}
static DirectShowManager *getSingletonPtr()
{
return ms_Singleton;
}
virtual bool frameStarted(const Ogre::FrameEvent& evt) ;
DirectShowControl
*createDirectshowControl(Ogre::String name,Ogre::String filename,int VWidth,int VHeight,bool overlay=true);void DestroyAll();private:
DirectShowControlList mDirectCtrlList;
Ogre::Viewport
*mVP;

};
}

#endif // __FILE_UTILSOGREDSHOW_INCLUDED

UtilsOgreDshow.cpp

代码

// Ogre Dshow: small wrapper for video reproduction in Ogre, using Direct Show 9.
/*

Wrapper for video reproduction using Direct Show in the Ogre 3d engine.

Coded by H. Hernán Moraldo from Moraldo Games
www.hernan.moraldo.com.ar/pmenglish/field.php

--------------------

Copyright (c) 2007 Horacio Hernan Moraldo

This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held liable
for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.

*/
#include
"stdafx.h"
#include
"UtilsOgreDshow.h"
#include
"UtilsOgreDshow_private.h"
#include
<OgreStringConverter.h>
#include
<dshow.h>

template

<> OgreUtils::DirectShowManager *Ogre::Singleton<OgreUtils::DirectShowManager>::ms_Singleton=NULL;namespace OgreUtils
{
DirectShowMovieTexture::DirectShowMovieTexture(
int width, int height, bool dontModifyDimensions)
{
// 1) CREATE DSDATA
dsdata=new DirectShowData;// 2) CREATE TEXTURE
// get width and height to the next square of two
int twoSquared;
mTexWidth
=0; mTexHeight=0;
for (twoSquared=2; mTexWidth==0 || mTexHeight==0; twoSquared*=2)
{
if (mTexWidth==0 && twoSquared>=width)
mTexWidth
=twoSquared;
if (mTexHeight==0 && twoSquared>=height)
mTexHeight
=twoSquared;
}
if (dontModifyDimensions)
{
// back to the original dimensions
mTexWidth=width;
mTexHeight
=height;
}
// log it
Ogre::LogManager::getSingletonPtr()->logMessage(
Ogre::String(
"[DSHOW] Creating texture with dimensions ")+
Ogre::StringConverter::toString(mTexWidth)
+"x"+
Ogre::StringConverter::toString(mTexHeight)
+".");// first, create the texture we are going to use
/*
mTexture=Ogre::TextureManager::getSingleton().createManual(
"DirectShowManualTexture",// name
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D,// texture type
mTexWidth,
mTexHeight,
0,// number of mipmaps
Ogre::PF_BYTE_BGRA,// pixel format
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE// usage
);
*/// 3) INITIALIZE DIRECT SHOW
HRESULT hr;

hr

=CoInitialize(NULL);
if (FAILED(hr)) throw("[DSHOW] Error in co initialize");// initialize all pointers
dsdata->pGraph=0;
dsdata
->pControl=0;
dsdata
->pEvent=0;
dsdata
->pGrabberF=0;
dsdata
->pGrabber=0;
dsdata
->pSeeking=0;
dsdata
->pWindow=0;

}

DirectShowMovieTexture::

~DirectShowMovieTexture()
{
// 1) DEINITIALIZE DIRECT SHOW
unloadMovie();
CoUninitialize();
// 2) DESTROY TEXTURE
Ogre::TextureManager::getSingleton().remove(mTexture->getName());// 3) DELETE DSDATA
delete dsdata;
}
void DirectShowMovieTexture::loadMovie(
const Ogre::String& moviePath, bool horizontalMirroring)
{
HRESULT hr;
// log it!
Ogre::LogManager::getSingletonPtr()->logMessage(
Ogre::String(
"[DSHOW] Loading movie named '")+
moviePath
+"'.");// destroy previous movie objects (if any)
unloadMovie();// create filter graph and get interfaces
hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
IID_IGraphBuilder, (
void**) &dsdata->pGraph);
if (FAILED(hr)) throw("[DSHOW] Error in creating graph");

hr

=dsdata->pGraph->QueryInterface(IID_IMediaControl, (void**) & dsdata->pControl);
if (FAILED(hr)) throw("[DSHOW] Error in querying media control");

hr

=dsdata->pGraph->QueryInterface(IID_IMediaEvent, (void**) & dsdata->pEvent);
if (FAILED(hr)) throw("[DSHOW] Error in querying media event");

hr

=dsdata->pGraph->QueryInterface(IID_IMediaSeeking, (void**) & dsdata->pSeeking);
if (FAILED(hr)) throw("[DSHOW] Error in querying seeking interface");// create sample grabber
hr=CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (
void**)&dsdata->pGrabberF);
if (FAILED(hr)) throw("[DSHOW] Error in creating sample grabber");// add sample grabber to the graph
hr=dsdata->pGraph->AddFilter(dsdata->pGrabberF, L"Sample Grabber");
if (FAILED(hr)) throw("[DSHOW] Error in adding sample grabber to the graph");// get sample grabber object
dsdata->pGrabberF->QueryInterface(IID_ISampleGrabber,
(
void**)&dsdata->pGrabber);// set sample grabber media type
AM_MEDIA_TYPE mt;
ZeroMemory(
&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype
= MEDIATYPE_Video;
mt.subtype
= MEDIASUBTYPE_RGB24;
mt.formattype
= FORMAT_VideoInfo;
hr
=dsdata->pGrabber->SetMediaType(&mt);
if (FAILED(hr)) throw("[DSHOW] Error in setting sample grabber media type");// open the file!
WCHAR* filepath=util_convertCStringToWString(moviePath.c_str());
hr
=dsdata->pGraph->RenderFile(filepath, NULL);
if (FAILED(hr)) throw("[DSHOW] Error opening video file!");// disable auto show
// (wouldn't be needed if we used the null renderer)
hr=dsdata->pGraph->QueryInterface(IID_IVideoWindow, (void**) & dsdata->pWindow);
if (FAILED(hr)) throw("[DSHOW] Error getting video window interface");
dsdata
->pWindow->put_AutoShow(OAFALSE);// get video information
AM_MEDIA_TYPE mtt;
hr
=dsdata->pGrabber->GetConnectedMediaType(&mtt);if (FAILED(hr)) throw("[DSHOW] Error getting connected media type info");

VIDEOINFOHEADER

*vih = (VIDEOINFOHEADER*) mtt.pbFormat;
dsdata
->videoWidth=vih->bmiHeader.biWidth;
dsdata
->videoHeight=vih->bmiHeader.biHeight;

ResetSize(dsdata

->videoWidth,dsdata->videoHeight);
//纹理的创建现在修改到了这里,原来在构造函数中
//放在这里可以根据视频的大小来生成纹理的大小
//这样可以让视频完全平铺到面片上
mTexture=Ogre::TextureManager::getSingleton().createManual(
"DirectShowManualTexture",// name
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D,
// texture type
mTexWidth,
mTexHeight,
0,// number of mipmaps
Ogre::PF_BYTE_BGRA,// pixel format
Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE// usage
);// microsoft's help version of free media type
if (mtt.cbFormat != 0)
{
CoTaskMemFree((PVOID)mtt.pbFormat);
mtt.cbFormat
= 0;
mtt.pbFormat
= NULL;
}
if (mtt.pUnk != NULL)
{
mtt.pUnk
->Release();
mtt.pUnk
= NULL;
}
// log it
Ogre::LogManager::getSingletonPtr()->logMessage(
Ogre::String(
"[DSHOW] -> This movie has dimensions: ")+
Ogre::StringConverter::toString(dsdata
->videoWidth)+"x"+
Ogre::StringConverter::toString(dsdata
->videoHeight)+".");// set sampling options
dsdata->pGrabber->SetOneShot(FALSE);
dsdata
->pGrabber->SetBufferSamples(TRUE);// set some basic data
mHorizontalMirroring=horizontalMirroring;// clean the texture, so that it's ready for rendering this video
cleanTextureContents();
}

Ogre::Vector2 DirectShowMovieTexture::getMovieDimensions()
{

return Ogre::Vector2(dsdata->videoWidth, dsdata->videoHeight);
}
void DirectShowMovieTexture::unloadMovie()
{
if (dsdata->pGraph==0)
return;if (dsdata->pGrabber!=0)
{
dsdata
->pGrabber->Release();
dsdata
->pGrabber=0;
}
if (dsdata->pGrabberF!=0)
{
dsdata
->pGrabberF->Release();
dsdata
->pGrabberF=0;
}
if (dsdata->pWindow!=0)
{
dsdata
->pWindow->Release();
dsdata
->pWindow=0;
}
if (dsdata->pSeeking!=0)
{
dsdata
->pSeeking->Release();
dsdata
->pSeeking=0;
}
if (dsdata->pControl!=0)
{
dsdata
->pControl->Release();
dsdata
->pControl=0;
}
if (dsdata->pEvent!=0)
{
dsdata
->pEvent->Release();
dsdata
->pEvent=0;
}
if (dsdata->pGraph!=0)
{
dsdata
->pGraph->Release();
dsdata
->pGraph=0;
}

}

void DirectShowMovieTexture::pauseMovie()
{
// pause!
if (dsdata->pControl)
dsdata
->pControl->Pause();
}
void DirectShowMovieTexture::playMovie()
{
// play!
if (dsdata->pControl)
dsdata
->pControl->Run();
}
void DirectShowMovieTexture::rewindMovie()
{
if (!dsdata->pSeeking) return;// rewind!
LONGLONG p1=0;
LONGLONG p2
=0;

dsdata

->pSeeking->SetPositions(
&p1, AM_SEEKING_AbsolutePositioning, &p2, AM_SEEKING_NoPositioning);
}
void DirectShowMovieTexture::stopMovie()
{
// stop!
if (dsdata->pControl)
dsdata
->pControl->Stop();
}

Ogre::TexturePtr DirectShowMovieTexture::getMovieTexture()
{

return mTexture;
}
void DirectShowMovieTexture::updateMovieTexture()
{
HRESULT hr;
unsigned
int i, idx;
int x, y;
BYTE
* bmpTmp;// only do this if there is a graph that has been set up
if (!dsdata->pGraph)
return;// Find the required buffer size.
long cbBuffer = 0;
hr
= dsdata->pGrabber->GetCurrentBuffer(&cbBuffer, NULL);
if (cbBuffer<=0)
{
// nothing to do here yet
return;
}
char *pBuffer = new char[cbBuffer];
if (!pBuffer)
{
// out of memory!
throw("[DSHOW] Out of memory or empty buffer");
}
hr
= dsdata->pGrabber->GetCurrentBuffer(&cbBuffer, (long*)pBuffer);
if (hr==E_INVALIDARG || hr==VFW_E_NOT_CONNECTED || hr==VFW_E_WRONG_STATE)
{
// we aren't buffering samples yet, do nothing
delete[] pBuffer;
return;
}
if (FAILED(hr)) throw("[DSHOW] Failed at GetCurrentBuffer!");// OGRE BEGIN
// OGRE TEXTURE LOCK
// get the texture pixel buffer
int texw=mTexture->getWidth();
int texh=mTexture->getHeight();
Ogre::HardwarePixelBufferSharedPtr pixelBuffer
= mTexture->getBuffer();
bmpTmp
=(BYTE*)pBuffer;// lock the pixel buffer and get a pixel box
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();

Ogre::uint8

* pDest = static_cast<Ogre::uint8*>(pixelBox.data);// FILL!
// check for mirroring...
bool shouldBeMirrored=mHorizontalMirroring;
if (shouldBeMirrored){
x
=dsdata->videoWidth-1; y=dsdata->videoHeight-1;
}
else{
x
=0; y=dsdata->videoHeight-1;
}
// go set all bits...
for (i=0; i<(dsdata->videoWidth*dsdata->videoHeight*3); i+=3){
idx
=(x*4)+y*pixelBox.rowPitch*4;// paint
pDest[idx]=bmpTmp[i];//b
pDest[idx+1]=bmpTmp[i+1];//g
pDest[idx+2]=bmpTmp[i+2];//r
pDest[idx+3]=255;//a

if (shouldBeMirrored){
x
--;
if (x<0){
x
=dsdata->videoWidth-1;
y
--; if (y<0) y=0;
}
}
else{
x
++;
if (x>=dsdata->videoWidth){
x
=0;
y
--; if (y<0) y=0;
}
}
}
// UNLOCK EVERYTHING!
// unlock the pixel buffer
pixelBuffer->unlock();
// OGRE END// bye
delete[] pBuffer;
}
void DirectShowMovieTexture::cleanTextureContents()
{
unsigned
int idx;
int x, y;// OGRE TEXTURE LOCK
// get the texture pixel buffer
int texw=mTexture->getWidth();
int texh=mTexture->getHeight();
Ogre::HardwarePixelBufferSharedPtr pixelBuffer
= mTexture->getBuffer();// lock the pixel buffer and get a pixel box
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();

Ogre::uint8

* pDest = static_cast<Ogre::uint8*>(pixelBox.data);// FILL!
for (x=0, y=0; y<texh; ){
idx
=(x*4)+y*pixelBox.rowPitch*4;// paint
pDest[idx]=0;//b
pDest[idx+1]=0;//g
pDest[idx+2]=0;//r
pDest[idx+3]=255;//a

x
++;
if (x>=texw)
{
x
=0;
y
++;
}
}
// UNLOCK EVERYTHING!
// unlock the pixel buffer
pixelBuffer->unlock();
// OGRE END
}bool DirectShowMovieTexture::isPlayingMovie()
{
OAFilterState pfs;
HRESULT hr;
if (dsdata->pEvent!=NULL){
long ev, p1, p2;while (E_ABORT!=dsdata->pEvent->GetEvent(&ev, &p1, &p2, 0)){
// check for completion
if (ev==EC_COMPLETE)
{
pauseMovie();
return false;
}
// release event params
hr=dsdata->pEvent->FreeEventParams(ev, p1, p2);
if (FAILED(hr))
{
pauseMovie();
return false;
}
}
}
// get the running state!
if (dsdata->pControl!=NULL)
{
hr
=dsdata->pControl->GetState(0, &pfs);
if (FAILED(hr))
{
pauseMovie();
return false;
}
return pfs==State_Running;
}
// it hasn't even been initialized!
return false;
}

WCHAR

* util_convertCStringToWString(const char* string)
{
const int MAX_STRINGZ=500;
static WCHAR wtext[MAX_STRINGZ+2];if (strlen(string)>MAX_STRINGZ)
return 0;// convert text to wchar
if (MultiByteToWideChar(
CP_ACP,
// ansi code page
0,// flags
string,// orig string
-1,// calculate len
wtext,// where to put the string
MAX_STRINGZ)// maximum allowed path
==0)
{
throw("[DSHOW] convertCStringToWString failed with no extra error info");
}
return wtext;
}

DirectShowControl::DirectShowControl(Ogre::String name,Ogre::String filename,

int width,int height,Ogre::Viewport *vp,bool overlay/*=true*/ ):isOverlay(overlay),
mName(name),mWidth(width),mHeight(height),mFilename(filename),mVp(vp)
{
mDirectshowTexture
= new DirectShowMovieTexture(mWidth,mHeight,false);
mDirectshowTexture
->loadMovie(mFilename);

createMaterial();

if(isOverlay)
createOverlay();

}

DirectShowControl::

~DirectShowControl()
{

}

void DirectShowControl::createOverlay()
{
mOverlay
= Ogre::OverlayManager::getSingleton().create(mName);

Ogre::OverlayContainer

*mContainer = (Ogre::OverlayContainer*)
(Ogre::OverlayManager::getSingleton().createOverlayElement(
"Panel", "Ogre/DebugTexPanel" +mName));

mContainer

->setMetricsMode(Ogre::GMM_PIXELS);
mContainer
->setDimensions(mVp->getActualWidth(),mVp->getActualHeight());
mContainer
->setMaterialName(mMaterial->getName());
mOverlay
->add2D(mContainer);
mOverlay
->show();
PlayMovie();
}
void DirectShowControl::createMaterial()
{
Ogre::String MatName
=mName+"_directShowMaterial";
mMaterial
=Ogre::MaterialManager::getSingleton().create(MatName,Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);//创建纹理对象并设置参数
Ogre::String texName = mName+"_DirectshowTexture";
mMaterial
->getTechnique(0)->getPass(0)->setSelfIllumination(1,1,1);
Ogre::TextureUnitState
*tex= mMaterial->getTechnique(0)->getPass(0)->createTextureUnitState( texName );
tex
->setTextureFiltering(Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);//获得纹理空间并赋上值
tex=mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0);
tex
->setTextureName(
mDirectshowTexture
->getMovieTexture()->getName());

PlayMovie();
}

Ogre::MaterialPtr DirectShowControl::getMaterial()
{

return mMaterial;

}

void DirectShowControl::Destroy()
{

delete mDirectshowTexture;
}

void DirectShowControl::PlayMovie()
{
if(mDirectshowTexture)
mDirectshowTexture
->playMovie();
}
void DirectShowControl::StopMovie()
{
if(mDirectshowTexture)
mDirectshowTexture
->stopMovie();
}

DirectShowManager::DirectShowManager(Ogre::Viewport

*vp):mVP(vp)
{

}
DirectShowManager::

~DirectShowManager()
{

}

DirectShowControl

* DirectShowManager::createDirectshowControl(Ogre::String name,Ogre::String filename,int VWidth,int VHeight,bool overlay/*=true*/ )
{
DirectShowControl
*mContrl=new DirectShowControl(name,filename,VWidth,VHeight,mVP,overlay);

mDirectCtrlList.push_back(mContrl);

return mContrl;
}
bool DirectShowManager::frameStarted( const Ogre::FrameEvent& evt )
{

DirectShowControlList::iterator it;

for (it=mDirectCtrlList.begin();it!=mDirectCtrlList.end();++it)
{
DirectShowControl
*con=*(it);
if(con)
{
con
->mDirectshowTexture->updateMovieTexture();if(!con->mDirectshowTexture->isPlayingMovie())//循环放
con->mDirectshowTexture->rewindMovie();

}
}

return true;
}
void DirectShowManager::DestroyAll()
{
DirectShowControlList::iterator it;
for (it=mDirectCtrlList.begin();it!=mDirectCtrlList.end();++it)
{
DirectShowControl
*con=*(it);
if(con)
con
->Destroy();
}
mDirectCtrlList.clear();
}

}

好了, 下面简单说一下使用方法:

1. 初始化, 在Ogre初始化时, 初始化一下视频的管理器

m_OgreRoot->addFrameListener(new OgreUtils::DirectShowManager(vp));   //Directshow 视频

2. 加载视频

 分两种情况

情况一,   把视频作为Overlay来全屏显示, 很简单, 一句话就搞定:

OgreUtils::DirectShowManager::getSingleton().createDirectshowControl("videotest","welcome.avi",640,480);

情况二. 作为材质来使用:

OgreUtils::DirectShowControl *dcontrol=OgreUtils::DirectShowManager::getSingleton().createDirectshowControl("videotest","1welcome.avi",640,480,false);


ent->setMaterial(dcontrol->getMaterial())  //对某个物体直接贴上该材质,dcontrol->getMaterial()即得到视频材质的句柄.

 BLOG不能上传附件, 需要完整的测试代码工程文件的直接跟我索取吧, 进群里面联系.