Commits

Fred...@Baator  committed 4e329e5

animated texture working, refactored into OgreVideoTexture

  • Participants
  • Parent commits 5a5f7b6

Comments (0)

Files changed (10)

File Debug/Plugins.cfg

 # Defines plugins to load
 
 # Define plugin folder
-PluginFolder=.
+PluginFolder=C:\libs\ogre-1.6.1\lib
 
 # Define plugins
 Plugin=RenderSystem_Direct3D9_d

File Debug/ogre.cfg

-Render System=OpenGL Rendering Subsystem
+Render System=Direct3D9 Rendering Subsystem
 
 [Direct3D9 Rendering Subsystem]
 Allow NVPerfHUD=No
 Floating-point mode=Fastest
 Full Screen=No
 Rendering Device=NVIDIA GeForce 8600 GT
-VSync=Yes
-Video Mode=800 x 600 @ 32-bit colour
+VSync=No
+Video Mode=1024 x 768 @ 32-bit colour
+sRGB Gamma Conversion=No
 
 [OpenGL Rendering Subsystem]
 Colour Depth=32
-Display Frequency=N/A
+Display Frequency=60
 FSAA=0
-Full Screen=No
+Full Screen=Yes
 RTT Preferred Mode=FBO
-VSync=Yes
-Video Mode=800 x 600
+VSync=No
+Video Mode=1024 x 768
+sRGB Gamma Conversion=No

File Debug/resources.cfg

 
 # Resource locations to be added to the default path
 [General]
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/fonts
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/materials/programs
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/materials/scripts
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/materials/textures
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/models
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/overlays
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/particle
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/gui
-FileSystem=C:/libs/ogre-1.4.9/Samples/Media/DeferredShading/media
-FileSystem=../../MyGUI_Media
-FileSystem=C:/auralias_models/mesh
+FileSystem=../media
 
-
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/cubemap.zip
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/cubemapsJS.zip
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/dragon.zip
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/fresneldemo.zip
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/ogretestmap.zip
-Zip=C:/libs/ogre-1.4.9/Samples/Media/packs/skybox.zip

File ogre-movingcube/OgreDShow/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 "UtilsOgreDshow.h"
+#include "UtilsOgreDshow_private.h"
+#include <OgreStringConverter.h>
+#include <dshow.h>
+
+
+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");
+
+                //--------------- Seregvan's modification 
+		IBaseFilter* srcFilter; 
+		WCHAR* filepath = util_convertCStringToWString(moviePath.c_str());    
+		hr = dsdata->pGraph->AddSourceFilter(filepath, L"Source", &srcFilter); 
+		if(FAILED(hr)) throw ("[DSHOW] Unsupported media type!"); 
+
+		// Connect the src and grabber 
+		hr = ConnectFilters(dsdata->pGraph, srcFilter, dsdata->pGrabberF); 
+		if(FAILED(hr)) throw ("[DSHOW] Unsupported media type!"); 
+
+		IBaseFilter * render;
+		hr = CoCreateInstance(CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&render);
+		if(FAILED(hr)) throw ("[DSHOW] Unsupported media type!"); 
+
+		dsdata->pGraph->AddFilter(render, L"Render");
+
+		hr = ConnectFilters(dsdata->pGraph, dsdata->pGrabberF, render); 
+		if(FAILED(hr)) throw ("[DSHOW] Can't create render!"); 
+
+		//--------------- End of modification
+
+		// 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;
+		// 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;
+	}
+
+
+}

File ogre-movingcube/OgreDShow/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 "11-18-2008a"
+
+#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();
+	};
+}
+
+
+#endif // __FILE_UTILSOGREDSHOW_INCLUDED

File ogre-movingcube/OgreDShow/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

File ogre-movingcube/OgreVideoTexture.cpp

+#include "OgreVideoTexture.h"
+
+#include <boost/format.hpp>
+
+//------------------------------------------------------------------------------
+OgreVideoTexture::OgreVideoTexture(const Ogre::String _filename)
+    :mVideoFileName(_filename)
+    ,mVideoStream(NULL)
+    ,mCurrentVideoFrame(NULL)
+{
+    mLog = Ogre::LogManager::getSingletonPtr()->createLog("OgreVideoTexture.log");
+    _init();
+}
+//------------------------------------------------------------------------------
+OgreVideoTexture::~OgreVideoTexture(void)
+{
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_init()
+{
+    mLog->logMessage("init");
+    
+    // OpenCv crap
+    Ogre::String fullName = Ogre::String("../media/videos/") + mVideoFileName;
+    mVideoStream = cvCreateFileCapture(fullName.c_str());
+
+    mLog->logMessage("openned " + fullName);
+
+    _createTextureFromCapture(mVideoStream);
+
+    // set first frame
+    cvGrabFrame(mVideoStream);
+    cvGrabFrame(mVideoStream);
+    mCurrentVideoFrame = cvRetrieveFrame(mVideoStream);
+
+    _updateTextureFromImage(mCurrentVideoFrame);
+
+    mMaterialName = "Video Texture "+ mVideoFileName;
+    mTimeSinceLastUpdate.reset();
+
+    mFrameCount = cvGetCaptureProperty(mVideoStream, CV_CAP_PROP_FRAME_COUNT);
+    mCurrentFrameIndex = 2;
+
+    mLog->logMessage("init done");
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::nextFrame()
+{
+    if (mTimeSinceLastUpdate.getMilliseconds() > 37 &&
+        mCurrentFrameIndex < mFrameCount) 
+    {
+        cvGrabFrame(mVideoStream);
+        mCurrentVideoFrame = cvRetrieveFrame(mVideoStream);
+        _updateTextureFromImage(mCurrentVideoFrame);
+        mTimeSinceLastUpdate.reset();
+        mCurrentFrameIndex++;
+    }
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_createTextureFromCapture(CvCapture *_capture)
+{
+
+    int w, h;
+    w = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH);
+    h = cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT);
+
+
+    // Create the texture
+    mVideoTexture = Ogre::TextureManager::getSingleton().createManual(
+        "DynamicTexture", // name
+        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
+        Ogre::TEX_TYPE_2D,      // type
+        1024, 1024,         // width & height
+        0,                // number of mipmaps
+        Ogre::PF_BYTE_RGBA,
+        Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);     
+
+    _initTexture(mVideoTexture);
+
+    // Create a material using the texture
+    mVideoMaterial = Ogre::MaterialManager::getSingleton().create(
+        mMaterialName, // name
+        Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+    mVideoMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("DynamicTexture");
+    mVideoMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
+
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_initTexture(Ogre::TexturePtr _texture)
+{
+    // Get the pixel buffer
+    Ogre::HardwarePixelBufferSharedPtr pixelBuffer = _texture->getBuffer();
+
+    // Lock the pixel buffer and get a pixel box
+    pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD!
+    const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
+
+    Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
+
+    // Fill in some pixel data. This will give a semi-transparent blue,
+    // but this is of course dependent on the chosen pixel format.
+    for (size_t j = 0; j < _texture->getHeight(); j++)
+        for(size_t i = 0; i < _texture->getWidth() ; i++)
+        {
+
+            if (j<480-5 && i<640-5)
+            {
+                *pDest++ = 255; // B
+                *pDest++ = 0; // G
+                *pDest++ = 255; // R
+            }
+            else
+            {
+                *pDest++ = 255; // B
+                *pDest++ = 0;   // G
+                *pDest++ = 0; // R
+            }
+
+        }
+
+        // Unlock the pixel buffer
+        pixelBuffer->unlock();
+}
+//------------------------------------------------------------------------------
+void OgreVideoTexture::_updateTextureFromImage(const IplImage *_image)
+{
+    mTimer.reset();
+    // Get the pixel buffer
+    Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mVideoTexture->getBuffer();
+
+    // Lock the pixel buffer and get a pixel box
+    pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL); // for best performance use HBL_DISCARD!
+    const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
+    
+    Ogre::uint8* pDest = static_cast<Ogre::uint8*>(pixelBox.data);
+
+    // Fill in some pixel data. This will give a semi-transparent blue,
+    // but this is of course dependent on the chosen pixel format.
+    for (size_t j = 0; j < _image->height; j++)
+        for(size_t i = 0; i < _image->width ; i++)
+        {
+            char pixelR = CV_IMAGE_ELEM(_image, char, j, i*3+2 );
+            char pixelG = CV_IMAGE_ELEM(_image, char, j, i*3+1);
+            char pixelB = CV_IMAGE_ELEM(_image, char, j, i*3 );
+
+            int w = mVideoTexture->getWidth();
+
+            pDest[j*w*4 + i*4]   = pixelB;
+            pDest[j*w*4 + i*4+1] = pixelG;
+            pDest[j*w*4 + i*4+2] = pixelR;
+            pDest[j*w*4 + i*4+3] = 255;
+        }
+
+    // Unlock the pixel buffer
+    pixelBuffer->unlock();
+
+    boost::format fmt("%1% : %2% �s");
+    
+    fmt % "write to texture" % mTimer.getMicroseconds();
+    
+    mLog->logMessage(fmt.str());
+}

File ogre-movingcube/OgreVideoTexture.h

+#pragma once
+
+
+#include <cv.h>
+#include <highgui.h>
+
+#include <Ogre.h>
+
+
+class OgreVideoTexture
+{
+public:
+    OgreVideoTexture(const Ogre::String);
+    ~OgreVideoTexture(void);
+    Ogre::String getMaterialName() const { return mVideoMaterial->getName();};
+    void nextFrame();
+
+protected:
+    void _init();
+    void _createTextureFromCapture(CvCapture*);
+    void _initTexture(Ogre::TexturePtr);
+    void _updateTextureFromImage(const IplImage*);
+
+protected:
+    Ogre::String mVideoFileName;
+    CvCapture *mVideoStream;
+    IplImage *mCurrentVideoFrame;
+    Ogre::TexturePtr mVideoTexture;
+    Ogre::MaterialPtr mVideoMaterial;
+    Ogre::String mMaterialName;
+    Ogre::Timer mTimeSinceLastUpdate;
+    int mFrameCount, mCurrentFrameIndex;
+    Ogre::Log *mLog;
+    Ogre::Timer mTimer;
+};

File ogre-movingcube/ogre-movingcube.cpp

+
+
+#include "OgreVideoTexture.h"
 #include "ExampleApplication.h"
-//#include <boost/interprocess/ipc/message_queue.hpp>
+
+
+
 
 class TutorialFrameListener : public ExampleFrameListener
 {
 public:
-	TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)
+    TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr, SceneNode *canvasNode, OgreVideoTexture *_videoTexture)
 		: ExampleFrameListener(win, cam, false, false)
 	{
 		// key and mouse state tracking
 		mRotate = 0.13;
 		mMove = 250;
 
-		
-		mq = new boost::interprocess::message_queue(boost::interprocess::open_only, "message_queue");
+		mCanvasNode = canvasNode;
+        mVideoTexture = _videoTexture;
+	
 	}
 
-	// Overriding the default processUnbufferedKeyInput so the key updates we define
-	// later on work as intended.
-	bool processUnbufferedKeyInput(const FrameEvent& evt)
-	{
-		return true;
-	}
+	//// Overriding the default processUnbufferedKeyInput so the key updates we define
+	//// later on work as intended.
+	//bool processUnbufferedKeyInput(const FrameEvent& evt)
+	//{
+	//	return true;
+	//}
 
-	// Overriding the default processUnbufferedMouseInput so the Mouse updates we define
-	// later on work as intended. 
-	bool processUnbufferedMouseInput(const FrameEvent& evt)
-	{
-		return true;
-	}
+	//// Overriding the default processUnbufferedMouseInput so the Mouse updates we define
+	//// later on work as intended. 
+	//bool processUnbufferedMouseInput(const FrameEvent& evt)
+	//{
+	//	return true;
+	//}
 
 	bool frameStarted(const FrameEvent &evt)
 	{
-		//mCamNode->getParentSceneNode()->yaw(Degree(1.0), SceneNode::TS_PARENT);
-		processMQEvents();
+		//mCamNode->getParentSceneNode()->yaw(Degree(1.0) * evt.timeSinceLastFrame * 200, SceneNode::TS_PARENT);
+        //mCanvasNode->roll(Degree(1.0) * evt.timeSinceLastFrame * 100);
+
+        mVideoTexture->nextFrame();
 
 		mMouse->capture();
 		mKeyboard->capture();
 
+
 		if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
 			return false;
 
 		return true;
-	}
 
-
-	//void processMQEvents()
-	//{
-	//	unsigned int priority;
-	//	std::size_t recvd_size;
-
-	//	int num = mq->get_num_msg();
-	//	
-	//	int number;
-	//	if(num > 0)
-	//	{
-	//		//for(int i = 0; i < 10; ++i)
-	//		//{
-	//		//	int number;
-	//		//	//number = buffer[i]
-	//		//	//mq->receive(&number, sizeof(number), recvd_size, priority);
-	//		//}
-	//		mq->receive(&number, sizeof(number), recvd_size, priority);
-	//		mCamNode->getParentSceneNode()->yaw(Degree(float(number)), SceneNode::TS_PARENT);
-	//	}
-	//	else
-	//	{
-	//		; //mCamNode->translate(Vector3(0, 10, 0));
-	//	}
 	}
 
 protected:
 	Real mMove;            // The movement constant
 	SceneManager *mSceneMgr;   // The current SceneManager
 	SceneNode *mCamNode;   // The SceneNode the camera is currently attached to
-
-	boost::interprocess::message_queue *mq;
+    SceneNode *mCanvasNode;
+    OgreVideoTexture *mVideoTexture;
 	char *mBuffer;
 };
 
 
 	void createScene(void)
 	{
+        
 		mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
 
-		Entity *ent = mSceneMgr->createEntity("Ninja", "cube.mesh");
-		SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode", Vector3(0, 100, 0));
-		node->attachObject(ent);
+
+        mCanvas = mSceneMgr->createManualObject("video canvas");
+        mCanvas->begin("BaseWhiteNoLighting", RenderOperation::OT_TRIANGLE_STRIP);
+        //mCanvas->position(-0.65,  0.5, 0);   mCanvas->textureCoord(    0, 0.9375);
+        //mCanvas->position( 0.65,  0.5, 0);   mCanvas->textureCoord(0.625, 0.9375);
+        //mCanvas->position(-0.65, -0.5, 0);   mCanvas->textureCoord(    0,      0);
+        //mCanvas->position( 0.65, -0.5, 0);   mCanvas->textureCoord(0.625,      0);
+
+    
+        float uMin = 0, vMin = 0;
+        float uMax = 640.0/1024, vMax = 480.0/1024;
+
+        mCanvas->position(-0.65,  0.5, 0);   mCanvas->textureCoord(uMin, vMax);
+        mCanvas->position( 0.65,  0.5, 0);   mCanvas->textureCoord(uMax, vMax);
+        mCanvas->position(-0.65, -0.5, 0);   mCanvas->textureCoord(uMin, vMin);
+        mCanvas->position( 0.65, -0.5, 0);   mCanvas->textureCoord(uMax, vMin);
+        mCanvas->end();
+
+
+        SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Canvas Node", Vector3(0, 100, 0));
+        node->attachObject(mCanvas);
+        node->scale(100, 100, 100);
+        node->yaw(Degree(180.0));
+        node->roll(Degree(180.0));
+        mCanvasNode = node;
+
+
 
 		Light *light = mSceneMgr->createLight("Light1");
 		light->setType(Light::LT_POINT);
 
 		// Create the scene node
 		SceneNode *yawnode = mSceneMgr->getRootSceneNode()->createChildSceneNode("YawCamNode1");
-		node = yawnode->createChildSceneNode("CamNode1", Vector3(-400, 200, 400));
-		node->yaw(Degree(-45));
+		node = yawnode->createChildSceneNode("CamNode1", Vector3(0, 100, 400));
 		node->attachObject(mCamera);
 
-		// create the second camera node
-		node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(0, 200, 400));
+
+        mVideoTexture = new OgreVideoTexture("indochine.avi");
+        mCanvas->setMaterialName(0, mVideoTexture->getMaterialName());
+        
 	}
 
+
+
+
+
+
 	void createFrameListener(void)
 	{
 		// Create the FrameListener
-		mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);
+		mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr, mCanvasNode, mVideoTexture);
 		mRoot->addFrameListener(mFrameListener);
 	}
+
+protected:
+    SceneNode *mCanvasNode;
+    ManualObject *mCanvas;
+    OgreVideoTexture *mVideoTexture;
 };
 
 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32

File ogre-movingcube/ogre-movingcube.vcproj

 			<Tool
 				Name="VCCLCompilerTool"
 				Optimization="0"
-				AdditionalIncludeDirectories="&quot;$(BOOST_HOME)\&quot;;&quot;$(OGRE_HOME)\OgreMain\include&quot;;&quot;$(OGRE_HOME)\Dependencies\include&quot;;&quot;$(OGRE_HOME)\Samples\Common\include&quot;"
+				AdditionalIncludeDirectories="&quot;$(BOOST_HOME)\&quot;;&quot;$(OGRE16_HOME)\OgreMain\include&quot;;&quot;$(OGRE16_HOME)\Dependencies\include&quot;;&quot;$(OGRE16_HOME)\Samples\Common\include&quot;;&quot;C:\libs\OpenCV-1.1\cvaux\include&quot;;&quot;C:\libs\OpenCV-1.1\cv\include&quot;;&quot;C:\libs\OpenCV-1.1\cxcore\include&quot;;&quot;C:\libs\OpenCV-1.1\otherlibs\highgui&quot;"
 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 			/>
 			<Tool
 				Name="VCLinkerTool"
-				AdditionalDependencies="OgreMain_d.lib OIS_d.lib OgreGUIRenderer_d.lib"
+				AdditionalDependencies="OgreMain_d.lib OIS_d.lib OgreGUIRenderer_d.lib cvd.lib cvauxd.lib cxcored.lib highguid.lib"
 				LinkIncremental="2"
-				AdditionalLibraryDirectories="&quot;$(BOOST_HOME)\stage\lib&quot;;&quot;$(OGRE_HOME)\lib&quot;;&quot;$(OGRE_HOME)\Dependencies\lib\Debug&quot;"
+				AdditionalLibraryDirectories="&quot;$(OGRE16_HOME)\lib&quot;;&quot;$(OGRE16_HOME)\Dependencies\lib\Debug&quot;;&quot;C:\libs\OpenCV-1.1\lib&quot;"
 				GenerateDebugInformation="true"
 				SubSystem="2"
 				TargetMachine="1"
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
+				AdditionalIncludeDirectories="&quot;$(BOOST_HOME)\&quot;;&quot;$(OGRE16_HOME)\OgreMain\include&quot;;&quot;$(OGRE16_HOME)\Dependencies\include&quot;;&quot;$(OGRE16_HOME)\Samples\Common\include&quot;;&quot;C:\libs\OpenCV-1.1\cvaux\include&quot;;&quot;C:\libs\OpenCV-1.1\cv\include&quot;;&quot;C:\libs\OpenCV-1.1\cxcore\include&quot;;&quot;C:\libs\OpenCV-1.1\otherlibs\highgui&quot;"
 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
 				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="true"
 			/>
 			<Tool
 				Name="VCLinkerTool"
+				AdditionalDependencies="OgreMain.lib OIS.lib OgreGUIRenderer.lib cv.lib cvaux.lib cxcore.lib highgui.lib"
 				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;$(OGRE16_HOME)\lib&quot;;&quot;$(OGRE16_HOME)\Dependencies\lib\Release&quot;;&quot;C:\libs\OpenCV-1.1\lib&quot;"
 				GenerateDebugInformation="true"
 				SubSystem="2"
 				OptimizeReferences="2"
 				RelativePath=".\ogre-movingcube.cpp"
 				>
 			</File>
+			<File
+				RelativePath=".\OgreVideoTexture.cpp"
+				>
+			</File>
+			<Filter
+				Name="OgreDShow"
+				>
+				<File
+					RelativePath=".\OgreDShow\UtilsOgreDshow.cpp"
+					>
+					<FileConfiguration
+						Name="Debug|Win32"
+						ExcludedFromBuild="true"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+						/>
+					</FileConfiguration>
+					<FileConfiguration
+						Name="Release|Win32"
+						ExcludedFromBuild="true"
+						>
+						<Tool
+							Name="VCCLCompilerTool"
+						/>
+					</FileConfiguration>
+				</File>
+			</Filter>
 		</Filter>
 		<Filter
 			Name="Header Files"
 			Filter="h;hpp;hxx;hm;inl;inc;xsd"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			<File
+				RelativePath=".\OgreVideoTexture.h"
+				>
+			</File>
+			<Filter
+				Name="OgreDShow"
+				>
+				<File
+					RelativePath=".\OgreDShow\UtilsOgreDshow.h"
+					>
+				</File>
+				<File
+					RelativePath=".\OgreDShow\UtilsOgreDshow_private.h"
+					>
+				</File>
+			</Filter>
 		</Filter>
 		<Filter
 			Name="Resource Files"