Playing movie in texture

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Sundar
Posts: 84
Joined: Mon Jun 05, 2006 11:05 am

Post by Sundar »

Same Problem Here Also. Only One diffrence instead of playing FirstFrame Only last frame is playing and also no audio. pls help with this. i need this feature desperatly for my new prototype.
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Hi,

I have been away from this topic for a long while, doing other things (like this: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=12953 :wink: )

But I have found the solution to the problem that the movie hangs on the (first) frame. And it is embarassingly simple .....
You just have to add another mesh to the scene. I used an addAnimatedMeshSceneNode with a .x file. Position and texture don't matter. After that the movie playes perfectly.
The cause of the problem lies (I think) in the updating of the texture after Buf->unlock(); is called. The video driver (OpenGL in my case) doesn't get a signal to update the texture.

I stumbled upon this solution when trying to create a movie player class using the avi player from the video-for-windows library. My class uses the same basic (and brilliant) idea to read frames and memcopy these into the irrlicht texture.
Drawback is of course the fact that you can only load avi's. Big advantage is performance. With the direct show code I got about 135 FPS. The vfw-avi code gave well over 1000 FPS :!: Both examples with exactly the same setup and no visible difference in quality.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

evo wrote:
I stumbled upon this solution when trying to create a movie player class using the avi player from the video-for-windows library. My class uses the same basic (and brilliant) idea to read frames and memcopy these into the irrlicht texture.
Drawback is of course the fact that you can only load avi's. Big advantage is performance. With the direct show code I got about 135 FPS. The vfw-avi code gave well over 1000 FPS :!: Both examples with exactly the same setup and no visible difference in quality.
evo:

are you going to post your avi class to the fourm, and if so could i merge
it with my new Magic3D Library,ofcourse i will cridte it for you.

thanks
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Sure. Posting code is no problem. Nor is using it in your Magic3d lib. I just had to clean it up a bit first.

There is however a to do list, so this code is not complete yet:
- fix code to run with dx9 : error locking texture
- running 2 or more avi's simultaneously
- gettting the texture mapped onto any mesh instead of the CSampleSceneNode. Maybe you have some ideas for this Emil ?
- speed up the 'memcopy' code further

Include 'vfw32.lib' under linker options. It can be found in: Microsoft Platform SDK for Windows Server 2003 R2

Code: Select all

#include <irrlicht.h> 
//#include <stdio.h>
#include <windows.h>
#include <vfw.h>

using namespace irr; 

class AVIMovie
{
public:
	PAVIFILE			Avi;
	AVIFILEINFO			avi_info;
	BITMAPINFOHEADER	bih;
	PAVISTREAM			pStream;
	PGETFRAME			getFrameObject;
	HRESULT				hr;
	u32					iNumFrames;
	u32					iFirstFrame;
	u32					iCurrentFrame;
	bool				FrameUpdate;		// true if new frame should be displayed
	bool				StreamOK;			// flag to signal that stream is OK to be displayed
	bool				LoopMovie;
	bool				IsMovieRunning;
	bool				NotPauzed;
	DWORD				time;
	DWORD				oldtick;

	AVIMovie()
	{
		StreamOK		= false;
		LoopMovie		= false;
		IsMovieRunning	= true;
		NotPauzed		= true;
		iCurrentFrame	= 0;
		oldtick			= GetTickCount();
	};

	~AVIMovie()
	{
	};


	void LogAVIError(HRESULT hres)
	{
		if (hres!=AVIERR_OK)
		{
			switch (hres)
			{
				case AVIERR_BADFORMAT		:	printf("The file couldn't be read, indicating a corrupt file or an unrecognized format\n");	break;
				case AVIERR_MEMORY			:	printf("The file could not be opened because of insufficient memory\n");	break;
				case AVIERR_FILEREAD		:	printf("A disk error occurred while reading the file\n");	break;
				case AVIERR_FILEOPEN		:	printf("A disk error occurred while opening the file\n");	break;
				case AVIERR_NODATA			:	printf("The file does not contain a stream corresponding to the values of fccType and lParam\n");	break;
				case AVIERR_UNSUPPORTED		:	printf("AVIERR_UNSUPPORTED\n");	break;
				case AVIERR_INTERNAL		:	printf("AVIERR_INTERNAL\n");	break;
				case AVIERR_BADFLAGS		:	printf("AVIERR_BADFLAGS\n");	break;
				case AVIERR_BADPARAM		:	printf("AVIERR_BADPARAM\n");	break;
				case AVIERR_BADSIZE			:	printf("AVIERR_BADSIZE\n");	break;
				case AVIERR_BADHANDLE		:	printf("AVIERR_BADHANDLE\n");	break;
				case AVIERR_FILEWRITE		:	printf("AVIERR_FILEWRITE\n");	break;
				case AVIERR_COMPRESSOR		:	printf("AVIERR_COMPRESSOR\n");	break;
				case AVIERR_NOCOMPRESSOR	:	printf("AVIERR_NOCOMPRESSOR\n");	break;
				case AVIERR_BUFFERTOOSMALL	:	printf("AVIERR_BUFFERTOOSMALL\n");	break;
				case AVIERR_CANTCOMPRESS	:	printf("AVIERR_CANTCOMPRESS\n");	break;
				case AVIERR_USERABORT		:	printf("AVIERR_USERABORT\n");	break;
				case AVIERR_ERROR			:	printf("AVIERR_ERROR\n");	break;
				case REGDB_E_CLASSNOTREG	:	printf("According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it\n");	break;
			}
			if (pStream!=NULL)	AVIStreamRelease(pStream);
			if (Avi!=NULL)		AVIFileRelease(Avi);
			AVIFileExit();
		}
	}
	void FrameOpen(short int countBitsPerPixel)
	{	
		bih.biBitCount = countBitsPerPixel;
		bih.biClrImportant = 0;
		bih.biClrUsed = 0;
		bih.biCompression = BI_RGB;
		bih.biPlanes = 1;
		bih.biSize = sizeof(bih);
		bih.biXPelsPerMeter = 0;
		bih.biYPelsPerMeter = 0;
		bih.biHeight = 0;
		bih.biWidth = 0;
		if (bih.biBitCount > 24)					bih.biBitCount = 32;
		else if (bih.biBitCount > 16)				bih.biBitCount = 24;
			else if (bih.biBitCount > 8)			bih.biBitCount = 16;
				else if (bih.biBitCount > 4)		bih.biBitCount =  8;
					else if (bih.biBitCount > 0)	bih.biBitCount =  4;
	
		bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight;	// = 0
	}

	// CreateFromPackedDIBPointer function is taken from:
	// http://www.codeproject.com/audio/ExtractAVIFrames.asp
	// Author: A. Riazi
	// This function creates a .bmp file on disk from the current frame
	bool CreateFromPackedDIBPointer(LPBYTE pDIB, int iFrame)
	{
		if (pDIB!=NULL)
		{
			//Creates a full-color (no palette) DIB from a pointer to a
			//full-color memory DIB

			//get the BitmapInfoHeader
			BITMAPINFOHEADER bih;
			RtlMoveMemory(&bih.biSize, pDIB, sizeof(BITMAPINFOHEADER));

			//now get the bitmap bits
			if (bih.biSizeImage < 1)
			{
				return FALSE;
			}

			BYTE* Bits=new BYTE[bih.biSizeImage];

			RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih.biSizeImage);

			//and BitmapInfo variable-length UDT
			BYTE memBitmapInfo[40];
			RtlMoveMemory(memBitmapInfo, &bih, sizeof(bih));

			BITMAPFILEHEADER bfh;
			bfh.bfType=19778;    //BM header
			bfh.bfSize=55 + bih.biSizeImage;
			bfh.bfReserved1=0;
			bfh.bfReserved2=0;
			bfh.bfOffBits=sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); //54
		    
			char * FileName = new char[200];
			sprintf(FileName, "Frame-%05d.bmp", iFrame);
		    
			FILE* fp=fopen(FileName, "wb");
			if (fp!=NULL)
			{
				fwrite(&bfh, sizeof(bfh), 1, fp);
				fwrite(&memBitmapInfo, sizeof(memBitmapInfo), 1, fp);
				fwrite(Bits, bih.biSizeImage, 1, fp);
				fclose(fp);
			}
			else
			{
				printf("Error writing the bitmap file\n");
				return false;
			}

			delete [] Bits;
			return true;
		}
		else return false;
	}

	bool GetNextFrame()
	{
		FrameUpdate = false;
		if((GetTickCount() - oldtick) > time)
		{
			oldtick = GetTickCount();
			if (iCurrentFrame < iFirstFrame) iCurrentFrame = iFirstFrame;
			else
			{
				iCurrentFrame++;
				FrameUpdate = true;
			}

			if (iCurrentFrame >= iNumFrames)
			{
				if (LoopMovie)
				{
					iCurrentFrame = iFirstFrame;
					FrameUpdate = true;
				}
				else return false;
			}
		}
		return true;
	}

	void DrawMovie(irr::video::ITexture* Buf)
	{
		if (NotPauzed)
		{
			BYTE* pBits = (BYTE*)Buf->lock();
			LONG  Pitch = Buf->getPitch();  
			IsMovieRunning = GetNextFrame();

			//printf("frame=%d %s\n",iCurrentFrame, FrameUpdate ? "U" : "");
			if (pBits && IsMovieRunning && FrameUpdate)
			{
				BYTE* pDIB = (BYTE*) AVIStreamGetFrame(getFrameObject, iCurrentFrame); // assuming 24bit BMP
				u32 wmin = bih.biWidth;
				u32 i = 0, t = 0;
				for(u32 h = 0; h < bih.biHeight; h++)
				{
					i = (bih.biHeight - h - 1) * wmin * 3  + sizeof(BITMAPINFOHEADER);	// BMP format starts with bottom line
					t = (h * Pitch);
					for(u32 w = 0; w < bih.biWidth; w++)
					{
						pBits[t + (w*4)    ] = pDIB[i + (w*3) + 2];	//B
						pBits[t + (w*4) + 1] = pDIB[i + (w*3) + 1];	//G
						pBits[t + (w*4) + 2] = pDIB[i + (w*3)    ];	//R
						pBits[t + (w*4) + 3] = 0;					//Alpha
					}
				}
				//if (iCurrentFrame==1) CreateFromPackedDIBPointer(pDIB, iCurrentFrame);	// make a snapshot
				Buf->unlock();
			}
		}
	}

	void SetMovieFPS(int fps)
	{
		time = (DWORD)(1000.0/fps);
	}

	void Stop()
	{
		NotPauzed = false;
	}

	void Run()
	{
		NotPauzed = true;
	}

	bool IsRunning()
	{
		return IsMovieRunning;
	}

	bool OpenAVIStream(char* filename)
	{
		AVIFileInit();
		
		hr = AVIFileOpen(&Avi, filename, OF_READ, NULL);
		if (hr!=AVIERR_OK)
		{
			LogAVIError(hr);
			return false;
		}
		
		AVIFileInfo(Avi, &avi_info, sizeof(AVIFILEINFO));

		hr = AVIFileGetStream(Avi, &pStream, streamtypeVIDEO, 0 );
		if (hr!=AVIERR_OK)
		{
			LogAVIError(hr);
			return false;
		}

		// get the stream
		iFirstFrame = AVIStreamStart(pStream);
		if (iFirstFrame==-1)
		{
			printf("Error retreiving the first frame\n");
			LogAVIError(0);
			return false;
		}

		iNumFrames = AVIStreamLength(pStream);
		if (iNumFrames==-1)
		{
			printf("Error retreiving the number of frames\n");
			LogAVIError(0);
			return false;
		}

		FrameOpen(24); // 24-bit colour BMP
		getFrameObject = AVIStreamGetFrameOpen(pStream, &bih);

		StreamOK = true;
		return true;
	}

	bool CloseAVIStream()
	{
		AVIStreamGetFrameClose(getFrameObject);
		if (pStream!=NULL)	AVIStreamRelease(pStream);
		if (Avi!=NULL)		AVIFileRelease(Avi);
		AVIFileExit();
		return true;
	}
};

class CSampleSceneNode : public scene::ISceneNode 
{ 
	core::aabbox3d<f32> Box;
	video::S3DVertex Vertices[4];
	video::SMaterial Material;
      
   public: 
	   CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id)
       {  
           float u = 320.0f/512.0f;
           float v = 240.0f/256.0f;
           Material.Wireframe = false;
           Material.Lighting = false;
           Vertices[0] = video::S3DVertex(-40,-30,0, 0,0,0,video::SColor(255,255,255,255),0,v);
           Vertices[1] = video::S3DVertex( 40,-30,0, 0,0,0,video::SColor(255,255,255,255),u,v); 
           Vertices[2] = video::S3DVertex( 40, 30,0, 0,0,0,video::SColor(255,255,255,255),u,0);
           Vertices[3] = video::S3DVertex(-40, 30,0, 0,0,0,video::SColor(255,255,255,255),0,0);
           
           Box.reset(Vertices[0].Pos);
           for (s32 i=1; i<4; ++i)  Box.addInternalPoint(Vertices[i].Pos);
       }
     
     virtual void OnPreRender()
      { 
          if (IsVisible)    SceneManager->registerNodeForRendering(this);
          ISceneNode::OnPreRender();
      }
      
     virtual void render()
      {  
          u16 indices[] = { 0,1,3, 3,1,2, 1,0,2, 2,0,3 };
		  video::IVideoDriver* driver = SceneManager->getVideoDriver();
          driver->setMaterial(Material);
          driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
          driver->drawIndexedTriangleList(&Vertices[0], (u16)4, &indices[0], 4);
      }

     virtual const core::aabbox3d<f32>& getBoundingBox() const 
      { 
          return Box; 
      }
 
     virtual s32 getMaterialCount()
      {
          return 1;
      }
 
     virtual video::SMaterial& getMaterial(s32 i)
      {
          return Material;
      } 
};

int main()
{
	// set up irrlicht
	IrrlichtDevice*			device		= createDevice(video::EDT_OPENGL,core::dimension2d<s32>(800,600),32,false,false,false,0);
	video::IVideoDriver*	irrVideo	= device->getVideoDriver();
	scene::ISceneManager*	irrSceneMgr	= device->getSceneManager();
	irrSceneMgr->addCameraSceneNode(0, core::vector3df(0,0,-60), core::vector3df(0,0,0));
	irrVideo->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT , TRUE);
	irrVideo->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, FALSE);

	// Create movie
	AVIMovie *MyAvi = new AVIMovie;
	MyAvi->SetMovieFPS(15);
	MyAvi->OpenAVIStream("some_avi_file.avi");

	// create node
	video::ITexture* movTxtr = irrVideo->addTexture(core::dimension2d<s32>(512,256),"movie",video::ECF_A8R8G8B8);
	CSampleSceneNode* myNode = new CSampleSceneNode(irrSceneMgr->getRootSceneNode(), irrSceneMgr, 100);
	myNode->setMaterialTexture( 0, movTxtr);
	myNode->drop();
	scene::ISceneNodeAnimator* anim = irrSceneMgr->createRotationAnimator(core::vector3df(0.1f,0,0.1f));
	myNode->addAnimator(anim);
	myNode->setMaterialTexture( 0, movTxtr);
	anim->drop();

	// create node to fix movie hanging on the first frame
	scene::IAnimatedMeshSceneNode* wallNode = irrSceneMgr->addAnimatedMeshSceneNode(irrSceneMgr->getMesh("some_x_file.x"), 0, 1000,
										core::vector3df(0, 0, 100), core::vector3df(0, 0, 0), core::vector3df(1, 1, 1) );
	
	int   FPS, lastFPS=-1;
	while(device->run() && MyAvi->IsRunning() )
	{
		irrVideo->beginScene(true, true, video::SColor(0,200,200,200));
		MyAvi->DrawMovie(movTxtr);
		irrSceneMgr->drawAll();
		irrVideo->endScene();

		FPS = irrVideo->getFPS();
		if (lastFPS != FPS)
		{	core::stringw Title = L"Evo's AVI Demo - FPS: ";
			Title += FPS;
			lastFPS = FPS;
			device->setWindowCaption(Title.c_str());
		}
	}
	device->drop();
	
	MyAvi->CloseAVIStream();
	delete MyAvi;
	
	//system("Pause");
    return 0;
}
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

the error of locking texture in Dx9 was take place because you but the
unlock function inside if statment block so here is the correct code

Code: Select all

void DrawMovie(irr::video::ITexture* Buf)
   {
      if (NotPauzed)
      {
         BYTE* pBits = (BYTE*)Buf->lock();
         LONG  Pitch = Buf->getPitch();
         IsMovieRunning = GetNextFrame();

         //printf("frame=%d %s\n",iCurrentFrame, FrameUpdate ? "U" : "");
         if (pBits && IsMovieRunning && FrameUpdate)
         {
            BYTE* pDIB = (BYTE*) AVIStreamGetFrame(getFrameObject, iCurrentFrame); // assuming 24bit BMP
            u32 wmin = bih.biWidth;
            u32 i = 0, t = 0;
            for(u32 h = 0; h < bih.biHeight; h++)
            {
               i = (bih.biHeight - h - 1) * wmin * 3  + sizeof(BITMAPINFOHEADER);   // BMP format starts with bottom line
               t = (h * Pitch);
               for(u32 w = 0; w < bih.biWidth; w++)
               {
                  pBits[t + (w*4)    ] = pDIB[i + (w*3) + 2];   //B
                  pBits[t + (w*4) + 1] = pDIB[i + (w*3) + 1];   //G
                  pBits[t + (w*4) + 2] = pDIB[i + (w*3)    ];   //R
                  pBits[t + (w*4) + 3] = 0;               //Alpha
               }
            }
            //if (iCurrentFrame==1) CreateFromPackedDIBPointer(pDIB, iCurrentFrame);   // make a snapshot
         }
         Buf->unlock();
      }
   }
but i do not successe get this code to work,i have to study your class
well then may i found the problem.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

evo:

i have successfully run it here is my AVI classes for playing movie with
Magic3D Library.

Code: Select all

/******************************************************

           AVIMovie class

         created by evo,big thanks for him
         for allowing to include his work
         with Magic3D Library.

         adapted for using with Magic3D Library
         By Emil Halim.


******************************************************/


#ifndef __I_AVIMovie_Magic_H_INCLUDED__
#define __I_AVIMovie_Magic_H_INCLUDED__


class AVIMovie
{
public:
   PAVIFILE            Avi;
   AVIFILEINFO         avi_info;
   BITMAPINFOHEADER    bih;
   PAVISTREAM          pStream;
   PGETFRAME           getFrameObject;
   HRESULT             hr;
   u32                 iNumFrames;
   u32                 iFirstFrame;
   u32                 iCurrentFrame;
   bool                FrameUpdate;      // true if new frame should be displayed
   bool                StreamOK;         // flag to signal that stream is OK to be displayed
   bool                LoopMovie;
   bool                IsMovieRunning;
   bool                NotPauzed;
   DWORD               time;
   DWORD               oldtick;

   AVIMovie()
   {
      StreamOK        = false;
      LoopMovie       = false;
      IsMovieRunning  = true;
      NotPauzed       = true;
      iCurrentFrame   = 0;
      oldtick         = GetTickCount();
   };

   ~AVIMovie()
   {
   };


   void LogAVIError(HRESULT hres)
   {
      if (hres!=AVIERR_OK)
      {
         switch (hres)
         {
            case AVIERR_BADFORMAT      :   printf("The file couldn't be read, indicating a corrupt file or an unrecognized format\n");   break;
            case AVIERR_MEMORY         :   printf("The file could not be opened because of insufficient memory\n");   break;
            case AVIERR_FILEREAD       :   printf("A disk error occurred while reading the file\n");   break;
            case AVIERR_FILEOPEN       :   printf("A disk error occurred while opening the file\n");   break;
            case AVIERR_NODATA         :   printf("The file does not contain a stream corresponding to the values of fccType and lParam\n");   break;
            case AVIERR_UNSUPPORTED    :   printf("AVIERR_UNSUPPORTED\n");    break;
            case AVIERR_INTERNAL       :   printf("AVIERR_INTERNAL\n");       break;
            case AVIERR_BADFLAGS       :   printf("AVIERR_BADFLAGS\n");       break;
            case AVIERR_BADPARAM       :   printf("AVIERR_BADPARAM\n");       break;
            case AVIERR_BADSIZE        :   printf("AVIERR_BADSIZE\n");        break;
            case AVIERR_BADHANDLE      :   printf("AVIERR_BADHANDLE\n");      break;
            case AVIERR_FILEWRITE      :   printf("AVIERR_FILEWRITE\n");      break;
            case AVIERR_COMPRESSOR     :   printf("AVIERR_COMPRESSOR\n");     break;
            case AVIERR_NOCOMPRESSOR   :   printf("AVIERR_NOCOMPRESSOR\n");   break;
            case AVIERR_BUFFERTOOSMALL :   printf("AVIERR_BUFFERTOOSMALL\n"); break;
            case AVIERR_CANTCOMPRESS   :   printf("AVIERR_CANTCOMPRESS\n");   break;
            case AVIERR_USERABORT      :   printf("AVIERR_USERABORT\n");      break;
            case AVIERR_ERROR          :   printf("AVIERR_ERROR\n");          break;
            case REGDB_E_CLASSNOTREG   :   printf("According to the registry, the type of file specified in AVIFileOpen does not have a handler to process it\n");   break;
         }
         if (pStream!=NULL)   AVIStreamRelease(pStream);
         if (Avi!=NULL)      AVIFileRelease(Avi);
         AVIFileExit();
      }
   }

   void FrameOpen(short int countBitsPerPixel)
   {
      bih.biBitCount = countBitsPerPixel;
      bih.biClrImportant = 0;
      bih.biClrUsed = 0;
      bih.biCompression = BI_RGB;
      bih.biPlanes = 1;
      bih.biSize = sizeof(bih);
      bih.biXPelsPerMeter = 0;
      bih.biYPelsPerMeter = 0;
      bih.biHeight = 0;
      bih.biWidth = 0;
      if (bih.biBitCount > 24)                bih.biBitCount = 32;
      else if (bih.biBitCount > 16)           bih.biBitCount = 24;
         else if (bih.biBitCount > 8)         bih.biBitCount = 16;
            else if (bih.biBitCount > 4)      bih.biBitCount =  8;
               else if (bih.biBitCount > 0)   bih.biBitCount =  4;

      bih.biSizeImage = (((bih.biWidth * 3) + 3) & 0xFFFC) * bih.biHeight;   // = 0
   }

   // CreateFromPackedDIBPointer function is taken from:
   // http://www.codeproject.com/audio/ExtractAVIFrames.asp
   // Author: A. Riazi
   // This function creates a .bmp file on disk from the current frame
   bool CreateFromPackedDIBPointer(LPBYTE pDIB, int iFrame)
   {
      if (pDIB!=NULL)
      {
         //Creates a full-color (no palette) DIB from a pointer to a
         //full-color memory DIB

         //get the BitmapInfoHeader
         BITMAPINFOHEADER bih;
         RtlMoveMemory(&bih.biSize, pDIB, sizeof(BITMAPINFOHEADER));

         //now get the bitmap bits
         if (bih.biSizeImage < 1)
         {
            return FALSE;
         }

         BYTE* Bits=new BYTE[bih.biSizeImage];

         RtlMoveMemory(Bits, pDIB + sizeof(BITMAPINFOHEADER), bih.biSizeImage);

         //and BitmapInfo variable-length UDT
         BYTE memBitmapInfo[40];
         RtlMoveMemory(memBitmapInfo, &bih, sizeof(bih));

         BITMAPFILEHEADER bfh;
         bfh.bfType=19778;    //BM header
         bfh.bfSize=55 + bih.biSizeImage;
         bfh.bfReserved1=0;
         bfh.bfReserved2=0;
         bfh.bfOffBits=sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER); //54

         char * FileName = new char[200];
         sprintf(FileName, "Frame-%05d.bmp", iFrame);

         FILE* fp=fopen(FileName, "wb");
         if (fp!=NULL)
         {
            fwrite(&bfh, sizeof(bfh), 1, fp);
            fwrite(&memBitmapInfo, sizeof(memBitmapInfo), 1, fp);
            fwrite(Bits, bih.biSizeImage, 1, fp);
            fclose(fp);
         }
         else
         {
            printf("Error writing the bitmap file\n");
            return false;
         }

         delete [] Bits;
         return true;
      }
      else return false;
   }

   bool GetNextFrame()
   {
      FrameUpdate = false;
      if((GetTickCount() - oldtick) > time)
      {
         oldtick = GetTickCount();
         if (iCurrentFrame < iFirstFrame) iCurrentFrame = iFirstFrame;
         else
         {
            iCurrentFrame++;
            FrameUpdate = true;
         }

         if (iCurrentFrame >= iNumFrames)
         {
            if (LoopMovie)
            {
               iCurrentFrame = iFirstFrame;
               FrameUpdate = true;
            }
            else return false;
         }
      }
      return true;
   }

   void DrawMovie(irr::video::ITexture* Buf)
   {
      if (NotPauzed)
      {
         BYTE* pBits = (BYTE*)Buf->lock();
         LONG  Pitch = Buf->getPitch();
         IsMovieRunning = GetNextFrame();

         //printf("frame=%d %s\n",iCurrentFrame, FrameUpdate ? "U" : "");
         if (pBits && IsMovieRunning && FrameUpdate)
         {
            BYTE* pDIB = (BYTE*) AVIStreamGetFrame(getFrameObject, iCurrentFrame); // assuming 24bit BMP
            u32 wmin = bih.biWidth;
            u32 i = 0, t = 0;
            for(u32 h = 0; h < bih.biHeight; h++)
            {
               i = (bih.biHeight - h - 1) * wmin * 3  + sizeof(BITMAPINFOHEADER);   // BMP format starts with bottom line
               t = (h * Pitch);
               for(u32 w = 0; w < bih.biWidth; w++)
               {
                  pBits[t + (w*4)    ] = pDIB[i + (w*3)    ];   //B
                  pBits[t + (w*4) + 1] = pDIB[i + (w*3) + 1];   //G
                  pBits[t + (w*4) + 2] = pDIB[i + (w*3) + 2];   //R
                  pBits[t + (w*4) + 3] = 255;               //Alpha
               }
            }
            //if (iCurrentFrame==1) CreateFromPackedDIBPointer(pDIB, iCurrentFrame);   // make a snapshot
         }
         Buf->unlock();
      }
   }

   void SetMovieFPS(int fps)
   {
      time = (DWORD)(1000.0/fps);
   }

   void Stop()
   {
      NotPauzed = false;
   }

   void Run()
   {
      NotPauzed = true;
   }

   bool IsRunning()
   {
      return IsMovieRunning;
   }

   bool OpenAVIStream(char* filename)
   {
      AVIFileInit();

      hr = AVIFileOpen(&Avi, filename, OF_READ, NULL);
      if (hr!=AVIERR_OK)
      {
         LogAVIError(hr);
         return false;
      }

      AVIFileInfo(Avi, &avi_info, sizeof(AVIFILEINFO));

      hr = AVIFileGetStream(Avi, &pStream, streamtypeVIDEO, 0 );
      if (hr!=AVIERR_OK)
      {
         LogAVIError(hr);
         return false;
      }

      // get the stream
      iFirstFrame = AVIStreamStart(pStream);
      if (iFirstFrame==-1)
      {
         printf("Error retreiving the first frame\n");
         LogAVIError(0);
         return false;
      }

      iNumFrames = AVIStreamLength(pStream);
      if (iNumFrames==-1)
      {
         printf("Error retreiving the number of frames\n");
         LogAVIError(0);
         return false;
      }

      FrameOpen(24); // 24-bit colour BMP
      getFrameObject = AVIStreamGetFrameOpen(pStream, &bih);

      StreamOK = true;
      return true;
   }

   bool CloseAVIStream()
   {
      AVIStreamGetFrameClose(getFrameObject);
      if (pStream!=NULL)   AVIStreamRelease(pStream);
      if (Avi!=NULL)      AVIFileRelease(Avi);
      AVIFileExit();
      return true;
   }

  void SetLooped(bool fl)
   {
      LoopMovie = fl;
   }
};

//===============================================================================
class CAviMovieMesh : public C2DImageSceneNode , public AVIMovie
 {
     public:
       CAviMovieMesh(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id);
       ~CAviMovieMesh();

       void LoadMovie(char* filename);
       virtual void CAviMovieMesh::render();

 };

//------------------------------------------------------------------------------
  CAviMovieMesh::CAviMovieMesh(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): C2DImageSceneNode(parent, mgr, id) , AVIMovie()
        {

        }

      CAviMovieMesh::~CAviMovieMesh()
        {
           AVIMovie::CloseAVIStream();
        }

       void CAviMovieMesh::LoadMovie(char* filename)
        {
           AVIMovie::OpenAVIStream(filename);
           float u = (float)bih.biWidth/512.0;
           float v = (float)bih.biHeight/512.0;
           Vertices[0] = video::S3DVertex(-1,-1,0, 0,0,0,video::SColor(255,255,255,255),0,v);
           Vertices[1] = video::S3DVertex( 1,-1,0, 0,0,0,video::SColor(255,255,255,255),u,v);
           Vertices[2] = video::S3DVertex( 1, 1,0, 0,0,0,video::SColor(255,255,255,255),u,0);
           Vertices[3] = video::S3DVertex(-1, 1,0, 0,0,0,video::SColor(255,255,255,255),0,0);

           Box.reset(Vertices[0].Pos);
           for (s32 i=1; i<4; ++i)  Box.addInternalPoint(Vertices[i].Pos);

           w=bih.biWidth/2;
           h=bih.biHeight/2;

           video::IVideoDriver* driver = SceneManager->getVideoDriver();
           driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT , TRUE);
           driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, FALSE);
           Material.Texture1 = driver->addTexture(core::dimension2d<s32>(512,512),"");
        }

      void CAviMovieMesh::render()
       {
           //DrawMovie(0,0,Material.Texture1);
           DrawMovie(Material.Texture1);
           C2DImageSceneNode::render();
       }

#endif
thanks
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Hi emil,

You were right about the cause of the dx9 texture locking problem. However, the solution you proposed has a serious performance impact. I have rewritten the DrawMovie function and also got rid of all the multiplications in the memcopy code. With a sample avi file running at 15 frames per second, Irrlicht runs at more than 1100FPS (OpenGL) / 1300FPS (DX9)

The To Do list has changed a bit:
- adding sound support
- gettting the texture mapped onto any mesh instead of the CSampleSceneNode
- create an IReadFile interface for the avi file
- running 2 or more avi's simultaneously

Any suggestions are much appreciated.

Code: Select all

	void DrawMovie(irr::video::ITexture* Buf)
	{
		if (NotPauzed)
		{
			IsMovieRunning = GetNextFrame();
			if (IsMovieRunning && FrameUpdate)
			{
				u8* pBits = (BYTE*)Buf->lock();
				if (pBits)
				{
					s32  Pitch = Buf->getPitch();  
					u8* pDIB  = (BYTE*) AVIStreamGetFrame(getFrameObject, iCurrentFrame) + sizeof(BITMAPINFOHEADER);
					u32 wmin    = bih.biWidth  * 3;
					u32 row_in  = bih.biHeight * wmin;
					u32 row_out = 0;
					u32 width, col_in, col_out;
					for(u32 h = 0; h < bih.biHeight; h++)
					{
						row_in  -= wmin;	// BMP format starts with bottom line
						row_out += Pitch;
						col_in   = 0;
						col_out  = 0;
						for(width = 0; width < bih.biWidth; width++)
						{
							col_in  += 3;
							col_out += 4;
							pBits[row_out + col_out    ] = pDIB[row_in + col_in + 2];	//B
							pBits[row_out + col_out + 1] = pDIB[row_in + col_in + 1];	//G
							pBits[row_out + col_out + 2] = pDIB[row_in + col_in    ];	//R
							pBits[row_out + col_out + 3] = 0;							//Alpha
						}
					//if (iCurrentFrame==1) CreateFromPackedDIBPointer(pDIB, iCurrentFrame);	// make a snapshot
					}
				}
				Buf->unlock();
			}
		}
	}
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi evo:

i have just made a small speed test to see that which is faster,
the CMovieMesh (relies on DirectShow) or CAviMovieMesh (relies on your avi vfw system).

i got those resultes

. CMovieMesh
==========
with DX9 fps = 411
with OpenGL fps = 406

. CAviMovieMesh
============
with DX9 fps = 260
with OpenGL fps = 150

here is the code of testing,using my Magic3D library

Code: Select all

/******************************************************

          movie speed test program

          using CMovieMesh  class
******************************************************/

#include <Magic3D.h>

int main()
{
	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_OPENGL;   break;
		default: return 0;
	}

    bool HighLevel;
	printf("type h for HighLevel Shader\n");
	std::cin >> i;
	if(i=='h')
	  HighLevel=true;
	else
	  HighLevel=false;

	IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(640, 480), 32);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

    IShaderProgram* sp=0;

    InitMagic(device,&sp,HighLevel);


    CMovieMesh* movie=new CMovieMesh(smgr->getRootSceneNode(), smgr, -1);
    movie->LoadMovie("../../media/Test.Avi");
    movie->SetMovieFPS(10);
    movie->SetLooped(true);
    movie->setPosition(core::vector3df(0,-150,0));
    movie->setScale(core::vector3df(1,0.5f,0));
    movie->setMaterialType(EMT_AlphaBlend);
    movie->setShaderProgram(sp);
    movie->setAlpha(0.5f);

    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 10.0f, 10.0f);
	cam->setPosition(core::vector3df(0,0,-1.0));
	cam->setTarget(core::vector3df(0,0,0));

     movie->setOrthogonal(true);

     HideMouse();

     int lastFPS = -1;
     while(device->run())
       {
	driver->beginScene(true, true, video::SColor(0,100,100,100));

                movie->NextMovieFrame();

     	 smgr->drawAll();

	driver->endScene();

	int fps = driver->getFPS();
	if (lastFPS != fps)
	{
	  core::stringw str = L"Speed test using Magic3D library [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
	}
        }
       device->drop();
}

Code: Select all

/******************************************************

          movie speed test program

          using CAviMovieMesh  class
******************************************************/

#include <Magic3D.h>

int main()
{
	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_OPENGL;   break;
		default: return 0;
	}

    bool HighLevel;
	printf("type h for HighLevel Shader\n");
	std::cin >> i;
	if(i=='h')
	  HighLevel=true;
	else
	  HighLevel=false;

	IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(640, 480), 32);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

    IShaderProgram* sp=0;

    InitMagic(device,&sp,HighLevel);

    CAviMovieMesh* AviMovie=new CAviMovieMesh(smgr->getRootSceneNode(), smgr, -1);
    AviMovie->LoadMovie("../../media/Test.Avi");
    AviMovie->SetMovieFPS(10);
    AviMovie->SetLooped(true);
    AviMovie->setPosition(core::vector3df(0,-150,0));
    AviMovie->setScale(core::vector3df(1,0.5f,0));
    AviMovie->setMaterialType(EMT_AlphaBlend);
    AviMovie->setShaderProgram(sp);
    AviMovie->setAlpha(0.5f);

    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 10.0f, 10.0f);
	cam->setPosition(core::vector3df(0,0,-1.0));
	cam->setTarget(core::vector3df(0,0,0));

     AviMovie->setOrthogonal(true);

     HideMouse();

     int lastFPS = -1;
     while(device->run())
       {
	driver->beginScene(true, true, video::SColor(0,100,100,100));

     	 smgr->drawAll();

	driver->endScene();

	int fps = driver->getFPS();
	if (lastFPS != fps)
	{
	  core::stringw str = L"Speed test using Magic3D library [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

		  device->setWindowCaption(str.c_str());
		  lastFPS = fps;
	}
        }
       device->drop();
}
gettting the texture mapped onto any mesh instead of the CSampleSceneNode
here is a demo from Magic2d that do what you wnat

Code: Select all

/************************************
       Magic library

   playing movie  in  Texture
   then apply texture to mesh

        By Emil Halim
*************************************/


#include <irrlicht.h>

#include <Magic2d.hpp>

using namespace irr;


using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

// global declration of Irrlicht interfaces
IrrlichtDevice* device;
IVideoDriver*   driver;
ISceneManager*  smgr;
IGUIEnvironment* guienv;


int main()
{

    device = createDevice(EDT_OPENGL, dimension2d<s32>(640, 480), 32);
    bool rslt = InitMagic(device);
    if(rslt == false)
          printf("Magic Library will only work with OpenGL driver");

	device->setWindowCaption(L"Hello World! - Magic 2d library for Irrlicht");

	driver = device->getVideoDriver();
	smgr = device->getSceneManager();
	guienv = device->getGUIEnvironment();

    driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,TRUE);

    TMovie* movie=new TMovie;
    movie->LoadMovie("../../media/Test.Avi");
    movie->SetMovieFPS(10);

    IAnimatedMesh* mesh = smgr->getMesh("../../media/sydney.md2");
    IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
    node->setMaterialFlag(EMF_LIGHTING, false);
    node->setFrameLoop(0, 310);
    ITexture* syd = driver->getTexture("../../media/sydney.bmp");
    node->setMaterialTexture( 0, syd);
   	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));

    int lastFPS = -1;

	while(device->run())
	{

		driver->beginScene(true, true, SColor(0,200,200,200));


                 movie->NextMovieFrame();
                 movie->DrawMovie(0,0,syd);

                 smgr->drawAll();
		         guienv->drawAll();

		driver->endScene();
		int fps = driver->getFPS();
         if (lastFPS != fps)
         {
            wchar_t tmp[1024];
            swprintf(tmp, 1024, L"Hello World! - Magic 2d library for Irrlicht (%s)(fps:%d)",driver->getName(), fps);
            device->setWindowCaption(tmp);
            lastFPS = fps;
         }
	}

	device->drop();

	return 0;
}
running 2 or more avi's simultaneously

Code: Select all

/******************************************************

          playing 3 movies at the same time


******************************************************/

#include <Magic3D.h>

int main()
{
	video::E_DRIVER_TYPE driverType;

	printf("Please select the driver you want for this example:\n"\
		" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
		" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
		" (f) NullDevice\n (otherKey) exit\n\n");

	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
		case 'b': driverType = video::EDT_OPENGL;   break;
		default: return 0;
	}

    bool HighLevel;
	printf("type h for HighLevel Shader\n");
	std::cin >> i;
	if(i=='h')
	  HighLevel=true;
	else
	  HighLevel=false;

	IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(640, 480), 32);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();

    IShaderProgram* sp=0;

    InitMagic(device,&sp,HighLevel);


    CAviMovieMesh* AviMovie=new CAviMovieMesh(smgr->getRootSceneNode(), smgr, -1);
    AviMovie->LoadMovie("../../media/Test.Avi");
    AviMovie->SetMovieFPS(10);
    AviMovie->SetLooped(true);
    AviMovie->setPosition(core::vector3df(0,150,0));
    AviMovie->setScale(core::vector3df(1,0.5f,0));
    AviMovie->setMaterialType(EMT_AlphaBlend);
    AviMovie->setShaderProgram(sp);
    AviMovie->setAlpha(0.5f);

    CAviMovieMesh* AviMovie2=new CAviMovieMesh(smgr->getRootSceneNode(), smgr, -1);
    AviMovie2->LoadMovie("../../media/myTest2.Avi");
    AviMovie2->SetMovieFPS(10);
    AviMovie2->SetLooped(true);
    AviMovie2->setPosition(core::vector3df(0,0,0));
    AviMovie2->setScale(core::vector3df(1,0.5f,0));
    AviMovie2->setMaterialType(EMT_AlphaBlend);
    AviMovie2->setShaderProgram(sp);
    AviMovie2->setAlpha(0.2f);


    CMovieMesh* movie=new CMovieMesh(smgr->getRootSceneNode(), smgr, -1);
    movie->LoadMovie("../../media/anotherMovie.Avi");
    movie->SetMovieFPS(10);
    movie->SetLooped(true);
    movie->setPosition(core::vector3df(0,-150,0));
    movie->setScale(core::vector3df(1,0.5f,0));
    movie->setMaterialType(EMT_AlphaBlend);
    movie->setShaderProgram(sp);
    movie->setAlpha(0.5f);


    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS(0, 10.0f, 10.0f);
	cam->setPosition(core::vector3df(0,0,-1.0));
	cam->setTarget(core::vector3df(0,0,0));



    AviMovie->setOrthogonal(true);
    AviMovie2->setOrthogonal(true);
    movie->setOrthogonal(true);

     HideMouse();

    int lastFPS = -1;
    while(device->run())
      {
            driver->beginScene(true, true, video::SColor(0,100,100,100));
 
                movie->NextMovieFrame();

                smgr->drawAll();

	driver->endScene();

	int fps = driver->getFPS();

	if (lastFPS != fps)
	{
   	   core::stringw str = L"playing 3 movies using Magic3D library [";
		  str += driver->getName();
		  str += "] FPS:";
		  str += fps;

	    device->setWindowCaption(str.c_str());
	    lastFPS = fps;
	}
          }

         device->drop();
}
so you can play many movies as you want.
thanks
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Emil_halim wrote:i have just made a small speed test to see that which is faster,
the CMovieMesh (relies on DirectShow) or CAviMovieMesh (relies on your avi vfw system).

i got these results

. CMovieMesh
==========
with DX9 fps = 411
with OpenGL fps = 406

. CAviMovieMesh
============
with DX9 fps = 260
with OpenGL fps = 150
Is this with the DrawMovie code I posted yesterday ?

Has the CMovieMesh code been changed since you last posted it ?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Is this with the DrawMovie code I posted yesterday ?
no, it is with the code i have posted at Sat Jul 01, 2006 6:33 am
i will test it with the new code that you post recently.
Has the CMovieMesh code been changed since you last posted it ?
no,it is the same code.
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

evo:

with your new improvment i got those resultes

with Dx9 fps = 380
with OpenGl fps = 310
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Hi,

Good to to see that there is some improvement in speed. What causes the difference compared to my results I don't really know. Maybe the test avi file that I use has a compression (Indeo 5.11) that is harder to handle for dshow than for vfw ??

Showing multiple avi's and on arbirtary meshes works for me now. What is also really cool is replacing the skybox textures with a movie, like this:

Code: Select all

	AVIMovie *MyAvi = new AVIMovie;
	MyAvi->SetMovieFPS(15);
	MyAvi->OpenAVIStream("some.avi");
	video::ITexture* movTxtr = irrVideo->addTexture(core::dimension2d<s32>(512,512),"movie",video::ECF_A8R8G8B8);
	irrVideo->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);	
		irrSceneMgr->addSkyBoxSceneNode(		
			0,
			0,
			movTxtr,
			movTxtr,
			movTxtr,
			movTxtr);
The To Do list now only has:
- add audio
- add IReadFile interface

Not the easiest item's I am afraid :?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi evo:

nice example,i wil put it with Movies examples of Magic3D Library and Credit it for you.

i have added new DrawMovie function to allows us to only copy a certain rectangle of the movie to any location in the texture.

Code: Select all

void CMovie::DrawMovie(int x,int y,int mx,int my,int mw,int mh,video::ITexture* Buf)
           {

               if(flg)
                {
                  s32* pBits =(s32*) Buf->lock();
                  LONG  Pitch = Buf->getPitch()>>2;
                  DDSURFACEDESC  ddsd;
                  ddsd.dwSize=sizeof(DDSURFACEDESC);
                  ((IDirectDrawSurface*)pSurface)->Lock( NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT , NULL);
                  LONG Spitch = ddsd.lPitch>>2;
                  //int wmin=(Pitch<Spitch)?Pitch:Spitch;
                  for(int h=my; h<mh; h++)
                   {
                     // memcpy((BYTE*)pBits+((y+h)*Pitch)+x*4,(BYTE*)ddsd.lpSurface+h*ddsd.lPitch,wmin);
                          s32* pdst = pBits+x+(y+h)*Pitch;
                          s32* psrc = (s32*)ddsd.lpSurface+h*Spitch;
                          for(s32 w=mx; w<mw; w++)
                                  *pdst++ = *psrc++ | 0xFF000000;

                   }
                  ((IDirectDrawSurface*)pSurface)->Unlock(NULL);
                  Buf->unlock();
                }
           }
so you could draw the movie to a certain part of any texture of SkyBox.
The To Do list now only has:
- add audio
actually when i was developing movie class ,i found that ,the sound of any midea has it's own speed playing and if we changed that it will play in unnormal rate, so i ahve decided to disable any sound.
evo
Posts: 96
Joined: Mon Jun 27, 2005 6:46 pm
Location: The Netherlands

Post by evo »

Hi,

I am going to play around with the sound stream a bit. My idea is to let sound always play at normal 'speed'. The problem will then lie in synchronizing sound with video.

Copying part of a video can be useful. Maybe you can make 2 overloaded functions. One with and one without selection of a rectangle. Also it could be helpful to users of the magic library if you add more desciptive argument names. For instance:
DrawMovie(core::vector2d texture_upper_left_corner, core::vector2d Movie_upper_left_corner, u16 Movie_Height, u16 Movie_Width, video::ITexture* Buf)

I think the assignment of the texture can be done in the LoadMovie function. Unless you plan to change the output texture at run-time.


To be continued ... after some vacation time :D

Evo
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

I am going to play around with the sound stream a bit. My idea is to let sound always play at normal 'speed'. The problem will then lie in synchronizing sound with video.
totally agree with you,the problem is in synchronizing sound with video,
and if we change the rate of the sound it will be not good.
Maybe you can make 2 overloaded functions. One with and one without selection of a rectangle
already done.
add more desciptive argument names
good idea ,i will do it.


I think the assignment of the texture can be done in the LoadMovie function. Unless you plan to change the output texture at run-time.
i think that by this way you could apply the same movie to more than one texture.
To be continued ... after some vacation time
have a nice time.
Post Reply