DX9SubPic.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:9k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* 
  2.  * Copyright (C) 2003-2005 Gabest
  3.  * http://www.gabest.org
  4.  *
  5.  *  This Program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *   
  10.  *  This Program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13.  *  GNU General Public License for more details.
  14.  *   
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with GNU Make; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  18.  *  http://www.gnu.org/copyleft/gpl.html
  19.  *
  20.  */
  21. #include "stdafx.h"
  22. #include <d3d9.h>
  23. #include <Vmr9.h>
  24. #include "DX9SubPic.h"
  25. //
  26. // CDX9SubPic
  27. //
  28. CDX9SubPic::CDX9SubPic(IDirect3DSurface9* pSurface)
  29. : m_pSurface(pSurface)
  30. {
  31. D3DSURFACE_DESC d3dsd;
  32. ZeroMemory(&d3dsd, sizeof(d3dsd));
  33. if(SUCCEEDED(m_pSurface->GetDesc(&d3dsd)))
  34. {
  35. m_maxsize.SetSize(d3dsd.Width, d3dsd.Height);
  36. m_rcDirty.SetRect(0, 0, d3dsd.Width, d3dsd.Height);
  37. }
  38. }
  39. // ISubPic
  40. STDMETHODIMP_(void*) CDX9SubPic::GetObject()
  41. {
  42. CComPtr<IDirect3DTexture9> pTexture;
  43. if(SUCCEEDED(m_pSurface->GetContainer(IID_IDirect3DTexture9, (void**)&pTexture)))
  44. return (void*)(IDirect3DTexture9*)pTexture;
  45. return NULL;
  46. }
  47. STDMETHODIMP CDX9SubPic::GetDesc(SubPicDesc& spd)
  48. {
  49. D3DSURFACE_DESC d3dsd;
  50. ZeroMemory(&d3dsd, sizeof(d3dsd));
  51. if(FAILED(m_pSurface->GetDesc(&d3dsd)))
  52. return E_FAIL;
  53. spd.type = 0;
  54. spd.w = m_size.cx;
  55. spd.h = m_size.cy;
  56. spd.bpp = 
  57. d3dsd.Format == D3DFMT_A8R8G8B8 ? 32 : 
  58. d3dsd.Format == D3DFMT_A4R4G4B4 ? 16 : 0;
  59. spd.pitch = 0;
  60. spd.bits = NULL;
  61. spd.vidrect = m_vidrect;
  62. return S_OK;
  63. }
  64. STDMETHODIMP CDX9SubPic::CopyTo(ISubPic* pSubPic)
  65. {
  66. HRESULT hr;
  67. if(FAILED(hr = __super::CopyTo(pSubPic)))
  68. return hr;
  69. if(m_rcDirty.IsRectEmpty())
  70. return S_FALSE;
  71. CComPtr<IDirect3DDevice9> pD3DDev;
  72. if(!m_pSurface || FAILED(m_pSurface->GetDevice(&pD3DDev)) || !pD3DDev)
  73. return E_FAIL;
  74. hr = pD3DDev->UpdateTexture((IDirect3DTexture9*)GetObject(), (IDirect3DTexture9*)pSubPic->GetObject());
  75. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  76. }
  77. STDMETHODIMP CDX9SubPic::ClearDirtyRect(DWORD color)
  78. {
  79. if(m_rcDirty.IsRectEmpty())
  80. return S_FALSE;
  81. CComPtr<IDirect3DDevice9> pD3DDev;
  82. if(!m_pSurface || FAILED(m_pSurface->GetDevice(&pD3DDev)) || !pD3DDev)
  83. return E_FAIL;
  84. SubPicDesc spd;
  85. if(SUCCEEDED(Lock(spd)))
  86. {
  87. int h = m_rcDirty.Height();
  88. BYTE* ptr = (BYTE*)spd.bits + spd.pitch*m_rcDirty.top + (m_rcDirty.left*spd.bpp>>3);
  89. if(spd.bpp == 16)
  90. {
  91. while(h-- > 0)
  92. {
  93. WORD* start = (WORD*)ptr;
  94. WORD* end = start + m_rcDirty.Width();
  95. while(start < end) *start++ = (WORD)color;
  96. ptr += spd.pitch;
  97. }
  98. }
  99. else if(spd.bpp == 32)
  100. {
  101. while(h-- > 0)
  102. {
  103. DWORD* start = (DWORD*)ptr;
  104. DWORD* end = start + m_rcDirty.Width();
  105. while(start < end) *start++ = color;
  106. ptr += spd.pitch;
  107. }
  108. }
  109. /*
  110. DWORD* ptr = (DWORD*)bm.bits;
  111. DWORD* end = ptr + bm.h*bm.wBytes/4;
  112. while(ptr < end) *ptr++ = color;
  113. */
  114. Unlock(NULL);
  115. }
  116. // HRESULT hr = pD3DDev->ColorFill(m_pSurface, m_rcDirty, color);
  117. m_rcDirty.SetRectEmpty();
  118. return S_OK;
  119. }
  120. STDMETHODIMP CDX9SubPic::Lock(SubPicDesc& spd)
  121. {
  122. D3DSURFACE_DESC d3dsd;
  123. ZeroMemory(&d3dsd, sizeof(d3dsd));
  124. if(FAILED(m_pSurface->GetDesc(&d3dsd)))
  125. return E_FAIL;
  126. D3DLOCKED_RECT LockedRect;
  127. ZeroMemory(&LockedRect, sizeof(LockedRect));
  128. if(FAILED(m_pSurface->LockRect(&LockedRect, NULL, 0)))
  129. return E_FAIL;
  130. spd.type = 0;
  131. spd.w = m_size.cx;
  132. spd.h = m_size.cy;
  133. spd.bpp = 
  134. d3dsd.Format == D3DFMT_A8R8G8B8 ? 32 : 
  135. d3dsd.Format == D3DFMT_A4R4G4B4 ? 16 : 0;
  136. spd.pitch = LockedRect.Pitch;
  137. spd.bits = LockedRect.pBits;
  138. spd.vidrect = m_vidrect;
  139. return S_OK;
  140. }
  141. STDMETHODIMP CDX9SubPic::Unlock(RECT* pDirtyRect)
  142. {
  143. m_pSurface->UnlockRect();
  144. if(pDirtyRect)
  145. {
  146. m_rcDirty = *pDirtyRect;
  147. m_rcDirty.InflateRect(1, 1);
  148. m_rcDirty &= CRect(CPoint(0, 0), m_size);
  149. }
  150. else
  151. {
  152. m_rcDirty = CRect(CPoint(0, 0), m_size);
  153. }
  154. return S_OK;
  155. }
  156. STDMETHODIMP CDX9SubPic::AlphaBlt(RECT* pSrc, RECT* pDst, SubPicDesc* pTarget)
  157. {
  158. ASSERT(pTarget == NULL);
  159. if(!pSrc || !pDst)
  160. return E_POINTER;
  161. CRect src(*pSrc), dst(*pDst);
  162. CComPtr<IDirect3DDevice9> pD3DDev;
  163. CComPtr<IDirect3DTexture9> pTexture = (IDirect3DTexture9*)GetObject();
  164. if(!pTexture || FAILED(pTexture->GetDevice(&pD3DDev)) || !pD3DDev)
  165. return E_NOINTERFACE;
  166. HRESULT hr;
  167.     do
  168. {
  169. D3DSURFACE_DESC d3dsd;
  170. ZeroMemory(&d3dsd, sizeof(d3dsd));
  171. if(FAILED(pTexture->GetLevelDesc(0, &d3dsd)) /*|| d3dsd.Type != D3DRTYPE_TEXTURE*/)
  172. break;
  173.         float w = (float)d3dsd.Width;
  174.         float h = (float)d3dsd.Height;
  175. struct
  176. {
  177. float x, y, z, rhw;
  178. float tu, tv;
  179. }
  180. pVertices[] =
  181. {
  182. {(float)dst.left, (float)dst.top, 0.5f, 2.0f, (float)src.left / w, (float)src.top / h},
  183. {(float)dst.right, (float)dst.top, 0.5f, 2.0f, (float)src.right / w, (float)src.top / h},
  184. {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, (float)src.left / w, (float)src.bottom / h},
  185. {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, (float)src.right / w, (float)src.bottom / h},
  186. };
  187. /*
  188. for(int i = 0; i < countof(pVertices); i++)
  189. {
  190. pVertices[i].x -= 0.5;
  191. pVertices[i].y -= 0.5;
  192. }
  193. */
  194.         hr = pD3DDev->SetTexture(0, pTexture);
  195.         hr = pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  196.         hr = pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
  197. hr = pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
  198.      hr = pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
  199.         hr = pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); // pre-multiplied src and ...
  200.         hr = pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA); // ... inverse alpha channel for dst
  201. hr = pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  202.         hr = pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  203.         hr = pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  204.         hr = pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  205.         hr = pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
  206.         hr = pD3DDev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
  207. hr = pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  208. hr = pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
  209. /*//
  210. D3DCAPS9 d3dcaps9;
  211. hr = pD3DDev->GetDeviceCaps(&d3dcaps9);
  212. if(d3dcaps9.AlphaCmpCaps & D3DPCMPCAPS_LESS)
  213. {
  214. hr = pD3DDev->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x000000FE);
  215. hr = pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); 
  216. hr = pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, D3DPCMPCAPS_LESS);
  217. }
  218. *///
  219. if(FAILED(hr = pD3DDev->BeginScene()))
  220. break;
  221.         hr = pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
  222. hr = pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0]));
  223. hr = pD3DDev->EndScene();
  224.         //
  225. pD3DDev->SetTexture(0, NULL);
  226. return S_OK;
  227.     }
  228. while(0);
  229.     return E_FAIL;
  230. }
  231. //
  232. // CDX9SubPicAllocator
  233. //
  234. CDX9SubPicAllocator::CDX9SubPicAllocator(IDirect3DDevice9* pD3DDev, SIZE maxsize, bool fPow2Textures) 
  235. : ISubPicAllocatorImpl(maxsize, true, fPow2Textures)
  236. , m_pD3DDev(pD3DDev)
  237. , m_maxsize(maxsize)
  238. {
  239. m_pD3DDev = pD3DDev;
  240. m_maxsize = maxsize;
  241. }
  242. // ISubPicAllocator
  243. STDMETHODIMP CDX9SubPicAllocator::ChangeDevice(IUnknown* pDev)
  244. {
  245. CComQIPtr<IDirect3DDevice9> pD3DDev = pDev;
  246. if(!pD3DDev) return E_NOINTERFACE;
  247. CAutoLock cAutoLock(this);
  248. m_pD3DDev = pD3DDev;
  249. return __super::ChangeDevice(pDev);
  250. }
  251. // ISubPicAllocatorImpl
  252. bool CDX9SubPicAllocator::Alloc(bool fStatic, ISubPic** ppSubPic)
  253. {
  254. if(!ppSubPic) 
  255. return(false);
  256. CAutoLock cAutoLock(this);
  257. *ppSubPic = NULL;
  258. CComPtr<IDirect3DSurface9> pSurface;
  259. int Width = m_maxsize.cx;
  260. int Height = m_maxsize.cy;
  261. if(m_fPow2Textures)
  262. {
  263. Width = Height = 1;
  264. while(Width < m_maxsize.cx) Width <<= 1;
  265. while(Height < m_maxsize.cy) Height <<= 1;
  266. }
  267. CComPtr<IDirect3DTexture9> pTexture;
  268. if(FAILED(m_pD3DDev->CreateTexture(Width, Height, 1, 0, D3DFMT_A8R8G8B8, fStatic?D3DPOOL_SYSTEMMEM:D3DPOOL_DEFAULT, &pTexture, NULL)))
  269. return(false);
  270. if(FAILED(pTexture->GetSurfaceLevel(0, &pSurface)))
  271. return(false);
  272. if(!(*ppSubPic = new CDX9SubPic(pSurface)))
  273. return(false);
  274. (*ppSubPic)->AddRef();
  275. return(true);
  276. }