home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / ddsurf.h < prev    next >
C/C++ Source or Header  |  2000-05-12  |  9KB  |  351 lines

  1. #pragma once
  2.  
  3. //-----------------------------------------------------------------------------------//
  4. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  5. //                             ISBN  0-13-086985-6                                   //
  6. //                                                                                   //
  7. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  8. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  9. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  10. //                                                                                   //
  11. //  FileName   : ddsurf.h                                                             //
  12. //  Description: DirectDraw surface wrapper                                          //
  13. //  Version    : 1.00.000, May 31, 2000                                              //
  14. //-----------------------------------------------------------------------------------//
  15.  
  16. #define SAFE_RELEASE(inf) { if ( inf ) { inf->Release(); inf = NULL; } }
  17.  
  18. // Wrapper for IDirectDrawSurface7 interface
  19. class KDDSurface
  20. {
  21. protected:
  22.     IDirectDrawSurface7 * m_pSurface;
  23.     DDSURFACEDESC2        m_ddsd;
  24.     HDC                      m_hDC;
  25.  
  26. public:
  27.  
  28.     KDDSurface();
  29.     virtual void Discharge(void); // release before destructor
  30.  
  31.     virtual ~KDDSurface() // make sure everything is released
  32.     {
  33.         Discharge();
  34.     }
  35.     
  36.     operator IDirectDrawSurface7 * & ()
  37.     {
  38.         return m_pSurface;
  39.     }
  40.  
  41.     operator HDC ()
  42.     {
  43.         return m_hDC;
  44.     }
  45.  
  46.     int GetWidth(void) const
  47.     {
  48.         return m_ddsd.dwWidth;
  49.     }
  50.  
  51.     int GetHeight(void) const
  52.     {
  53.         return m_ddsd.dwHeight;
  54.     }
  55.  
  56.     HRESULT CreatePrimarySurface(IDirectDraw7 * pDD, int nBackBuffer);
  57.     
  58.     const DDSURFACEDESC2 * GetSurfaceDesc(void);
  59.     virtual HRESULT RestoreSurface(void); // restore surface if lost
  60.  
  61.     // DirectDraw Blting
  62.     HRESULT  SetClipper(IDirectDraw7 * pDD, HWND hWnd);
  63.     
  64.     HRESULT Blt(LPRECT prDest, IDirectDrawSurface7 * pSrc, LPRECT prSrc, DWORD dwFlags, LPDDBLTFX pDDBltFx=NULL)
  65.     {
  66.         return m_pSurface->Blt(prDest, pSrc, prSrc, dwFlags, pDDBltFx);
  67.     }
  68.  
  69.     DWORD   ColorMatch(BYTE red, BYTE green, BYTE blue);
  70.  
  71.     HRESULT FillColor(int x0, int y0, int x1, int y1, DWORD fillcolor);
  72.     HRESULT BitBlt(int x, int y, int w, int h, IDirectDrawSurface7 * pSrc, DWORD flag=0);
  73.  
  74.     HRESULT BitBlt(int x, int y, KDDSurface & src, DWORD flag=0)
  75.     {
  76.         return BitBlt(x, y, src.GetWidth(), src.GetHeight(), src, flag);
  77.     }
  78.  
  79.     HRESULT SetSourceColorKey(DWORD color);
  80.  
  81.     // Drawing using GDI device context
  82.     HRESULT GetDC(void);        // Get DC device context handle
  83.     HRESULT ReleaseDC(void);
  84.     
  85.     HRESULT DrawBitmap(const BITMAPINFO * pDIB, int dx, int dy, int dw, int dh);
  86.     
  87.     // Direct Pixel Access
  88.     BYTE  * LockSurface(RECT * pRect=NULL);
  89.     HRESULT Unlock(RECT * pRect=NULL);
  90.  
  91.     int GetPitch(void) const
  92.     {
  93.         return m_ddsd.lPitch;
  94.     }
  95.  
  96.     DWORD GetPixel(int x, int y);
  97.     BOOL  SetPixel(int x, int y, DWORD color);
  98.     BOOL  Line(int x0, int y0, int x1, int y1, DWORD color);
  99.     BOOL  FillRgn(HRGN hRgn, DWORD color);
  100. };
  101.  
  102.  
  103. class KLockedSurface
  104. {
  105. public:
  106.     BYTE * pSurface;
  107.     int    pitch;
  108.     int    bpp;
  109.  
  110.     bool Initialize(KDDSurface & surface)
  111.     {
  112.         pSurface = surface.LockSurface(NULL);
  113.         pitch    = surface.GetPitch();
  114.         bpp      = surface.GetSurfaceDesc()->ddpfPixelFormat.dwRGBBitCount;
  115.         
  116.         return pSurface!=NULL;
  117.     }
  118.  
  119.     BYTE & ByteAt(int x, int y)
  120.     {
  121.         BYTE * pPixel = (BYTE *) (pSurface + pitch * y);
  122.  
  123.         return pPixel[x];
  124.     }
  125.  
  126.     WORD & WordAt(int x, int y)
  127.     {
  128.         WORD * pPixel = (WORD *) (pSurface + pitch * y);
  129.  
  130.         return pPixel[x];
  131.     }
  132.  
  133.     RGBTRIPLE & RGBTripleAt(int x, int y)
  134.     {
  135.         RGBTRIPLE * pPixel = (RGBTRIPLE *) (pSurface + pitch * y);
  136.  
  137.         return pPixel[x];
  138.     }
  139.  
  140.     DWORD & DWordAt(int x, int y)
  141.     {
  142.         DWORD * pPixel = (DWORD *) (pSurface + pitch * y);
  143.  
  144.         return pPixel[x];
  145.     }
  146.  
  147.     BOOL SetPixel(int x, int y, DWORD color)
  148.     {
  149.         switch ( bpp )
  150.         {
  151.             case  8:      ByteAt(x, y) =  (BYTE) color; break;
  152.             case 15:
  153.             case 16:      WordAt(x, y) =  (WORD) color; break;
  154.             case 24: RGBTripleAt(x, y) = * (RGBTRIPLE *) & color; break;
  155.             case 32:     DWordAt(x, y) = (DWORD) color; break;
  156.             default: return FALSE;
  157.         }
  158.  
  159.         return TRUE;
  160.     }
  161.  
  162.     DWORD GetPixel(int x, int y)
  163.     {
  164.         switch ( bpp )
  165.         {
  166.             case  8:  return ByteAt(x, y);
  167.             case 15:
  168.             case 16:  return WordAt(x, y);
  169.             case 32:  return DWordAt(x, y);
  170.             case 24: 
  171.                 {
  172.                     DWORD rslt = 0;
  173.                     
  174.                     * (RGBTRIPLE *) rslt = RGBTripleAt(x, y); 
  175.                     return rslt;
  176.                 }
  177.         }
  178.  
  179.         return 0;
  180.     }
  181.  
  182.     void Line(int x0, int y0, int x1, int y1, DWORD color);
  183. };
  184.  
  185. /////////////////////////////////////////////////////////////
  186.  
  187. typedef enum
  188. {
  189.     mem_default,
  190.     mem_system,
  191.     mem_nonlocalvideo,
  192.     mem_localvideo
  193. };
  194.  
  195. class KOffScreenSurface : public KDDSurface
  196. {
  197. public:
  198.     HRESULT CreateOffScreenSurface(IDirectDraw7 * pDD, int width, int height, int mem=mem_default);
  199.     HRESULT CreateOffScreenSurfaceBpp(IDirectDraw7 * pDD, int width, int height, int bpp, int mem=mem_default);
  200.     
  201.     HRESULT CreateBitmapSurface(IDirectDraw7 * pDD, const BITMAPINFO * pDIB, int mem=mem_default);
  202.     HRESULT CreateBitmapSurface(IDirectDraw7 * pDD, const TCHAR * pFileName, int mem=mem_default);
  203.  
  204.     HRESULT CreateTextureSurface(IDirect3DDevice7 * pD3DDevice, IDirectDraw7 * pDD, unsigned width, unsigned height);
  205.     HRESULT    CreateTextureSurface(IDirect3DDevice7 * pD3DDevice, IDirectDraw7 * pDD, const BITMAPINFO * pDIB);
  206.     HRESULT    CreateTextureSurface(IDirect3DDevice7 * pD3DDevice, IDirectDraw7 * pDD, const TCHAR * pFileName);
  207.  
  208.     HRESULT CreateZBuffer(IDirect3D7 * pD3D, IDirectDraw7 * pDD, REFCLSID riidDevice, int width, int height);
  209.  
  210.     HRESULT Attach(IDirectDrawSurface7 * pAttach)
  211.     {
  212.         return m_pSurface->AddAttachedSurface(pAttach);
  213.     }
  214. };    
  215.  
  216. template <int MaxChar>
  217. class KDDFont : public KOffScreenSurface
  218. {
  219.     int      m_offset [MaxChar];  // A width
  220.     int      m_advance[MaxChar];  // A + B + C
  221.  
  222.     int         m_pos      [MaxChar];  // horizontal position within font surface
  223.     int      m_width  [MaxChar];  // - min(A, 0) + B - min(C,0)
  224.  
  225.     unsigned m_firstchar;
  226.     int         m_nChar;
  227.  
  228. public:
  229.     
  230.     HRESULT CreateFont(IDirectDraw7 * pDD, const LOGFONT & lf, unsigned firstchar, unsigned lastchar, COLORREF crColor);
  231.     int     TextOut(IDirectDrawSurface7 * pSurface, int x, int y, const TCHAR * mess, int nChar=0);
  232. };
  233.  
  234. template <int MaxChar>
  235. HRESULT KDDFont<MaxChar>::CreateFont(IDirectDraw7 * pDD, const LOGFONT & lf, unsigned firstchar, unsigned lastchar, COLORREF crColor)
  236. {
  237.     m_firstchar = firstchar;
  238.     m_nChar     = lastchar - firstchar + 1;
  239.     
  240.     if ( m_nChar > MaxChar )
  241.         return E_INVALIDARG;
  242.     
  243.     HFONT hFont = CreateFontIndirect(&lf);
  244.  
  245.     if ( hFont==NULL )
  246.         return E_INVALIDARG;
  247.  
  248.     HRESULT hr;
  249.     ABC     abc[MaxChar];
  250.  
  251.     int height;
  252.     {
  253.         HDC hDC = ::GetDC(NULL);
  254.  
  255.         if ( hDC )
  256.         {
  257.             HGDIOBJ hOld = SelectObject(hDC, hFont);
  258.  
  259.             TEXTMETRIC tm;
  260.  
  261.             GetTextMetrics(hDC, & tm);
  262.             height = tm.tmHeight;
  263.  
  264.             if ( GetCharABCWidths(hDC, firstchar, lastchar, abc) )
  265.                 hr = S_OK;
  266.             else
  267.                 hr = E_INVALIDARG;
  268.  
  269.             SelectObject(hDC, hOld);
  270.             ::ReleaseDC(NULL, hDC);
  271.         }
  272.     }
  273.  
  274.     if ( SUCCEEDED(hr) )
  275.     {
  276.         int width = 0;
  277.         
  278.         for (int i=0; i<m_nChar; i++)
  279.         {
  280.             m_offset[i]  = abc[i].abcA;
  281.             m_width[i]   =  - min(abc[i].abcA, 0) + abc[i].abcB - min(abc[i].abcC, 0);
  282.             m_advance[i] = abc[i].abcA + abc[i].abcB + abc[i].abcC;
  283.             
  284.             width += m_width[i];
  285.         }
  286.  
  287.         hr = CreateOffScreenSurface(pDD, width, height);
  288.  
  289.         if ( SUCCEEDED(hr) )
  290.         {
  291.             GetDC();
  292.  
  293.             int x = 0;
  294.             
  295.             PatBlt(m_hDC, 0, 0, GetWidth(), GetHeight(), BLACKNESS); // black
  296.             
  297.             SetBkMode(m_hDC, TRANSPARENT);
  298.             SetTextColor(m_hDC, crColor); // white forground
  299.  
  300.             HGDIOBJ hOld = SelectObject(m_hDC, hFont);
  301.             SetTextAlign(m_hDC, TA_TOP | TA_LEFT);
  302.             
  303.             for (int i=0; i<m_nChar; i++)
  304.             {
  305.                 TCHAR ch = firstchar + i;
  306.  
  307.                 m_pos[i] = x;
  308.                 ::TextOut(m_hDC, x-m_offset[i], 0, & ch, 1);
  309.                 x += m_width[i];
  310.             }
  311.  
  312.             SelectObject(m_hDC, hOld);
  313.             ReleaseDC();
  314.  
  315.             SetSourceColorKey(0); // black as source color key
  316.         }
  317.     }
  318.  
  319.     DeleteObject(hFont);
  320.  
  321.     return hr;
  322. };
  323.  
  324.  
  325. template<int MaxChar>
  326. int KDDFont<MaxChar>::TextOut(IDirectDrawSurface7 * pDest, int x, int y, const TCHAR * mess, int nChar)
  327. {
  328.     if ( nChar<=0 )
  329.         nChar = _tcslen(mess);
  330.  
  331.     for (int i=0; i<nChar; i++)
  332.     {
  333.         int ch = mess[i] - m_firstchar;
  334.  
  335.         if ( (ch<0) || (ch>m_nChar) )
  336.             ch = 0;
  337.  
  338.         RECT dst = { x + m_offset[ch],                 y, 
  339.                      x + m_offset[ch] + m_width[ch], y + GetHeight() };
  340.  
  341.         RECT src = { m_pos[ch], 0, m_pos[ch] + m_width[ch], GetHeight() };
  342.  
  343.         pDest->Blt(& dst, m_pSurface, & src, DDBLT_KEYSRC, NULL);
  344.  
  345.         x += m_advance[ch];
  346.     }
  347.  
  348.     return x;
  349. }
  350.  
  351.