⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 animtexture.cpp

📁 用DirectX制作高级动画-[Advanced.Animation.with.DirectX]
💻 CPP
字号:
#include "AnimTexture.h"

cTextureFilter::cTextureFilter(IDirect3DDevice9 *pD3DDevice, 
                               LPUNKNOWN pUnk, HRESULT *phr) 
               : CBaseVideoRenderer(__uuidof(CLSID_AnimatedTexture), 
                 NAME("ANIMATEDTEXTURE"), pUnk, phr)
{
  // Save device pointer
  m_pD3DDevice  = pD3DDevice;

  // Return success
  *phr = S_OK;
}

HRESULT cTextureFilter::CheckMediaType(const CMediaType *pMediaType)
{
  // Only accept video type media
  if(*pMediaType->FormatType() != FORMAT_VideoInfo)
    return E_INVALIDARG;

  // Make sure media data is using RGB 24-bit color format
  if(IsEqualGUID(*pMediaType->Type(),    MEDIATYPE_Video) &&
     IsEqualGUID(*pMediaType->Subtype(), MEDIASUBTYPE_RGB24))
    return S_OK;

  return E_FAIL;
}

HRESULT cTextureFilter::SetMediaType(const CMediaType *pMediaType)
{
  HRESULT          hr;
  VIDEOINFO       *pVideoInfo;
  D3DSURFACE_DESC  ddsd;

  // Retrive the size of this media type
  pVideoInfo     = (VIDEOINFO *)pMediaType->Format();
  m_lVideoWidth  = pVideoInfo->bmiHeader.biWidth;
  m_lVideoHeight = abs(pVideoInfo->bmiHeader.biHeight);
  m_lVideoPitch  = (m_lVideoWidth * 3 + 3) & ~(3);

  // Create the texture that maps to this media type
  if(FAILED(hr = D3DXCreateTexture(m_pD3DDevice,
                 m_lVideoWidth, m_lVideoHeight,
                 1, 0, D3DFMT_A8R8G8B8, 
                 D3DPOOL_MANAGED, &m_pTexture)))
    return hr;

  // Get texture description and verify settings
  if(FAILED(hr = m_pTexture->GetLevelDesc(0, &ddsd)))
    return hr;
  m_Format = ddsd.Format;
  if(m_Format != D3DFMT_A8R8G8B8 && m_Format != D3DFMT_A1R5G5B5)
    return VFW_E_TYPE_NOT_ACCEPTED;

  return S_OK;
}

HRESULT cTextureFilter::DoRenderSample(IMediaSample *pMediaSample)
{
  // Get a pointer to video sample buffer
  BYTE *pSamplePtr;
  pMediaSample->GetPointer(&pSamplePtr);

  // Lock the texture surface
  D3DLOCKED_RECT d3dlr;
  if(FAILED(m_pTexture->LockRect(0, &d3dlr, 0, 0)))
    return E_FAIL;

  // Get texture pitch and pointer to texture data
  BYTE *pTexturePtr  = (BYTE*)d3dlr.pBits;
  LONG lTexturePitch = d3dlr.Pitch;

  // Offset texture to bottom line, since video 
  // is stored upside down in buffer
  pTexturePtr += (lTexturePitch * (m_lVideoHeight-1));
  
  // Copy the bits using specified video format
  int x, y, SrcPos, DestPos;
  switch(m_Format) {
    case D3DFMT_A8R8G8B8:  // 32-bit

      // Loop through each row, copying bytes as you go
      for(y=0;y<m_lVideoHeight;y++) {

        // Copy each column
        SrcPos = DestPos = 0;
        for(x=0;x<m_lVideoWidth;x++) {
          pTexturePtr[DestPos++] = pSamplePtr[SrcPos++];
          pTexturePtr[DestPos++] = pSamplePtr[SrcPos++];
          pTexturePtr[DestPos++] = pSamplePtr[SrcPos++];
          pTexturePtr[DestPos++] = 0xff;
        }

        // Move pointers to next line
        pSamplePtr  += m_lVideoPitch;
        pTexturePtr -= lTexturePitch;
      }
      break;

    case D3DFMT_A1R5G5B5:  // 16-bit

      // Loop through each row, copying bytes as you go
      for(y=0;y<m_lVideoHeight;y++) {

        // Copy each column
        SrcPos = DestPos = 0;
        for(x=0;x<m_lVideoWidth;x++) {
          *(WORD*)pTexturePtr[DestPos++] = 0x8000 + 
                   ((pSamplePtr[SrcPos+2] & 0xF8) << 7) +
                   ((pSamplePtr[SrcPos+1] & 0xF8) << 2) +
                   (pSamplePtr[SrcPos] >> 3);
          SrcPos += 3;
        }
         
        // Move pointers to next line
        pSamplePtr  += m_lVideoPitch;
        pTexturePtr -= lTexturePitch;
      }
      break;
  }
      
  // Unlock the Texture
  if(FAILED(m_pTexture->UnlockRect(0)))
    return E_FAIL;

  return S_OK;
}

IDirect3DTexture9 *cTextureFilter::GetTexture()
{
  return m_pTexture;
}

cAnimatedTexture::cAnimatedTexture()
{
  // Clear class data
  m_pGraph         = NULL;
  m_pMediaControl  = NULL;
  m_pMediaPosition = NULL;
  m_pMediaEvent    = NULL;

  m_pD3DDevice     = NULL;
  m_pTexture       = NULL;
}

cAnimatedTexture::~cAnimatedTexture()
{
  Free();
}

BOOL cAnimatedTexture::Load(IDirect3DDevice9 *pDevice, char *Filename)
{
  cTextureFilter *pTextureFilter = NULL;
  IBaseFilter    *pFilter        = NULL;
  IPin           *pFilterPinIn   = NULL;
  IBaseFilter    *pSourceFilter  = NULL;
  IPin           *pSourcePinOut  = NULL;

  WCHAR           wFilename[MAX_PATH];
  HRESULT         hr;

  // Free prior instance
  Free();

  // Store device
  if((m_pD3DDevice = pDevice) == NULL)
    return FALSE;

  // Create the filter graph manager
  CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
                   IID_IGraphBuilder, (void **)&m_pGraph);

  // Add filter
  pTextureFilter = new cTextureFilter(m_pD3DDevice, NULL, &hr);
  pFilter = pTextureFilter;
  m_pGraph->AddFilter(pFilter, L"ANIMATEDTEXTURE");

  // Add source filter
  mbstowcs(wFilename, Filename, MAX_PATH);
  m_pGraph->AddSourceFilter(wFilename, L"SOURCE", &pSourceFilter);

  // Find the input and out pins and connect together
  pFilter->FindPin(L"In", &pFilterPinIn);
  pSourceFilter->FindPin(L"Output", &pSourcePinOut);
  m_pGraph->Connect(pSourcePinOut, pFilterPinIn);

  // Query for interfaces
  m_pGraph->QueryInterface(IID_IMediaControl,  (void **)&m_pMediaControl);
  m_pGraph->QueryInterface(IID_IMediaPosition, (void **)&m_pMediaPosition);
  m_pGraph->QueryInterface(IID_IMediaEvent,    (void **)&m_pMediaEvent);

  // Get pointer to texture
  m_pTexture = pTextureFilter->GetTexture();

  // Start the graph running
  Play();

  // Free interfaces used here
  ReleaseCOM(pFilterPinIn);
  ReleaseCOM(pSourceFilter);
  ReleaseCOM(pSourcePinOut);

  return TRUE;
}

BOOL cAnimatedTexture::Free()
{
  // Stop any playback
  Stop();

  // Release all COM objects
  ReleaseCOM(m_pMediaControl);
  ReleaseCOM(m_pMediaEvent);
  ReleaseCOM(m_pMediaPosition);
  ReleaseCOM(m_pGraph);

  // Release the texture
  ReleaseCOM(m_pTexture);

  // Clear Direct3D object pointer
  m_pD3DDevice = NULL;

  return TRUE;
}

BOOL cAnimatedTexture::Update()
{
  long lEventCode;
  long lParam1;
  long lParam2;

  // Error checking
  if(!m_pMediaEvent)
    return FALSE;

  // Process all waiting events
  while(1) {

    // Get the event
    if(FAILED(m_pMediaEvent->GetEvent(&lEventCode, &lParam1, &lParam2, 1)))
      break;

    // Call the end of animation function if playback complete
    if(lEventCode == EC_COMPLETE)
      EndOfAnimation();

    // Free the event resources
    m_pMediaEvent->FreeEventParams(lEventCode, lParam1, lParam2);
  }
  
  return TRUE;
}

BOOL cAnimatedTexture::EndOfAnimation()
{
  return Restart();
}

BOOL cAnimatedTexture::Play()
{
  if(m_pMediaControl != NULL)
    m_pMediaControl->Run();

  return TRUE;
}

BOOL cAnimatedTexture::Stop()
{
  if(m_pMediaControl != NULL)
    m_pMediaControl->Stop();
  return TRUE;
}

BOOL cAnimatedTexture::Restart()
{
  return GotoTime(0);
}

BOOL cAnimatedTexture::GotoTime(REFTIME Time)
{
  if(m_pMediaPosition != NULL)
    m_pMediaPosition->put_CurrentPosition(Time);
  return TRUE;
}

IDirect3DTexture9 *cAnimatedTexture::GetTexture()
{
  return m_pTexture;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -