⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zfxd3d_enum.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      return -1;
   if (pdm1->RefreshRate > pdm2->RefreshRate)
      return 1;
   if (pdm1->RefreshRate < pdm2->RefreshRate)
      return -1;
   return 0;
   } // SortModesCallback
/*----------------------------------------------------------------*/


HRESULT ZFXD3DEnum::EnumAdapters(void) {
   D3DDISPLAYMODE d3ddspmd;
   HRESULT        hr;
   UINT           nNumAdapters=0;
   UINT           nNumModes=0;

   if (!m_pD3D) return ZFX_INVALIDPARAM;

   // get number of attached adapters
   nNumAdapters = m_pD3D->GetAdapterCount();

   // loop through adapters
   for (UINT nAdapter=0; nAdapter<nNumAdapters; nAdapter++) {
      m_xAdapterInfo[m_dwNumAdapters].nAdapter  = nAdapter;
      m_xAdapterInfo[m_dwNumAdapters].nNumModes = 0;

      // get adapter information struct
      m_pD3D->GetAdapterIdentifier(nAdapter, 0, 
                                   &m_xAdapterInfo[m_dwNumAdapters].
                                   d3dAdapterIdentifier);

      // loop through allowed bpp formats
      for (UINT nFmt=0; nFmt<m_nNumFmt; nFmt++) {
        // get available display modes for this adapter/bpp format
         nNumModes = m_pD3D->GetAdapterModeCount(nAdapter, m_fmtAdapter[nFmt]);
         
         for (UINT nMode=0; nMode<nNumModes; nMode++) {
            // get number of available display modes
            m_pD3D->EnumAdapterModes(nAdapter, m_fmtAdapter[nFmt], 
                                     nMode, &d3ddspmd);

            // don't use less than we asked for
            if (d3ddspmd.Width           < m_nMinWidth  ||
                d3ddspmd.Height          < m_nMinHeight ||
                GetBits(d3ddspmd.Format) < m_nMinBits) {
               continue;
               }
            // else save this mode
            else {
               m_xAdapterInfo[m_dwNumAdapters].d3ddspmd[
                  m_xAdapterInfo[m_dwNumAdapters].nNumModes] = d3ddspmd;
               m_xAdapterInfo[m_dwNumAdapters].nNumModes++;
               }
            } // for [modes]
         } // for [formats]

      // we got the data, now sort it
      qsort(m_xAdapterInfo[m_dwNumAdapters].d3ddspmd, 
            m_xAdapterInfo[m_dwNumAdapters].nNumModes,
            sizeof(D3DDISPLAYMODE),
            SortModesCallback);

      if (FAILED(hr=EnumDevices(m_xAdapterInfo[m_dwNumAdapters]))) 
         return hr;

      // keep this one if any device is found
      if (m_xAdapterInfo[m_dwNumAdapters].nNumDevs > 0)
         m_dwNumAdapters++;
      } // for [adapters]

   return ZFX_OK;
   } //EnumAdapters
/*----------------------------------------------------------------*/


HRESULT ZFXD3DEnum::EnumDevices(ZFXADAPTERINFO &xAdapter) {
   ZFXDEVICEINFO *pDev;
   HRESULT        hr;

   const D3DDEVTYPE d3dDevTypes[] = { 
               D3DDEVTYPE_HAL, 
               D3DDEVTYPE_SW, 
               D3DDEVTYPE_REF 
               };

   xAdapter.nNumDevs = 0;

   for (UINT nDev=0; nDev<3; nDev++) {
      pDev = &xAdapter.d3dDevs[xAdapter.nNumDevs];

      pDev->nNumCombo   = 0;
      pDev->nAdapter    = xAdapter.nAdapter;
      pDev->d3dDevType  = d3dDevTypes[nDev];

      // will fail if unsupported devtype
      if (FAILED(m_pD3D->GetDeviceCaps(pDev->nAdapter,
                 pDev->d3dDevType, &pDev->d3dCaps)))
         continue;

      // this should not fail
      if (FAILED(hr=EnumCombos(*pDev)))
         return hr;
      
      // at least one supportet combo?
      if (pDev->nNumCombo <= 0)
         continue;

      // keep valid device
      xAdapter.nNumDevs++;
      } // for

   return ZFX_OK;
   } // EnumDevices
/*----------------------------------------------------------------*/


HRESULT ZFXD3DEnum::EnumCombos(ZFXDEVICEINFO &xDev) {
   ZFXCOMBOINFO *pCombo;
   bool          bWindowed;
   bool          bFmtCheck=false;
   bool          bAny=false;

   xDev.nNumCombo = 0;

   // all adapter Formats
   for (UINT nFmt_A=0; nFmt_A<m_nNumFmt; nFmt_A++) {

      // for all allowed backbuffer formats
      for (UINT nFmt_B=0; nFmt_B<g_nFormats_B; nFmt_B++) {

         // check windowed and fullscreen
         for (UINT n=0; n<2; n++) {
            if (n==0) bWindowed=true;
            else bWindowed=false;

            // valid combo?
            if (FAILED(m_pD3D->CheckDeviceType(
                        xDev.nAdapter, 
                        xDev.d3dDevType, 
                        m_fmtAdapter[nFmt_A], 
                        g_fmtBackBuffer[nFmt_B], 
                        bWindowed)))
               continue;

            // at this point we have a valid combo that is supported
            // by the system. still need to find depth/stencil fmt
            // and best vertex processing type. 
            pCombo = &xDev.d3dCombo[xDev.nNumCombo];
            pCombo->nAdapter      = xDev.nAdapter;
            pCombo->d3dDevType    = xDev.d3dDevType;
            pCombo->bWindowed     = bWindowed;
            pCombo->fmtBackBuffer = g_fmtBackBuffer[nFmt_B];
            pCombo->fmtAdapter    = m_fmtAdapter[nFmt_A];

      // SELECT DEPTH/STENCIL FORMAT

             // select depth fmt & stencil buffer
            if (m_nMinStencil) {
               pCombo->fmtDepthStencil = D3DFMT_D24S8;
               bFmtCheck = ConfirmDepthFmt(pCombo);
              
               if (!bFmtCheck) {
                  pCombo->fmtDepthStencil = D3DFMT_D24X4S4;
                  bFmtCheck = ConfirmDepthFmt(pCombo);
                  }
               if (!bFmtCheck) {
                  pCombo->fmtDepthStencil = D3DFMT_D15S1;
                  bFmtCheck = ConfirmDepthFmt(pCombo);
                  }
               }
            // or without stencil buffer
            else {
               if (m_nMinDepth > 24) {
                  pCombo->fmtDepthStencil = D3DFMT_D32;
                  bFmtCheck = ConfirmDepthFmt(pCombo);
                  }
               if (!bFmtCheck && (m_nMinDepth > 16)) {
                  pCombo->fmtDepthStencil = D3DFMT_D24X8;
                  bFmtCheck = ConfirmDepthFmt(pCombo);
                  }
               else {
                  pCombo->fmtDepthStencil = D3DFMT_D16;
                  bFmtCheck = ConfirmDepthFmt(pCombo);
                  }
               }

            // no suitable fmt => ignore this combo
            if (!bFmtCheck) continue;

      // SELECT VERTEX PROCESSING

            // we have hardware T&L
            if ((xDev.d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0) {
               
               // 1.case: pure device
               if ( ((xDev.d3dCaps.DevCaps & D3DDEVCAPS_PUREDEVICE)!=0) 
                  && (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_PUREDEVICE, 
                                    pCombo->fmtBackBuffer)==ZFX_OK) ) {
                  pCombo->dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING 
                                     | D3DCREATE_PUREDEVICE;
                  bAny = true;
                  }
               // 2.case: hardware device
               else if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_HARDWARE_VERTEXPROCESSING, 
                                      pCombo->fmtBackBuffer)==ZFX_OK) {
                  pCombo->dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING;
                  bAny = true;
                  }
               // 3.case: mixed sw/hw
               else if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_MIXED_VERTEXPROCESSING, 
                                      pCombo->fmtBackBuffer)==ZFX_OK) {
                  pCombo->dwBehavior = D3DCREATE_MIXED_VERTEXPROCESSING;
                  bAny = true;
                  }
               } // if [HW]
            // 4.case: must be sw processing
            else {
               if (ConfirmDevice(&xDev.d3dCaps, D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
                                 pCombo->fmtBackBuffer)==ZFX_OK) {
                  pCombo->dwBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
                  bAny = true;
                  }
               }

            // none combo found that supports everything we need
            if (!bAny) continue;

      // SELECT MULTISAMPLE TYPE

            DWORD msQuality;
            for(UINT nMS=g_nMS-1; nMS>=0; nMS--) {
               if (SUCCEEDED(m_pD3D->
                     CheckDeviceMultiSampleType(
                        pCombo->nAdapter, 
                        pCombo->d3dDevType, 
                        pCombo->fmtBackBuffer, 
                        pCombo->bWindowed,
                        g_msType[nMS], &msQuality))) {
                  pCombo->msType = g_msType[nMS];
                  break;
                  }
               } // for [multisample]


            // NO WE GOT EVERYTHING WE NEE AND KEEP THIS COMBO
            xDev.nNumCombo++;

            } // for [windowed/fullscreen]
         } // for [BackbufferFormats]
      } // for [AdapterFormats]

   return ZFX_OK;
   }
/*----------------------------------------------------------------*/


bool ZFXD3DEnum::ConfirmDepthFmt(ZFXCOMBOINFO *pCombo) {
   // compatible with adapter?
   if (FAILED(m_pD3D->CheckDeviceFormat(pCombo->nAdapter, 
                                  pCombo->d3dDevType, 
                                  pCombo->fmtAdapter, 
                                  D3DUSAGE_DEPTHSTENCIL, 
                                  D3DRTYPE_SURFACE, 
                                  pCombo->fmtDepthStencil)))
      return false;

   // compatible with backbuffer format?
   if (FAILED(m_pD3D->CheckDepthStencilMatch(
                                  pCombo->nAdapter, 
                                  pCombo->d3dDevType, 
                                  pCombo->fmtAdapter, 
                                  pCombo->fmtBackBuffer,
                                  pCombo->fmtDepthStencil)))
      return false;

   return true;
   } // ConfirmDepthFmt
/*----------------------------------------------------------------*/


HRESULT ZFXD3DEnum::ConfirmDevice(D3DCAPS9* pCaps, DWORD dwBehavior, 
                                  D3DFORMAT fmtBackbuffer) {
   if ( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING) ||
        (dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING) ) {
      // alphablending from texture pixels supported
      if ( !(pCaps->TextureCaps & D3DPTEXTURECAPS_ALPHA) ) {
         fprintf(m_pLog, "[ZFXD3D_ENUM] error: no alphablending from texture \n");
         return ZFX_FAIL;
         }
      }
 
   return ZFX_OK;
   } // ConfirmDevice
/*----------------------------------------------------------------*/


UINT ZFXD3DEnum::GetBits(D3DFORMAT fmt) {
   switch(fmt) {
      case D3DFMT_A2B10G10R10: return 30;
      case D3DFMT_R8G8B8:      return 24;
      case D3DFMT_A8R8G8B8:    return 24;
      case D3DFMT_X8R8G8B8:    return 24;
      case D3DFMT_R5G6B5:      return 16;
      case D3DFMT_X1R5G5B5:    return 15;
      case D3DFMT_A1R5G5B5:    return 15;
      case D3DFMT_X4R4G4B4:    return 12;
      case D3DFMT_A4R4G4B4:    return 12;
      case D3DFMT_R3G3B2:      return 8;
      case D3DFMT_A8R3G3B2:    return 8;
      default:                 return 0;
      }
   } // GetBits
/*----------------------------------------------------------------*/


TCHAR* D3DDevTypeToString(D3DDEVTYPE devType) {
   switch (devType) {
      case D3DDEVTYPE_HAL:    return TEXT("D3DDEVTYPE_HAL");
      case D3DDEVTYPE_SW:     return TEXT("D3DDEVTYPE_SW");
      case D3DDEVTYPE_REF:    return TEXT("D3DDEVTYPE_REF");
      default:                return TEXT("Unknown devType");
      }
   }
/*----------------------------------------------------------------*/


TCHAR* D3DFormatToString(D3DFORMAT format) {
   switch (format) {
      case D3DFMT_UNKNOWN:         return TEXT("D3DFMT_UNKNOWN");
      case D3DFMT_R8G8B8:          return TEXT("D3DFMT_R8G8B8");
      case D3DFMT_A8R8G8B8:        return TEXT("D3DFMT_A8R8G8B8");
      case D3DFMT_X8R8G8B8:        return TEXT("D3DFMT_X8R8G8B8");
      case D3DFMT_R5G6B5:          return TEXT("D3DFMT_R5G6B5");
      case D3DFMT_X1R5G5B5:        return TEXT("D3DFMT_X1R5G5B5");
      case D3DFMT_A1R5G5B5:        return TEXT("D3DFMT_A1R5G5B5");
      case D3DFMT_A4R4G4B4:        return TEXT("D3DFMT_A4R4G4B4");
      case D3DFMT_R3G3B2:          return TEXT("D3DFMT_R3G3B2");
      case D3DFMT_A8R3G3B2:        return TEXT("D3DFMT_A8R3G3B2");
      case D3DFMT_X4R4G4B4:        return TEXT("D3DFMT_X4R4G4B4");
      case D3DFMT_A2B10G10R10:     return TEXT("D3DFMT_A2B10G10R10");
      case D3DFMT_D16_LOCKABLE:    return TEXT("D3DFMT_D16_LOCKABLE");
      case D3DFMT_D32:             return TEXT("D3DFMT_D32");
      case D3DFMT_D15S1:           return TEXT("D3DFMT_D15S1");
      case D3DFMT_D24S8:           return TEXT("D3DFMT_D24S8");
      case D3DFMT_D16:             return TEXT("D3DFMT_D16");
      case D3DFMT_D24X8:           return TEXT("D3DFMT_D24X8");
      case D3DFMT_D24X4S4:         return TEXT("D3DFMT_D24X4S4");
      case D3DFMT_VERTEXDATA:      return TEXT("D3DFMT_VERTEXDATA");
      case D3DFMT_INDEX16:         return TEXT("D3DFMT_INDEX16");
      case D3DFMT_INDEX32:         return TEXT("D3DFMT_INDEX32");
      default:                     return TEXT("Unknown format");
      }
   }
/*----------------------------------------------------------------*/


TCHAR* BehaviorTypeToString(DWORD vpt) {
   switch (vpt) {
      case D3DCREATE_SOFTWARE_VERTEXPROCESSING: return TEXT("SOFTWARE_VP");
      case D3DCREATE_MIXED_VERTEXPROCESSING:    return TEXT("MIXED_VP");
      case D3DCREATE_HARDWARE_VERTEXPROCESSING: return TEXT("HARDWARE_VP");
      case D3DCREATE_PUREDEVICE:                return TEXT("PURE_HARDWARE_VP");
      default:                                  return TEXT("Unknown VP");
      }
   }
/*----------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -