Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cDXSurface.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cDXSurface_H
7 #define _INC_cDXSurface_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 #include "cDXTexture.h"
13 
14 #ifdef USE_DX9
15 
16 namespace Gray3D
17 {
18  class cDXTexture;
19 
20  class GRAY3D_LINK cDXSurface : public cDXBase
21  {
28  typedef cDXBase SUPER_t;
29 
30  public:
31  cIUnkPtr<ID3DSurface> m_pDXSurf;
32  cDXTexture m_Tex;
33 
34  public:
35  cDXSurface(PIXELS_t nWidth, PIXELS_t nHeight, D3DFORMAT eFormat, DWORD dwUsage);
36  virtual ~cDXSurface();
37 
38  void InitSurfaceSize(PIXELS_t cx, PIXELS_t cy);
39 
40  STDMETHOD_(cString, get_Name)() const
41  {
42  return "DXTextureSurf";
43  }
44 
45  virtual HRESULT InitDeviceObjects(cDXDevice* pDXDev);
46  virtual HRESULT DeleteDeviceObjects();
47 
48  HRESULT LoadSurfaceFromFile(const FILECHAR_t* pszPath);
49  HRESULT CreateSurface(PIXELS_t Width, PIXELS_t Height, D3DFORMAT eFormat, D3DPOOL ePool);
50  HRESULT MakeBackBuffer(void);
51  HRESULT PasteFromSurface(cDXSurface* Source, cRectI* pSourceRect, int x, int y);
52 
53  private:
54  cDXSurface(const cDXSurface&);
55  };
56 
59 
60  template<D3DFORMAT _FMT> inline D3DCOLOR GetPixel(const D3DLOCKED_RECT& lr, int x, int y);
61  template<> D3DCOLOR GetPixel<D3DFMT_DXT1>(const D3DLOCKED_RECT& lr, int x, int y);
62 
63  template<> inline D3DCOLOR GetPixel<D3DFMT_X8R8G8B8>(const D3DLOCKED_RECT& lr, int x, int y)
64  {
65  return *((D3DCOLOR*)((const BYTE*)lr.pBits + y * lr.Pitch) + x);
66  }
67  template<> inline D3DCOLOR GetPixel<D3DFMT_A8R8G8B8>(const D3DLOCKED_RECT& lr, int x, int y)
68  {
69  return *((D3DCOLOR*)((const BYTE*)lr.pBits + y * lr.Pitch) + x);
70  }
71 
72  template< D3DFORMAT _FMT, bool _FORCE_CLONE = false >
73  class cDXSurfaceLock // : public cLockerT<>
74  {
78 
79  public:
80  cIUnkPtr<ID3DTexture> m_pTexture;
81  cIUnkPtr<ID3DSurface> m_pSurface;
82  D3DSURFACE_DESC m_sSurfDesc;
83 
84  // Locking data.
85  cRectI m_LockRect;
86  DWORD m_dwLockFlags;
87  D3DLOCKED_RECT m_LockData;
88 
89  private:
90  cRectI m_sTmpRect;
91  cIUnkPtr<ID3DSurface> m_pTmpSurface;
92 
93  public:
94  cDXSurfaceLock()
95  {
96  m_LockData.pBits = nullptr;
97  }
98  cDXSurfaceLock(ID3DSurface* pSurf, const cRectI* pRect, DWORD dwFlags)
99  : m_pSurface(pSurf)
100  {
103  ASSERT(m_pSurface != nullptr);
104  m_LockData.pBits = nullptr;
105  m_pSurface->GetDesc(&m_sSurfDesc);
106  Lock(pRect, dwFlags);
107  }
108 
109  cDXSurfaceLock(ID3DTexture* pTex, const cRectI* pRect, DWORD dwFlags)
110  : m_pTexture(pTex)
111  {
113  ASSERT(pTex != nullptr);
114  m_LockData.pBits = nullptr;
115  HRESULT hRes = pTex->GetSurfaceLevel(0, IUNK_GETPPTR(m_pSurface, IDirect3DSurface9));
116  m_pSurface->GetDesc(&m_sSurfDesc);
117  Lock(pRect, dwFlags);
118  }
119 
120  ~cDXSurfaceLock()
121  {
122  Unlock();
123  }
124 
125  bool isLocked() const
126  {
127  return m_LockData.pBits != nullptr;
128  }
129 
130  HRESULT Attach(ID3DSurface* pSurf)
131  {
132  ASSERT(!isLocked());
133  m_pSurface = pSurf;
134  m_pTexture.ReleasePtr();
135  if (pSurf == nullptr)
136  {
137  return S_FALSE;
138  }
139  return m_pSurface->GetDesc(&m_sSurfDesc);
140  }
141 
142  HRESULT Attach(ID3DTexture* pTex, int iSurfaceLevel = 0)
143  {
144  ASSERT(!isLocked());
145  m_pSurface.ReleasePtr();
146  m_pTexture = pTex;
147  if (pTex == nullptr)
148  {
149  return S_FALSE;
150  }
151  HRESULT hRes = pTex->GetSurfaceLevel(iSurfaceLevel, IUNK_GETPPTR(m_pSurface, IDirect3DSurface9));
152  if (FAILED(hRes))
153  {
154  return hRes;
155  }
156  return m_pSurface->GetDesc(&m_sSurfDesc);
157  }
158 
159  void Detach()
160  {
161  ASSERT(!isLocked());
162  m_pSurface.ReleasePtr();
163  m_pTexture.ReleasePtr();
164  }
165 
166  HRESULT Lock(const cRectI* pRect, DWORD dwFlags)
167  {
170 
171  if (m_pSurface == nullptr)
172  {
173  DEBUG_CHECK(0);
174  return E_POINTER;
175  }
176  if (isLocked())
177  {
178  DEBUG_CHECK(0);
179  return E_FAIL; // already Locked!
180  }
181  m_dwLockFlags = dwFlags;
182  if (pRect == nullptr) // all.
183  {
184  m_LockRect = cRectI(0, 0, m_sSurfDesc.Width, m_sSurfDesc.Height);
185  }
186  else
187  {
188  m_LockRect = *pRect;
189  ASSERT(m_LockRect.left >= 0);
190  ASSERT(m_LockRect.top >= 0);
191  ASSERT(m_LockRect.right <= (int)m_sSurfDesc.Width);
192  ASSERT(m_LockRect.bottom <= (int)m_sSurfDesc.Height);
193  }
194 
195  HRESULT hRes;
196  if (!_FORCE_CLONE && _FMT == m_sSurfDesc.Format)
197  {
198  // use it directly.
199  if (!(m_sSurfDesc.Usage & D3DUSAGE_DYNAMIC))
200  dwFlags &= ~D3DLOCK_DISCARD;
201  hRes = m_pSurface->LockRect(&m_LockData, (RECT*)pRect, dwFlags);
202  m_sTmpRect = cRectI(0, 0, m_sSurfDesc.Width, m_sSurfDesc.Height);
203  }
204  else
205  {
206  // Clone it to deal with format change.
207  m_sTmpRect = cRectI(0, 0, m_LockRect.Width(), m_LockRect.Height());
208 
209  cIUnkPtr<ID3DDevice> pDev;
210  hRes = m_pSurface->GetDevice(IUNK_GETPPTR(pDev, ID3DDevice));
211 
212  hRes = pDev->CreateOffscreenPlainSurface(m_sTmpRect.right, m_sTmpRect.bottom,
213  _FMT, D3DPOOL_SCRATCH, IUNK_GETPPTR(m_pTmpSurface, IDirect3DSurface9), nullptr);
214  if (FAILED(hRes))
215  return hRes;
216  if (!(dwFlags & D3DLOCK_DISCARD))
217  {
218  hRes = ::D3DXLoadSurfaceFromSurface(m_pTmpSurface, nullptr, m_sTmpRect,
219  m_pSurface, nullptr, m_LockRect, D3DX_FILTER_NONE, 0);
220  if (FAILED(hRes))
221  {
222  return hRes;
223  }
224  }
225  hRes = m_pTmpSurface->LockRect(&m_LockData, nullptr, dwFlags & ~D3DLOCK_DISCARD);
226  }
227  return hRes;
228  }
229 
230  void Unlock()
231  {
232  if (!isLocked())
233  return;
234  if (m_pTmpSurface != nullptr)
235  {
236  m_pTmpSurface->UnlockRect();
237  if (!(m_dwLockFlags & D3DLOCK_READONLY))
238  {
239  HRESULT hRes = ::D3DXLoadSurfaceFromSurface(m_pSurface, nullptr, m_LockRect,
240  m_pTmpSurface, nullptr, m_sTmpRect, D3DX_FILTER_DITHER, 0);
242  }
243  m_pTmpSurface.ReleasePtr();
244  }
245  else
246  {
247  m_pSurface->UnlockRect();
248  }
249  m_LockData.pBits = nullptr;
250  }
251 
252  D3DCOLOR GetPixel(PIXELS_t x, PIXELS_t y) const
253  {
255  ASSERT(isLocked());
256  return Gray3D::GetPixel<_FMT>(m_LockData, x, y);
257  }
258 
259  template<bool _BWRAP> D3DCOLOR GetPixel(PIXELS_t x, PIXELS_t y)
260  {
261  ASSERT(isLocked());
262  if (_BWRAP)
263  {
264  x %= m_sTmpRect.right;
265  if (x < 0)
266  x += m_sTmpRect.right;
267  y %= m_sTmpRect.bottom;
268  if (y < 0)
269  y += m_sTmpRect.bottom;
270  }
271  else // clamp
272  {
273  if (x < 0)
274  x = 0;
275  else if (x >= m_sTmpRect.right)
276  x = m_sTmpRect.right - 1;
277  if (y < 0)
278  y = 0;
279  else if (y >= m_sTmpRect.bottom)
280  y = m_sTmpRect.bottom - 1;
281  }
282 
283  return GetPixel(x, y);
284  }
285 
286  template<bool _BWRAP, bool _BILERP> D3DCOLOR GetPixelFC(float tx, float ty)
287  {
289  // ASSERT( isLocked());
290  if (_BILERP)
291  {
292  tx -= 0.5f;
293  ty -= 0.5f;
294 
295  int cx = cFloat32::ifloor(tx); tx -= cx;
296  int cy = cFloat32::ifloor(ty); ty -= cy;
297 
298  cColorf c00 = GetPixel<_BWRAP>(cx, cy);
299  cColorf c01 = GetPixel<_BWRAP>(cx + 1, cy);
300  cColorf c10 = GetPixel<_BWRAP>(cx, cy + 1);
301  cColorf c11 = GetPixel<_BWRAP>(cx + 1, cy + 1);
302 
303  float itx = 1 - tx;
304  float ity = 1 - ty;
305 
306  c00.DoScale(itx * ity);
307  c01.DoScale(tx * ity);
308  c10.DoScale(itx * ty);
309  c11.DoScale(tx * ty);
310 
311  return cColorf(c00 + c01 + c10 + c11);
312  }
313  else
314  {
315  return GetPixel<_BWRAP>(cFloat32::ifloor(tx), cFloat32::ifloor(ty));
316  }
317  }
318 
319  template<bool _BWRAP, bool _BILERP> D3DCOLOR GetPixelTC(float x, float y)
320  {
322  // ASSERT( isLocked());
323  float tx = x * m_sTmpRect.right;
324  float ty = y * m_sTmpRect.bottom;
325  return GetPixelFC< _BWRAP, _BILERP >(tx, ty);
326  }
327  };
328 }
329 #endif // USE_DX9
330 #endif
#define GRAY3D_LINK
Definition: Gray3D.h:15
#define FAILED(x)
Definition: HResult.h:30
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
enum _D3DPOOL D3DPOOL
@ D3DPOOL_SCRATCH
Definition: UseDX.h:288
enum _D3DFORMAT D3DFORMAT
#define D3DLOCK_READONLY
Definition: UseDX.h:115
DWORD D3DCOLOR
Stuff normally defined in windows.h or DirectX headers.
Definition: cColorRef.h:24
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define DEBUG_CHECK(exp)
Definition: cDebugAssert.h:90
#define IUNK_GETPPTR(p, TYPE)
Definition: cIUnkPtr.h:309
Definition: IUnknown.h:68
Definition: Gray3D.cpp:12
int PIXELS_t
Count of pixels in a dimension of some image/surface.
Definition: cSurfaceInfo.h:20
char FILECHAR_t
a UTF8 char in a file name. like TCHAR
Definition: FileName.h:22
cStringT< GChar_t > cString
Definition: cString.h:636
Definition: UseDX.h:340
void * pBits
Definition: UseDX.h:342
int Pitch
Definition: UseDX.h:341
Definition: UseDX.h:326
DWORD Usage
Definition: UseDX.h:329
UINT Height
Definition: UseDX.h:335
D3DFORMAT Format
Definition: UseDX.h:327
UINT Width
Definition: UseDX.h:334