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

多媒体编程

开发平台:

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 <ddraw.h>
  23. #include <d3d.h>
  24. #include "DX7SubPic.h"
  25. //
  26. // CDX7SubPic
  27. //
  28. CDX7SubPic::CDX7SubPic(IDirect3DDevice7* pD3DDev, IDirectDrawSurface7* pSurface)
  29. : m_pSurface(pSurface)
  30. , m_pD3DDev(pD3DDev)
  31. {
  32. DDSURFACEDESC2 ddsd;
  33. INITDDSTRUCT(ddsd);
  34. if(SUCCEEDED(m_pSurface->GetSurfaceDesc(&ddsd)))
  35. {
  36. m_maxsize.SetSize(ddsd.dwWidth, ddsd.dwHeight);
  37. m_rcDirty.SetRect(0, 0, ddsd.dwWidth, ddsd.dwHeight);
  38. }
  39. }
  40. // ISubPic
  41. STDMETHODIMP_(void*) CDX7SubPic::GetObject()
  42. {
  43. return (void*)(IDirectDrawSurface7*)m_pSurface;
  44. }
  45. STDMETHODIMP CDX7SubPic::GetDesc(SubPicDesc& spd)
  46. {
  47. DDSURFACEDESC2 ddsd;
  48. INITDDSTRUCT(ddsd);
  49. if(FAILED(m_pSurface->GetSurfaceDesc(&ddsd)))
  50. return E_FAIL;
  51. spd.type = 0;
  52. spd.w = m_size.cx;
  53. spd.h = m_size.cy;
  54. spd.bpp = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
  55. spd.pitch = ddsd.lPitch;
  56. spd.bits = ddsd.lpSurface; // should be NULL
  57. spd.vidrect = m_vidrect;
  58. return S_OK;
  59. }
  60. STDMETHODIMP CDX7SubPic::CopyTo(ISubPic* pSubPic)
  61. {
  62. HRESULT hr;
  63. if(FAILED(hr = __super::CopyTo(pSubPic)))
  64. return hr;
  65. CPoint p = m_rcDirty.TopLeft();
  66. hr = m_pD3DDev->Load((IDirectDrawSurface7*)pSubPic->GetObject(), &p, (IDirectDrawSurface7*)GetObject(), m_rcDirty, 0);
  67. return SUCCEEDED(hr) ? S_OK : E_FAIL;
  68. }
  69. STDMETHODIMP CDX7SubPic::ClearDirtyRect(DWORD color)
  70. {
  71. if(m_rcDirty.IsRectEmpty())
  72. return S_FALSE;
  73. DDBLTFX fx;
  74. INITDDSTRUCT(fx);
  75. fx.dwFillColor = color;
  76. m_pSurface->Blt(&m_rcDirty, NULL, NULL, DDBLT_WAIT|DDBLT_COLORFILL, &fx);
  77. m_rcDirty.SetRectEmpty();
  78. return S_OK;
  79. }
  80. STDMETHODIMP CDX7SubPic::Lock(SubPicDesc& spd)
  81. {
  82. DDSURFACEDESC2 ddsd;
  83. INITDDSTRUCT(ddsd);
  84. if(FAILED(m_pSurface->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT, NULL)))
  85. return E_FAIL;
  86. spd.type = 0;
  87. spd.w = m_size.cx;
  88. spd.h = m_size.cy;
  89. spd.bpp = (WORD)ddsd.ddpfPixelFormat.dwRGBBitCount;
  90. spd.pitch = ddsd.lPitch;
  91. spd.bits = ddsd.lpSurface;
  92. spd.vidrect = m_vidrect;
  93. return S_OK;
  94. }
  95. STDMETHODIMP CDX7SubPic::Unlock(RECT* pDirtyRect)
  96. {
  97. m_pSurface->Unlock(NULL);
  98. if(pDirtyRect)
  99. {
  100. m_rcDirty = *pDirtyRect;
  101. m_rcDirty.InflateRect(1, 1);
  102. m_rcDirty &= CRect(CPoint(0, 0), m_size);
  103. }
  104. else
  105. {
  106. m_rcDirty = CRect(CPoint(0, 0), m_size);
  107. }
  108. return S_OK;
  109. }
  110. STDMETHODIMP CDX7SubPic::AlphaBlt(RECT* pSrc, RECT* pDst, SubPicDesc* pTarget)
  111. {
  112. ASSERT(pTarget == NULL);
  113. if(!m_pD3DDev || !m_pSurface || !pSrc || !pDst)
  114. return E_POINTER;
  115. CRect src(*pSrc), dst(*pDst);
  116. HRESULT hr;
  117.     do
  118. {
  119. DDSURFACEDESC2 ddsd;
  120. INITDDSTRUCT(ddsd);
  121. if(FAILED(hr = m_pSurface->GetSurfaceDesc(&ddsd)))
  122. break;
  123.         float w = (float)ddsd.dwWidth;
  124.         float h = (float)ddsd.dwHeight;
  125. struct
  126. {
  127. float x, y, z, rhw;
  128. float tu, tv;
  129. }
  130. pVertices[] =
  131. {
  132. {(float)dst.left, (float)dst.top, 0.5f, 2.0f, (float)src.left / w, (float)src.top / h},
  133. {(float)dst.right, (float)dst.top, 0.5f, 2.0f, (float)src.right / w, (float)src.top / h},
  134. {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, (float)src.left / w, (float)src.bottom / h},
  135. {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, (float)src.right / w, (float)src.bottom / h},
  136. };
  137. /*
  138. for(int i = 0; i < countof(pVertices); i++)
  139. {
  140. pVertices[i].x -= 0.5;
  141. pVertices[i].y -= 0.5;
  142. }
  143. */
  144.         hr = m_pD3DDev->SetTexture(0, m_pSurface);
  145.         m_pD3DDev->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
  146.         m_pD3DDev->SetRenderState(D3DRENDERSTATE_LIGHTING, FALSE);
  147.         m_pD3DDev->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE);
  148.         m_pD3DDev->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE); // pre-multiplied src and ...
  149.         m_pD3DDev->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_SRCALPHA); // ... inverse alpha channel for dst
  150. m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  151.         m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  152.         m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  153.         m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTFG_LINEAR);
  154.         m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTFN_LINEAR);
  155.         m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTFP_LINEAR);
  156.         m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);
  157. /*//
  158. D3DDEVICEDESC7 d3ddevdesc;
  159. m_pD3DDev->GetCaps(&d3ddevdesc);
  160. if(d3ddevdesc.dpcTriCaps.dwAlphaCmpCaps & D3DPCMPCAPS_LESS)
  161. {
  162. m_pD3DDev->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)0x000000FE);
  163. m_pD3DDev->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, TRUE); 
  164. m_pD3DDev->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DPCMPCAPS_LESS);
  165. }
  166.         *///
  167.         if(FAILED(hr = m_pD3DDev->BeginScene()))
  168. break;
  169.         
  170. hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP,
  171. D3DFVF_XYZRHW | D3DFVF_TEX1,
  172. pVertices, 4, D3DDP_WAIT);
  173. m_pD3DDev->EndScene();
  174.         //
  175. m_pD3DDev->SetTexture(0, NULL);
  176. return S_OK;
  177.     }
  178. while(0);
  179.     return E_FAIL;
  180. }
  181. //
  182. // CDX7SubPicAllocator
  183. //
  184. CDX7SubPicAllocator::CDX7SubPicAllocator(IDirect3DDevice7* pD3DDev, SIZE maxsize, bool fPow2Textures) 
  185. : ISubPicAllocatorImpl(maxsize, true, fPow2Textures)
  186. , m_pD3DDev(pD3DDev)
  187. , m_maxsize(maxsize)
  188. {
  189. }
  190. // ISubPicAllocator
  191. STDMETHODIMP CDX7SubPicAllocator::ChangeDevice(IUnknown* pDev)
  192. {
  193. CComQIPtr<IDirect3DDevice7, &IID_IDirect3DDevice7> pD3DDev = pDev;
  194. if(!pD3DDev) return E_NOINTERFACE;
  195. CAutoLock cAutoLock(this);
  196. m_pD3DDev = pD3DDev;
  197. return __super::ChangeDevice(pDev);
  198. }
  199. // ISubPicAllocatorImpl
  200. bool CDX7SubPicAllocator::Alloc(bool fStatic, ISubPic** ppSubPic)
  201. {
  202. if(!ppSubPic) 
  203. return(false);
  204. CAutoLock cAutoLock(this);
  205. DDSURFACEDESC2 ddsd;
  206. INITDDSTRUCT(ddsd);
  207. ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;
  208. ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | (fStatic ? DDSCAPS_SYSTEMMEMORY : 0);
  209. ddsd.ddsCaps.dwCaps2 = fStatic ? 0 : (DDSCAPS2_TEXTUREMANAGE|DDSCAPS2_HINTSTATIC);
  210. ddsd.dwWidth = m_maxsize.cx;
  211. ddsd.dwHeight = m_maxsize.cy;
  212. ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
  213. ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_ALPHAPIXELS;
  214. ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
  215. ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0xFF000000;
  216. ddsd.ddpfPixelFormat.dwRBitMask        = 0x00FF0000;
  217. ddsd.ddpfPixelFormat.dwGBitMask        = 0x0000FF00;
  218. ddsd.ddpfPixelFormat.dwBBitMask        = 0x000000FF;
  219. if(m_fPow2Textures)
  220. {
  221. ddsd.dwWidth = ddsd.dwHeight = 1;
  222. while(ddsd.dwWidth < m_maxsize.cx) ddsd.dwWidth <<= 1;
  223. while(ddsd.dwHeight < m_maxsize.cy) ddsd.dwHeight <<= 1;
  224. }
  225. CComPtr<IDirect3D7> pD3D;
  226. CComQIPtr<IDirectDraw7, &IID_IDirectDraw7> pDD;
  227. if(FAILED(m_pD3DDev->GetDirect3D(&pD3D)) || !pD3D || !(pDD = pD3D))
  228. return(false);
  229. CComPtr<IDirectDrawSurface7> pSurface;
  230. if(FAILED(pDD->CreateSurface(&ddsd, &pSurface, NULL)))
  231. return(false);
  232. if(!(*ppSubPic = new CDX7SubPic(m_pD3DDev, pSurface)))
  233. return(false);
  234. (*ppSubPic)->AddRef();
  235. return(true);
  236. }