TextureAviMovie.cpp
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:9k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // TextureAviMovie.cpp : implementation file
  3. //
  4. // glOOP (OpenGL Object Oriented Programming library)
  5. // Copyright (c) Craig Fahrnbach 1997, 1998
  6. //
  7. // OpenGL is a registered trademark of Silicon Graphics
  8. //
  9. //
  10. // This program is provided for educational and personal use only and
  11. // is provided without guarantee or warrantee expressed or implied.
  12. //
  13. // Commercial use is strickly prohibited without written permission
  14. // from ImageWare Development.
  15. //
  16. // This program is -not- in the public domain.
  17. //
  18. // This source code has been adapted, with permission, from:
  19. // IDC Imagery
  20. //     --GLVid C++ Class---
  21. //       Kister S閎astien
  22. //      leseb@compuserve.com
  23. //
  24. // 08/08/98 Added capability to display avi files of any size and color
  25. // depth.
  26. // 10/04/98 Added audio capability
  27. /////////////////////////////////////////////////////////////////////////////
  28. #include "stdafx.h"
  29. #include "glOOP.h"
  30. #include "DIBUtil.h"
  31. #include <time.h>
  32. #include <vfw.h>
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CTextureAviMovie Global definitions
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CTextureAviMovie
  42. IMPLEMENT_DYNAMIC(CTextureAviMovie, CTexture)
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CTextureAviMovie construction
  45. CTextureAviMovie::CTextureAviMovie()
  46. {
  47. // Opens the AVI File library
  48. AVIFileInit();
  49. // Clear the pointers
  50. m_pFile = NULL; // File interface pointer
  51. m_pBMI = NULL; // Pointer to our current AVI frame DIB
  52. m_pAnimAVI = NULL; // Pointer to our animation object (AVI 'driver')
  53. m_pGetFrame = NULL; // Pointer to an AVI GetFrame object
  54. m_pVideoStream = NULL; // Pointer to the AVI Video stream interface.
  55. m_pAudioPlayer = NULL; // Pointer to our audio player
  56. // Clear the handles
  57. m_hPalette        = NULL; // Handle to our applications palette
  58. // Set our default flags
  59. m_bEnableAudio   = TRUE; // Enable audio flag
  60. m_bPlayContinuous = TRUE; // Play AVI file continuously?
  61. m_bStartAudio   = TRUE; // Start the audio track?
  62. // Set default values
  63. m_lLastTimeIndex  = 0L; // Time index of the stream last played;
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CTextureAviMovie Destructor
  67. CTextureAviMovie::~CTextureAviMovie()
  68. {
  69. // Close and delete our audio player device
  70. if(m_pAudioPlayer)
  71. {
  72. m_pAudioPlayer->Close();
  73. delete m_pAudioPlayer;
  74. }
  75. // Close our AVI stream
  76. if(m_pGetFrame)
  77. AVIStreamGetFrameClose(m_pGetFrame);
  78. // Release the file
  79. if(m_pFile)
  80. AVIFileRelease(m_pFile);
  81. // Closes AVI File library
  82. AVIFileExit();
  83. }
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CTextureAviMovie virtual overrides
  86. BOOL CTextureAviMovie::OpenTexture(char* pFileName, HPALETTE hPalette)
  87. {
  88. int iResult;
  89. // Initialize the AVI file
  90. iResult = InitAVI(pFileName);
  91. if(iResult < 0)
  92. return FALSE;
  93. // Get the first frame from the AVI stream
  94. if(!GetFrameRGBA(0L, hPalette))
  95. return FALSE;
  96. // For this type of TextureMap, we do NOT want to create
  97. // a display list.
  98. m_bCreateList = FALSE;
  99. // Save the file name of the texture map
  100. m_szFileName.Format("%s", pFileName);
  101. // Save the handle to our palette for future use
  102. m_hPalette = hPalette;
  103. return TRUE;
  104. }
  105. void CTextureAviMovie::Serialize(CArchive& ar, int iVersion)
  106. {
  107. CString szBuffer;
  108. if (ar.IsStoring())
  109. {
  110. // Save the Object Class header...
  111. szBuffer.Format("%sCTextureAviMovie {n", szIndent);
  112. ar.WriteString(szBuffer);
  113. // Save the this objects' specific data...
  114. // szBuffer.Format("%stSolid         < %d >n", szIndent, m_bSolid);
  115. // ar.WriteString(szBuffer);
  116. // Save the base class CTexture data...
  117. CTexture::Serialize(ar, iVersion);
  118. szBuffer.Format("%s}n", szIndent); // end of texture map def
  119. ar.WriteString(szBuffer);
  120. // Now that we have saved the CTexture derived and base data
  121. // serialize the CAnimAVI data.
  122. if(m_pAnimAVI)
  123. m_pAnimAVI->Serialize(ar, iVersion);
  124. }
  125. else
  126. {
  127. // Read the derived class data..
  128. ar.ReadString(szBuffer); // Read the class header
  129. // ar.ReadString(szBuffer);
  130. // szBuffer.TrimLeft(); // Remove leading white spaces
  131. // sscanf(szBuffer, "Solid         < %d >n", &m_bSolid);
  132. // Read the base class CTexture data...
  133. CTexture::Serialize(ar, iVersion);
  134. // Now that we have read the CTexture derived and base data
  135. // serialize the CAnimAVI data.
  136. if(m_pAnimAVI)
  137. m_pAnimAVI->Serialize(ar, iVersion);
  138. }
  139. }
  140. /////////////////////////////////////////////////////////////////////////////
  141. // CTextureAviMovie function implementation
  142. DWORD CTextureAviMovie::InitAVI(LPSTR szFile)
  143. {
  144. AVIFILEINFO FAR pfi; // AVI File Info header pointer
  145. AVISTREAMINFO FAR psi; // AVI Stream Info header pointer
  146. UINT wResult; // Return error code
  147. // Open the AVI file and get the address of a file interface used to access it
  148. wResult = AVIFileOpen(&m_pFile,
  149.   szFile,
  150.   OF_READ | OF_SHARE_DENY_NONE,
  151.   NULL);
  152. if(wResult)
  153. {
  154. if(the3dEngine.m_bDisplayErrorMessages)
  155. {
  156. char buf[128];
  157. sprintf(buf, "CTextureAviMovie::InitAVI - Could not open file: '%s'n", szFile);
  158. AfxMessageBox(buf, MB_OK);
  159. }
  160. return (wResult); // Return Error
  161. }
  162. // Get the stream interface that is associated with the AVI file.
  163. wResult = AVIFileGetStream(m_pFile,
  164.    &m_pVideoStream,
  165.    streamtypeVIDEO,
  166.    0);
  167. if(wResult)
  168. return (wResult); // Return Error
  169. // Define the length of the video (necessary for RGBA frame reading)
  170. // and its size.
  171. m_lVideoLength = AVIStreamLengthTime(m_pVideoStream);
  172. // Get the AVI video frame
  173. m_pGetFrame = AVIStreamGetFrameOpen(m_pVideoStream, NULL);
  174. if(m_pGetFrame == NULL)
  175. return (1); // Error: No frame
  176. wResult = AVIFileInfo(m_pFile, &pfi, sizeof(AVIFILEINFO FAR));
  177. wResult = AVIStreamInfo(m_pVideoStream, &psi, sizeof(AVISTREAMINFO FAR));
  178. // Now that we have the video stream open, attempt to create our
  179. // CAudioPlayer
  180. m_pAudioPlayer = CAudioPlayer::Create(szFile);
  181. return (0); // No errors
  182. }
  183. void CTextureAviMovie::Play(double dTime)
  184. {
  185. UINT wResult; // Return error code
  186. long lTime;
  187. if(m_bStartAudio && m_bEnableAudio && m_pAudioPlayer)
  188. {
  189. // If we have an Audio player device and the enable flag is set,
  190. // Open the file and Start!
  191. wResult = PlayAudio(dTime);
  192. if(wResult)
  193. m_bEnableAudio = FALSE; // Error.  Audio track not present, 
  194. // could not Open the audio track, or
  195. // audio device is Busy.
  196. }
  197. // Calculate the index (time) of the requested video frame.  Note that this
  198. // algorithum will cause the AVI to continually cycle.
  199. lTime = (long)((int)(dTime*1000)) % m_lVideoLength;
  200. if(m_pAudioPlayer)
  201. {
  202. if(lTime < m_lLastTimeIndex)
  203. {
  204. // We have wrapped back around to the beginning of the AVI file, 
  205. // Force synchronization of the audio track although this is only
  206. // necessary if the avi has been playing for quite some time.
  207. m_pAudioPlayer->SynchAudio((double)lTime/1000.f);
  208. }
  209. }
  210. GetFrameRGBA(lTime, m_hPalette);
  211. // Save the time index
  212. m_lLastTimeIndex = lTime;
  213. }
  214. DWORD CTextureAviMovie::PlayAudio(double dTime)
  215. {
  216. UINT wResult; // Return error code
  217. // If we have an Audio player device and the enable flags are set,
  218. // Open the file and Start!
  219. if(m_bStartAudio && m_bEnableAudio && m_pAudioPlayer)
  220. {
  221. wResult = m_pAudioPlayer->Open(m_szFileName.GetBuffer(128));
  222. if(!wResult)
  223. {
  224. wResult = m_pAudioPlayer->Play(dTime);
  225. if(!wResult)
  226. m_bStartAudio = FALSE; // Reset the flag since our audio
  227. } // track has started.
  228. return (wResult);
  229. }
  230. return (1);
  231. }
  232. void CTextureAviMovie::Stop()
  233. {
  234. // Stop our audio player
  235. StopAudio();
  236. // Reset our flag so that we can restart
  237. m_bStartAudio = TRUE;
  238. // Set default values
  239. m_lLastTimeIndex  = 0L; // Time index of the stream last played;
  240. // Get the first frame
  241. GetFrameRGBA(0L, m_hPalette);
  242. }
  243. void CTextureAviMovie::StopAudio()
  244. {
  245. // Stop our audio player
  246. if(m_pAudioPlayer)
  247. m_pAudioPlayer->Stop();
  248. }
  249. BOOL CTextureAviMovie::GetFrameRGBA(long lTime, HPALETTE hPalette)
  250. {
  251. long lSample;
  252. // Convert from milliseconds to sample
  253. lSample = AVIStreamTimeToSample(m_pVideoStream, lTime);
  254. // Get the address of the decompressed video frame.
  255. // Note:  The frame data is returned as a packed DIB.
  256. m_pBMI = (BITMAPINFO*) AVIStreamGetFrame(m_pGetFrame, lSample);
  257. if(!m_pBMI)
  258. return FALSE;
  259. // Convert DIB to a 32bpp DIB compatable with OpenGL
  260. m_pBits = (GLubyte*)ScaleDIB(hPalette, (HANDLE)m_pBMI);
  261. if(!m_pBits)
  262. return FALSE;
  263. // Now we have a square 32bpp DIB, use it as the texture.
  264. m_bApplyImage = TRUE;
  265. // Reset our AVI frame DIB pointer
  266. m_pBMI = NULL;
  267. return TRUE;
  268. }