home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / tri3 / d3dcalls.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  13KB  |  347 lines

  1. /*
  2.  *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
  3.  *
  4.  *  File: d3dcalls.c
  5.  *
  6.  *  Calls to Direct3D objects needed for rendering.  Part of D3DApp.
  7.  *
  8.  *  D3DApp is a collection of helper functions for Direct3D applications.
  9.  *  D3DApp consists of the following files:
  10.  *    d3dapp.h    Main D3DApp header to be included by application
  11.  *      d3dappi.h   Internal header
  12.  *      d3dapp.c    D3DApp functions seen by application.
  13.  *      ddcalls.c   All calls to DirectDraw objects except textures
  14.  *      d3dcalls.c  All calls to Direct3D objects except textures
  15.  *      texture.c   Texture loading and managing texture list
  16.  *      misc.c        Miscellaneous calls
  17.  */
  18.  
  19. #define INITGUID
  20. #include "d3dappi.h"
  21.  
  22. /***************************************************************************/
  23. /*                            Creation of D3D                              */
  24. /***************************************************************************/
  25. BOOL
  26. D3DAppICreateD3D(void)
  27. {
  28.     LastError = d3dappi.lpDD->lpVtbl->QueryInterface(d3dappi.lpDD,
  29.                     &IID_IDirect3D2, (LPVOID*)&d3dappi.lpD3D);
  30.     if (LastError != DD_OK) {
  31.         D3DAppISetErrorString("Creation of IDirect3D failed.\n%s",
  32.                   D3DAppErrorToString(LastError));
  33.     goto exit_with_error;
  34.     }
  35.     return TRUE;
  36. exit_with_error:
  37.     return FALSE;
  38. }
  39.  
  40. /***************************************************************************/
  41. /*                           D3D Device Enumeration                        */
  42. /***************************************************************************/
  43. /*
  44.  * enumDeviceFunc
  45.  * Device enumeration callback.  Record information about the D3D device
  46.  * reported by D3D.
  47.  */
  48. static BOOL bRampHasEnumerated = FALSE;
  49. static HRESULT
  50. WINAPI enumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription,
  51.               LPSTR lpDeviceName, LPD3DDEVICEDESC lpHWDesc,
  52.               LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
  53. {
  54.     lpContext = lpContext;
  55. /*    if (! bRampHasEnumerated)
  56.     {
  57.         bRampHasEnumerated = TRUE;
  58.         return D3DENUMRET_OK;
  59.     }*/
  60.     /*
  61.      * Don't accept any hardware D3D devices if emulation only option is set
  62.      */
  63.     if (lpHWDesc->dcmColorModel && d3dappi.bOnlyEmulation)
  64.     return D3DENUMRET_OK;
  65.     /*
  66.      * Record the D3D driver's inforamation
  67.      */
  68.     memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Guid, lpGuid, sizeof(GUID));
  69.     lstrcpy(d3dappi.Driver[d3dappi.NumDrivers].About, lpDeviceDescription);
  70.     lstrcpy(d3dappi.Driver[d3dappi.NumDrivers].Name, lpDeviceName);
  71.     /*
  72.      * Is this a hardware device or software emulation?  Checking the color
  73.      * model for a valid model works.
  74.      */
  75.     if (lpHWDesc->dcmColorModel) {
  76.     d3dappi.Driver[d3dappi.NumDrivers].bIsHardware = TRUE;
  77.     memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Desc, lpHWDesc,
  78.            sizeof(D3DDEVICEDESC));
  79.     } else {
  80.     d3dappi.Driver[d3dappi.NumDrivers].bIsHardware = FALSE;
  81.     memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Desc, lpHELDesc,
  82.            sizeof(D3DDEVICEDESC));
  83.     }
  84.     /*
  85.      * Does this driver do texture mapping?
  86.      */
  87.     d3dappi.Driver[d3dappi.NumDrivers].bDoesTextures =
  88.     (d3dappi.Driver[d3dappi.NumDrivers].Desc.dpcTriCaps.dwTextureCaps &
  89.      D3DPTEXTURECAPS_PERSPECTIVE) ? TRUE : FALSE;
  90.     /*
  91.      * Can this driver use a z-buffer?
  92.      */
  93.     d3dappi.Driver[d3dappi.NumDrivers].bDoesZBuffer =
  94.     d3dappi.Driver[d3dappi.NumDrivers].Desc.dwDeviceZBufferBitDepth
  95.         ? TRUE : FALSE;
  96.     /*
  97.      * Can this driver render to the Windows display depth
  98.      */
  99.     d3dappi.Driver[d3dappi.NumDrivers].bCanDoWindow =
  100.     (d3dappi.Driver[d3dappi.NumDrivers].Desc.dwDeviceRenderBitDepth &
  101.      D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp)) ? TRUE : FALSE;
  102.     if (!d3dappi.bIsPrimary)
  103.     d3dappi.Driver[d3dappi.NumDrivers].bCanDoWindow = FALSE;
  104.  
  105.     d3dappi.NumDrivers++;
  106.     if (d3dappi.NumDrivers == D3DAPP_MAXD3DDRIVERS)
  107.         return (D3DENUMRET_CANCEL);
  108.     return (D3DENUMRET_OK);
  109. }
  110.  
  111. /*
  112.  * D3DAppIEnumDevices
  113.  * Get the available drivers from Direct3D by enumeration.
  114.  */
  115. BOOL
  116. D3DAppIEnumDevices(void)
  117. {
  118.     d3dappi.NumDrivers = 0;
  119.     LastError = d3dappi.lpD3D->lpVtbl->EnumDevices(d3dappi.lpD3D,
  120.                            enumDeviceFunc, NULL);
  121.     if (LastError != DD_OK) {
  122.         D3DAppISetErrorString("Enumeration of drivers failed.\n%s",
  123.                   D3DAppErrorToString(LastError));
  124.     return FALSE;
  125.     }
  126.     d3dappi.CurrDriver = 0;
  127.     return TRUE;
  128. }
  129.  
  130. /***************************************************************************/
  131. /*                    Enumeration of texure format                         */
  132. /***************************************************************************/
  133. /*
  134.  * EnumTextureFormatsCallback
  135.  * Record information about each texture format the current D3D driver can
  136.  * support. Choose one as the default format (paletted formats are prefered)
  137.  * and return it through lpContext.
  138.  */
  139. static HRESULT
  140. CALLBACK EnumTextureFormatsCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext)
  141. {
  142.     unsigned long m;
  143.     int r, g, b;
  144.     int *lpStartFormat = (int *)lpContext;
  145.     /*
  146.      * Record the DDSURFACEDESC of this texture format
  147.      */
  148.     memset(&d3dappi.TextureFormat[d3dappi.NumTextureFormats], 0,
  149.        sizeof(D3DAppTextureFormat));
  150.     memcpy(&d3dappi.TextureFormat[d3dappi.NumTextureFormats].ddsd, lpDDSD,
  151.        sizeof(DDSURFACEDESC));
  152.     /*
  153.      * Is this format palettized?  How many bits?  Otherwise, how many RGB
  154.      * bits?
  155.      */
  156.     if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
  157.         d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = TRUE;
  158.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 8;
  159.     } else if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) {
  160.         d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = TRUE;
  161.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 4;
  162.     } else if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) {
  163.         /*
  164.          * The sample apps don't currently understand
  165.          * the alpha bit - just filter this format
  166.          * away for now.
  167.          */
  168.  
  169.         return DDENUMRET_OK;
  170.     } else
  171.     {
  172.         d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = FALSE;
  173.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 0;
  174.         for (r = 0, m = lpDDSD->ddpfPixelFormat.dwRBitMask; !(m & 1);
  175.                                    r++, m >>= 1);
  176.         for (r = 0; m & 1; r++, m >>= 1);
  177.         for (g = 0, m = lpDDSD->ddpfPixelFormat.dwGBitMask; !(m & 1);
  178.                                    g++, m >>= 1);
  179.         for (g = 0; m & 1; g++, m >>= 1);
  180.         for (b = 0, m = lpDDSD->ddpfPixelFormat.dwBBitMask; !(m & 1);
  181.                                    b++, m >>= 1);
  182.         for (b = 0; m & 1; b++, m >>= 1);
  183.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].RedBPP = r;
  184.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].GreenBPP = g;
  185.     d3dappi.TextureFormat[d3dappi.NumTextureFormats].BlueBPP = b;
  186.     }
  187.     /*
  188.      * If lpStarFormat is -1, this is the first format.  Select it.
  189.      */
  190.     if (*lpStartFormat == -1)
  191.         *lpStartFormat = d3dappi.NumTextureFormats;
  192.     /* 
  193.      * If this format is paletted, select it.
  194.      */
  195.     if (d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized) {
  196.         *lpStartFormat = d3dappi.NumTextureFormats;
  197.     }
  198.     d3dappi.NumTextureFormats++;
  199.     return DDENUMRET_OK;
  200. }
  201.  
  202. /*
  203.  * D3DAppIEnumTextureFormats
  204.  * Get a list of available texture map formats from the Direct3D driver by
  205.  * enumeration.  Choose a default format (paletted is prefered).
  206.  */
  207. BOOL
  208. D3DAppIEnumTextureFormats(void)
  209. {
  210.     int StartFormat;
  211.     /*
  212.      * Set the default format to -1 to let the callback know it's being 
  213.      * called for the first time.
  214.      */
  215.     StartFormat = -1;
  216.     d3dappi.NumTextureFormats = 0;
  217.     LastError =
  218.      d3dappi.lpD3DDevice->lpVtbl->EnumTextureFormats(d3dappi.lpD3DDevice,
  219.                           EnumTextureFormatsCallback,
  220.                                                   (LPVOID)&StartFormat);
  221.     if (LastError != DD_OK) {
  222.     D3DAppISetErrorString("Enumeration of texture formats failed.\n%s",
  223.                   D3DAppErrorToString(LastError));
  224.     return FALSE;
  225.     }
  226.     memcpy(&d3dappi.ThisTextureFormat, &d3dappi.TextureFormat[StartFormat],
  227.        sizeof(D3DAppTextureFormat));
  228.     d3dappi.CurrTextureFormat = StartFormat;
  229.     return TRUE;
  230. }
  231.  
  232. /***************************************************************************/
  233. /*                               Device creation                           */
  234. /***************************************************************************/
  235. /*
  236.  * D3DAppICreateDevice
  237.  * Create the D3D device and enumerate the texture formats
  238.  */
  239. BOOL
  240. D3DAppICreateDevice(int driver)
  241. {
  242.     RELEASE(d3dappi.lpD3DDevice);
  243.  
  244.     if (d3dappi.Driver[driver].bIsHardware && !d3dappi.bBackBufferInVideo) {
  245.     D3DAppISetErrorString("Could not fit the rendering surfaces in video memory for this hardware device.\n");
  246.     goto exit_with_error;
  247.     }
  248.  
  249.     d3dappi.CurrDriver = driver;
  250.     memcpy(&d3dappi.ThisDriver, &d3dappi.Driver[driver], sizeof(D3DAppD3DDriver));
  251. #if 1
  252.     LastError = d3dappi.lpD3D->lpVtbl->CreateDevice(d3dappi.lpD3D, 
  253.         &d3dappi.Driver[driver].Guid,
  254.         d3dappi.lpBackBuffer, &d3dappi.lpD3DDevice);
  255. #else
  256.     LastError =
  257.        d3dappi.lpBackBuffer->lpVtbl->QueryInterface(d3dappi.lpBackBuffer,
  258.                         &d3dappi.Driver[driver].Guid,
  259.                           (LPVOID*)&d3dappi.lpD3DDevice);
  260. #endif
  261.     if (LastError != DD_OK) {
  262.         D3DAppISetErrorString("Create D3D device failed.\n%s",
  263.                   D3DAppErrorToString(LastError));
  264.         goto exit_with_error;
  265.     }
  266.     d3dappi.CurrDriver = driver;
  267.     d3dappi.NumTextureFormats = 0;
  268.     if (d3dappi.Driver[driver].bDoesTextures) {
  269.     if (!D3DAppIEnumTextureFormats())
  270.         goto exit_with_error;
  271.     }
  272.  
  273.     return TRUE;
  274. exit_with_error:
  275.     RELEASE(d3dappi.lpD3DDevice);
  276.     return FALSE;
  277. }
  278.  
  279. /***************************************************************************/
  280. /*                      Setting the render state                           */
  281. /***************************************************************************/
  282. /*
  283.  * D3DAppISetRenderState
  284.  * Create and execute an execute buffer which will set the render state and
  285.  * light state for the current viewport.
  286.  */
  287. BOOL
  288. D3DAppISetRenderState()
  289. {
  290.     LPDIRECT3DDEVICE2 pDev = d3dappi.lpD3DDevice;
  291.  
  292.     /*
  293.      * If there is no D3D Viewport, we must return true because it is not
  294.      * required.
  295.      */
  296.     if (!d3dappi.lpD3DViewport)
  297.     return TRUE;
  298.     LastError = pDev->lpVtbl->BeginScene(pDev);
  299.     if (LastError != D3D_OK) {
  300.         D3DAppISetErrorString("BeginScene failed in SetRenderState.\n%s",
  301.                               D3DAppErrorToString(LastError));
  302.         goto exit_with_error;
  303.     }
  304.     LastError = pDev->lpVtbl->SetCurrentViewport(pDev, d3dappi.lpD3DViewport);
  305.     if (LastError !=D3D_OK) {
  306.         D3DAppISetErrorString("SetViewport failed in SetRenderState.\n%s",
  307.                   D3DAppErrorToString(LastError));
  308.     goto exit_with_error;
  309.     }
  310.     /*
  311.      * Set render state
  312.      */
  313.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_SHADEMODE, (DWORD)d3dapprs.ShadeMode);
  314.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_TEXTUREPERSPECTIVE, (DWORD)d3dapprs.bPerspCorrect);
  315.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_ZENABLE, (DWORD)(d3dapprs.bZBufferOn &&
  316.                                   d3dappi.ThisDriver.bDoesZBuffer));
  317.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_ZWRITEENABLE, (DWORD)d3dapprs.bZBufferOn);
  318.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL);
  319.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_TEXTUREMAG, (DWORD)d3dapprs.TextureFilter);
  320.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_TEXTUREMIN, (DWORD)d3dapprs.TextureFilter);
  321.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_TEXTUREMAPBLEND, (DWORD)d3dapprs.TextureBlend);
  322.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_FILLMODE, (DWORD)d3dapprs.FillMode);
  323.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_DITHERENABLE, (DWORD)d3dapprs.bDithering);
  324.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_SPECULARENABLE, (DWORD)d3dapprs.bSpecular);
  325.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_ANTIALIAS, (DWORD)d3dapprs.bAntialiasing);
  326.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_FOGENABLE, (DWORD)d3dapprs.bFogEnabled);
  327.     pDev->lpVtbl->SetRenderState(pDev, D3DRENDERSTATE_FOGCOLOR, (DWORD)d3dapprs.FogColor);
  328.     /*
  329.      * Set light state
  330.      */
  331.     pDev->lpVtbl->SetLightState(pDev, D3DLIGHTSTATE_FOGMODE, (DWORD)d3dapprs.bFogEnabled ?
  332.                  d3dapprs.FogMode : D3DFOG_NONE);
  333.     pDev->lpVtbl->SetLightState(pDev, D3DLIGHTSTATE_FOGSTART, *(unsigned long*)&d3dapprs.FogStart);
  334.     pDev->lpVtbl->SetLightState(pDev, D3DLIGHTSTATE_FOGEND, *(unsigned long*)&d3dapprs.FogEnd);
  335.  
  336.     LastError = pDev->lpVtbl->EndScene(pDev);
  337.     if (LastError != D3D_OK) {
  338.         D3DAppISetErrorString("EndScene failed in SetRenderState.\n%s",
  339.                   D3DAppErrorToString(LastError));
  340.     goto exit_with_error;
  341.     }
  342.     return TRUE;
  343. exit_with_error:
  344.     return FALSE;
  345. }
  346.  
  347.