www.pudn.com > XmudOSr.rar > d3dcalls.cpp


//---------------------------------------------------------------- 
// 
//  File: d3dcalls.c 
// 
//  Calls to Direct3D objects needed for rendering.  Part of D3DApp. 
// 
//---------------------------------------------------------------- 
 
// Borland CBuilder3 doesn't support nameless unions... 
#include "stdafx.h" 
#include "XMudClient.h" 
#include "d3dappi.h" 
 
//************************************************************************** 
//                            Creation of D3D 
//************************************************************************* 
BOOL D3DAppICreateD3D(void) 
{ 
  LastError = d3dappi.lpDD->QueryInterface(IID_IDirect3D2, (LPVOID*)&d3dappi.lpD3D); 
  if (LastError != DD_OK) 
  { 
    D3DAppISetErrorString("Creation of IDirect3D failed.\n%s", 
      D3DAppErrorToString(LastError)); 
    goto exit_with_error; 
  } 
  return TRUE; 
exit_with_error: 
  return FALSE; 
} 
 
/***************************************************************************/ 
/*                           D3D Device Enumeration                        */ 
/***************************************************************************/ 
/* 
* enumDeviceFunc 
* Device enumeration callback.  Record information about the D3D device 
* reported by D3D. 
*/ 
static HRESULT 
WINAPI enumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription, 
                      LPSTR lpDeviceName, LPD3DDEVICEDESC lpHWDesc, 
                      LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext) 
{ 
  lpContext = lpContext; 
  /* 
  * Don't accept any hardware D3D devices if emulation only option is set 
  */ 
  if (lpHWDesc->dcmColorModel && d3dappi.bOnlyEmulation) 
    return D3DENUMRET_OK; 
    /* 
    * Record the D3D driver's inforamation 
  */ 
  memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Guid, lpGuid, sizeof(GUID)); 
  lstrcpy(d3dappi.Driver[d3dappi.NumDrivers].About, lpDeviceDescription); 
  lstrcpy(d3dappi.Driver[d3dappi.NumDrivers].Name, lpDeviceName); 
  /* 
  * Is this a hardware device or software emulation?  Checking the color 
  * model for a valid model works. 
  */ 
  if (lpHWDesc->dcmColorModel) { 
    d3dappi.Driver[d3dappi.NumDrivers].bIsHardware = TRUE; 
    memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Desc, lpHWDesc, 
      sizeof(D3DDEVICEDESC)); 
  } else { 
    d3dappi.Driver[d3dappi.NumDrivers].bIsHardware = FALSE; 
    memcpy(&d3dappi.Driver[d3dappi.NumDrivers].Desc, lpHELDesc, 
      sizeof(D3DDEVICEDESC)); 
  } 
  /* 
  * Does this driver do texture mapping? 
  */ 
  d3dappi.Driver[d3dappi.NumDrivers].bDoesTextures = 
    (d3dappi.Driver[d3dappi.NumDrivers].Desc.dpcTriCaps.dwTextureCaps & 
    D3DPTEXTURECAPS_PERSPECTIVE) ? TRUE : FALSE; 
    /* 
    * Can this driver use a z-buffer? 
  */ 
  d3dappi.Driver[d3dappi.NumDrivers].bDoesZBuffer = 
    d3dappi.Driver[d3dappi.NumDrivers].Desc.dwDeviceZBufferBitDepth 
    ? TRUE : FALSE; 
    /* 
    * Can this driver render to the Windows display depth 
  */ 
  d3dappi.Driver[d3dappi.NumDrivers].bCanDoWindow = 
    (d3dappi.Driver[d3dappi.NumDrivers].Desc.dwDeviceRenderBitDepth & 
    D3DAppIBPPToDDBD(d3dappi.WindowsDisplay.bpp)) ? TRUE : FALSE; 
  if (!d3dappi.bIsPrimary) 
    d3dappi.Driver[d3dappi.NumDrivers].bCanDoWindow = FALSE; 
   
  d3dappi.NumDrivers++; 
  if (d3dappi.NumDrivers == D3DAPP_MAXD3DDRIVERS) 
    return (D3DENUMRET_CANCEL); 
  return (D3DENUMRET_OK); 
} 
 
/* 
* D3DAppIEnumDevices 
* Get the available drivers from Direct3D by enumeration. 
*/ 
BOOL D3DAppIEnumDevices(void) 
{ 
  d3dappi.NumDrivers = 0; 
  LastError = d3dappi.lpD3D->EnumDevices(enumDeviceFunc, NULL); 
  if (LastError != DD_OK) 
  { 
    D3DAppISetErrorString("Enumeration of drivers failed.\n%s", 
      D3DAppErrorToString(LastError)); 
    return FALSE; 
  } 
  d3dappi.CurrDriver = 0; 
  return TRUE; 
} 
 
//***************************************************************************/ 
//*                    Enumeration of texure format                         */ 
//***************************************************************************/ 
// 
// EnumTextureFormatsCallback 
// Record information about each texture format the current D3D driver can 
// support. Choose one as the default format (paletted formats are prefered) 
// and return it through lpContext. 
// 
static HRESULT CALLBACK EnumTextureFormatsCallback(LPDDSURFACEDESC lpDDSD, LPVOID lpContext) 
{ 
  unsigned long m; 
  int r, g, b; 
  int *lpStartFormat = (int *)lpContext; 
  // 
  // Record the DDSURFACEDESC of this texture format 
  // 
  memset(&d3dappi.TextureFormat[d3dappi.NumTextureFormats], 0, 
    sizeof(D3DAppTextureFormat)); 
  memcpy(&d3dappi.TextureFormat[d3dappi.NumTextureFormats].ddsd, lpDDSD, 
    sizeof(DDSURFACEDESC)); 
  // 
  // Is this format palettized?  How many bits?  Otherwise, how many RGB 
  // bits? 
  // 
  if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) 
  { 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = TRUE; 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 8; 
  }  
  else if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) 
  { 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = TRUE; 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 4; 
  } 
  else if (lpDDSD->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS) 
  { 
    // 
    // The sample apps don't currently understand 
    // the alpha bit - just filter this format 
    // away for now. 
    // 
    return DDENUMRET_OK; 
  } 
  else 
  { 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized = FALSE; 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].IndexBPP = 0; 
    for (r = 0, m = lpDDSD->ddpfPixelFormat.dwRBitMask; !(m & 1); 
    r++, m >>= 1); 
    for (r = 0; m & 1; r++, m >>= 1); 
    for (g = 0, m = lpDDSD->ddpfPixelFormat.dwGBitMask; !(m & 1); 
    g++, m >>= 1); 
    for (g = 0; m & 1; g++, m >>= 1); 
    for (b = 0, m = lpDDSD->ddpfPixelFormat.dwBBitMask; !(m & 1); 
    b++, m >>= 1); 
    for (b = 0; m & 1; b++, m >>= 1); 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].RedBPP = r; 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].GreenBPP = g; 
    d3dappi.TextureFormat[d3dappi.NumTextureFormats].BlueBPP = b; 
  } 
  // 
  // If lpStarFormat is -1, this is the first format.  Select it. 
  // 
  if (*lpStartFormat == -1) 
    *lpStartFormat = d3dappi.NumTextureFormats; 
  // 
  // If this format is paletted, select it. 
  // 
  if (d3dappi.TextureFormat[d3dappi.NumTextureFormats].bPalettized) 
  { 
    *lpStartFormat = d3dappi.NumTextureFormats; 
  } 
  d3dappi.NumTextureFormats++; 
  return DDENUMRET_OK; 
} 
 
// 
// D3DAppIEnumTextureFormats 
// Get a list of available texture map formats from the Direct3D driver by 
// enumeration.  Choose a default format (paletted is prefered). 
// 
BOOL D3DAppIEnumTextureFormats(void) 
{ 
  int StartFormat; 
  // 
  // Set the default format to -1 to let the callback know it's being 
  // called for the first time. 
  // 
  StartFormat = -1; 
  d3dappi.NumTextureFormats = 0; 
  LastError = d3dappi.lpD3DDevice->EnumTextureFormats(EnumTextureFormatsCallback, (LPVOID)&StartFormat); 
  if (LastError != DD_OK) 
  { 
    D3DAppISetErrorString("Enumeration of texture formats failed.\n%s", 
      D3DAppErrorToString(LastError)); 
    return FALSE; 
  } 
  memcpy(&d3dappi.ThisTextureFormat, &d3dappi.TextureFormat[StartFormat], sizeof(D3DAppTextureFormat)); 
  d3dappi.CurrTextureFormat = StartFormat; 
  return TRUE; 
} 
 
/***************************************************************************/ 
/*                               Device creation                           */ 
/***************************************************************************/ 
/* 
* D3DAppICreateDevice 
* Create the D3D device and enumerate the texture formats 
*/ 
BOOL D3DAppICreateDevice(int driver) 
{ 
  RELEASE(d3dappi.lpD3DDevice); 
   
  if (d3dappi.Driver[driver].bIsHardware && !d3dappi.bBackBufferInVideo) { 
    D3DAppISetErrorString("Could not fit the rendering surfaces in video memory for this hardware device.\n"); 
    goto exit_with_error; 
  } 
   
  d3dappi.CurrDriver = driver; 
  memcpy(&d3dappi.ThisDriver, &d3dappi.Driver[driver], sizeof(D3DAppD3DDriver)); 
   
  LastError = d3dappi.lpD3D->CreateDevice(d3dappi.Driver[driver].Guid, 
    d3dappi.lpBackBuffer, 
    &d3dappi.lpD3DDevice); 
  if (LastError != DD_OK) 
  { 
    D3DAppISetErrorString("Create D3D device failed.\n%s", 
      D3DAppErrorToString(LastError)); 
    goto exit_with_error; 
  } 
   
  d3dappi.CurrDriver = driver; 
  d3dappi.NumTextureFormats = 0; 
  if (d3dappi.Driver[driver].bDoesTextures) 
  { 
    if (!D3DAppIEnumTextureFormats()) 
      goto exit_with_error; 
  } 
   
  return TRUE; 
exit_with_error: 
  RELEASE(d3dappi.lpD3DDevice); 
  return FALSE; 
} 
 
/***************************************************************************/ 
/*                      Setting the render state                           */ 
/***************************************************************************/ 
/* 
* D3DAppISetRenderState 
* Set the render state and light state for the current viewport. 
*/ 
BOOL D3DAppISetRenderState() 
{ 
//  return TRUE;//[1999.9.1] 
  // 
  // Set render state 
  // 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, d3dapprs.ShadeMode); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE, d3dapprs.bPerspCorrect); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, d3dapprs.bZBufferOn && d3dappi.ThisDriver.bDoesZBuffer); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, d3dapprs.bZBufferOn); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ZFUNC, D3DCMP_LESSEQUAL); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAG, d3dapprs.TextureFilter); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMIN, d3dapprs.TextureFilter); 
   
//  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND, d3dapprs.TextureBlend); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FILLMODE, d3dapprs.FillMode); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_DITHERENABLE, d3dapprs.bDithering); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_SPECULARENABLE, d3dapprs.bSpecular); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ANTIALIAS, d3dapprs.bAntialiasing); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGENABLE, d3dapprs.bFogEnabled); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGCOLOR, d3dapprs.FogColor); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); 
 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_BLENDENABLE, TRUE); 
 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); 
 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); 
 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND, D3DTBLEND_MODULATEALPHA); 
  /* 
  * Set light state 
  */ 
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEMODE, d3dapprs.bFogEnabled ? d3dapprs.FogMode : D3DFOG_NONE); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLESTART, *(unsigned long*)&d3dapprs.FogStart); 
   
  d3dappi.lpD3DDevice->SetRenderState(D3DRENDERSTATE_FOGTABLEEND, *(unsigned long*)&d3dapprs.FogEnd); 
  return TRUE; 
}