home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / include / ddwrap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-23  |  7.9 KB  |  348 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : ddwrap.cpp                                                             //
  10. //  Description: DirectDraw/Direct3D IM wrapper                                      //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <mmsystem.h>
  19. #include <stdio.h>
  20. #include <assert.h>
  21.  
  22. #include <ddraw.h>
  23. #include <d3d.h>
  24.  
  25. #include "basicdib.h"
  26. #include "ddsurf.h"
  27. #include "ddwrap.h"
  28.  
  29. //////////////////////////////////////////////
  30.  
  31. KDirectDraw::KDirectDraw(void)
  32. {
  33.     m_pDD    = NULL;
  34. }
  35.  
  36. HRESULT KDirectDraw::Discharge(void)
  37. {
  38.     m_primary.Discharge();
  39.  
  40.     SAFE_RELEASE(m_pDD);
  41.  
  42.     return S_OK;
  43. }
  44.  
  45. void KDirectDraw::SetClientRect(HWND hWnd)
  46. {
  47.     GetClientRect(hWnd, & m_rcDest);
  48.     ClientToScreen(hWnd, (POINT*)& m_rcDest.left);
  49.     ClientToScreen(hWnd, (POINT*)& m_rcDest.right);
  50. }
  51.  
  52.  
  53. #define pDriverGUID NULL
  54.  
  55. HRESULT KDirectDraw::SetupDirectDraw(HWND hTop, HWND hWnd, int nBufferCount,
  56.              bool bFullScreen, int width, int height, int bpp)
  57. {
  58.     HRESULT hr = DirectDrawCreateEx(pDriverGUID, (void **) &m_pDD, IID_IDirectDraw7, NULL);
  59.     if ( FAILED( hr ) )
  60.         return hr;
  61.  
  62.     if ( bFullScreen )
  63.         hr = m_pDD->SetCooperativeLevel(hTop, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
  64.     else
  65.         hr = m_pDD->SetCooperativeLevel(hTop, DDSCL_NORMAL);
  66.     
  67.     if ( FAILED(hr) )
  68.         return hr;
  69.  
  70.     if ( bFullScreen )
  71.     {
  72.         hr = m_pDD->SetDisplayMode(width, height, bpp, 0, 0);
  73.         if ( FAILED(hr) )
  74.             return hr;
  75.  
  76.         SetRect(& m_rcDest, 0, 0, width, height);
  77.     }
  78.     else
  79.         SetClientRect(hWnd);
  80.     
  81.     hr = m_primary.CreatePrimarySurface(m_pDD, nBufferCount);
  82.  
  83.     if ( FAILED(hr) )
  84.         return hr;
  85.  
  86.     if ( ! bFullScreen )
  87.         hr = m_primary.SetClipper(m_pDD, hWnd);
  88.  
  89.     return hr;
  90. }
  91.  
  92.  
  93. ////////////////////////////////////////////////
  94.  
  95. HRESULT KDDPalette::LoadPalette(IDirectDraw7 * pDD, const BITMAPINFO * pDIB)
  96. {
  97.     PALETTEENTRY colortable[256];
  98.  
  99.     memset(colortable, 0, sizeof(colortable));
  100.     
  101.     for (int i=0; i<256; i++)
  102.     {
  103.         colortable[i].peRed   = i;
  104.         colortable[i].peGreen = i;
  105.         colortable[i].peBlue  = i;
  106.     }
  107.  
  108.     if ( pDIB && (pDIB->bmiHeader.biBitCount<=8) )
  109.     {
  110.         int nColor = min(256, GetDIBColorCount(pDIB));
  111.  
  112.         const RGBQUAD * pQuad = (const RGBQUAD *) ((BYTE *) pDIB + pDIB->bmiHeader.biSize);
  113.  
  114.         for (i=0; i<nColor; i++)
  115.         {
  116.             colortable[i].peRed   = pQuad[i].rgbRed;
  117.             colortable[i].peGreen = pQuad[i].rgbGreen;
  118.             colortable[i].peBlue  = pQuad[i].rgbBlue;
  119.         }
  120.     }
  121.  
  122.     return pDD->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256, colortable, & m_pPalette, NULL);
  123.  
  124. }
  125.  
  126.  
  127.  
  128. RGNDATA * GetClipRegionData(HRGN hRgn)
  129. {
  130.     DWORD dwSize = GetRegionData(hRgn, 0, NULL);
  131.  
  132.     RGNDATA * pRgnData = (RGNDATA *) new BYTE[dwSize];
  133.  
  134.     if ( pRgnData )
  135.         GetRegionData(hRgn, dwSize, pRgnData);
  136.     
  137.     return pRgnData;
  138. }
  139.  
  140. HRGN GetClipRegion(IDirectDrawClipper * pClipper)
  141. {
  142.     DWORD dwSize = 0;
  143.  
  144.     if ( FAILED(pClipper->GetClipList(NULL, NULL, & dwSize)) )
  145.         return NULL;
  146.  
  147.     RGNDATA * pClipData = (RGNDATA *) new BYTE[dwSize];
  148.  
  149.     if ( pClipData==NULL )
  150.         return NULL;
  151.  
  152.     pClipper->GetClipList(NULL, pClipData, & dwSize);
  153.  
  154.     HRGN hRgn = ExtCreateRegion(NULL, dwSize, pClipData);
  155.  
  156.     delete [] (BYTE *) pClipData;
  157.  
  158.     return hRgn;
  159. }
  160.  
  161. BOOL SetClipRegion(IDirectDrawClipper * pClipper, HRGN hRgn)
  162. {
  163.     RGNDATA * pRgnData = GetClipRegionData(hRgn);
  164.  
  165.     if ( pRgnData==NULL )
  166.         return FALSE;
  167.  
  168.     HRESULT hr = pClipper->SetClipList(pRgnData, 0);
  169.  
  170.     delete (BYTE *) pRgnData;
  171.  
  172.     return SUCCEEDED(hr);
  173. }
  174.  
  175.  
  176. ///////////////////////////////////////////////
  177.     
  178. //    return m_backsurface.RestoreSurface();
  179.  
  180. KDirect3D::KDirect3D(void)
  181. {
  182.     m_pD3D         = NULL;
  183.     m_pD3DDevice = NULL;
  184.     m_bReady     = false;
  185. }
  186.  
  187.  
  188. HRESULT KDirect3D::Discharge(void)
  189. {
  190.     SAFE_RELEASE(m_pD3DDevice);
  191.     m_backsurface.Discharge();
  192.         m_zbuffer.Discharge();
  193.  
  194.     SAFE_RELEASE(m_pD3D);
  195.     
  196.     return KDirectDraw::Discharge();
  197. }
  198.  
  199.  
  200.  
  201. HRESULT KDirect3D::RestoreSurfaces(void)
  202. {
  203.        m_backsurface.RestoreSurface();
  204.            m_zbuffer.RestoreSurface();
  205.     return m_primary.RestoreSurface();
  206. }
  207.  
  208.  
  209. int GetDisplayBpp(IDirectDraw7 * pDD)
  210. {
  211.     DDSURFACEDESC2  ddsd;
  212.  
  213.     memset(& ddsd, 0, sizeof(ddsd));
  214.     
  215.     ddsd.dwSize = sizeof(DDSURFACEDESC2);
  216.     
  217.     if ( SUCCEEDED(pDD->GetDisplayMode(& ddsd)) )
  218.         return ddsd.ddpfPixelFormat.dwRGBBitCount;
  219.     else
  220.         return 0;
  221. }
  222.  
  223.  
  224. HRESULT KDirect3D::SetupDirectDraw(HWND hTop, HWND hWnd, int nBufferCount,
  225.                                    bool bFullScreen, int width, int height, int bpp)
  226. {
  227.     HRESULT hr = KDirectDraw::SetupDirectDraw(hTop, hWnd, nBufferCount, bFullScreen, width, height, bpp);
  228.     if ( FAILED( hr ) )
  229.         return hr;
  230.     
  231.     // reject 8-bpp device
  232.     if ( GetDisplayBpp(m_pDD)<=8 )
  233.         return  DDERR_INVALIDMODE;
  234.     
  235.     // create back surface
  236.     hr = m_backsurface.CreateOffScreenSurface(m_pDD, width, height);
  237.     if ( FAILED(hr) )
  238.         return hr;
  239.  
  240. //    m_backsurface.FillColor(0, 0, width, height, m_backsurface.ColorMatch(0xFF, 0xFF, 0xFF));
  241.     
  242.     // Query DirectDraw for access to Direct3D
  243.     m_pDD->QueryInterface( IID_IDirect3D7, (void **) & m_pD3D );
  244.     if ( FAILED(hr) )
  245.         return hr;
  246.     
  247.     CLSID iidDevice = IID_IDirect3DHALDevice;
  248.  
  249.     // create Z-buffer
  250.     hr = m_zbuffer.CreateZBuffer(m_pD3D, m_pDD, iidDevice, width, height);
  251.     
  252.     if ( FAILED(hr) )
  253.     {
  254.         iidDevice = IID_IDirect3DRGBDevice; 
  255.         hr = m_zbuffer.CreateZBuffer(m_pD3D, m_pDD, iidDevice, width, height);
  256.     }
  257.  
  258.     if ( FAILED(hr) )
  259.         return hr;
  260.  
  261.     // attach Z-buffer to back surface
  262.     hr = m_backsurface.Attach(m_zbuffer);
  263.     if ( FAILED(hr) )
  264.         return hr;
  265.  
  266.     hr = m_pD3D->CreateDevice( iidDevice, m_backsurface, & m_pD3DDevice );
  267.     if ( FAILED(hr) )
  268.         return hr;
  269.     
  270.     {
  271.         D3DVIEWPORT7 vp = { 0, 0, width, height, (float)0.0, (float)1.0 };
  272.     
  273.         return m_pD3DDevice->SetViewport( &vp );
  274.     }
  275. }
  276.  
  277. HRESULT KDirect3D::ShowFrame(HWND hWnd)
  278. {
  279.     if ( m_bReady )
  280.     {
  281.         SetClientRect(hWnd);
  282.         
  283.         return m_primary.Blt(& m_rcDest, m_backsurface, NULL, DDBLT_WAIT);
  284.     }
  285.     else
  286.         return S_OK;
  287. }
  288.  
  289. HRESULT KDirect3D::Render(HWND hWnd)
  290. {
  291.     if ( ! m_bReady )
  292.         return S_OK;
  293.  
  294.     HRESULT hr = OnRender();
  295.  
  296.     if ( FAILED(hr) )
  297.         return hr;
  298.  
  299.     hr = ShowFrame(hWnd);
  300.         
  301.     if ( hr = DDERR_SURFACELOST )
  302.         return RestoreSurfaces();
  303.     else
  304.         return hr;
  305. }
  306.  
  307.  
  308. HRESULT KDirect3D::ReCreate(HINSTANCE hInst, HWND hTop, HWND hWnd)
  309. {
  310.     if ( FAILED(OnDischarge()) )
  311.         return E_FAIL;
  312.  
  313.     if ( FAILED( Discharge() ) ) // free all resources
  314.         return E_FAIL;
  315.  
  316.     SetClientRect(hWnd);
  317.  
  318.     HRESULT hr = SetupDirectDraw(hTop, hWnd, 0, false, 
  319.                     m_rcDest.right  - m_rcDest.left, 
  320.                     m_rcDest.bottom - m_rcDest.top);
  321.  
  322.     if ( SUCCEEDED(hr) )
  323.         return OnInit(hInst);
  324.     else
  325.         return hr;
  326. }
  327.  
  328.  
  329. HRESULT KDirect3D::OnResize(HINSTANCE hInst, int width, int height, HWND hTop, HWND hWnd)
  330. {
  331.     if ( ! m_bReady )
  332.         return S_OK;
  333.  
  334.     if ( width ==(m_rcDest.right - m_rcDest.left) ) 
  335.     if ( height==(m_rcDest.bottom - m_rcDest.top) )
  336.         return S_OK;
  337.  
  338. #ifdef _DEBUG
  339.     char temp[MAX_PATH];
  340.     wsprintf(temp, "OnResize %d %d -> %d %d\n", 
  341.         m_rcDest.right - m_rcDest.left, m_rcDest.bottom - m_rcDest.top,
  342.         width, height);
  343.     OutputDebugString(temp);
  344. #endif
  345.  
  346.     return ReCreate(hInst, hTop, hWnd);
  347. }
  348.