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

📄 zfxd3d_enum.cpp

📁 This is a book introduce some tech about Game Engine 3D
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// File: ZFXD3D_enum.cpp

#include "resource.h"      // control id's
#include "ZFX.h"           // return values and stuff
#include "ZFXD3D.h"        // class definition

extern bool g_bLF;

// some common backbuffer formats
const UINT g_nFormats_B=9;
const D3DFORMAT g_fmtBackBuffer[] = {
           D3DFMT_R8G8B8,   D3DFMT_A8R8G8B8, 
           D3DFMT_X8R8G8B8, D3DFMT_R5G6B5, 
           D3DFMT_A1R5G5B5, D3DFMT_X1R5G5B5,
           D3DFMT_X4R4G4B4, D3DFMT_A4R4G4B4,
           D3DFMT_A2B10G10R10 
           };


// some good multisample modes, list best ones last
const UINT g_nMS = 8;
const D3DMULTISAMPLE_TYPE g_msType[] = { 
           D3DMULTISAMPLE_NONE,
           D3DMULTISAMPLE_2_SAMPLES,
           D3DMULTISAMPLE_3_SAMPLES,
           D3DMULTISAMPLE_4_SAMPLES,
           D3DMULTISAMPLE_5_SAMPLES,
           D3DMULTISAMPLE_6_SAMPLES,
           D3DMULTISAMPLE_7_SAMPLES,
           D3DMULTISAMPLE_8_SAMPLES,
           };



// F U N C T I O N S ///////////////////////////////////////////////

/**
 * Enumerates all available display modes and fills the given combo
 * boxes with corresponding values.
 * -> IN: HWND - combobox to receive available adapters
 *        HWND - combobox used for display modes
 *        HWND - combobox used for device types
 *        HWND - combobox used for adapter formats
 *        HWND - combobox used for backbuffer formats
 *        HWND - radiobutton windowed
 *        HWND - radiobutton fullscreen
 *        FILE - already open log file
 */
HRESULT ZFXD3DEnum::Enum(HWND hAdapter, HWND hMode,
                         HWND hDevice,  HWND hAdapterFmt,
                         HWND hBackFmt, HWND hWnd,
                         HWND hFull,    FILE *pLog) {
   HRESULT hr;

   if (pLog) m_pLog = pLog;

   // create main Direct3D object
   m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
   if(m_pD3D == NULL){
      return ZFX_CREATEAPI;
      }

   // save handles to comboboxes
   m_hADAPTER    = hAdapter;
   m_hMODE       = hMode;
   m_hDEVICE     = hDevice;
   m_hADAPTERFMT = hAdapterFmt;
   m_hBACKFMT    = hBackFmt;
   m_hWND        = hWnd;
   m_hFULL       = hFull;

   // nothing yet
   m_dwNumAdapters = 0;

   // set misc values
   m_nMinWidth  = 800;
   m_nMinHeight = 600;
   m_nMinBits   = 16;
   
   // set allowed bpp formats
   m_fmtAdapter[0] = D3DFMT_X8R8G8B8;  // 32 Bit
   m_fmtAdapter[1] = D3DFMT_X1R5G5B5;  // 15 Bit
   m_fmtAdapter[2] = D3DFMT_R5G6B5;    // 16 Bit
   m_nNumFmt = 3;

   // get current adapters display mode
   if (FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_dspmd))) {
      if (m_pLog) {
         fprintf(m_pLog, "Enum: GetAdapterDisplayMode() failed \n");
         fflush(m_pLog);
         }
      }

   // enumerate available adapters
   hr = EnumAdapters();
   
   // we don't need this for now
   m_pD3D->Release();
   m_pD3D = NULL;

   if(FAILED(hr) || !hAdapter)
      return ZFX_FAIL;

   if (m_dwNumAdapters == 0)
      return ZFX_NOTCOMPATIBLE;

   // list the found graphics adapter
   SendMessage(m_hADAPTER,CB_RESETCONTENT,0,0);

   for (UINT a=0; a<m_dwNumAdapters; a++) {
      AddItem(m_hADAPTER, m_xAdapterInfo[a].
              d3dAdapterIdentifier.Description, 
              &m_xAdapterInfo[a]);
      }

   // treat enum like adapter change
   SendMessage(m_hADAPTER, CB_SETCURSEL, (WPARAM)0, 0);
   ChangedAdapter();

   // select first entry from each combo
   SendMessage(m_hADAPTER, CB_SETCURSEL, (WPARAM)0, 0);
   SendMessage(m_hMODE,    CB_SETCURSEL, (WPARAM)0, 0);
   SendMessage(m_hDEVICE,  CB_SETCURSEL, (WPARAM)0, 0);
   SendMessage(m_hBACKFMT, CB_SETCURSEL, (WPARAM)0, 0);
   SendMessage(m_hADAPTERFMT, CB_SETCURSEL, (WPARAM)0, 0);

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

/**
 * Three helper function for combobox-convenience.
 */
void* GetSelectedItem(HWND hWnd) {
   WPARAM nI = (WPARAM)((int)(DWORD)SendMessage(hWnd,CB_GETCURSEL,0,0));
   return ((void*)SendMessage(hWnd,CB_GETITEMDATA,nI,0));
   }
/*----------------------------------------------------------------*/

void AddItem(HWND hWnd, char *ch, void *pData) {
   WPARAM nI = (WPARAM)((int)(DWORD)SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM)ch));
   SendMessage(hWnd,CB_SETITEMDATA, nI, (LPARAM)pData);
   }
/*----------------------------------------------------------------*/

bool ContainsString(HWND hWnd, char *ch) {
   int n = (int)SendMessage(hWnd, CB_GETCOUNT, 0, 0);
   char buffer[200];

   for(int nIndex=0; nIndex<n; nIndex++) {
      SendMessage(hWnd, CB_GETLBTEXT, (WPARAM)nIndex, (LPARAM)buffer);
      if (lstrcmp(buffer, ch) == 0)
         return true;
    }
   return false;
   }
/*----------------------------------------------------------------*/


/**
 * Ask the Comboboxes for the final settings.
 */
void ZFXD3DEnum::GetSelections(ZFXDEVICEINFO *pD, D3DDISPLAYMODE *dspmd,
                               D3DFORMAT *fmtA, D3DFORMAT *fmtB) {

   if (pD)
      memcpy(pD, GetSelectedItem(m_hDEVICE), sizeof(ZFXDEVICEINFO));
   if (fmtA)
      memcpy(fmtA, GetSelectedItem(m_hADAPTERFMT), sizeof(D3DFORMAT));
   if (fmtB)
      memcpy(fmtB, GetSelectedItem(m_hBACKFMT), sizeof(D3DFORMAT));

   if (dspmd) {
      D3DDISPLAYMODE *pDspmd = (D3DDISPLAYMODE*)GetSelectedItem(m_hMODE);
      // fullscreen mode
      if (pDspmd) memcpy(dspmd, pDspmd, sizeof(D3DDISPLAYMODE));
      // windowed mode
      else
         memcpy(dspmd, &m_dspmd, sizeof(D3DDISPLAYMODE));
      }
   } // GetSelections
/*----------------------------------------------------------------*/


/**
 * Call when adapter selection changed. This will reset device
 * combobox, list devices for new adapter, and call ChangedDevice().
 */
void ZFXD3DEnum::ChangedAdapter(void) {
   ZFXADAPTERINFO *pA=NULL;

   // delete content of device combobox
   SendMessage(m_hDEVICE, CB_RESETCONTENT, 0, 0);

   pA = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);

   for (UINT d=0; d<pA->nNumDevs; d++) {
      AddItem(m_hDEVICE, D3DDevTypeToString(pA->d3dDevs[d].
              d3dDevType), &pA->d3dDevs[d]);
     }
   SendMessage(m_hDEVICE, CB_SETCURSEL, (WPARAM)0, 0);
   
   // treat as if device slectio changed
   ChangedDevice();
   } // ChangedAdapter
/*----------------------------------------------------------------*/

/**
 * Call when device selection changed. This will reset radio button
 * states for windowed/fullscreen mode and call ChangedWindowMode().
 */
void ZFXD3DEnum::ChangedDevice(void) {
   ZFXDEVICEINFO *pD=NULL;
   bool           bWindowed=false,
                  bFullscreen=false;

   pD = (ZFXDEVICEINFO *)GetSelectedItem(m_hDEVICE);

   // check if windowed/fullscreen mode possible
   for (UINT c=0; c<pD->nNumCombo; c++) {
      if (pD->d3dCombo[c].bWindowed)
         bWindowed = true;
      else
         bFullscreen = true;
      }

   // active radio buttons accordingliy
   EnableWindow(m_hWND,  bWindowed);
   EnableWindow(m_hFULL, bFullscreen);

   if (!bWindowed && (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED))
      SendMessage(m_hFULL, BM_SETCHECK, BST_CHECKED, 0);

   // treat as if radio button changed
   ChangedWindowMode();
   } // ChangedDevice
/*----------------------------------------------------------------*/

/**
 * Call when window/fullscreen selection changed. Will relist adapter-
 * format and mode combobox and call ChangedAdapterFmt().
 */
void ZFXD3DEnum::ChangedWindowMode(void) {
   ZFXADAPTERINFO *pA=NULL;
   ZFXDEVICEINFO  *pD=NULL;
   ZFXCOMBOINFO   *pC=NULL;
   char            buffer[100];

   pA = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);
   pD = (ZFXDEVICEINFO  *)GetSelectedItem(m_hDEVICE);

   // clear'em out
   SendMessage(m_hADAPTERFMT, CB_RESETCONTENT, 0, 0);
   SendMessage(m_hMODE,       CB_RESETCONTENT, 0, 0);

   // windowed mode?
   if (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED) {
      // use current desktop format
      AddItem(m_hADAPTERFMT, D3DFormatToString(m_dspmd.Format), 
              &m_dspmd.Format);
      // use current desktop resolution
      sprintf(buffer, "%d x %d", m_dspmd.Width, m_dspmd.Height);
      SendMessage(m_hMODE, CB_ADDSTRING, 0, (LPARAM)buffer);

      EnableWindow(m_hADAPTERFMT, false);
      EnableWindow(m_hMODE, false);
      }
   else {
      SendMessage(m_hADAPTERFMT, CB_RESETCONTENT, 0, 0);
      SendMessage(m_hMODE, CB_RESETCONTENT, 0, 0);
      EnableWindow(m_hADAPTERFMT, true);
      EnableWindow(m_hMODE, true);

      // list all combos for this device
      for (UINT c=0; c<pD->nNumCombo; c++) {
         pC = &pD->d3dCombo[c];

         if (!ContainsString(m_hADAPTERFMT, D3DFormatToString(pC->fmtAdapter)))
            AddItem(m_hADAPTERFMT, 
                    D3DFormatToString(pC->fmtAdapter), 
                    &pC->fmtAdapter);
         } // for [combos]
      }

   // select first item each
   SendMessage(m_hADAPTERFMT, CB_SETCURSEL, (WPARAM)0, 0);
   SendMessage(m_hMODE,       CB_SETCURSEL, (WPARAM)0, 0);

   // treat as if adapter format changed
   ChangedAdapterFmt();
   } // ChangedWindowMode
/*----------------------------------------------------------------*/

/**
 * Call when adapter format selection changed. Will relist mode and
 * backbuffer-format combobox.
 */
void ZFXD3DEnum::ChangedAdapterFmt(void) {
   ZFXADAPTERINFO *pA=NULL;
   ZFXDEVICEINFO  *pD=NULL;
   ZFXCOMBOINFO   *pC=NULL;
   D3DDISPLAYMODE *dpsmd=NULL;
   D3DFORMAT      *pFmt=NULL;
   char            buffer[200];
   bool            bWindowed;

   pA   = (ZFXADAPTERINFO *)GetSelectedItem(m_hADAPTER);
   pD   = (ZFXDEVICEINFO *)GetSelectedItem(m_hDEVICE);
   pFmt = (D3DFORMAT *)GetSelectedItem(m_hADAPTERFMT);
   
   bWindowed = (SendMessage(m_hWND,BM_GETCHECK,0,0)==BST_CHECKED);
   SendMessage(m_hBACKFMT, CB_RESETCONTENT, 0, 0);

   // windowed mode?
   if (!bWindowed) {
      SendMessage(m_hMODE, CB_RESETCONTENT, 0, 0);

      // loop through all available modes
      for (UINT m=0; m<pA->nNumModes; m++) {
         dpsmd = &pA->d3ddspmd[m];
         sprintf(buffer, "%d x %d", dpsmd->Width, dpsmd->Height);
         if (!ContainsString(m_hMODE, buffer)) {
            AddItem(m_hMODE, buffer, &pA->d3ddspmd[m]);
            }
         } // for [modes]

      // set backbuffer format to adapter format
      AddItem(m_hBACKFMT,D3DFormatToString(*pFmt),&(*pFmt));

      SendMessage(m_hMODE, CB_SETCURSEL, (WPARAM)0, 0);
      } // [!windowed]
   else {
      for (UINT c=0; c<pD->nNumCombo; c++) {
         pC = &pD->d3dCombo[c];

         // if same window mode and adapter format
         if ((bWindowed == pC->bWindowed) && 
             (*pFmt == pC->fmtAdapter) ) {
            if (!ContainsString(m_hBACKFMT, 
                D3DFormatToString(pC->fmtAdapter)))
                AddItem(m_hBACKFMT, 
                        D3DFormatToString(pC->fmtBackBuffer), 
                        &pC->fmtBackBuffer);
            }
         }
      }

   SendMessage(m_hBACKFMT, CB_SETCURSEL, (WPARAM)0, 0);
   } // ChangedAdapterFmt
/*----------------------------------------------------------------*/

static int __cdecl SortModesCallback(const void* arg1, const void* arg2) {
   D3DDISPLAYMODE* pdm1 = (D3DDISPLAYMODE*)arg1;
   D3DDISPLAYMODE* pdm2 = (D3DDISPLAYMODE*)arg2;
   
   if (pdm1->Width > pdm2->Width)
      return 1;
   if (pdm1->Width < pdm2->Width)
      return -1;
   if (pdm1->Height > pdm2->Height)
      return 1;
   if (pdm1->Height < pdm2->Height)
      return -1;
   if (pdm1->Format > pdm2->Format)
      return 1;
   if (pdm1->Format < pdm2->Format)

⌨️ 快捷键说明

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